From 432f5857b23e4505380301000ffb43c5f9eecfba Mon Sep 17 00:00:00 2001 From: mshanemc Date: Thu, 27 Jun 2024 17:41:04 -0500 Subject: [PATCH 1/3] feat: guarantee that FileResponseSuccess will always have a filepath --- src/client/deployMessages.ts | 2 +- src/client/metadataApiRetrieve.ts | 9 +++++---- src/client/types.ts | 4 ++-- test/client/metadataApiDeploy.test.ts | 28 +++++++++++++-------------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/client/deployMessages.ts b/src/client/deployMessages.ts index c86568ba79..799eda9780 100644 --- a/src/client/deployMessages.ts +++ b/src/client/deployMessages.ts @@ -73,7 +73,7 @@ const shouldWalkContent = (component: SourceComponent): boolean => export const createResponses = (component: SourceComponent, responseMessages: DeployMessage[]): FileResponse[] => responseMessages.flatMap((message): FileResponse[] => { const state = getState(message); - const base = { fullName: component.fullName, type: component.type.name }; + const base = { fullName: component.fullName, type: component.type.name } as const; if (state === ComponentStatus.Failed) { return [{ ...base, state, ...parseDeployDiagnostic(component, message) } satisfies FileResponseFailure]; diff --git a/src/client/metadataApiRetrieve.ts b/src/client/metadataApiRetrieve.ts index c9f7b7beed..4f0cc48c97 100644 --- a/src/client/metadataApiRetrieve.ts +++ b/src/client/metadataApiRetrieve.ts @@ -16,6 +16,7 @@ import { AsyncResult, ComponentStatus, FileResponse, + FileResponseSuccess, MetadataApiRetrieveStatus, MetadataTransferResult, PackageOptions, @@ -88,20 +89,20 @@ export class RetrieveResult implements MetadataTransferResult { // construct successes for (const retrievedComponent of this.components.getSourceComponents()) { const { fullName, type, xml } = retrievedComponent; - const baseResponse: FileResponse = { + const baseResponse = { fullName, type: type.name, state: this.localComponents.has(retrievedComponent) ? ComponentStatus.Changed : ComponentStatus.Created, - }; + } as const; if (!type.children || Object.values(type.children.types).some((t) => t.unaddressableWithoutParent)) { for (const filePath of retrievedComponent.walkContent()) { - this.fileResponses.push(Object.assign({}, baseResponse, { filePath })); + this.fileResponses.push({ ...baseResponse, filePath } satisfies FileResponseSuccess); } } if (xml) { - this.fileResponses.push(Object.assign({}, baseResponse, { filePath: xml })); + this.fileResponses.push({ ...baseResponse, filePath: xml } satisfies FileResponseSuccess); } } diff --git a/src/client/types.ts b/src/client/types.ts index ca552a3cd7..e88bbb6f6f 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -55,9 +55,9 @@ type FileResponseBase = { filePath?: string; }; -export type FileResponseSuccess = { +export type FileResponseSuccess = Required & { state: Exclude; -} & FileResponseBase; +}; export type FileResponseFailure = { state: ComponentStatus.Failed; diff --git a/test/client/metadataApiDeploy.test.ts b/test/client/metadataApiDeploy.test.ts index ed8f96bbfe..621babe757 100644 --- a/test/client/metadataApiDeploy.test.ts +++ b/test/client/metadataApiDeploy.test.ts @@ -7,7 +7,7 @@ import { basename, join, sep } from 'node:path'; import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup'; import chai, { assert, expect } from 'chai'; -import { AnyJson, getString } from '@salesforce/ts-types'; +import { AnyJson, ensureString, getString } from '@salesforce/ts-types'; import { Lifecycle, Messages, PollingClient, StatusResult } from '@salesforce/core'; import { Duration } from '@salesforce/kit'; import deepEqualInAnyOrder = require('deep-equal-in-any-order'); @@ -548,13 +548,13 @@ describe('MetadataApiDeploy', () => { fullName, type: type.name, state: ComponentStatus.Changed, - filePath: content, + filePath: ensureString(content), }, { fullName, type: type.name, state: ComponentStatus.Changed, - filePath: xml, + filePath: ensureString(xml), }, ]; @@ -584,13 +584,13 @@ describe('MetadataApiDeploy', () => { fullName, type: type.name, state: ComponentStatus.Created, - filePath: content, + filePath: ensureString(content), }, { fullName, type: type.name, state: ComponentStatus.Created, - filePath: xml, + filePath: ensureString(xml), }, ]; @@ -620,13 +620,13 @@ describe('MetadataApiDeploy', () => { fullName, type: type.name, state: ComponentStatus.Deleted, - filePath: content, + filePath: ensureString(content), }, { fullName, type: type.name, state: ComponentStatus.Deleted, - filePath: xml, + filePath: ensureString(xml), }, ]; @@ -695,13 +695,13 @@ describe('MetadataApiDeploy', () => { fullName, type: type.name, state: ComponentStatus.Unchanged, - filePath: content, + filePath: ensureString(content), }, { fullName, type: type.name, state: ComponentStatus.Unchanged, - filePath: xml, + filePath: ensureString(xml), }, ]; @@ -1031,19 +1031,19 @@ describe('MetadataApiDeploy', () => { fullName: DECOMPOSED_CHILD_COMPONENT_1.fullName, type: DECOMPOSED_CHILD_COMPONENT_1.type.name, state: ComponentStatus.Changed, - filePath: DECOMPOSED_CHILD_COMPONENT_1.xml, + filePath: ensureString(DECOMPOSED_CHILD_COMPONENT_1.xml), }, { fullName: DECOMPOSED_CHILD_COMPONENT_2.fullName, type: DECOMPOSED_CHILD_COMPONENT_2.type.name, state: ComponentStatus.Changed, - filePath: DECOMPOSED_CHILD_COMPONENT_2.xml, + filePath: ensureString(DECOMPOSED_CHILD_COMPONENT_2.xml), }, { fullName: component.fullName, type: component.type.name, state: ComponentStatus.Changed, - filePath: component.xml, + filePath: ensureString(component.xml), }, ]; @@ -1074,13 +1074,13 @@ describe('MetadataApiDeploy', () => { fullName: component.fullName, type: component.type.name, state: ComponentStatus.Deleted, - filePath: component.content, + filePath: ensureString(component.content), }, { fullName: component.fullName, type: component.type.name, state: ComponentStatus.Deleted, - filePath: component.xml, + filePath: ensureString(component.xml), }, ]; From 04afb376174599a0c4cb92e9df1f67d182657db2 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Thu, 27 Jun 2024 17:45:05 -0500 Subject: [PATCH 2/3] test: mocks follow real life --- test/client/metadataApiRetrieve.test.ts | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/client/metadataApiRetrieve.test.ts b/test/client/metadataApiRetrieve.test.ts index 5ae15f0cf7..4951eeeaca 100644 --- a/test/client/metadataApiRetrieve.test.ts +++ b/test/client/metadataApiRetrieve.test.ts @@ -11,7 +11,7 @@ import { assert, expect } from 'chai'; import chai = require('chai'); import deepEqualInAnyOrder = require('deep-equal-in-any-order'); import { SinonStub } from 'sinon'; -import { getString } from '@salesforce/ts-types'; +import { ensureString, getString } from '@salesforce/ts-types'; import fs from 'graceful-fs'; import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup'; import { @@ -549,14 +549,14 @@ hY2thZ2VkL3BhY2thZ2UueG1sUEsFBgAAAAADAAMA7QAAAJoCAAAAAA==`; const result = new RetrieveResult(apiStatus as MetadataApiRetrieveStatus, retrievedSet, retrievedSet); const responses = result.getFileResponses(); - const baseResponse: FileResponse = { + const baseResponse = { state: ComponentStatus.Changed, fullName: component.fullName, type: component.type.name, - }; + } as const; const expected: FileResponse[] = [ - Object.assign({}, baseResponse, { filePath: component.content }), - Object.assign({}, baseResponse, { filePath: component.xml }), + { ...baseResponse, filePath: ensureString(component.content) }, + { ...baseResponse, filePath: ensureString(component.xml) }, ]; expect(responses).to.deep.equal(expected); @@ -572,20 +572,20 @@ hY2thZ2VkL3BhY2thZ2UueG1sUEsFBgAAAAADAAMA7QAAAJoCAAAAAA==`; const result = new RetrieveResult(apiStatus as MetadataApiRetrieveStatus, retrievedSet, localSet); const responses = result.getFileResponses(); - const baseResponse: FileResponse = { + const baseResponse = { state: ComponentStatus.Changed, fullName: component.fullName, type: component.type.name, - }; + } as const; // Since the DECOMPOSED_COMPONENT was in the retrieved ComponentSet but // not the local source ComponentSet it should have a state of 'Created' // rather than 'Changed'. const expected: FileResponse[] = [ - Object.assign({}, baseResponse, { filePath: component.content }), - Object.assign({}, baseResponse, { filePath: component.xml }), + { ...baseResponse, filePath: ensureString(component.content) }, + { ...baseResponse, filePath: ensureString(component.xml) }, { fullName: DECOMPOSED_COMPONENT.fullName, - filePath: DECOMPOSED_COMPONENT.xml, + filePath: ensureString(DECOMPOSED_COMPONENT.xml), state: ComponentStatus.Created, type: DECOMPOSED_COMPONENT.type.name, }, @@ -646,7 +646,7 @@ hY2thZ2VkL3BhY2thZ2UueG1sUEsFBgAAAAADAAMA7QAAAJoCAAAAAA==`; state: ComponentStatus.Changed, fullName: successComponent.fullName, type: successComponent.type.name, - filePath: successComponent.xml, + filePath: ensureString(successComponent.xml), }, ]; @@ -695,7 +695,7 @@ hY2thZ2VkL3BhY2thZ2UueG1sUEsFBgAAAAADAAMA7QAAAJoCAAAAAA==`; state: ComponentStatus.Changed, fullName: component.fullName, type: component.type.name, - filePath: component.xml, + filePath: ensureString(component.xml), }, ]; @@ -721,7 +721,7 @@ hY2thZ2VkL3BhY2thZ2UueG1sUEsFBgAAAAADAAMA7QAAAJoCAAAAAA==`; state: ComponentStatus.Changed, fullName: component.fullName, type: component.type.name, - filePath: component.content, + filePath: ensureString(component.content), }, ]; From 24f4f6fb3dda5cc87f4e7901b83725ccc411d758 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Thu, 27 Jun 2024 17:53:44 -0500 Subject: [PATCH 3/3] chore: bump deps for xnuts --- package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 6e03e3ffce..691fca30ae 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@salesforce/core": "^8.0.3", + "@salesforce/core": "^8.1.0", "@salesforce/kit": "^3.1.6", "@salesforce/ts-types": "^2.0.10", "fast-levenshtein": "^3.0.0", @@ -39,7 +39,7 @@ "proxy-agent": "^6.4.0" }, "devDependencies": { - "@jsforce/jsforce-node": "^3.2.0", + "@jsforce/jsforce-node": "^3.2.1", "@salesforce/cli-plugins-testkit": "^5.3.16", "@salesforce/dev-scripts": "^10.2.2", "@types/deep-equal-in-any-order": "^1.0.1", diff --git a/yarn.lock b/yarn.lock index 86cebf8b9f..094c0d87c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -502,10 +502,10 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@jsforce/jsforce-node@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.2.0.tgz#4b104613fc9bb74e0e38d2c00936ea2b228ba73a" - integrity sha512-3GjWNgWs0HFajVhIhwvBPb0B45o500wTBNEBYxy8XjeeRra+qw8A9xUrfVU7TAGev8kXuKhjJwaTiSzThpEnew== +"@jsforce/jsforce-node@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.2.1.tgz#00fab05919e0cbe91ae4d873377e56cfbc087b98" + integrity sha512-hjmZQbYVikm6ATmaErOp5NaKR2VofNZsrcGGHrdbGA+bAgpfg/+MA/HzRTb8BvYyPDq3RRc5A8Yk8gx9Vtcrxg== dependencies: "@sindresorhus/is" "^4" "@types/node" "^18.15.3" @@ -564,12 +564,12 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.1" -"@salesforce/core@^8.0.3": - version "8.0.3" - resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.0.3.tgz#8b25ce46100baef0a8e731b42d373edf508ab144" - integrity sha512-HirswUFGQIF5Ipaa+5l3kulBOf3L25Z3fzf5QqEI4vOxgBKN2bEdKHCA/PROufi3/ejFstiXcn9/jfgyjDdBqA== +"@salesforce/core@^8.0.3", "@salesforce/core@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.1.0.tgz#8ee25acdacf9d70a6249907a2fe3503461f18766" + integrity sha512-oItr8cdeMe67glJN3dP1Gh/kasD0DUT6S6RfcLTH32wwuZNQAwMXNgBOCvlskr8nxPZ+YSSw7CVuqYMUmCtUXA== dependencies: - "@jsforce/jsforce-node" "^3.2.0" + "@jsforce/jsforce-node" "^3.2.1" "@salesforce/kit" "^3.1.6" "@salesforce/schemas" "^1.9.0" "@salesforce/ts-types" "^2.0.10"