@squiz/dxp-cli-next 5.31.0 → 5.32.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/cdp/instance/activate/activate.js +6 -7
- package/lib/cdp/instance/activate/activate.spec.js +2 -8
- package/lib/cdp/utils.d.ts +2 -1
- package/lib/cdp/utils.js +4 -2
- package/lib/migration/create/create.js +5 -8
- package/lib/migration/create/create.spec.js +1 -0
- package/lib/migration/index.js +2 -0
- package/lib/migration/pre/pre.d.ts +3 -0
- package/lib/migration/pre/pre.js +54 -0
- package/lib/migration/pre/pre.spec.d.ts +1 -0
- package/lib/migration/pre/pre.spec.js +269 -0
- package/lib/migration/types/common.types.d.ts +10 -0
- package/lib/migration/types/createMigration.types.d.ts +4 -0
- package/lib/migration/types/index.d.ts +1 -0
- package/lib/migration/types/index.js +1 -0
- package/lib/migration/types/preMigration.types.d.ts +10 -0
- package/lib/migration/types/preMigration.types.js +2 -0
- package/lib/migration/utils/common.d.ts +8 -0
- package/lib/migration/utils/common.js +19 -1
- package/lib/migration/utils/createMigration.d.ts +26 -2
- package/lib/migration/utils/createMigration.js +13 -6
- package/lib/migration/utils/loadCctIdsFromFile.d.ts +1 -0
- package/lib/migration/utils/loadCctIdsFromFile.js +32 -0
- package/lib/migration/utils/loadCctIdsFromFile.spec.d.ts +1 -0
- package/lib/migration/utils/loadCctIdsFromFile.spec.js +91 -0
- package/lib/migration/utils/options.d.ts +2 -1
- package/lib/migration/utils/options.js +8 -0
- package/lib/page/layouts/deploy/deploy.js +44 -9
- package/lib/page/layouts/deploy/deploy.spec.js +110 -19
- package/lib/page/layouts/dev/dev.js +18 -4
- package/lib/page/layouts/dev/dev.spec.js +117 -8
- package/lib/page/layouts/validation/index.d.ts +2 -0
- package/lib/page/layouts/validation/index.js +5 -1
- package/lib/page/layouts/validation/property-consistency.d.ts +7 -0
- package/lib/page/layouts/validation/property-consistency.js +92 -0
- package/lib/page/layouts/validation/property-consistency.spec.d.ts +1 -0
- package/lib/page/layouts/validation/property-consistency.spec.js +305 -0
- package/lib/page/layouts/validation/validateLayoutFormat.d.ts +2 -0
- package/lib/page/layouts/validation/validateLayoutFormat.js +27 -0
- package/lib/page/layouts/validation/validateLayoutFormat.spec.d.ts +1 -0
- package/lib/page/layouts/validation/validateLayoutFormat.spec.js +42 -0
- package/lib/page/layouts/validation/zone-consistency.d.ts +1 -1
- package/lib/page/layouts/validation/zone-consistency.js +10 -9
- package/lib/page/layouts/validation/zone-consistency.spec.js +32 -34
- package/lib/page/utils/definitions.d.ts +347 -50
- package/lib/page/utils/definitions.js +103 -22
- package/lib/page/utils/definitions.spec.js +516 -267
- package/lib/page/utils/normalize.d.ts +8 -0
- package/lib/page/utils/normalize.js +61 -0
- package/lib/page/utils/normalize.spec.d.ts +1 -0
- package/lib/page/utils/normalize.spec.js +315 -0
- package/lib/page/utils/parse-args.d.ts +20 -4
- package/lib/page/utils/parse-args.js +48 -13
- package/lib/page/utils/parse-args.spec.js +159 -21
- package/lib/page/utils/render.d.ts +27 -9
- package/lib/page/utils/render.js +66 -12
- package/lib/page/utils/render.spec.js +14 -14
- package/lib/page/utils/server.d.ts +1 -1
- package/lib/page/utils/server.js +2 -2
- package/lib/page/utils/server.spec.js +13 -13
- package/package.json +1 -1
|
@@ -62,10 +62,11 @@ const createActivateCommand = () => {
|
|
|
62
62
|
else {
|
|
63
63
|
apiUrl = `${scvDeployBaseUrl.dxpUrl}`;
|
|
64
64
|
}
|
|
65
|
+
const headerConfig = {
|
|
66
|
+
headers: Object.assign({}, (!hasRegion && { 'x-dxp-tenant': tenant })),
|
|
67
|
+
};
|
|
65
68
|
const getDeployResponse = (yield apiService.client
|
|
66
|
-
.get(apiUrl,
|
|
67
|
-
headers: Object.assign({ 'Content-Type': 'application/json' }, (!hasRegion && { 'x-dxp-tenant': tenant })),
|
|
68
|
-
})
|
|
69
|
+
.get(apiUrl, headerConfig)
|
|
69
70
|
.catch((err) => {
|
|
70
71
|
(0, utils_1.logDebug)(`RAW ERROR: ${JSON.stringify(err)}`);
|
|
71
72
|
if (err.response && err.response.status != 404) {
|
|
@@ -77,9 +78,7 @@ const createActivateCommand = () => {
|
|
|
77
78
|
}
|
|
78
79
|
(0, utils_1.logDebug)(`PUT ${apiUrl}`);
|
|
79
80
|
const activateInstanceAndDeploySchemaResponse = (yield apiService.client
|
|
80
|
-
.put(apiUrl, undefined,
|
|
81
|
-
headers: Object.assign({ 'Content-Type': 'application/json' }, (!hasRegion && { 'x-dxp-tenant': tenant })),
|
|
82
|
-
})
|
|
81
|
+
.put(apiUrl, undefined, headerConfig)
|
|
83
82
|
.catch((err) => {
|
|
84
83
|
(0, utils_1.logDebug)(`RAW ERROR: ${JSON.stringify(err)}`);
|
|
85
84
|
if (err.response) {
|
|
@@ -90,7 +89,7 @@ const createActivateCommand = () => {
|
|
|
90
89
|
if (activateInstanceAndDeploySchemaResponse.status === 409) {
|
|
91
90
|
throw new Error('Currently activating instance. Please try again later.');
|
|
92
91
|
}
|
|
93
|
-
yield (0, utils_1.pollForDeployedSchema)(apiUrl, apiService);
|
|
92
|
+
yield (0, utils_1.pollForDeployedSchema)(apiUrl, apiService, headerConfig);
|
|
94
93
|
spinner.succeed('Done!');
|
|
95
94
|
console.log('');
|
|
96
95
|
console.log('Your Schema has been deployed and instance has been activated.');
|
|
@@ -103,9 +103,7 @@ describe('cdpInstanceCommand', () => {
|
|
|
103
103
|
const program = (0, activate_1.default)();
|
|
104
104
|
yield program.parseAsync((0, utils_1.createMockActivateArgs)(region));
|
|
105
105
|
expect(mockedAxiosInstance.put).toHaveBeenCalledWith(`http://localhost:9999/__dxp/${region}/scv-deploy/${mockTenant}`, undefined, {
|
|
106
|
-
headers: {
|
|
107
|
-
'Content-Type': 'application/json',
|
|
108
|
-
},
|
|
106
|
+
headers: {},
|
|
109
107
|
});
|
|
110
108
|
expect(logSpy).toHaveBeenNthCalledWith(1, '');
|
|
111
109
|
expect(logSpy).toHaveBeenNthCalledWith(2, '');
|
|
@@ -139,9 +137,7 @@ describe('cdpInstanceCommand', () => {
|
|
|
139
137
|
const program = (0, activate_1.default)();
|
|
140
138
|
yield program.parseAsync((0, utils_1.createMockActivateArgs)(region));
|
|
141
139
|
expect(mockedAxios.put).toHaveBeenCalledWith(`http://localhost:9999/__dxp/${region}/scv-deploy/${mockTenant}`, undefined, {
|
|
142
|
-
headers: {
|
|
143
|
-
'Content-Type': 'application/json',
|
|
144
|
-
},
|
|
140
|
+
headers: {},
|
|
145
141
|
});
|
|
146
142
|
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('Currently activating instance. Please try again later.'));
|
|
147
143
|
}));
|
|
@@ -209,7 +205,6 @@ describe('cdpInstanceCommand', () => {
|
|
|
209
205
|
yield program.parseAsync(createMockArgs());
|
|
210
206
|
expect(mockedAxiosInstance.put).toHaveBeenCalledWith('http://localhost:9999/__dxp/service/scv-deploy', undefined, {
|
|
211
207
|
headers: {
|
|
212
|
-
'Content-Type': 'application/json',
|
|
213
208
|
'x-dxp-tenant': 'myTenant',
|
|
214
209
|
},
|
|
215
210
|
});
|
|
@@ -250,7 +245,6 @@ describe('cdpInstanceCommand', () => {
|
|
|
250
245
|
yield program.parseAsync(createMockArgs());
|
|
251
246
|
expect(mockedAxios.put).toHaveBeenCalledWith('http://localhost:9999/__dxp/service/scv-deploy', undefined, {
|
|
252
247
|
headers: {
|
|
253
|
-
'Content-Type': 'application/json',
|
|
254
248
|
'x-dxp-tenant': 'myTenant',
|
|
255
249
|
},
|
|
256
250
|
});
|
package/lib/cdp/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { AxiosRequestConfig } from 'axios';
|
|
2
3
|
import { ApiService } from '../ApiService';
|
|
3
4
|
export interface tenantDetails {
|
|
4
5
|
tenantid: string;
|
|
@@ -19,4 +20,4 @@ export declare function createMockActivateArgs(region: string): Array<string>;
|
|
|
19
20
|
/**
|
|
20
21
|
* Poll the schema to be deployed.
|
|
21
22
|
*/
|
|
22
|
-
export declare function pollForDeployedSchema(endpointUrl: string, apiService: ApiService): Promise<unknown>;
|
|
23
|
+
export declare function pollForDeployedSchema(endpointUrl: string, apiService: ApiService, requestConfig?: AxiosRequestConfig | null): Promise<unknown>;
|
package/lib/cdp/utils.js
CHANGED
|
@@ -93,7 +93,7 @@ exports.createMockActivateArgs = createMockActivateArgs;
|
|
|
93
93
|
/**
|
|
94
94
|
* Poll the schema to be deployed.
|
|
95
95
|
*/
|
|
96
|
-
function pollForDeployedSchema(endpointUrl, apiService) {
|
|
96
|
+
function pollForDeployedSchema(endpointUrl, apiService, requestConfig = null) {
|
|
97
97
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
98
|
return new Promise((resolve, reject) => {
|
|
99
99
|
const errHandler = (err) => {
|
|
@@ -104,7 +104,9 @@ function pollForDeployedSchema(endpointUrl, apiService) {
|
|
|
104
104
|
}, API_TIMEOUT);
|
|
105
105
|
const poll = () => __awaiter(this, void 0, void 0, function* () {
|
|
106
106
|
logDebug(`GET ${endpointUrl}`);
|
|
107
|
-
const { data, status } =
|
|
107
|
+
const { data, status } = requestConfig
|
|
108
|
+
? yield apiService.client.get(endpointUrl, requestConfig)
|
|
109
|
+
: yield apiService.client.get(endpointUrl);
|
|
108
110
|
logDebug(`Response: ${JSON.stringify(data)}`);
|
|
109
111
|
if (status !== 200) {
|
|
110
112
|
return reject(`Unexpected poll request status: ${status}`);
|
|
@@ -16,6 +16,7 @@ const commander_1 = require("commander");
|
|
|
16
16
|
const chalk_1 = __importDefault(require("chalk"));
|
|
17
17
|
const ora_1 = __importDefault(require("ora"));
|
|
18
18
|
const utils_1 = require("../utils");
|
|
19
|
+
const loadCctIdsFromFile_1 = require("../utils/loadCctIdsFromFile");
|
|
19
20
|
const createMigrationCommand = () => {
|
|
20
21
|
const createCommand = new commander_1.Command('create')
|
|
21
22
|
.name('create')
|
|
@@ -23,6 +24,7 @@ const createMigrationCommand = () => {
|
|
|
23
24
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID))
|
|
24
25
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.PREVIEW_ASSET_ID))
|
|
25
26
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_URL))
|
|
27
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.CCT_IDS, false))
|
|
26
28
|
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
|
|
27
29
|
.configureOutput({
|
|
28
30
|
outputError(str, write) {
|
|
@@ -33,18 +35,13 @@ const createMigrationCommand = () => {
|
|
|
33
35
|
yield (0, utils_1.throwErrorIfNotLoggedIn)(createCommand);
|
|
34
36
|
const spinner = (0, ora_1.default)('Creating migration').start();
|
|
35
37
|
try {
|
|
38
|
+
const cctIds = (0, loadCctIdsFromFile_1.loadCctIdsFromFile)(options.cctIds);
|
|
36
39
|
// Create migration
|
|
37
|
-
const response = yield (0, utils_1.createMigration)(options);
|
|
40
|
+
const response = yield (0, utils_1.createMigration)(Object.assign(Object.assign({}, options), { cctIds }));
|
|
38
41
|
if (!response) {
|
|
39
42
|
throw new Error('Migration creation failed');
|
|
40
43
|
}
|
|
41
|
-
spinner.succeed('
|
|
42
|
-
spinner.succeed(`Successfully created migration: ${JSON.stringify({
|
|
43
|
-
migrationId: response.assetMigration.migrationId,
|
|
44
|
-
assetId: response.assetMigration.assetId,
|
|
45
|
-
stage: response.assetMigration.stage,
|
|
46
|
-
status: response.assetMigration.status,
|
|
47
|
-
})}`);
|
|
44
|
+
spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('migration', response.assetMigration));
|
|
48
45
|
}
|
|
49
46
|
catch (error) {
|
|
50
47
|
spinner.fail();
|
|
@@ -52,6 +52,7 @@ describe('createMigrationCommand', () => {
|
|
|
52
52
|
jest.resetAllMocks();
|
|
53
53
|
logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
54
54
|
mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
|
|
55
|
+
mockUtils.buildMigrationSuccessMessage.mockReturnValue('Migration created successfully');
|
|
55
56
|
mockCreateMigrationResponse = {
|
|
56
57
|
assetMigration: {
|
|
57
58
|
migrationId: 'migration-123',
|
package/lib/migration/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const commander_1 = require("commander");
|
|
|
7
7
|
const create_1 = __importDefault(require("./create/create"));
|
|
8
8
|
const get_1 = __importDefault(require("./get/get"));
|
|
9
9
|
const next_1 = __importDefault(require("./next/next"));
|
|
10
|
+
const pre_1 = __importDefault(require("./pre/pre"));
|
|
10
11
|
const settings_1 = __importDefault(require("./settings/settings"));
|
|
11
12
|
const revert_1 = __importDefault(require("./revert/revert"));
|
|
12
13
|
const list_1 = __importDefault(require("./list/list"));
|
|
@@ -17,6 +18,7 @@ migrationCommand
|
|
|
17
18
|
.addCommand((0, get_1.default)())
|
|
18
19
|
.addCommand((0, list_1.default)())
|
|
19
20
|
.addCommand((0, next_1.default)())
|
|
21
|
+
.addCommand((0, pre_1.default)())
|
|
20
22
|
.addCommand((0, settings_1.default)())
|
|
21
23
|
.addCommand((0, revert_1.default)());
|
|
22
24
|
exports.default = migrationCommand;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const commander_1 = require("commander");
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
const loadCctIdsFromFile_1 = require("../utils/loadCctIdsFromFile");
|
|
20
|
+
const preMigrationCommand = () => {
|
|
21
|
+
const preCommand = new commander_1.Command('pre')
|
|
22
|
+
.name('pre')
|
|
23
|
+
.description('Create a new pre-migration using the AI Page Migration service')
|
|
24
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_URL))
|
|
25
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.CCT_IDS))
|
|
26
|
+
.addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
|
|
27
|
+
.configureOutput({
|
|
28
|
+
outputError(str, write) {
|
|
29
|
+
write(chalk_1.default.red(str));
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(preCommand);
|
|
34
|
+
const spinner = (0, ora_1.default)('Creating pre-migration').start();
|
|
35
|
+
try {
|
|
36
|
+
const cctIds = (0, loadCctIdsFromFile_1.loadCctIdsFromFile)(options.cctIds);
|
|
37
|
+
// Create pre-migration
|
|
38
|
+
const response = yield (0, utils_1.createMigration)(Object.assign(Object.assign({}, options), { cctIds }));
|
|
39
|
+
if (!response) {
|
|
40
|
+
throw new Error('Pre-migration creation failed');
|
|
41
|
+
}
|
|
42
|
+
spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('pre-migration', response.assetMigration));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
spinner.fail();
|
|
46
|
+
(0, utils_1.handleCommandError)(preCommand, error);
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
if (process.env.ENABLE_OVERRIDE_MIGRATION_URL === 'true') {
|
|
50
|
+
preCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire migration url with a custom value'));
|
|
51
|
+
}
|
|
52
|
+
return preCommand;
|
|
53
|
+
};
|
|
54
|
+
exports.default = preMigrationCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const nock_1 = __importDefault(require("nock"));
|
|
39
|
+
const pre_1 = __importDefault(require("./pre"));
|
|
40
|
+
const utils = __importStar(require("../utils/common"));
|
|
41
|
+
const createMigration = __importStar(require("../utils/createMigration"));
|
|
42
|
+
const loadCctIdsFromFile = __importStar(require("../utils/loadCctIdsFromFile"));
|
|
43
|
+
jest.mock('../utils/common');
|
|
44
|
+
jest.mock('../utils/createMigration');
|
|
45
|
+
jest.mock('../utils/loadCctIdsFromFile');
|
|
46
|
+
const mockUtils = utils;
|
|
47
|
+
const mockCreateMigration = createMigration;
|
|
48
|
+
const mockLoadCctIdsFromFile = loadCctIdsFromFile;
|
|
49
|
+
describe('preMigrationCommand', () => {
|
|
50
|
+
let logSpy;
|
|
51
|
+
let mockCreateMigrationResponse;
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
nock_1.default.cleanAll();
|
|
54
|
+
jest.clearAllMocks();
|
|
55
|
+
jest.resetAllMocks();
|
|
56
|
+
logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
57
|
+
mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
|
|
58
|
+
mockUtils.buildMigrationSuccessMessage.mockReturnValue('Pre-migration created successfully');
|
|
59
|
+
mockLoadCctIdsFromFile.loadCctIdsFromFile.mockReturnValue([
|
|
60
|
+
'cct-id-1',
|
|
61
|
+
'cct-id-2',
|
|
62
|
+
]);
|
|
63
|
+
mockCreateMigrationResponse = {
|
|
64
|
+
assetMigration: {
|
|
65
|
+
migrationId: 'migration-123',
|
|
66
|
+
assetId: 'asset-456',
|
|
67
|
+
stage: 'pending',
|
|
68
|
+
status: 'created',
|
|
69
|
+
xmlFilePath: '/path/to/xml',
|
|
70
|
+
matrixUrl: 'https://matrix.example.com',
|
|
71
|
+
previewAssetId: 'preview-789',
|
|
72
|
+
created: 1234567890,
|
|
73
|
+
updated: 1234567890,
|
|
74
|
+
migrationIdAssetId: 'migration-123-asset-456',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
mockCreateMigration.createMigration.mockResolvedValue(mockCreateMigrationResponse);
|
|
78
|
+
});
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
logSpy.mockRestore();
|
|
81
|
+
});
|
|
82
|
+
describe('successful pre-migration creation', () => {
|
|
83
|
+
it('should create pre-migration successfully with all required options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
const program = (0, pre_1.default)();
|
|
85
|
+
yield program.parseAsync([
|
|
86
|
+
'node',
|
|
87
|
+
'dxp-cli',
|
|
88
|
+
'--matrix-url',
|
|
89
|
+
'https://matrix.example.com',
|
|
90
|
+
'--cct-ids',
|
|
91
|
+
'/path/to/cct-ids.json',
|
|
92
|
+
]);
|
|
93
|
+
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
94
|
+
expect(mockLoadCctIdsFromFile.loadCctIdsFromFile).toHaveBeenCalledWith('/path/to/cct-ids.json');
|
|
95
|
+
expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
|
|
96
|
+
matrixUrl: 'https://matrix.example.com',
|
|
97
|
+
cctIds: ['cct-id-1', 'cct-id-2'],
|
|
98
|
+
});
|
|
99
|
+
expect(mockCreateMigration.createMigration).toHaveBeenCalledTimes(1);
|
|
100
|
+
expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
|
|
101
|
+
}));
|
|
102
|
+
it('should create pre-migration with tenant option', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
const program = (0, pre_1.default)();
|
|
104
|
+
yield program.parseAsync([
|
|
105
|
+
'node',
|
|
106
|
+
'dxp-cli',
|
|
107
|
+
'--matrix-url',
|
|
108
|
+
'https://matrix.example.com',
|
|
109
|
+
'--cct-ids',
|
|
110
|
+
'/path/to/cct-ids.json',
|
|
111
|
+
'--tenant',
|
|
112
|
+
'test-tenant',
|
|
113
|
+
]);
|
|
114
|
+
expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
|
|
115
|
+
matrixUrl: 'https://matrix.example.com',
|
|
116
|
+
cctIds: ['cct-id-1', 'cct-id-2'],
|
|
117
|
+
tenant: 'test-tenant',
|
|
118
|
+
});
|
|
119
|
+
}));
|
|
120
|
+
it('should create pre-migration with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
+
const originalEnv = process.env.ENABLE_OVERRIDE_MIGRATION_URL;
|
|
122
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = 'true';
|
|
123
|
+
const program = (0, pre_1.default)();
|
|
124
|
+
yield program.parseAsync([
|
|
125
|
+
'node',
|
|
126
|
+
'dxp-cli',
|
|
127
|
+
'--matrix-url',
|
|
128
|
+
'https://matrix.example.com',
|
|
129
|
+
'--cct-ids',
|
|
130
|
+
'/path/to/cct-ids.json',
|
|
131
|
+
'--overrideUrl',
|
|
132
|
+
'https://custom.migration.url',
|
|
133
|
+
]);
|
|
134
|
+
expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
|
|
135
|
+
matrixUrl: 'https://matrix.example.com',
|
|
136
|
+
cctIds: ['cct-id-1', 'cct-id-2'],
|
|
137
|
+
overrideUrl: 'https://custom.migration.url',
|
|
138
|
+
});
|
|
139
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
|
|
140
|
+
}));
|
|
141
|
+
});
|
|
142
|
+
describe('error scenarios', () => {
|
|
143
|
+
it('should handle pre-migration creation failure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
mockCreateMigration.createMigration.mockResolvedValue(null);
|
|
145
|
+
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
146
|
+
const program = (0, pre_1.default)();
|
|
147
|
+
yield program.parseAsync([
|
|
148
|
+
'node',
|
|
149
|
+
'dxp-cli',
|
|
150
|
+
'--matrix-url',
|
|
151
|
+
'https://matrix.example.com',
|
|
152
|
+
'--cct-ids',
|
|
153
|
+
'/path/to/cct-ids.json',
|
|
154
|
+
]);
|
|
155
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, new Error('Pre-migration creation failed'));
|
|
156
|
+
}));
|
|
157
|
+
it('should handle migration API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
const apiError = new Error('Migration API failed');
|
|
159
|
+
mockCreateMigration.createMigration.mockRejectedValue(apiError);
|
|
160
|
+
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
161
|
+
const program = (0, pre_1.default)();
|
|
162
|
+
yield program.parseAsync([
|
|
163
|
+
'node',
|
|
164
|
+
'dxp-cli',
|
|
165
|
+
'--matrix-url',
|
|
166
|
+
'https://matrix.example.com',
|
|
167
|
+
'--cct-ids',
|
|
168
|
+
'/path/to/cct-ids.json',
|
|
169
|
+
]);
|
|
170
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, apiError);
|
|
171
|
+
}));
|
|
172
|
+
it('should handle not being logged in', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
173
|
+
const loginError = new Error('Not logged in');
|
|
174
|
+
mockUtils.throwErrorIfNotLoggedIn.mockImplementation(() => {
|
|
175
|
+
throw loginError;
|
|
176
|
+
});
|
|
177
|
+
const program = (0, pre_1.default)();
|
|
178
|
+
yield expect(program.parseAsync([
|
|
179
|
+
'node',
|
|
180
|
+
'dxp-cli',
|
|
181
|
+
'--matrix-url',
|
|
182
|
+
'https://matrix.example.com',
|
|
183
|
+
'--cct-ids',
|
|
184
|
+
'/path/to/cct-ids.json',
|
|
185
|
+
])).rejects.toThrow('Not logged in');
|
|
186
|
+
expect(mockCreateMigration.createMigration).not.toHaveBeenCalled();
|
|
187
|
+
}));
|
|
188
|
+
it('should handle loadCctIdsFromFile error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
|
+
const loadError = new Error('Failed to load CCT IDs from file');
|
|
190
|
+
mockLoadCctIdsFromFile.loadCctIdsFromFile.mockImplementation(() => {
|
|
191
|
+
throw loadError;
|
|
192
|
+
});
|
|
193
|
+
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
194
|
+
const program = (0, pre_1.default)();
|
|
195
|
+
yield program.parseAsync([
|
|
196
|
+
'node',
|
|
197
|
+
'dxp-cli',
|
|
198
|
+
'--matrix-url',
|
|
199
|
+
'https://matrix.example.com',
|
|
200
|
+
'--cct-ids',
|
|
201
|
+
'/path/to/invalid.json',
|
|
202
|
+
]);
|
|
203
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, loadError);
|
|
204
|
+
expect(mockCreateMigration.createMigration).not.toHaveBeenCalled();
|
|
205
|
+
}));
|
|
206
|
+
});
|
|
207
|
+
describe('required options validation', () => {
|
|
208
|
+
it('should require matrixUrl option', () => {
|
|
209
|
+
const program = (0, pre_1.default)().exitOverride();
|
|
210
|
+
expect(() => {
|
|
211
|
+
program.parse([
|
|
212
|
+
'node',
|
|
213
|
+
'dxp-cli',
|
|
214
|
+
'--cct-ids',
|
|
215
|
+
'/path/to/cct-ids.json',
|
|
216
|
+
]);
|
|
217
|
+
}).toThrow();
|
|
218
|
+
});
|
|
219
|
+
it('should require cctIds option', () => {
|
|
220
|
+
const program = (0, pre_1.default)().exitOverride();
|
|
221
|
+
expect(() => {
|
|
222
|
+
program.parse([
|
|
223
|
+
'node',
|
|
224
|
+
'dxp-cli',
|
|
225
|
+
'--matrix-url',
|
|
226
|
+
'https://matrix.example.com',
|
|
227
|
+
]);
|
|
228
|
+
}).toThrow();
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
describe('command configuration', () => {
|
|
232
|
+
it('should have correct command name and description', () => {
|
|
233
|
+
const program = (0, pre_1.default)();
|
|
234
|
+
expect(program.name()).toBe('pre');
|
|
235
|
+
expect(program.description()).toBe('Create a new pre-migration using the AI Page Migration service');
|
|
236
|
+
});
|
|
237
|
+
it('should parse options correctly', () => {
|
|
238
|
+
const program = (0, pre_1.default)();
|
|
239
|
+
program.parse([
|
|
240
|
+
'node',
|
|
241
|
+
'dxp-cli',
|
|
242
|
+
'--matrix-url',
|
|
243
|
+
'https://matrix.example.com',
|
|
244
|
+
'--cct-ids',
|
|
245
|
+
'/path/to/cct-ids.json',
|
|
246
|
+
'--tenant',
|
|
247
|
+
'test-tenant',
|
|
248
|
+
]);
|
|
249
|
+
const opts = program.opts();
|
|
250
|
+
expect(opts.matrixUrl).toBe('https://matrix.example.com');
|
|
251
|
+
expect(opts.cctIds).toBe('/path/to/cct-ids.json');
|
|
252
|
+
expect(opts.tenant).toBe('test-tenant');
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
describe('spinner and output behavior', () => {
|
|
256
|
+
it('should display appropriate spinner messages during execution', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
+
const program = (0, pre_1.default)();
|
|
258
|
+
yield program.parseAsync([
|
|
259
|
+
'node',
|
|
260
|
+
'dxp-cli',
|
|
261
|
+
'--matrix-url',
|
|
262
|
+
'https://matrix.example.com',
|
|
263
|
+
'--cct-ids',
|
|
264
|
+
'/path/to/cct-ids.json',
|
|
265
|
+
]);
|
|
266
|
+
expect(mockCreateMigration.createMigration).toHaveBeenCalled();
|
|
267
|
+
}));
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -3,6 +3,16 @@ export interface CommonCommandOptions {
|
|
|
3
3
|
overrideUrl?: string;
|
|
4
4
|
}
|
|
5
5
|
export interface AssetMigration {
|
|
6
|
+
/**
|
|
7
|
+
* Will be programmatically set while creating a migration or pre-migration,
|
|
8
|
+
* depending on whether assetId and cctIds are provided.
|
|
9
|
+
*/
|
|
10
|
+
isPreMigration?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* In pre-migrations, this will be the CCT IDs to generate specs for.
|
|
13
|
+
* In migrations, this will be the CCT IDs to be skipped (because they were already converted and deployed).
|
|
14
|
+
*/
|
|
15
|
+
cctIds?: string[];
|
|
6
16
|
migrationId: string;
|
|
7
17
|
assetId: string;
|
|
8
18
|
xmlFilePath: string;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { AssetMigration, CommonCommandOptions } from '.';
|
|
2
2
|
export interface CreateMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'assetId' | 'previewAssetId' | 'matrixUrl'> {
|
|
3
|
+
/**
|
|
4
|
+
* The path to a JSON file containing the CCT IDs to be skipped in a migration (because they were already converted and deployed)
|
|
5
|
+
*/
|
|
6
|
+
cctIds?: string;
|
|
3
7
|
}
|
|
4
8
|
export interface CreateMigrationApiResponse {
|
|
5
9
|
assetMigration: AssetMigration;
|
|
@@ -18,5 +18,6 @@ __exportStar(require("./common.types"), exports);
|
|
|
18
18
|
__exportStar(require("./createMigration.types"), exports);
|
|
19
19
|
__exportStar(require("./getMigration.types"), exports);
|
|
20
20
|
__exportStar(require("./nextStage.types"), exports);
|
|
21
|
+
__exportStar(require("./preMigration.types"), exports);
|
|
21
22
|
__exportStar(require("./settings.types"), exports);
|
|
22
23
|
__exportStar(require("./revert.types"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AssetMigration, CommonCommandOptions } from '.';
|
|
2
|
+
export interface PreMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'matrixUrl'> {
|
|
3
|
+
/**
|
|
4
|
+
* The path to a JSON file containing the CCT IDs to generate specs
|
|
5
|
+
*/
|
|
6
|
+
cctIds: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PreMigrationApiResponse {
|
|
9
|
+
assetMigration: AssetMigration;
|
|
10
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { AssetMigration } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* The purpose of this file is to provide utilities in common
|
|
4
5
|
* such as functions that can be reused across the migration service.
|
|
@@ -29,3 +30,10 @@ export declare function buildMigrationUrl(tenantID?: string, overrideUrl?: strin
|
|
|
29
30
|
export declare function validateAxiosStatus(status: number): boolean;
|
|
30
31
|
export declare function getMigrationHeaders(tenantID?: string, isJson?: boolean): Promise<Record<string, string>>;
|
|
31
32
|
export declare function redactKey(key: string, visibleChars?: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Builds a success message for migration creation.
|
|
35
|
+
* @param label - The label for the migration type (e.g., "migration" or "pre-migration").
|
|
36
|
+
* @param assetMigration - The asset migration response.
|
|
37
|
+
* @returns The formatted success message.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildMigrationSuccessMessage(label: string, assetMigration: AssetMigration): string;
|
|
@@ -12,7 +12,7 @@ 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
|
-
exports.redactKey = exports.getMigrationHeaders = exports.validateAxiosStatus = exports.buildMigrationUrl = exports.throwErrorIfNotLoggedIn = exports.handleCommandError = void 0;
|
|
15
|
+
exports.buildMigrationSuccessMessage = exports.redactKey = exports.getMigrationHeaders = exports.validateAxiosStatus = exports.buildMigrationUrl = exports.throwErrorIfNotLoggedIn = exports.handleCommandError = void 0;
|
|
16
16
|
const chalk_1 = __importDefault(require("chalk"));
|
|
17
17
|
const ApplicationConfig_1 = require("../../ApplicationConfig");
|
|
18
18
|
const axios_1 = __importDefault(require("axios"));
|
|
@@ -114,3 +114,21 @@ function redactKey(key, visibleChars = 3) {
|
|
|
114
114
|
return masked + key.slice(-visibleChars);
|
|
115
115
|
}
|
|
116
116
|
exports.redactKey = redactKey;
|
|
117
|
+
/**
|
|
118
|
+
* Builds a success message for migration creation.
|
|
119
|
+
* @param label - The label for the migration type (e.g., "migration" or "pre-migration").
|
|
120
|
+
* @param assetMigration - The asset migration response.
|
|
121
|
+
* @returns The formatted success message.
|
|
122
|
+
*/
|
|
123
|
+
function buildMigrationSuccessMessage(label, assetMigration) {
|
|
124
|
+
const { isPreMigration, cctIds, migrationId, assetId, stage, status } = assetMigration;
|
|
125
|
+
return `Successfully created ${label}: ${JSON.stringify({
|
|
126
|
+
isPreMigration,
|
|
127
|
+
migrationId,
|
|
128
|
+
assetId,
|
|
129
|
+
stage,
|
|
130
|
+
status,
|
|
131
|
+
cctIds: (cctIds === null || cctIds === void 0 ? void 0 : cctIds.length) ? JSON.stringify(cctIds).substring(0, 100) : '[]',
|
|
132
|
+
})}`;
|
|
133
|
+
}
|
|
134
|
+
exports.buildMigrationSuccessMessage = buildMigrationSuccessMessage;
|
|
@@ -1,5 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
1
|
+
import { CommonCommandOptions, CreateMigrationApiResponse } from '../types';
|
|
2
|
+
export interface CreateMigrationInput extends CommonCommandOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Optional for pre-migrations, required for migrations.
|
|
5
|
+
*/
|
|
6
|
+
assetId?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional for pre-migrations, required for migrations.
|
|
9
|
+
*/
|
|
10
|
+
previewAssetId?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Required for both migrations and pre-migrations.
|
|
13
|
+
*/
|
|
14
|
+
matrixUrl: string;
|
|
15
|
+
/**
|
|
16
|
+
* Optional for migrations, required for pre-migrations.
|
|
17
|
+
*/
|
|
18
|
+
cctIds?: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new migration or pre-migration using the AI Page Migration service.
|
|
22
|
+
* Pre-migrations are used to generate specs for CCTs so they can be converted and deployed in advance.
|
|
23
|
+
* @param {CreateMigrationInput} input - The input parameters for the migration/pre-migration creation.
|
|
24
|
+
* @returns {Promise<CreateMigrationApiResponse>}
|
|
25
|
+
*/
|
|
26
|
+
export declare function createMigration({ tenant, overrideUrl, assetId, previewAssetId, matrixUrl, cctIds, }: CreateMigrationInput): Promise<CreateMigrationApiResponse>;
|
|
3
27
|
export declare function validateExportFolder(exportPath: string): void;
|
|
4
28
|
/**
|
|
5
29
|
* Creates a tar file from the export path.
|