@squiz/dxp-cli-next 5.33.0-develop.2 → 5.33.0-develop.4
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/README.md +1 -0
- package/lib/migration/batch-get/batch-get.d.ts +3 -0
- package/lib/migration/batch-get/batch-get.js +45 -0
- package/lib/migration/batch-get/batch-get.spec.js +182 -0
- package/lib/migration/batch-next/batch-next.d.ts +3 -0
- package/lib/migration/batch-next/batch-next.js +60 -0
- package/lib/migration/batch-next/batch-next.spec.d.ts +1 -0
- package/lib/migration/batch-next/batch-next.spec.js +251 -0
- package/lib/migration/batch-revert/batch-revert.d.ts +3 -0
- package/lib/migration/batch-revert/batch-revert.js +45 -0
- package/lib/migration/batch-revert/batch-revert.spec.d.ts +1 -0
- package/lib/migration/batch-revert/batch-revert.spec.js +197 -0
- package/lib/migration/create/create.js +27 -7
- package/lib/migration/create/create.spec.js +48 -20
- package/lib/migration/get/get.js +3 -3
- package/lib/migration/get/get.spec.js +8 -19
- package/lib/migration/index.js +9 -1
- package/lib/migration/list/list.spec.js +7 -6
- package/lib/migration/mark-deployed/mark-deployed.d.ts +3 -0
- package/lib/migration/mark-deployed/mark-deployed.js +55 -0
- package/lib/migration/mark-deployed/mark-deployed.spec.d.ts +1 -0
- package/lib/migration/mark-deployed/mark-deployed.spec.js +217 -0
- package/lib/migration/next/next.spec.js +6 -5
- package/lib/migration/pre/pre.js +3 -3
- package/lib/migration/pre/pre.spec.js +8 -8
- package/lib/migration/revert/revert.js +1 -1
- package/lib/migration/revert/revert.spec.js +1 -1
- package/lib/migration/settings/settings.spec.js +2 -2
- package/lib/migration/types/common.types.d.ts +33 -2
- package/lib/migration/types/common.types.js +17 -0
- package/lib/migration/types/createMigration.types.d.ts +41 -3
- package/lib/migration/types/getMigration.types.d.ts +5 -1
- package/lib/migration/types/index.d.ts +1 -0
- package/lib/migration/types/index.js +1 -0
- package/lib/migration/types/markDeployed.types.d.ts +20 -0
- package/lib/migration/types/markDeployed.types.js +2 -0
- package/lib/migration/types/nextStage.types.d.ts +22 -1
- package/lib/migration/types/revert.types.d.ts +12 -0
- package/lib/migration/utils/common.d.ts +17 -3
- package/lib/migration/utils/common.js +56 -24
- package/lib/migration/utils/common.spec.js +73 -2
- package/lib/migration/utils/createMigration.d.ts +4 -21
- package/lib/migration/utils/createMigration.js +23 -32
- package/lib/migration/utils/createMigration.spec.js +19 -18
- package/lib/migration/utils/getMigration.d.ts +2 -1
- package/lib/migration/utils/getMigration.js +23 -18
- package/lib/migration/utils/getMigration.spec.js +146 -7
- package/lib/migration/utils/index.d.ts +1 -0
- package/lib/migration/utils/index.js +1 -0
- package/lib/migration/utils/listMigrations.spec.js +7 -6
- package/lib/migration/utils/loadAssetIdsFromFile.d.ts +9 -0
- package/lib/migration/utils/loadAssetIdsFromFile.js +40 -0
- package/lib/migration/utils/loadAssetIdsFromFile.spec.d.ts +1 -0
- package/lib/migration/utils/{loadCctIdsFromFile.spec.js → loadAssetIdsFromFile.spec.js} +13 -13
- package/lib/migration/utils/loadStageOptionsFromFile.d.ts +2 -1
- package/lib/migration/utils/markComponentsDeployed.d.ts +2 -0
- package/lib/migration/utils/markComponentsDeployed.js +37 -0
- package/lib/migration/utils/markComponentsDeployed.spec.d.ts +1 -0
- package/lib/migration/utils/markComponentsDeployed.spec.js +222 -0
- package/lib/migration/utils/nextStage.d.ts +2 -1
- package/lib/migration/utils/nextStage.js +32 -22
- package/lib/migration/utils/nextStage.spec.js +179 -7
- package/lib/migration/utils/options.d.ts +4 -1
- package/lib/migration/utils/options.js +32 -2
- package/lib/migration/utils/revertMigration.d.ts +2 -1
- package/lib/migration/utils/revertMigration.js +21 -1
- package/lib/migration/utils/revertMigration.spec.js +115 -0
- package/lib/page/utils/definitions.js +1 -1
- package/lib/page/utils/definitions.spec.js +19 -8
- package/package.json +1 -1
- package/lib/migration/utils/loadCctIdsFromFile.d.ts +0 -1
- package/lib/migration/utils/loadCctIdsFromFile.js +0 -32
- /package/lib/migration/{utils/loadCctIdsFromFile.spec.d.ts → batch-get/batch-get.spec.d.ts} +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
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 mark_deployed_1 = __importDefault(require("./mark-deployed"));
|
|
40
|
+
const utils = __importStar(require("../utils/common"));
|
|
41
|
+
const ApplicationStore = __importStar(require("../../ApplicationStore"));
|
|
42
|
+
const markComponentsDeployedModule = __importStar(require("../utils/markComponentsDeployed"));
|
|
43
|
+
const loadAssetIdsModule = __importStar(require("../utils/loadAssetIdsFromFile"));
|
|
44
|
+
jest.mock('../utils/common');
|
|
45
|
+
jest.mock('../utils/markComponentsDeployed');
|
|
46
|
+
jest.mock('../utils/loadAssetIdsFromFile');
|
|
47
|
+
jest.mock('../../ApplicationStore');
|
|
48
|
+
const mockUtils = utils;
|
|
49
|
+
const mockMarkComponentsDeployed = markComponentsDeployedModule;
|
|
50
|
+
const mockLoadAssetIds = loadAssetIdsModule;
|
|
51
|
+
const mockApplicationStore = ApplicationStore;
|
|
52
|
+
describe('markDeployedCommand', () => {
|
|
53
|
+
let logSpy;
|
|
54
|
+
let mockMarkDeployedResponse;
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
nock_1.default.cleanAll();
|
|
57
|
+
jest.clearAllMocks();
|
|
58
|
+
jest.resetAllMocks();
|
|
59
|
+
logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
60
|
+
mockApplicationStore.getApplicationFile.mockResolvedValue('session-cookie');
|
|
61
|
+
mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
|
|
62
|
+
mockLoadAssetIds.loadAssetIdsFromFile.mockReturnValue([
|
|
63
|
+
'cct-1',
|
|
64
|
+
'cct-2',
|
|
65
|
+
'cct-3',
|
|
66
|
+
]);
|
|
67
|
+
mockMarkDeployedResponse = {
|
|
68
|
+
success: ['cct-1', 'cct-2', 'cct-3'],
|
|
69
|
+
failed: [],
|
|
70
|
+
};
|
|
71
|
+
mockMarkComponentsDeployed.markComponentsDeployed.mockResolvedValue(mockMarkDeployedResponse);
|
|
72
|
+
});
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
logSpy.mockRestore();
|
|
75
|
+
});
|
|
76
|
+
describe('successful mark deployed execution', () => {
|
|
77
|
+
it('should mark components as deployed successfully with required options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
const program = (0, mark_deployed_1.default)();
|
|
79
|
+
yield program.parseAsync(['node', 'dxp-cli', '--cct-ids', './ccts.json']);
|
|
80
|
+
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
81
|
+
expect(mockLoadAssetIds.loadAssetIdsFromFile).toHaveBeenCalledWith('./ccts.json');
|
|
82
|
+
expect(mockMarkComponentsDeployed.markComponentsDeployed).toHaveBeenCalledWith({
|
|
83
|
+
cctIds: ['cct-1', 'cct-2', 'cct-3'],
|
|
84
|
+
});
|
|
85
|
+
expect(mockMarkComponentsDeployed.markComponentsDeployed).toHaveBeenCalledTimes(1);
|
|
86
|
+
expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
|
|
87
|
+
}));
|
|
88
|
+
it('should mark components as deployed with tenant option', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
+
const program = (0, mark_deployed_1.default)();
|
|
90
|
+
yield program.parseAsync([
|
|
91
|
+
'node',
|
|
92
|
+
'dxp-cli',
|
|
93
|
+
'--cct-ids',
|
|
94
|
+
'./ccts.json',
|
|
95
|
+
'--tenant',
|
|
96
|
+
'test-tenant',
|
|
97
|
+
]);
|
|
98
|
+
expect(mockMarkComponentsDeployed.markComponentsDeployed).toHaveBeenCalledWith({
|
|
99
|
+
cctIds: ['cct-1', 'cct-2', 'cct-3'],
|
|
100
|
+
tenant: 'test-tenant',
|
|
101
|
+
});
|
|
102
|
+
}));
|
|
103
|
+
it('should mark components as deployed with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
|
+
const originalEnv = process.env.ENABLE_OVERRIDE_MIGRATION_URL;
|
|
105
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = 'true';
|
|
106
|
+
const program = (0, mark_deployed_1.default)();
|
|
107
|
+
yield program.parseAsync([
|
|
108
|
+
'node',
|
|
109
|
+
'dxp-cli',
|
|
110
|
+
'--cct-ids',
|
|
111
|
+
'./ccts.json',
|
|
112
|
+
'--overrideUrl',
|
|
113
|
+
'https://custom.migration.url',
|
|
114
|
+
]);
|
|
115
|
+
expect(mockMarkComponentsDeployed.markComponentsDeployed).toHaveBeenCalledWith({
|
|
116
|
+
cctIds: ['cct-1', 'cct-2', 'cct-3'],
|
|
117
|
+
overrideUrl: 'https://custom.migration.url',
|
|
118
|
+
});
|
|
119
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
|
|
120
|
+
}));
|
|
121
|
+
it('should handle mixed success and failure response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
|
+
mockMarkDeployedResponse = {
|
|
123
|
+
success: ['cct-1'],
|
|
124
|
+
failed: [
|
|
125
|
+
{ cctId: 'cct-2', error: 'Component not found' },
|
|
126
|
+
{ cctId: 'cct-3', error: 'Already deployed' },
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
mockMarkComponentsDeployed.markComponentsDeployed.mockResolvedValue(mockMarkDeployedResponse);
|
|
130
|
+
const program = (0, mark_deployed_1.default)();
|
|
131
|
+
yield program.parseAsync(['node', 'dxp-cli', '--cct-ids', './ccts.json']);
|
|
132
|
+
expect(mockMarkComponentsDeployed.markComponentsDeployed).toHaveBeenCalledTimes(1);
|
|
133
|
+
expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
|
|
134
|
+
}));
|
|
135
|
+
});
|
|
136
|
+
describe('error scenarios', () => {
|
|
137
|
+
it('should handle markComponentsDeployed API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
138
|
+
const apiError = new Error('Failed to mark components as deployed');
|
|
139
|
+
mockMarkComponentsDeployed.markComponentsDeployed.mockRejectedValue(apiError);
|
|
140
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
141
|
+
const program = (0, mark_deployed_1.default)();
|
|
142
|
+
yield program.parseAsync(['node', 'dxp-cli', '--cct-ids', './ccts.json']);
|
|
143
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, apiError);
|
|
144
|
+
}));
|
|
145
|
+
it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
146
|
+
const networkError = new Error('Network connection failed');
|
|
147
|
+
mockMarkComponentsDeployed.markComponentsDeployed.mockRejectedValue(networkError);
|
|
148
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
149
|
+
const program = (0, mark_deployed_1.default)();
|
|
150
|
+
yield program.parseAsync(['node', 'dxp-cli', '--cct-ids', './ccts.json']);
|
|
151
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, networkError);
|
|
152
|
+
}));
|
|
153
|
+
it('should handle empty CCT IDs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
|
+
mockLoadAssetIds.loadAssetIdsFromFile.mockReturnValue([]);
|
|
155
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
156
|
+
const program = (0, mark_deployed_1.default)();
|
|
157
|
+
yield program.parseAsync([
|
|
158
|
+
'node',
|
|
159
|
+
'dxp-cli',
|
|
160
|
+
'--cct-ids',
|
|
161
|
+
'./empty-ccts.json',
|
|
162
|
+
]);
|
|
163
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, expect.objectContaining({
|
|
164
|
+
message: 'No CCT IDs provided',
|
|
165
|
+
}));
|
|
166
|
+
}));
|
|
167
|
+
it('should handle undefined CCT IDs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
+
mockLoadAssetIds.loadAssetIdsFromFile.mockReturnValue(undefined);
|
|
169
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
170
|
+
const program = (0, mark_deployed_1.default)();
|
|
171
|
+
yield program.parseAsync([
|
|
172
|
+
'node',
|
|
173
|
+
'dxp-cli',
|
|
174
|
+
'--cct-ids',
|
|
175
|
+
'./invalid-ccts.json',
|
|
176
|
+
]);
|
|
177
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, expect.objectContaining({
|
|
178
|
+
message: 'No CCT IDs provided',
|
|
179
|
+
}));
|
|
180
|
+
}));
|
|
181
|
+
});
|
|
182
|
+
describe('required options validation', () => {
|
|
183
|
+
it('should require cct-ids option', () => {
|
|
184
|
+
const program = (0, mark_deployed_1.default)().exitOverride();
|
|
185
|
+
expect(() => {
|
|
186
|
+
program.parse(['node', 'dxp-cli']);
|
|
187
|
+
}).toThrow();
|
|
188
|
+
});
|
|
189
|
+
it('should not require tenant option', () => {
|
|
190
|
+
const program = (0, mark_deployed_1.default)().exitOverride();
|
|
191
|
+
expect(() => {
|
|
192
|
+
program.parse(['node', 'dxp-cli', '--cct-ids', './ccts.json']);
|
|
193
|
+
}).not.toThrow();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
describe('command configuration', () => {
|
|
197
|
+
it('should have correct command name and description', () => {
|
|
198
|
+
const program = (0, mark_deployed_1.default)();
|
|
199
|
+
expect(program.name()).toBe('mark-deployed');
|
|
200
|
+
expect(program.description()).toBe('Mark components as deployed in the AI Page Migration service');
|
|
201
|
+
});
|
|
202
|
+
it('should parse options correctly', () => {
|
|
203
|
+
const program = (0, mark_deployed_1.default)();
|
|
204
|
+
program.parse([
|
|
205
|
+
'node',
|
|
206
|
+
'dxp-cli',
|
|
207
|
+
'--cct-ids',
|
|
208
|
+
'./ccts.json',
|
|
209
|
+
'--tenant',
|
|
210
|
+
'test-tenant',
|
|
211
|
+
]);
|
|
212
|
+
const opts = program.opts();
|
|
213
|
+
expect(opts.cctIds).toBe('./ccts.json');
|
|
214
|
+
expect(opts.tenant).toBe('test-tenant');
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -41,6 +41,7 @@ const utils = __importStar(require("../utils/common"));
|
|
|
41
41
|
const ApplicationStore = __importStar(require("../../ApplicationStore"));
|
|
42
42
|
const nextStageModule = __importStar(require("../utils/nextStage"));
|
|
43
43
|
const getMigrationModule = __importStar(require("../utils/getMigration"));
|
|
44
|
+
const types_1 = require("../types");
|
|
44
45
|
jest.mock('../utils/common');
|
|
45
46
|
jest.mock('../utils/nextStage');
|
|
46
47
|
jest.mock('../utils/getMigration');
|
|
@@ -66,8 +67,8 @@ describe('nextStageCommand', () => {
|
|
|
66
67
|
mockGetMigration.getMigration.mockResolvedValue({
|
|
67
68
|
migrationId: 'migration-123',
|
|
68
69
|
assetId: 'asset-456',
|
|
69
|
-
stage:
|
|
70
|
-
status:
|
|
70
|
+
stage: types_1.MigrationStage.create,
|
|
71
|
+
status: types_1.MigrationStatus.running,
|
|
71
72
|
xmlFilePath: 'test.xml',
|
|
72
73
|
matrixUrl: 'http://test.com',
|
|
73
74
|
previewAssetId: 'preview-123',
|
|
@@ -159,7 +160,7 @@ describe('nextStageCommand', () => {
|
|
|
159
160
|
it('should handle getMigration error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
161
|
const migrationError = new Error('Failed to get migration: TypeError: Invalid URL');
|
|
161
162
|
mockGetMigration.getMigration.mockRejectedValue(migrationError);
|
|
162
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
163
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
163
164
|
const program = (0, next_1.default)();
|
|
164
165
|
yield program.parseAsync([
|
|
165
166
|
'node',
|
|
@@ -175,7 +176,7 @@ describe('nextStageCommand', () => {
|
|
|
175
176
|
it('should handle nextStage API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
177
|
const apiError = new Error('Failed to start next stage');
|
|
177
178
|
mockNextStage.nextStage.mockRejectedValue(apiError);
|
|
178
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
179
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
179
180
|
const program = (0, next_1.default)();
|
|
180
181
|
yield program.parseAsync([
|
|
181
182
|
'node',
|
|
@@ -191,7 +192,7 @@ describe('nextStageCommand', () => {
|
|
|
191
192
|
it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
192
193
|
const networkError = new Error('Network connection failed');
|
|
193
194
|
mockNextStage.nextStage.mockRejectedValue(networkError);
|
|
194
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
195
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
195
196
|
const program = (0, next_1.default)();
|
|
196
197
|
yield program.parseAsync([
|
|
197
198
|
'node',
|
package/lib/migration/pre/pre.js
CHANGED
|
@@ -16,7 +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
|
|
19
|
+
const loadAssetIdsFromFile_1 = require("../utils/loadAssetIdsFromFile");
|
|
20
20
|
const preMigrationCommand = () => {
|
|
21
21
|
const preCommand = new commander_1.Command('pre')
|
|
22
22
|
.name('pre')
|
|
@@ -33,13 +33,13 @@ const preMigrationCommand = () => {
|
|
|
33
33
|
yield (0, utils_1.throwErrorIfNotLoggedIn)(preCommand);
|
|
34
34
|
const spinner = (0, ora_1.default)('Creating pre-migration').start();
|
|
35
35
|
try {
|
|
36
|
-
const cctIds = (0,
|
|
36
|
+
const cctIds = (0, loadAssetIdsFromFile_1.loadAssetIdsFromFile)(options.cctIds);
|
|
37
37
|
// Create pre-migration
|
|
38
38
|
const response = yield (0, utils_1.createMigration)(Object.assign(Object.assign({}, options), { cctIds }));
|
|
39
39
|
if (!response) {
|
|
40
40
|
throw new Error('Pre-migration creation failed');
|
|
41
41
|
}
|
|
42
|
-
spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('pre-migration', response
|
|
42
|
+
spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('pre-migration', response));
|
|
43
43
|
}
|
|
44
44
|
catch (error) {
|
|
45
45
|
spinner.fail();
|
|
@@ -39,10 +39,10 @@ const nock_1 = __importDefault(require("nock"));
|
|
|
39
39
|
const pre_1 = __importDefault(require("./pre"));
|
|
40
40
|
const utils = __importStar(require("../utils/common"));
|
|
41
41
|
const createMigration = __importStar(require("../utils/createMigration"));
|
|
42
|
-
const loadCctIdsFromFile = __importStar(require("../utils/
|
|
42
|
+
const loadCctIdsFromFile = __importStar(require("../utils/loadAssetIdsFromFile"));
|
|
43
43
|
jest.mock('../utils/common');
|
|
44
44
|
jest.mock('../utils/createMigration');
|
|
45
|
-
jest.mock('../utils/
|
|
45
|
+
jest.mock('../utils/loadAssetIdsFromFile');
|
|
46
46
|
const mockUtils = utils;
|
|
47
47
|
const mockCreateMigration = createMigration;
|
|
48
48
|
const mockLoadCctIdsFromFile = loadCctIdsFromFile;
|
|
@@ -56,7 +56,7 @@ describe('preMigrationCommand', () => {
|
|
|
56
56
|
logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
57
57
|
mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
|
|
58
58
|
mockUtils.buildMigrationSuccessMessage.mockReturnValue('Pre-migration created successfully');
|
|
59
|
-
mockLoadCctIdsFromFile.
|
|
59
|
+
mockLoadCctIdsFromFile.loadAssetIdsFromFile.mockReturnValue([
|
|
60
60
|
'cct-id-1',
|
|
61
61
|
'cct-id-2',
|
|
62
62
|
]);
|
|
@@ -91,7 +91,7 @@ describe('preMigrationCommand', () => {
|
|
|
91
91
|
'/path/to/cct-ids.json',
|
|
92
92
|
]);
|
|
93
93
|
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
94
|
-
expect(mockLoadCctIdsFromFile.
|
|
94
|
+
expect(mockLoadCctIdsFromFile.loadAssetIdsFromFile).toHaveBeenCalledWith('/path/to/cct-ids.json');
|
|
95
95
|
expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
|
|
96
96
|
matrixUrl: 'https://matrix.example.com',
|
|
97
97
|
cctIds: ['cct-id-1', 'cct-id-2'],
|
|
@@ -142,7 +142,7 @@ describe('preMigrationCommand', () => {
|
|
|
142
142
|
describe('error scenarios', () => {
|
|
143
143
|
it('should handle pre-migration creation failure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
144
|
mockCreateMigration.createMigration.mockResolvedValue(null);
|
|
145
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
145
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
146
146
|
const program = (0, pre_1.default)();
|
|
147
147
|
yield program.parseAsync([
|
|
148
148
|
'node',
|
|
@@ -157,7 +157,7 @@ describe('preMigrationCommand', () => {
|
|
|
157
157
|
it('should handle migration API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
158
|
const apiError = new Error('Migration API failed');
|
|
159
159
|
mockCreateMigration.createMigration.mockRejectedValue(apiError);
|
|
160
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
160
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
161
161
|
const program = (0, pre_1.default)();
|
|
162
162
|
yield program.parseAsync([
|
|
163
163
|
'node',
|
|
@@ -187,10 +187,10 @@ describe('preMigrationCommand', () => {
|
|
|
187
187
|
}));
|
|
188
188
|
it('should handle loadCctIdsFromFile error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
189
|
const loadError = new Error('Failed to load CCT IDs from file');
|
|
190
|
-
mockLoadCctIdsFromFile.
|
|
190
|
+
mockLoadCctIdsFromFile.loadAssetIdsFromFile.mockImplementation(() => {
|
|
191
191
|
throw loadError;
|
|
192
192
|
});
|
|
193
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
193
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
194
194
|
const program = (0, pre_1.default)();
|
|
195
195
|
yield program.parseAsync([
|
|
196
196
|
'node',
|
|
@@ -20,7 +20,7 @@ const options_1 = require("../utils/options");
|
|
|
20
20
|
const revertMigrationCommand = () => {
|
|
21
21
|
const revertCommand = new commander_1.Command('revert')
|
|
22
22
|
.name('revert')
|
|
23
|
-
.description('Revert
|
|
23
|
+
.description('Revert asset with stage "morph" and status "awaiting-confirmation" using the AI Page migration service')
|
|
24
24
|
.addOption((0, options_1.getParamOption)(options_1.OptionName.MIGRATION_ID))
|
|
25
25
|
.addOption((0, options_1.getParamOption)(options_1.OptionName.ASSET_ID, false))
|
|
26
26
|
.addOption((0, options_1.getParamOption)(options_1.OptionName.TENANT, false))
|
|
@@ -52,7 +52,7 @@ describe('revertMigrationCommand', () => {
|
|
|
52
52
|
it('should have correct command name and description', () => {
|
|
53
53
|
const program = (0, revert_1.default)();
|
|
54
54
|
expect(program.name()).toBe('revert');
|
|
55
|
-
expect(program.description()).toBe('Revert
|
|
55
|
+
expect(program.description()).toBe('Revert asset with stage "morph" and status "awaiting-confirmation" using the AI Page migration service');
|
|
56
56
|
});
|
|
57
57
|
it('should have required migration-id option', () => {
|
|
58
58
|
const program = (0, revert_1.default)();
|
|
@@ -186,7 +186,7 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
186
186
|
it('should handle setMigrationSetting API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
187
|
const apiError = new Error('Settings update failed');
|
|
188
188
|
mockSetMigrationSettings.setMigrationSettings.mockRejectedValue(apiError);
|
|
189
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
189
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
190
190
|
const program = (0, settings_1.default)();
|
|
191
191
|
yield program.parseAsync([
|
|
192
192
|
'node',
|
|
@@ -207,7 +207,7 @@ describe('setMigrationSettingsCommand', () => {
|
|
|
207
207
|
it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
208
208
|
const networkError = new Error('Network connection failed');
|
|
209
209
|
mockSetMigrationSettings.setMigrationSettings.mockRejectedValue(networkError);
|
|
210
|
-
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
210
|
+
mockUtils.handleCommandError.mockImplementation((() => { }));
|
|
211
211
|
const program = (0, settings_1.default)();
|
|
212
212
|
yield program.parseAsync([
|
|
213
213
|
'node',
|
|
@@ -2,6 +2,20 @@ export interface CommonCommandOptions {
|
|
|
2
2
|
tenant?: string;
|
|
3
3
|
overrideUrl?: string;
|
|
4
4
|
}
|
|
5
|
+
export declare enum MigrationStage {
|
|
6
|
+
create = "create",
|
|
7
|
+
exportToJson = "export-to-json",
|
|
8
|
+
cctExport = "cct-export",
|
|
9
|
+
mapFromCctToCmp = "map-from-cct-to-cmp",
|
|
10
|
+
preview = "preview",
|
|
11
|
+
morph = "morph"
|
|
12
|
+
}
|
|
13
|
+
export declare enum MigrationStatus {
|
|
14
|
+
running = "running",
|
|
15
|
+
awaitingConfirmation = "awaiting-confirmation",
|
|
16
|
+
complete = "complete",
|
|
17
|
+
failed = "failed"
|
|
18
|
+
}
|
|
5
19
|
export interface AssetMigration {
|
|
6
20
|
/**
|
|
7
21
|
* Will be programmatically set while creating a migration or pre-migration,
|
|
@@ -13,17 +27,34 @@ export interface AssetMigration {
|
|
|
13
27
|
* In migrations, this will be the CCT IDs to be skipped (because they were already converted and deployed).
|
|
14
28
|
*/
|
|
15
29
|
cctIds?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Whether to trigger the next stage of the migration automatically.
|
|
32
|
+
* This will automatically be set to true for pre and bulk migrations.
|
|
33
|
+
* For single asset migrations, it will be set to false by default but can be overridden by the user.
|
|
34
|
+
*/
|
|
35
|
+
triggerNextStage?: boolean;
|
|
16
36
|
migrationId: string;
|
|
17
37
|
assetId: string;
|
|
18
38
|
xmlFilePath: string;
|
|
19
39
|
matrixUrl: string;
|
|
20
40
|
previewAssetId: string;
|
|
21
41
|
previewPageAssetId?: string;
|
|
22
|
-
stage:
|
|
23
|
-
status:
|
|
42
|
+
stage: MigrationStage;
|
|
43
|
+
status: MigrationStatus;
|
|
24
44
|
stageDetails?: string;
|
|
45
|
+
stageOptions?: Record<string, unknown>;
|
|
25
46
|
created: number;
|
|
26
47
|
updated: number;
|
|
27
48
|
migrationIdAssetId: string;
|
|
28
49
|
componentsTarDownloadUrl?: string;
|
|
29
50
|
}
|
|
51
|
+
declare type MigrationStageRecord = Partial<Record<MigrationStatus, {
|
|
52
|
+
assetIds: string[];
|
|
53
|
+
}>>;
|
|
54
|
+
export declare type AssetMigrationSummary = {
|
|
55
|
+
created: number;
|
|
56
|
+
expiry: number;
|
|
57
|
+
migrationId: string;
|
|
58
|
+
cctIds?: string[];
|
|
59
|
+
} & Partial<Record<MigrationStage, MigrationStageRecord>>;
|
|
60
|
+
export {};
|
|
@@ -1,2 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MigrationStatus = exports.MigrationStage = void 0;
|
|
4
|
+
var MigrationStage;
|
|
5
|
+
(function (MigrationStage) {
|
|
6
|
+
MigrationStage["create"] = "create";
|
|
7
|
+
MigrationStage["exportToJson"] = "export-to-json";
|
|
8
|
+
MigrationStage["cctExport"] = "cct-export";
|
|
9
|
+
MigrationStage["mapFromCctToCmp"] = "map-from-cct-to-cmp";
|
|
10
|
+
MigrationStage["preview"] = "preview";
|
|
11
|
+
MigrationStage["morph"] = "morph";
|
|
12
|
+
})(MigrationStage = exports.MigrationStage || (exports.MigrationStage = {}));
|
|
13
|
+
var MigrationStatus;
|
|
14
|
+
(function (MigrationStatus) {
|
|
15
|
+
MigrationStatus["running"] = "running";
|
|
16
|
+
MigrationStatus["awaitingConfirmation"] = "awaiting-confirmation";
|
|
17
|
+
MigrationStatus["complete"] = "complete";
|
|
18
|
+
MigrationStatus["failed"] = "failed";
|
|
19
|
+
})(MigrationStatus = exports.MigrationStatus || (exports.MigrationStatus = {}));
|
|
@@ -1,10 +1,48 @@
|
|
|
1
|
-
import { AssetMigration, CommonCommandOptions } from '.';
|
|
2
|
-
export interface CreateMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, '
|
|
1
|
+
import { AssetMigration, BatchNextStageResults, CommonCommandOptions, StageOptions, AssetMigrationSummary } from '.';
|
|
2
|
+
export interface CreateMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'previewAssetId' | 'matrixUrl'> {
|
|
3
|
+
/**
|
|
4
|
+
* Optional for bulk migrations, required for single asset migrations.
|
|
5
|
+
*/
|
|
6
|
+
assetId?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The path to a JSON file containing the IDs of the assets to be migrated. Required for bulk migrations, optional for single asset migrations.
|
|
9
|
+
*/
|
|
10
|
+
assetIds?: string;
|
|
3
11
|
/**
|
|
4
12
|
* The path to a JSON file containing the CCT IDs to be skipped in a migration (because they were already converted and deployed)
|
|
5
13
|
*/
|
|
6
14
|
cctIds?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The path to a JSON file containing stage options for the next stage of the migration.
|
|
17
|
+
*/
|
|
18
|
+
stageOptions?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Whether to trigger the next stage of the migration automatically.
|
|
21
|
+
* This will automatically be set to true for pre and bulk migrations.
|
|
22
|
+
* For single asset migrations, it will be set to false by default but can be overridden by the user.
|
|
23
|
+
*/
|
|
24
|
+
triggerNextStage?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface CreateMigrationInput extends Omit<CreateMigrationOptions, 'stageOptions' | 'cctIds' | 'assetId' | 'assetIds' | 'previewAssetId'> {
|
|
27
|
+
/**
|
|
28
|
+
* The IDs of the assets to be migrated.
|
|
29
|
+
*/
|
|
30
|
+
assetIds?: string[];
|
|
31
|
+
/**
|
|
32
|
+
* The CCT IDs to be skipped in a migration (because they were already converted and deployed).
|
|
33
|
+
*/
|
|
34
|
+
cctIds?: string[];
|
|
35
|
+
/**
|
|
36
|
+
* Stage options for the next stage of the migration.
|
|
37
|
+
*/
|
|
38
|
+
stageOptions?: StageOptions;
|
|
39
|
+
/**
|
|
40
|
+
* The ID of the folder that will be used as the parent of the migrated asset generated during the Preview stage.
|
|
41
|
+
*/
|
|
42
|
+
previewAssetId?: string;
|
|
7
43
|
}
|
|
8
44
|
export interface CreateMigrationApiResponse {
|
|
9
|
-
assetMigration
|
|
45
|
+
assetMigration?: AssetMigration;
|
|
46
|
+
summary?: AssetMigrationSummary;
|
|
47
|
+
nextStageResults?: BatchNextStageResults;
|
|
10
48
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { AssetMigration, CommonCommandOptions } from '.';
|
|
1
|
+
import { AssetMigration, CommonCommandOptions, AssetMigrationSummary } from '.';
|
|
2
2
|
export interface GetMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId' | 'assetId'> {
|
|
3
3
|
}
|
|
4
4
|
export interface GetMigrationApiResponse extends AssetMigration {
|
|
5
5
|
}
|
|
6
|
+
export interface BatchGetMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId'> {
|
|
7
|
+
}
|
|
8
|
+
export interface BatchGetMigrationApiResponse extends AssetMigrationSummary {
|
|
9
|
+
}
|
|
@@ -21,3 +21,4 @@ __exportStar(require("./nextStage.types"), exports);
|
|
|
21
21
|
__exportStar(require("./preMigration.types"), exports);
|
|
22
22
|
__exportStar(require("./settings.types"), exports);
|
|
23
23
|
__exportStar(require("./revert.types"), exports);
|
|
24
|
+
__exportStar(require("./markDeployed.types"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CommonCommandOptions } from '.';
|
|
2
|
+
export interface MarkDeployedOptions extends CommonCommandOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Path to a JSON file containing the CCT IDs to mark as deployed
|
|
5
|
+
*/
|
|
6
|
+
cctIds: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MarkDeployedInput extends CommonCommandOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The CCT IDs to mark as deployed
|
|
11
|
+
*/
|
|
12
|
+
cctIds: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface MarkDeployedApiResponse {
|
|
15
|
+
success: string[];
|
|
16
|
+
failed: {
|
|
17
|
+
cctId: string;
|
|
18
|
+
error: string;
|
|
19
|
+
}[];
|
|
20
|
+
}
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
import { AssetMigration, CommonCommandOptions } from '.';
|
|
2
|
+
export interface StageOptions {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
2
5
|
export interface NextStageOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId' | 'assetId'> {
|
|
3
6
|
stageOptions?: string;
|
|
4
7
|
}
|
|
5
8
|
export interface NextStageParsedOptions extends Omit<NextStageOptions, 'stageOptions'> {
|
|
6
|
-
stageOptions?:
|
|
9
|
+
stageOptions?: StageOptions;
|
|
7
10
|
}
|
|
8
11
|
export interface NextStageApiResponse {
|
|
9
12
|
message: string;
|
|
10
13
|
}
|
|
14
|
+
export interface BatchNextStageResults {
|
|
15
|
+
success: {
|
|
16
|
+
assetIds: string[];
|
|
17
|
+
message: string;
|
|
18
|
+
}[];
|
|
19
|
+
failed: {
|
|
20
|
+
assetIds: string[];
|
|
21
|
+
error: string;
|
|
22
|
+
}[];
|
|
23
|
+
}
|
|
24
|
+
export interface BatchNextStageApiResponse extends BatchNextStageResults {
|
|
25
|
+
}
|
|
26
|
+
export interface BatchNextStageOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId' | 'stage'> {
|
|
27
|
+
stageOptions?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BatchNextStageParsedOptions extends Omit<BatchNextStageOptions, 'stageOptions'> {
|
|
30
|
+
stageOptions?: StageOptions;
|
|
31
|
+
}
|
|
@@ -4,3 +4,15 @@ export interface RevertMigrationOptions extends CommonCommandOptions, Pick<Asset
|
|
|
4
4
|
export interface RevertMigrationApiResponse {
|
|
5
5
|
message: string;
|
|
6
6
|
}
|
|
7
|
+
export interface BatchRevertMigrationOptions extends CommonCommandOptions, Pick<AssetMigration, 'migrationId'> {
|
|
8
|
+
}
|
|
9
|
+
export interface BatchRevertMigrationApiResponse {
|
|
10
|
+
success: {
|
|
11
|
+
assetIds: string[];
|
|
12
|
+
message: string;
|
|
13
|
+
}[];
|
|
14
|
+
failed: {
|
|
15
|
+
assetIds: string[];
|
|
16
|
+
error: string;
|
|
17
|
+
}[];
|
|
18
|
+
}
|