@squiz/dxp-cli-next 5.26.0 → 5.27.0-develop.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/job-runner/job/uploadJob/uploadJob.js +4 -3
- package/lib/migration/next/next.js +15 -1
- package/lib/migration/next/next.spec.js +23 -0
- package/lib/migration/settings/settings.js +16 -1
- package/lib/migration/settings/settings.spec.js +56 -0
- package/lib/migration/types/nextStage.types.d.ts +4 -0
- package/lib/migration/types/settings.types.d.ts +5 -0
- package/lib/migration/utils/index.d.ts +1 -0
- package/lib/migration/utils/index.js +1 -0
- package/lib/migration/utils/loadStageOptionsFromFile.d.ts +1 -0
- package/lib/migration/utils/loadStageOptionsFromFile.js +32 -0
- package/lib/migration/utils/loadStageOptionsFromFile.spec.d.ts +1 -0
- package/lib/migration/utils/loadStageOptionsFromFile.spec.js +77 -0
- package/lib/migration/utils/nextStage.d.ts +2 -2
- package/lib/migration/utils/nextStage.js +2 -1
- package/lib/migration/utils/nextStage.spec.js +1 -1
- package/lib/migration/utils/options.d.ts +3 -1
- package/lib/migration/utils/options.js +16 -0
- package/lib/migration/utils/setMigrationSettings.d.ts +2 -2
- package/lib/migration/utils/setMigrationSettings.js +4 -5
- package/lib/migration/utils/setMigrationSettings.spec.js +15 -8
- package/package.json +3 -2
|
@@ -12,11 +12,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const
|
|
15
|
+
const job_runner_lib_1 = require("@squiz/job-runner-lib");
|
|
16
16
|
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const commander_1 = require("commander");
|
|
17
18
|
const ora_1 = __importDefault(require("ora"));
|
|
18
19
|
const ApiService_1 = require("../../../ApiService");
|
|
19
|
-
const component_cli_lib_1 = require("@squiz/component-cli-lib");
|
|
20
20
|
const utils_1 = require("../../utils");
|
|
21
21
|
const createUploadJobCommand = () => {
|
|
22
22
|
const uploadJobCommand = new commander_1.Command('uploadJob')
|
|
@@ -37,7 +37,8 @@ const createUploadJobCommand = () => {
|
|
|
37
37
|
validateStatus: utils_1.validateAxiosStatus,
|
|
38
38
|
baseUrl: yield (0, utils_1.buildJobRunnerUrl)(options.tenant, options.overrideUrl),
|
|
39
39
|
});
|
|
40
|
-
|
|
40
|
+
const jobUploadService = new job_runner_lib_1.JobUploadService();
|
|
41
|
+
yield jobUploadService.uploadJobFolder(apiService.client, inputSource);
|
|
41
42
|
spinner.succeed();
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
24
|
};
|
|
@@ -23,6 +34,7 @@ const nextStageCommand = () => {
|
|
|
23
34
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MIGRATION_ID))
|
|
24
35
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID))
|
|
25
36
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
|
|
37
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.STAGE_OPTIONS, false))
|
|
26
38
|
.configureOutput({
|
|
27
39
|
outputError(str, write) {
|
|
28
40
|
write(chalk_1.default.red(str));
|
|
@@ -32,7 +44,9 @@ const nextStageCommand = () => {
|
|
|
32
44
|
yield (0, utils_1.throwErrorIfNotLoggedIn)(nextCommand);
|
|
33
45
|
const spinner = (0, ora_1.default)('Starting next stage').start();
|
|
34
46
|
try {
|
|
35
|
-
const
|
|
47
|
+
const { stageOptions: stageOptionsPath } = options, otherOptions = __rest(options, ["stageOptions"]);
|
|
48
|
+
const stageOptions = (0, utils_1.loadStageOptionsFromFile)(stageOptionsPath);
|
|
49
|
+
const response = yield (0, utils_1.nextStage)(Object.assign(Object.assign({}, otherOptions), (stageOptions && { stageOptions })));
|
|
36
50
|
spinner.succeed(response.message);
|
|
37
51
|
}
|
|
38
52
|
catch (error) {
|
|
@@ -103,6 +103,29 @@ describe('nextStageCommand', () => {
|
|
|
103
103
|
tenant: 'test-tenant',
|
|
104
104
|
});
|
|
105
105
|
}));
|
|
106
|
+
it('should execute next stage with stageOptions from JSON file', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
107
|
+
const program = (0, next_1.default)();
|
|
108
|
+
yield program.parseAsync([
|
|
109
|
+
'node',
|
|
110
|
+
'dxp-cli',
|
|
111
|
+
'next',
|
|
112
|
+
'--migration-id',
|
|
113
|
+
'migration-123',
|
|
114
|
+
'--asset-id',
|
|
115
|
+
'asset-456',
|
|
116
|
+
'--stage-options',
|
|
117
|
+
'./src/__tests__/migration/stageOptionsInput.json',
|
|
118
|
+
]);
|
|
119
|
+
expect(mockNextStage.nextStage).toHaveBeenCalledWith({
|
|
120
|
+
migrationId: 'migration-123',
|
|
121
|
+
assetId: 'asset-456',
|
|
122
|
+
stageOptions: {
|
|
123
|
+
'cct-to-cmp': {
|
|
124
|
+
overwriteSuccessful: false,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}));
|
|
106
129
|
});
|
|
107
130
|
describe('error scenarios', () => {
|
|
108
131
|
it('should handle nextStage API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
24
|
};
|
|
@@ -24,7 +35,9 @@ const setMigrationSettingsCommand = () => {
|
|
|
24
35
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_URL))
|
|
25
36
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_IDENTIFIER))
|
|
26
37
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_KEY))
|
|
38
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.CONTENT_API_KEY))
|
|
27
39
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
|
|
40
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.STAGE_OPTIONS, false))
|
|
28
41
|
.configureOutput({
|
|
29
42
|
outputError(str, write) {
|
|
30
43
|
write(chalk_1.default.red(str));
|
|
@@ -34,7 +47,9 @@ const setMigrationSettingsCommand = () => {
|
|
|
34
47
|
const spinner = (0, ora_1.default)('Setting migration configuration...').start();
|
|
35
48
|
yield (0, utils_1.throwErrorIfNotLoggedIn)(settingsCommand);
|
|
36
49
|
try {
|
|
37
|
-
const
|
|
50
|
+
const { stageOptions: stageOptionsPath } = options, otherOptions = __rest(options, ["stageOptions"]);
|
|
51
|
+
const stageOptions = (0, utils_1.loadStageOptionsFromFile)(stageOptionsPath);
|
|
52
|
+
const response = yield (0, utils_1.setMigrationSettings)(Object.assign(Object.assign({}, otherOptions), (stageOptions && { stageOptions })));
|
|
38
53
|
spinner.succeed(`Migration settings updated: ${JSON.stringify(response, null, 2)}`);
|
|
39
54
|
}
|
|
40
55
|
catch (error) {
|
|
@@ -65,6 +65,7 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
65
65
|
matrixUrl: 'https://matrix.example.com',
|
|
66
66
|
matrixIdentifier: '@user:matrix.example.com',
|
|
67
67
|
matrixKey: '***********123',
|
|
68
|
+
contentApiKey: '***********456',
|
|
68
69
|
};
|
|
69
70
|
mockSetMigrationSettings.setMigrationSettings.mockResolvedValue(mockSetMigrationSettingResponse);
|
|
70
71
|
});
|
|
@@ -82,12 +83,15 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
82
83
|
'@user:matrix.example.com',
|
|
83
84
|
'--matrix-key',
|
|
84
85
|
'secret-key-123',
|
|
86
|
+
'--content-api-key',
|
|
87
|
+
'content-api-key-456',
|
|
85
88
|
]);
|
|
86
89
|
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
87
90
|
expect(mockSetMigrationSettings.setMigrationSettings).toHaveBeenCalledWith({
|
|
88
91
|
matrixUrl: 'https://matrix.example.com',
|
|
89
92
|
matrixIdentifier: '@user:matrix.example.com',
|
|
90
93
|
matrixKey: 'secret-key-123',
|
|
94
|
+
contentApiKey: 'content-api-key-456',
|
|
91
95
|
});
|
|
92
96
|
expect(mockSetMigrationSettings.setMigrationSettings).toHaveBeenCalledTimes(1);
|
|
93
97
|
expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
|
|
@@ -107,12 +111,45 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
107
111
|
'secret-key-123',
|
|
108
112
|
'--tenant',
|
|
109
113
|
'test-tenant',
|
|
114
|
+
'--content-api-key',
|
|
115
|
+
'content-api-key-456',
|
|
110
116
|
]);
|
|
111
117
|
expect(mockSetMigrationSettings.setMigrationSettings).toHaveBeenCalledWith({
|
|
112
118
|
matrixUrl: 'https://matrix.example.com',
|
|
113
119
|
matrixIdentifier: '@user:matrix.example.com',
|
|
114
120
|
matrixKey: 'secret-key-123',
|
|
115
121
|
tenant: 'test-tenant',
|
|
122
|
+
contentApiKey: 'content-api-key-456',
|
|
123
|
+
});
|
|
124
|
+
}));
|
|
125
|
+
it('should set migration settings with stageOptions from JSON file', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
const program = (0, settings_1.default)();
|
|
127
|
+
yield program.parseAsync([
|
|
128
|
+
'node',
|
|
129
|
+
'dxp-cli',
|
|
130
|
+
'migration',
|
|
131
|
+
'settings',
|
|
132
|
+
'--matrix-url',
|
|
133
|
+
'https://matrix.example.com',
|
|
134
|
+
'--matrix-identifier',
|
|
135
|
+
'@user:matrix.example.com',
|
|
136
|
+
'--matrix-key',
|
|
137
|
+
'secret-key-123',
|
|
138
|
+
'--content-api-key',
|
|
139
|
+
'content-api-key-456',
|
|
140
|
+
'--stage-options',
|
|
141
|
+
'./src/__tests__/migration/stageOptionsInput.json',
|
|
142
|
+
]);
|
|
143
|
+
expect(mockSetMigrationSettings.setMigrationSettings).toHaveBeenCalledWith({
|
|
144
|
+
matrixUrl: 'https://matrix.example.com',
|
|
145
|
+
matrixIdentifier: '@user:matrix.example.com',
|
|
146
|
+
matrixKey: 'secret-key-123',
|
|
147
|
+
contentApiKey: 'content-api-key-456',
|
|
148
|
+
stageOptions: {
|
|
149
|
+
'cct-to-cmp': {
|
|
150
|
+
overwriteSuccessful: false,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
116
153
|
});
|
|
117
154
|
}));
|
|
118
155
|
it('should set migration settings with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -132,12 +169,15 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
132
169
|
'secret-key-123',
|
|
133
170
|
'--overrideUrl',
|
|
134
171
|
'https://custom.migration.url',
|
|
172
|
+
'--content-api-key',
|
|
173
|
+
'content-api-key-456',
|
|
135
174
|
]);
|
|
136
175
|
expect(mockSetMigrationSettings.setMigrationSettings).toHaveBeenCalledWith({
|
|
137
176
|
matrixUrl: 'https://matrix.example.com',
|
|
138
177
|
matrixIdentifier: '@user:matrix.example.com',
|
|
139
178
|
matrixKey: 'secret-key-123',
|
|
140
179
|
overrideUrl: 'https://custom.migration.url',
|
|
180
|
+
contentApiKey: 'content-api-key-456',
|
|
141
181
|
});
|
|
142
182
|
process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
|
|
143
183
|
}));
|
|
@@ -159,6 +199,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
159
199
|
'@user:matrix.example.com',
|
|
160
200
|
'--matrix-key',
|
|
161
201
|
'secret-key-123',
|
|
202
|
+
'--content-api-key',
|
|
203
|
+
'content-api-key-456',
|
|
162
204
|
]);
|
|
163
205
|
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, apiError);
|
|
164
206
|
}));
|
|
@@ -178,6 +220,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
178
220
|
'@user:matrix.example.com',
|
|
179
221
|
'--matrix-key',
|
|
180
222
|
'secret-key-123',
|
|
223
|
+
'--content-api-key',
|
|
224
|
+
'content-api-key-456',
|
|
181
225
|
]);
|
|
182
226
|
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, networkError);
|
|
183
227
|
}));
|
|
@@ -195,6 +239,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
195
239
|
'@user:matrix.example.com',
|
|
196
240
|
'--matrix-key',
|
|
197
241
|
'secret-key-123',
|
|
242
|
+
'--content-api-key',
|
|
243
|
+
'content-api-key-456',
|
|
198
244
|
]);
|
|
199
245
|
}).toThrow();
|
|
200
246
|
});
|
|
@@ -210,6 +256,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
210
256
|
'https://matrix.example.com',
|
|
211
257
|
'--matrix-key',
|
|
212
258
|
'secret-key-123',
|
|
259
|
+
'--content-api-key',
|
|
260
|
+
'content-api-key-456',
|
|
213
261
|
]);
|
|
214
262
|
}).toThrow();
|
|
215
263
|
});
|
|
@@ -225,6 +273,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
225
273
|
'https://matrix.example.com',
|
|
226
274
|
'--matrix-identifier',
|
|
227
275
|
'@user:matrix.example.com',
|
|
276
|
+
'--content-api-key',
|
|
277
|
+
'content-api-key-456',
|
|
228
278
|
]);
|
|
229
279
|
}).toThrow();
|
|
230
280
|
});
|
|
@@ -248,6 +298,8 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
248
298
|
'@user:matrix.example.com',
|
|
249
299
|
'--matrix-key',
|
|
250
300
|
'secret-key-123',
|
|
301
|
+
'--content-api-key',
|
|
302
|
+
'content-api-key-456',
|
|
251
303
|
'--tenant',
|
|
252
304
|
'test-tenant',
|
|
253
305
|
]);
|
|
@@ -255,6 +307,7 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
255
307
|
expect(opts.matrixUrl).toBe('https://matrix.example.com');
|
|
256
308
|
expect(opts.matrixIdentifier).toBe('@user:matrix.example.com');
|
|
257
309
|
expect(opts.matrixKey).toBe('secret-key-123');
|
|
310
|
+
expect(opts.contentApiKey).toBe('content-api-key-456');
|
|
258
311
|
expect(opts.tenant).toBe('test-tenant');
|
|
259
312
|
});
|
|
260
313
|
it('should parse options with kebab-case to camelCase conversion', () => {
|
|
@@ -270,11 +323,14 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
270
323
|
'@user:matrix.example.com',
|
|
271
324
|
'--matrix-key',
|
|
272
325
|
'secret-key-123',
|
|
326
|
+
'--content-api-key',
|
|
327
|
+
'content-api-key-456',
|
|
273
328
|
]);
|
|
274
329
|
const opts = program.opts();
|
|
275
330
|
expect(opts.matrixUrl).toBe('https://matrix.example.com');
|
|
276
331
|
expect(opts.matrixIdentifier).toBe('@user:matrix.example.com');
|
|
277
332
|
expect(opts.matrixKey).toBe('secret-key-123');
|
|
333
|
+
expect(opts.contentApiKey).toBe('content-api-key-456');
|
|
278
334
|
});
|
|
279
335
|
});
|
|
280
336
|
afterEach(() => {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { AssetMigration, CommonCommandOptions } from '.';
|
|
2
2
|
export interface NextStageOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId' | 'assetId'> {
|
|
3
|
+
stageOptions?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface NextStageParsedOptions extends Omit<NextStageOptions, 'stageOptions'> {
|
|
6
|
+
stageOptions?: Record<string, any>;
|
|
3
7
|
}
|
|
4
8
|
export interface NextStageApiResponse {
|
|
5
9
|
message: string;
|
|
@@ -3,8 +3,13 @@ export interface MatrixIdentifierSchema {
|
|
|
3
3
|
matrixUrl: string;
|
|
4
4
|
matrixIdentifier: string;
|
|
5
5
|
matrixKey: string;
|
|
6
|
+
contentApiKey: string;
|
|
6
7
|
}
|
|
7
8
|
export interface SetMigrationSettingOptions extends CommonCommandOptions, MatrixIdentifierSchema {
|
|
9
|
+
stageOptions?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SetMigrationSettingParsedOptions extends Omit<SetMigrationSettingOptions, 'stageOptions'>, MatrixIdentifierSchema {
|
|
12
|
+
stageOptions?: Record<string, any>;
|
|
8
13
|
}
|
|
9
14
|
export interface SetMigrationSettingApiResponse extends MatrixIdentifierSchema {
|
|
10
15
|
}
|
|
@@ -21,3 +21,4 @@ __exportStar(require("./getMigration"), exports);
|
|
|
21
21
|
__exportStar(require("./nextStage"), exports);
|
|
22
22
|
__exportStar(require("./setMigrationSettings"), exports);
|
|
23
23
|
__exportStar(require("./revertMigration"), exports);
|
|
24
|
+
__exportStar(require("./loadStageOptionsFromFile"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const loadStageOptionsFromFile: (filePath?: string) => any;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadStageOptionsFromFile = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const loadStageOptionsFromFile = (filePath) => {
|
|
9
|
+
if (!filePath) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
14
|
+
throw new Error(`Stage options file not found: ${filePath}`);
|
|
15
|
+
}
|
|
16
|
+
const fileContent = fs_1.default.readFileSync(filePath, 'utf8');
|
|
17
|
+
const stageOptions = JSON.parse(fileContent);
|
|
18
|
+
if (typeof stageOptions !== 'object' ||
|
|
19
|
+
stageOptions === null ||
|
|
20
|
+
Array.isArray(stageOptions)) {
|
|
21
|
+
throw new Error('Stage options file must contain a valid JSON object');
|
|
22
|
+
}
|
|
23
|
+
return stageOptions;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
throw new Error(`Failed to load stage options from file: ${error.message}`);
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Failed to load stage options from file: ${error}`);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.loadStageOptionsFromFile = loadStageOptionsFromFile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const loadStageOptionsFromFile_1 = require("./loadStageOptionsFromFile");
|
|
8
|
+
jest.mock('fs');
|
|
9
|
+
const mockFs = fs_1.default;
|
|
10
|
+
describe('loadStageOptionsFromFile', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
});
|
|
14
|
+
it('should return undefined when no file path is provided', () => {
|
|
15
|
+
const result = (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)();
|
|
16
|
+
expect(result).toBeUndefined();
|
|
17
|
+
});
|
|
18
|
+
it('should load and parse valid JSON file', () => {
|
|
19
|
+
const mockFilePath = '/test/path/options.json';
|
|
20
|
+
const mockJsonContent = '{"option1": "value1", "option2": "value2"}';
|
|
21
|
+
const expectedResult = { option1: 'value1', option2: 'value2' };
|
|
22
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
23
|
+
mockFs.readFileSync.mockReturnValue(mockJsonContent);
|
|
24
|
+
const result = (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath);
|
|
25
|
+
expect(mockFs.existsSync).toHaveBeenCalledWith(mockFilePath);
|
|
26
|
+
expect(mockFs.readFileSync).toHaveBeenCalledWith(mockFilePath, 'utf8');
|
|
27
|
+
expect(result).toEqual(expectedResult);
|
|
28
|
+
});
|
|
29
|
+
it('should throw error when file does not exist', () => {
|
|
30
|
+
const mockFilePath = '/test/path/nonexistent.json';
|
|
31
|
+
mockFs.existsSync.mockReturnValue(false);
|
|
32
|
+
expect(() => (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath)).toThrow(`Stage options file not found: ${mockFilePath}`);
|
|
33
|
+
});
|
|
34
|
+
it('should throw error when JSON is invalid', () => {
|
|
35
|
+
const mockFilePath = '/test/path/invalid.json';
|
|
36
|
+
const invalidJson = '{"invalid": json}';
|
|
37
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
38
|
+
mockFs.readFileSync.mockReturnValue(invalidJson);
|
|
39
|
+
expect(() => (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath)).toThrow('Failed to load stage options from file:');
|
|
40
|
+
});
|
|
41
|
+
it('should throw error when JSON is not an object', () => {
|
|
42
|
+
const mockFilePath = '/test/path/array.json';
|
|
43
|
+
const arrayJson = '["item1", "item2"]';
|
|
44
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
45
|
+
mockFs.readFileSync.mockReturnValue(arrayJson);
|
|
46
|
+
expect(() => (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath)).toThrow('Stage options file must contain a valid JSON object');
|
|
47
|
+
});
|
|
48
|
+
it('should throw error when JSON is null', () => {
|
|
49
|
+
const mockFilePath = '/test/path/null.json';
|
|
50
|
+
const nullJson = 'null';
|
|
51
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
52
|
+
mockFs.readFileSync.mockReturnValue(nullJson);
|
|
53
|
+
expect(() => (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath)).toThrow('Stage options file must contain a valid JSON object');
|
|
54
|
+
});
|
|
55
|
+
it('should handle complex nested objects', () => {
|
|
56
|
+
const mockFilePath = '/test/path/complex.json';
|
|
57
|
+
const complexJson = JSON.stringify({
|
|
58
|
+
option1: 'value1',
|
|
59
|
+
nestedOption: {
|
|
60
|
+
subOption1: 'subValue1',
|
|
61
|
+
subOption2: 'subValue2',
|
|
62
|
+
},
|
|
63
|
+
arrayOption: ['item1', 'item2'],
|
|
64
|
+
});
|
|
65
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
66
|
+
mockFs.readFileSync.mockReturnValue(complexJson);
|
|
67
|
+
const result = (0, loadStageOptionsFromFile_1.loadStageOptionsFromFile)(mockFilePath);
|
|
68
|
+
expect(result).toEqual({
|
|
69
|
+
option1: 'value1',
|
|
70
|
+
nestedOption: {
|
|
71
|
+
subOption1: 'subValue1',
|
|
72
|
+
subOption2: 'subValue2',
|
|
73
|
+
},
|
|
74
|
+
arrayOption: ['item1', 'item2'],
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { NextStageApiResponse,
|
|
2
|
-
export declare function nextStage(options:
|
|
1
|
+
import { NextStageApiResponse, NextStageParsedOptions } from '../types';
|
|
2
|
+
export declare function nextStage(options: NextStageParsedOptions): Promise<NextStageApiResponse>;
|
|
@@ -19,7 +19,8 @@ function nextStage(options) {
|
|
|
19
19
|
});
|
|
20
20
|
const migrationUrl = yield (0, _1.buildMigrationUrl)(options.tenant, options.overrideUrl);
|
|
21
21
|
try {
|
|
22
|
-
const
|
|
22
|
+
const payload = Object.assign({}, (options.stageOptions && { stageOptions: options.stageOptions }));
|
|
23
|
+
const response = yield apiService.client.post(`${migrationUrl}/${options.migrationId}/assets/${options.assetId}/next`, payload, {
|
|
23
24
|
headers: yield (0, _1.getMigrationHeaders)(options.tenant),
|
|
24
25
|
});
|
|
25
26
|
if (response.status !== 202) {
|
|
@@ -97,7 +97,7 @@ describe('nextStage', () => {
|
|
|
97
97
|
data: {},
|
|
98
98
|
};
|
|
99
99
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
100
|
-
yield expect((0, nextStage_1.nextStage)(mockOptions)).rejects.toThrow('Invalid response format from next stage');
|
|
100
|
+
yield expect((0, nextStage_1.nextStage)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }))).rejects.toThrow('Invalid response format from next stage');
|
|
101
101
|
}));
|
|
102
102
|
it('handles API service errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
103
|
const error = new Error('Network error');
|
|
@@ -6,7 +6,9 @@ export declare enum OptionName {
|
|
|
6
6
|
TENANT = "tenant",
|
|
7
7
|
MIGRATION_ID = "migration-id",
|
|
8
8
|
MATRIX_IDENTIFIER = "matrix-identifier",
|
|
9
|
-
MATRIX_KEY = "matrix-key"
|
|
9
|
+
MATRIX_KEY = "matrix-key",
|
|
10
|
+
CONTENT_API_KEY = "content-api-key",
|
|
11
|
+
STAGE_OPTIONS = "stage-options"
|
|
10
12
|
}
|
|
11
13
|
export declare const getParamOption: (param: OptionName, makeOptionMandatory?: boolean) => Option;
|
|
12
14
|
export declare const addOverrideUrlOption: (command: Command) => void;
|
|
@@ -11,6 +11,8 @@ var OptionName;
|
|
|
11
11
|
OptionName["MIGRATION_ID"] = "migration-id";
|
|
12
12
|
OptionName["MATRIX_IDENTIFIER"] = "matrix-identifier";
|
|
13
13
|
OptionName["MATRIX_KEY"] = "matrix-key";
|
|
14
|
+
OptionName["CONTENT_API_KEY"] = "content-api-key";
|
|
15
|
+
OptionName["STAGE_OPTIONS"] = "stage-options";
|
|
14
16
|
})(OptionName = exports.OptionName || (exports.OptionName = {}));
|
|
15
17
|
const params = new Map([
|
|
16
18
|
[
|
|
@@ -62,6 +64,20 @@ const params = new Map([
|
|
|
62
64
|
description: 'The Asset Management API key for the Migrator API to interact with Matrix API',
|
|
63
65
|
},
|
|
64
66
|
],
|
|
67
|
+
[
|
|
68
|
+
OptionName.CONTENT_API_KEY,
|
|
69
|
+
{
|
|
70
|
+
flags: '--content-api-key <string>',
|
|
71
|
+
description: 'The Content API key for the Migrator API to interact with Content API',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
OptionName.STAGE_OPTIONS,
|
|
76
|
+
{
|
|
77
|
+
flags: '--stage-options <path>',
|
|
78
|
+
description: 'Path to a JSON file containing stage options',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
65
81
|
]);
|
|
66
82
|
const getParamOption = (param, makeOptionMandatory = true) => {
|
|
67
83
|
const paramInfo = params.get(param);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function setMigrationSettings(options:
|
|
1
|
+
import { SetMigrationSettingParsedOptions, SetMigrationSettingApiResponse } from '../types';
|
|
2
|
+
export declare function setMigrationSettings(options: SetMigrationSettingParsedOptions): Promise<SetMigrationSettingApiResponse>;
|
|
@@ -19,11 +19,7 @@ function setMigrationSettings(options) {
|
|
|
19
19
|
});
|
|
20
20
|
const migrationUrl = yield (0, _1.buildMigrationUrl)(options.tenant, options.overrideUrl, 'settings');
|
|
21
21
|
try {
|
|
22
|
-
const payload = {
|
|
23
|
-
matrixUrl: options.matrixUrl,
|
|
24
|
-
matrixIdentifier: options.matrixIdentifier,
|
|
25
|
-
matrixKey: options.matrixKey,
|
|
26
|
-
};
|
|
22
|
+
const payload = Object.assign({ matrixUrl: options.matrixUrl, matrixIdentifier: options.matrixIdentifier, matrixKey: options.matrixKey, contentApiKey: options.contentApiKey }, (options.stageOptions && { stageOptions: options.stageOptions }));
|
|
27
23
|
const response = yield apiService.client.post(migrationUrl, payload, {
|
|
28
24
|
headers: yield (0, _1.getMigrationHeaders)(options.tenant),
|
|
29
25
|
});
|
|
@@ -39,6 +35,9 @@ function setMigrationSettings(options) {
|
|
|
39
35
|
matrixKey: response.data.matrixKey
|
|
40
36
|
? (0, _1.redactKey)(response.data.matrixKey, 3)
|
|
41
37
|
: '',
|
|
38
|
+
contentApiKey: response.data.contentApiKey
|
|
39
|
+
? (0, _1.redactKey)(response.data.contentApiKey, 3)
|
|
40
|
+
: '',
|
|
42
41
|
};
|
|
43
42
|
return responseData;
|
|
44
43
|
}
|
|
@@ -48,6 +48,7 @@ describe('setMigrationSettings', () => {
|
|
|
48
48
|
matrixUrl: 'https://matrix.example.com',
|
|
49
49
|
matrixIdentifier: 'test-identifier',
|
|
50
50
|
matrixKey: 'test-key-123',
|
|
51
|
+
contentApiKey: 'test-content-api-key-456',
|
|
51
52
|
};
|
|
52
53
|
mockBuildMigrationUrl.mockResolvedValue('https://migration.example.com');
|
|
53
54
|
mockGetMigrationHeaders.mockResolvedValue({
|
|
@@ -63,14 +64,16 @@ describe('setMigrationSettings', () => {
|
|
|
63
64
|
matrixUrl: 'https://matrix.example.com',
|
|
64
65
|
matrixIdentifier: 'test-identifier',
|
|
65
66
|
matrixKey: 'test-key-123',
|
|
67
|
+
contentApiKey: 'test-content-api-key-456',
|
|
66
68
|
},
|
|
67
69
|
};
|
|
68
70
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
69
|
-
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(mockOptions);
|
|
71
|
+
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }));
|
|
70
72
|
expect(result).toEqual({
|
|
71
73
|
matrixUrl: 'https://matrix.example.com',
|
|
72
74
|
matrixIdentifier: 'test-identifier',
|
|
73
75
|
matrixKey: '***123',
|
|
76
|
+
contentApiKey: '***456',
|
|
74
77
|
});
|
|
75
78
|
expect(mockBuildMigrationUrl).toHaveBeenCalledWith('test-tenant', undefined, 'settings');
|
|
76
79
|
expect(mockGetMigrationHeaders).toHaveBeenCalledWith('test-tenant');
|
|
@@ -78,6 +81,8 @@ describe('setMigrationSettings', () => {
|
|
|
78
81
|
matrixUrl: 'https://matrix.example.com',
|
|
79
82
|
matrixIdentifier: 'test-identifier',
|
|
80
83
|
matrixKey: 'test-key-123',
|
|
84
|
+
contentApiKey: 'test-content-api-key-456',
|
|
85
|
+
stageOptions: {},
|
|
81
86
|
}, {
|
|
82
87
|
headers: {
|
|
83
88
|
'Content-Type': 'application/json',
|
|
@@ -94,10 +99,11 @@ describe('setMigrationSettings', () => {
|
|
|
94
99
|
matrixUrl: 'https://matrix.example.com',
|
|
95
100
|
matrixIdentifier: 'test-identifier',
|
|
96
101
|
matrixKey: 'test-key-123',
|
|
102
|
+
contentApiKey: 'test-content-api-key-456',
|
|
97
103
|
},
|
|
98
104
|
};
|
|
99
105
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
100
|
-
yield (0, setMigrationSettings_1.setMigrationSettings)(optionsWithOverride);
|
|
106
|
+
yield (0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, optionsWithOverride), { stageOptions: {} }));
|
|
101
107
|
expect(mockBuildMigrationUrl).toHaveBeenCalledWith('test-tenant', 'https://custom.migration.url', 'settings');
|
|
102
108
|
}));
|
|
103
109
|
it('should handle non-success status codes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -106,7 +112,7 @@ describe('setMigrationSettings', () => {
|
|
|
106
112
|
data: {},
|
|
107
113
|
};
|
|
108
114
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
109
|
-
yield expect((0, setMigrationSettings_1.setMigrationSettings)(mockOptions)).rejects.toThrow('Migration settings update failed with status: 400');
|
|
115
|
+
yield expect((0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }))).rejects.toThrow('Migration settings update failed with status: 400');
|
|
110
116
|
}));
|
|
111
117
|
it('should handle missing response data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
118
|
const mockResponse = {
|
|
@@ -114,16 +120,16 @@ describe('setMigrationSettings', () => {
|
|
|
114
120
|
data: null,
|
|
115
121
|
};
|
|
116
122
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
117
|
-
yield expect((0, setMigrationSettings_1.setMigrationSettings)(mockOptions)).rejects.toThrow('No data returned from migration service');
|
|
123
|
+
yield expect((0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }))).rejects.toThrow('No data returned from migration service');
|
|
118
124
|
}));
|
|
119
125
|
it('should handle API service errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
126
|
const error = new Error('Network error');
|
|
121
127
|
mockApiServiceInstance.client.post.mockRejectedValue(error);
|
|
122
|
-
yield expect((0, setMigrationSettings_1.setMigrationSettings)(mockOptions)).rejects.toThrow('Network error');
|
|
128
|
+
yield expect((0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }))).rejects.toThrow('Network error');
|
|
123
129
|
}));
|
|
124
130
|
it('should handle unknown errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
131
|
mockApiServiceInstance.client.post.mockRejectedValue('Unknown error');
|
|
126
|
-
yield expect((0, setMigrationSettings_1.setMigrationSettings)(mockOptions)).rejects.toThrow('Failed to set migration settings: Unknown error');
|
|
132
|
+
yield expect((0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }))).rejects.toThrow('Failed to set migration settings: Unknown error');
|
|
127
133
|
}));
|
|
128
134
|
it('should redact matrix key in response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
135
|
const mockResponse = {
|
|
@@ -132,11 +138,12 @@ describe('setMigrationSettings', () => {
|
|
|
132
138
|
matrixUrl: 'https://matrix.example.com',
|
|
133
139
|
matrixIdentifier: 'test-identifier',
|
|
134
140
|
matrixKey: 'test-key-123',
|
|
141
|
+
contentApiKey: 'test-content-api-key-456',
|
|
135
142
|
},
|
|
136
143
|
};
|
|
137
144
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
138
145
|
mockRedactKey.mockReturnValue('***123');
|
|
139
|
-
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(mockOptions);
|
|
146
|
+
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }));
|
|
140
147
|
expect(result.matrixKey).toBe('***123');
|
|
141
148
|
expect(mockRedactKey).toHaveBeenCalledWith('test-key-123', 3);
|
|
142
149
|
}));
|
|
@@ -149,7 +156,7 @@ describe('setMigrationSettings', () => {
|
|
|
149
156
|
},
|
|
150
157
|
};
|
|
151
158
|
mockApiServiceInstance.client.post.mockResolvedValue(mockResponse);
|
|
152
|
-
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(mockOptions);
|
|
159
|
+
const result = yield (0, setMigrationSettings_1.setMigrationSettings)(Object.assign(Object.assign({}, mockOptions), { stageOptions: {} }));
|
|
153
160
|
expect(result.matrixKey).toBe('');
|
|
154
161
|
expect(mockRedactKey).not.toHaveBeenCalled();
|
|
155
162
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiz/dxp-cli-next",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.27.0-develop.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "https://gitlab.squiz.net/dxp/dxp-cli-next"
|
|
6
6
|
},
|
|
@@ -42,9 +42,10 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@apidevtools/swagger-parser": "10.1.0",
|
|
44
44
|
"@squiz/component-cli-lib": "1.72.12",
|
|
45
|
+
"@squiz/dx-logger-lib": "^1.65.1",
|
|
45
46
|
"@squiz/dxp-porter-shared": "0.4.0",
|
|
47
|
+
"@squiz/job-runner-lib": "2.1.0",
|
|
46
48
|
"@squiz/local-component-dev-ui": "0.6.20",
|
|
47
|
-
"@squiz/dx-logger-lib": "^1.65.1",
|
|
48
49
|
"axios": "1.1.3",
|
|
49
50
|
"cli-color": "2.0.3",
|
|
50
51
|
"commander": "9.4.0",
|