diff --git a/src/config/configStore.ts b/src/config/configStore.ts index 4529dda4e0..010f1ea2c4 100644 --- a/src/config/configStore.ts +++ b/src/config/configStore.ts @@ -5,7 +5,7 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { AsyncOptionalCreatable, cloneJson } from '@salesforce/kit'; +import { AsyncOptionalCreatable } from '@salesforce/kit'; import { entriesOf, isPlainObject } from '@salesforce/ts-types'; import { definiteEntriesOf, definiteValuesOf, isJsonMap, isString, JsonMap, Optional } from '@salesforce/ts-types'; import { Crypto } from '../crypto/crypto'; @@ -95,7 +95,7 @@ export abstract class BaseConfigStore< if (this.hasEncryption() && decrypt) { if (isJsonMap(rawValue)) { - return this.recursiveDecrypt(cloneJson(rawValue), key); + return this.recursiveDecrypt(structuredClone(rawValue), key); } else if (this.isCryptoKey(key)) { return this.decrypt(rawValue) as P[K] | ConfigValue; } @@ -219,7 +219,7 @@ export abstract class BaseConfigStore< */ public getContents(decrypt = false): Readonly

{ if (this.hasEncryption() && decrypt) { - return this.recursiveDecrypt(cloneJson(this.contents?.value ?? {})) as P; + return this.recursiveDecrypt(structuredClone(this.contents?.value ?? {})) as P; } return this.contents?.value ?? ({} as P); } diff --git a/src/org/authInfo.ts b/src/org/authInfo.ts index ed837cfedd..d0a1fc6e17 100644 --- a/src/org/authInfo.ts +++ b/src/org/authInfo.ts @@ -11,7 +11,7 @@ import { resolve as pathResolve } from 'node:path'; import * as os from 'node:os'; import * as fs from 'node:fs'; import { Record as RecordType } from 'jsforce'; -import { AsyncOptionalCreatable, cloneJson, env, isEmpty, parseJson, parseJsonMap } from '@salesforce/kit'; +import { AsyncOptionalCreatable, env, isEmpty, parseJson, parseJsonMap } from '@salesforce/kit'; import { AnyJson, asString, @@ -847,7 +847,7 @@ export class AuthInfo extends AsyncOptionalCreatable { let authConfig: AuthFields; if (options) { - options = cloneJson(options); + options = structuredClone(options); if (this.isTokenOptions(options)) { authConfig = options; diff --git a/src/schema/validator.ts b/src/schema/validator.ts index ab4baa6078..b249006c2c 100644 --- a/src/schema/validator.ts +++ b/src/schema/validator.ts @@ -110,7 +110,7 @@ export class SchemaValidator { // AJV will modify the original json object. We need to make a clone of the // json to keep this backwards compatible with JSEN functionality - const jsonClone: T = JSON.parse(JSON.stringify(json)) as T; + const jsonClone = structuredClone(json); const valid = validate(jsonClone); diff --git a/test/unit/config/configTest.ts b/test/unit/config/configTest.ts index a732a117ec..8519484d9b 100644 --- a/test/unit/config/configTest.ts +++ b/test/unit/config/configTest.ts @@ -11,7 +11,7 @@ import * as fs from 'node:fs'; import { stubMethod } from '@salesforce/ts-sinon'; -import { ensureString, JsonMap } from '@salesforce/ts-types'; +import { ensureString } from '@salesforce/ts-types'; import { expect } from 'chai'; import * as lockfileLib from 'proper-lockfile'; import { Config, ConfigPropertyMeta } from '../../../src/config/config'; @@ -23,8 +23,6 @@ import { shouldThrowSync, TestContext } from '../../../src/testSetup'; const configFileContentsString = '{"target-dev-hub": "configTest_devhub","target-org": "configTest_default"}'; const configFileContentsJson = { 'target-dev-hub': 'configTest_devhub', 'target-org': 'configTest_default' }; -const clone = (obj: JsonMap) => JSON.parse(JSON.stringify(obj)); - describe('Config', () => { const $$ = new TestContext(); @@ -99,7 +97,7 @@ describe('Config', () => { it('calls Config.write with updated file contents', async () => { const writeStub = stubMethod($$.SANDBOX, fs.promises, 'writeFile'); - const expectedFileContents = clone(configFileContentsJson); + const expectedFileContents = structuredClone(configFileContentsJson); const newUsername = 'updated_val'; expectedFileContents['target-org'] = newUsername; @@ -109,7 +107,7 @@ describe('Config', () => { }); it('calls Config.write with deleted file contents', async () => { - const expectedFileContents = clone(configFileContentsJson); + const expectedFileContents = structuredClone(configFileContentsJson); const newUsername = 'updated_val'; expectedFileContents['target-org'] = newUsername; @@ -236,8 +234,8 @@ describe('Config', () => { stubMethod($$.SANDBOX, fs.promises, 'stat').resolves({ mtimeNs: BigInt(new Date().valueOf() - 1_000 * 60 * 5) }); const writeStub = stubMethod($$.SANDBOX, fs.promises, 'writeFile'); - const expectedFileContents = clone(configFileContentsJson); - delete expectedFileContents['target-org']; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { 'target-org': deleteThis, ...expectedFileContents } = structuredClone(configFileContentsJson); const config = await Config.create({ isGlobal: false }); config.unset('target-org'); diff --git a/test/unit/messagesTest.ts b/test/unit/messagesTest.ts index fa53054305..bf894a4cb4 100644 --- a/test/unit/messagesTest.ts +++ b/test/unit/messagesTest.ts @@ -10,7 +10,6 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { EOL } from 'node:os'; -import { cloneJson } from '@salesforce/kit'; import { assert, expect } from 'chai'; import { SinonStub } from 'sinon'; import { Messages } from '../../src/messages'; @@ -30,8 +29,8 @@ describe('Messages', () => { msgMap.set('msg1', testMessages.msg1); msgMap.set('msg1.actions', testMessages.msg2); msgMap.set('msg2', testMessages.msg2); - msgMap.set('msg3', cloneJson(testMessages)); - msgMap.get('msg3').msg3 = cloneJson(testMessages); + msgMap.set('msg3', structuredClone(testMessages)); + msgMap.get('msg3').msg3 = structuredClone(testMessages); msgMap.set('manyMsgs', testMessages.manyMsgs); describe('getMessage', () => { diff --git a/test/unit/org/authInfoTest.ts b/test/unit/org/authInfoTest.ts index cbb41d5972..324a6d9a04 100644 --- a/test/unit/org/authInfoTest.ts +++ b/test/unit/org/authInfoTest.ts @@ -12,7 +12,7 @@ import * as pathImport from 'node:path'; import * as dns from 'node:dns'; import * as jwt from 'jsonwebtoken'; -import { cloneJson, env, includes } from '@salesforce/kit'; +import { env, includes } from '@salesforce/kit'; import { spyMethod, stubMethod } from '@salesforce/ts-sinon'; import { AnyJson, getJsonMap, JsonMap, toJsonMap } from '@salesforce/ts-types'; import { expect } from 'chai'; @@ -335,7 +335,7 @@ describe('AuthInfo', () => { loginUrl: testOrg.loginUrl, privateKey: testOrg.privateKey, }; - const jwtConfigClone = cloneJson(jwtConfig); + const jwtConfigClone = structuredClone(jwtConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl, @@ -469,7 +469,7 @@ describe('AuthInfo', () => { loginUrl: testOrg.loginUrl, privateKey: testOrg.privateKey, }; - const jwtConfigClone = cloneJson(jwtConfig); + const jwtConfigClone = structuredClone(jwtConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl, @@ -535,7 +535,7 @@ describe('AuthInfo', () => { refreshToken: testOrg.refreshToken, loginUrl: testOrg.loginUrl, }; - const refreshTokenConfigClone = cloneJson(refreshTokenConfig); + const refreshTokenConfigClone = structuredClone(refreshTokenConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl, @@ -590,7 +590,7 @@ describe('AuthInfo', () => { loginUrl: testOrg.loginUrl, username: testOrg.username, }; - const refreshTokenConfigClone = cloneJson(refreshTokenConfig); + const refreshTokenConfigClone = structuredClone(refreshTokenConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl, @@ -643,7 +643,7 @@ describe('AuthInfo', () => { refreshToken: testOrg.refreshToken, loginUrl: testOrg.loginUrl, }; - const refreshTokenConfigClone = cloneJson(refreshTokenConfig); + const refreshTokenConfigClone = structuredClone(refreshTokenConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl, @@ -786,7 +786,7 @@ describe('AuthInfo', () => { authCode: testOrg.authcode, loginUrl: testOrg.loginUrl, }; - const authCodeConfigClone = cloneJson(authCodeConfig); + const authCodeConfigClone = structuredClone(authCodeConfig); const authResponse = { access_token: testOrg.accessToken, instance_url: testOrg.instanceUrl,