Skip to content

Commit fb529dd

Browse files
authored
fix: Merge pull request #17 from salesforcecli/ew/qa
@W-22796074 qa
2 parents cc5d939 + 1550829 commit fb529dd

9 files changed

Lines changed: 7863 additions & 11251 deletions

File tree

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,4 @@ All rights reserved.
203203
distributed under the License is distributed on an "AS IS" BASIS,
204204
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205205
See the License for the specific language governing permissions and
206-
limitations under the License.
206+
limitations under the License.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# plugin-data-setup-transfer
22

3-
[![NPM](https://img.shields.io/npm/v/plugin-data-setup-transfer.svg?label=plugin-data-setup-transfer)](https://www.npmjs.com/package/plugin-data-setup-transfer) [![Downloads/week](https://img.shields.io/npm/dw/plugin-data-setup-transfer.svg)](https://npmjs.org/package/plugin-data-setup-transfer) [![License](https://img.shields.io/badge/License-BSD%203--Clause-brightgreen.svg)](https://raw.githubusercontent.com/salesforcecli/plugin-data-setup-transfer/main/LICENSE.txt)
3+
[![NPM](https://img.shields.io/npm/v/plugin-data-setup-transfer.svg?label=plugin-data-setup-transfer)](https://www.npmjs.com/package/plugin-data-setup-transfer) [![Downloads/week](https://img.shields.io/npm/dw/plugin-data-setup-transfer.svg)](https://npmjs.org/package/plugin-data-setup-transfer) [![License](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://opensource.org/license/apache-2-0)
44

55

66
This plugin is bundled with the [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli). For more information on the CLI, read the [getting started guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm).

command-snapshot.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"alias": [],
4+
"command": "data:setup:transfer",
5+
"flagAliases": [],
6+
"flagChars": ["e", "i", "o", "s", "v", "x"],
7+
"flags": [
8+
"api-version",
9+
"definition-identifier",
10+
"extended-definition-file",
11+
"filter-value",
12+
"flags-dir",
13+
"json",
14+
"source-org",
15+
"target-org",
16+
"version"
17+
],
18+
"plugin": "plugin-data-setup-transfer"
19+
}
20+
]

package.json

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@
1111
"@oclif/plugin-command-snapshot": "^5.3.22",
1212
"@salesforce/cli-plugins-testkit": "^5.3.58",
1313
"@salesforce/dev-scripts": "^11.0.4",
14-
"@types/mocha": "^10.0.10",
15-
"@types/node": "^25.9.1",
1614
"eslint-plugin-sf-plugin": "^1.20.33",
17-
"husky": "^9.1.7",
1815
"oclif": "^4.23.8",
1916
"ts-node": "^10.9.2",
20-
"typescript": "^6.0.3",
21-
"wireit": "^0.14.12"
17+
"typescript": "^5.9.3"
2218
},
2319
"engines": {
2420
"node": ">=18.0.0"
@@ -38,17 +34,24 @@
3834
"sfdx",
3935
"sfdx-plugin"
4036
],
41-
"license": "BSD-3-Clause",
37+
"license": "Apache-2.0",
4238
"oclif": {
4339
"commands": "./lib/commands",
4440
"bin": "sf",
4541
"topicSeparator": " ",
4642
"devPlugins": [
47-
"@oclif/plugin-help"
43+
"@oclif/plugin-help",
44+
"@oclif/plugin-command-snapshot"
4845
],
4946
"topics": {
50-
"hello": {
51-
"description": "Commands to say hello."
47+
"data": {
48+
"description": "Manage records in your org.",
49+
"subtopics": {
50+
"setup": {
51+
"description": "Retrieve setup data from one org and deploy it to another."
52+
}
53+
},
54+
"external": true
5255
}
5356
},
5457
"flexibleTaxonomy": true
@@ -59,14 +62,15 @@
5962
"clean-all": "sf-clean all",
6063
"compile": "wireit",
6164
"docs": "sf-docs",
65+
"fix-license": "eslint src test --fix --rule \"header/header: [2]\"",
6266
"format": "wireit",
6367
"link-check": "wireit",
6468
"lint": "wireit",
65-
"postinstall": "yarn husky install",
6669
"postpack": "sf-clean --ignore-signing-artifacts",
6770
"prepack": "sf-prepack",
71+
"prepare": "sf-install",
6872
"test": "wireit",
69-
"test:nuts": "nyc mocha \"**/*.nut.ts\" --slow 4500 --timeout 600000 --parallel",
73+
"test:nuts": "echo 'No NUT tests'",
7074
"test:only": "wireit",
7175
"version": "oclif readme"
7276
},
@@ -133,8 +137,7 @@
133137
"test:only": {
134138
"command": "nyc mocha \"test/**/*.test.ts\"",
135139
"env": {
136-
"FORCE_COLOR": "2",
137-
"TS_NODE_PROJECT": "test/tsconfig.json"
140+
"FORCE_COLOR": "2"
138141
},
139142
"files": [
140143
"test/**/*.ts",
@@ -176,7 +179,7 @@
176179
"output": []
177180
},
178181
"link-check": {
179-
"command": "node -e \"process.exit(process.env.CI ? 0 : 1)\" || linkinator \"**/*.md\" --skip \"CHANGELOG.md|node_modules|test/|confluence.internal.salesforce.com|my.salesforce.com|%s\" --markdown --retry --directory-listing --verbosity error",
182+
"command": "node -e \"process.exit(process.env.CI ? 0 : 1)\" || linkinator \"**/*.md\" --skip \"CHANGELOG.md|node_modules|test/|confluence.internal.salesforce.com|my.salesforce.com|localhost|%s\" --markdown --retry --directory-listing --verbosity error",
180183
"files": [
181184
"./*.md",
182185
"./!(CHANGELOG).md",

schemas/data-setup-transfer.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$ref": "#/definitions/SetupTransferResult",
4+
"definitions": {
5+
"SetupTransferResult": {
6+
"type": "object",
7+
"properties": {
8+
"success": {
9+
"type": "boolean"
10+
},
11+
"exportResponse": {},
12+
"importResponse": {}
13+
},
14+
"required": ["success", "exportResponse", "importResponse"],
15+
"additionalProperties": false
16+
}
17+
}
18+
}

src/commands/data/setup/transfer.ts

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -269,39 +269,19 @@ export default class SetupTransfer extends SfCommand<SetupTransferResult> {
269269
this.spinner.status = messages.getMessage('info.callingExportApi');
270270
const sourceApiVersion = sourceConnection.version;
271271
const exportApiPath = `/services/data/v${sourceApiVersion}/connect/industries/setup/dataset/actions/export`;
272-
const instanceUrl = sourceConnection.instanceUrl ?? '';
273-
const fullUrl = `${instanceUrl}${exportApiPath}`;
274272

275-
const exportAbort = new AbortController();
276-
const exportTimeoutId = setTimeout(() => exportAbort.abort(), SetupTransfer.HTTP_TIMEOUT_MS);
277-
let httpResponse: Response;
278-
try {
279-
httpResponse = await fetch(fullUrl, {
273+
const exportResponse = await sourceConnection.request<ExportResponse>(
274+
{
280275
method: 'POST',
276+
url: exportApiPath,
277+
body: JSON.stringify(exportPayload),
281278
headers: {
282279
'Content-Type': 'application/json',
283-
Authorization: `Bearer ${sourceConnection.accessToken ?? ''}`,
284280
},
285-
body: JSON.stringify(exportPayload),
286-
signal: exportAbort.signal,
287-
});
288-
} finally {
289-
clearTimeout(exportTimeoutId);
290-
}
291-
292-
const rawBody = await httpResponse.text();
293-
294-
if (!httpResponse.ok) {
295-
throw new Error(`Export API returned ${httpResponse.status}: ${rawBody}`);
296-
}
297-
298-
// eslint-disable-next-line no-control-regex
299-
const sanitizedBody = rawBody.replace(/[\x00-\x1F\x7F]/g, (ch) =>
300-
ch === '\n' || ch === '\r' || ch === '\t' ? ch : ''
281+
},
282+
{ timeout: SetupTransfer.HTTP_TIMEOUT_MS }
301283
);
302284

303-
const exportResponse = JSON.parse(sanitizedBody) as ExportResponse;
304-
305285
const errors = exportResponse.errors as Array<{ message?: string }> | undefined;
306286
if (exportResponse.isSuccess === false) {
307287
const errorDetails = errors?.map((e) => e.message ?? JSON.stringify(e)).join('\n') ?? 'Unknown error';

test/commands/data/setup/transfer.test.ts

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,12 @@ describe('data setup transfer', () => {
4040
sfCommandStubs = stubSfCommandUx($$.SANDBOX);
4141
await $$.stubAuths(mockSourceOrg, mockTargetOrg);
4242

43-
// Stub fetch for export API
44-
$$.SANDBOX.stub(global, 'fetch').resolves({
45-
ok: true,
46-
status: 200,
47-
text: async () => JSON.stringify(mockExportResponse),
48-
} as Response);
49-
50-
// Stub connection.request for import API
51-
const targetConnection = await mockTargetOrg.getConnection();
52-
targetConnection.request = $$.SANDBOX.stub().resolves(mockImportResponse);
43+
$$.fakeConnectionRequest = (request) => {
44+
if (typeof request === 'string' || (request as { url: string }).url.includes('/export')) {
45+
return Promise.resolve(mockExportResponse);
46+
}
47+
return Promise.resolve(mockImportResponse);
48+
};
5349
});
5450

5551
afterEach(() => {
@@ -171,21 +167,15 @@ describe('data setup transfer', () => {
171167

172168
describe('error handling', () => {
173169
it('throws error when export API returns error', async () => {
174-
$$.SANDBOX.restore();
175-
await $$.stubAuths(mockSourceOrg, mockTargetOrg);
176-
177-
$$.SANDBOX.stub(global, 'fetch').resolves({
178-
ok: true,
179-
status: 200,
180-
text: async () =>
181-
JSON.stringify({
170+
$$.fakeConnectionRequest = (request) => {
171+
if (typeof request === 'string' || (request as { url: string }).url.includes('/export')) {
172+
return Promise.resolve({
182173
isSuccess: false,
183174
errors: [{ message: 'Invalid definition identifier' }],
184-
}),
185-
} as Response);
186-
187-
const targetConnection = await mockTargetOrg.getConnection();
188-
targetConnection.request = $$.SANDBOX.stub().resolves(mockImportResponse);
175+
});
176+
}
177+
return Promise.resolve(mockImportResponse);
178+
};
189179

190180
try {
191181
await SetupTransfer.run([
@@ -205,18 +195,13 @@ describe('data setup transfer', () => {
205195
}
206196
});
207197

208-
it('throws error when export API returns non-200 status', async () => {
209-
$$.SANDBOX.restore();
210-
await $$.stubAuths(mockSourceOrg, mockTargetOrg);
211-
212-
$$.SANDBOX.stub(global, 'fetch').resolves({
213-
ok: false,
214-
status: 400,
215-
text: async () => 'Bad Request',
216-
} as Response);
217-
218-
const targetConnection = await mockTargetOrg.getConnection();
219-
targetConnection.request = $$.SANDBOX.stub().resolves(mockImportResponse);
198+
it('throws error when export API request fails', async () => {
199+
$$.fakeConnectionRequest = (request) => {
200+
if (typeof request === 'string' || (request as { url: string }).url.includes('/export')) {
201+
return Promise.reject(new Error('REQUEST_FAILED: Bad Request'));
202+
}
203+
return Promise.resolve(mockImportResponse);
204+
};
220205

221206
try {
222207
await SetupTransfer.run([
@@ -231,7 +216,7 @@ describe('data setup transfer', () => {
231216
]);
232217
expect.fail('Should have thrown an error');
233218
} catch (error) {
234-
expect((error as Error).message).to.include('Export API returned 400');
219+
expect((error as Error).message).to.include('REQUEST_FAILED');
235220
}
236221
});
237222
});

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "@salesforce/dev-config/tsconfig-strict-esm",
33
"compilerOptions": {
44
"outDir": "lib",
5-
"rootDir": "src"
5+
"rootDir": "src",
6+
"skipLibCheck": true
67
},
78
"include": ["./src/**/*.ts"]
89
}

0 commit comments

Comments
 (0)