@squiz/dxp-cli-next 5.26.0-develop.1 → 5.26.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/migration/get/getMigration.d.ts +3 -0
- package/lib/migration/get/getMigration.js +47 -0
- package/lib/migration/get/getMigration.spec.d.ts +1 -0
- package/lib/migration/get/getMigration.spec.js +278 -0
- package/lib/migration/index.js +3 -1
- package/lib/migration/types.d.ts +37 -0
- package/lib/migration/types.js +2 -0
- package/lib/migration/utils.d.ts +2 -22
- package/lib/migration/utils.js +36 -1
- package/lib/migration/utils.spec.js +132 -0
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
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 chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
const commander_1 = require("commander");
|
|
17
|
+
const utils_1 = require("../utils");
|
|
18
|
+
const ora_1 = __importDefault(require("ora"));
|
|
19
|
+
const getMigrationCommand = () => {
|
|
20
|
+
const getCommand = new commander_1.Command('get')
|
|
21
|
+
.name('get')
|
|
22
|
+
.description('Get a migration using the AI Page migration service')
|
|
23
|
+
.addOption(new commander_1.Option('--migration-id <string>', 'The ID of the migration to get').makeOptionMandatory())
|
|
24
|
+
.addOption(new commander_1.Option('--asset-id <string>', 'The ID of the asset to get the migration for'))
|
|
25
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
26
|
+
.configureOutput({
|
|
27
|
+
outputError(str, write) {
|
|
28
|
+
write(chalk_1.default.red(str));
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
const spinner = (0, ora_1.default)('Getting migration').start();
|
|
33
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(getCommand);
|
|
34
|
+
try {
|
|
35
|
+
const response = yield (0, utils_1.getMigration)(options);
|
|
36
|
+
spinner.succeed(`Migration details: ${JSON.stringify(response, null, 2)}`);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
(0, utils_1.handleCommandError)(getCommand, error);
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
if (process.env.ENABLE_OVERRIDE_MIGRATION_URL === 'true') {
|
|
43
|
+
getCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire migration url with a custom value'));
|
|
44
|
+
}
|
|
45
|
+
return getCommand;
|
|
46
|
+
};
|
|
47
|
+
exports.default = getMigrationCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,278 @@
|
|
|
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 getMigration_1 = __importDefault(require("./getMigration"));
|
|
40
|
+
const utils = __importStar(require("../utils"));
|
|
41
|
+
const ApplicationStore = __importStar(require("../../ApplicationStore"));
|
|
42
|
+
jest.mock('../utils');
|
|
43
|
+
jest.mock('../../ApplicationStore');
|
|
44
|
+
const mockUtils = utils;
|
|
45
|
+
const mockApplicationStore = ApplicationStore;
|
|
46
|
+
describe('getMigrationCommand', () => {
|
|
47
|
+
let logSpy;
|
|
48
|
+
let mockGetMigrationResponse;
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
nock_1.default.cleanAll();
|
|
51
|
+
jest.clearAllMocks();
|
|
52
|
+
jest.resetAllMocks();
|
|
53
|
+
logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
54
|
+
mockApplicationStore.getApplicationFile.mockResolvedValue('session-cookie');
|
|
55
|
+
mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
|
|
56
|
+
mockGetMigrationResponse = {
|
|
57
|
+
migrationId: 'migration-123',
|
|
58
|
+
assetId: 'asset-456',
|
|
59
|
+
stage: 'completed',
|
|
60
|
+
status: 'success',
|
|
61
|
+
stageDetail: 'Migration completed successfully',
|
|
62
|
+
previewPageAssetId: 'preview-789',
|
|
63
|
+
componentDownloadUrl: 'https://download.example.com/components.zip',
|
|
64
|
+
};
|
|
65
|
+
mockUtils.getMigration.mockResolvedValue(mockGetMigrationResponse);
|
|
66
|
+
});
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
logSpy.mockRestore();
|
|
69
|
+
});
|
|
70
|
+
describe('successful migration retrieval', () => {
|
|
71
|
+
it('should get migration successfully with required options', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
const program = (0, getMigration_1.default)();
|
|
73
|
+
yield program.parseAsync([
|
|
74
|
+
'node',
|
|
75
|
+
'dxp-cli',
|
|
76
|
+
'--migration-id',
|
|
77
|
+
'migration-123',
|
|
78
|
+
'--asset-id',
|
|
79
|
+
'asset-456',
|
|
80
|
+
]);
|
|
81
|
+
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
82
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
83
|
+
migrationId: 'migration-123',
|
|
84
|
+
assetId: 'asset-456',
|
|
85
|
+
});
|
|
86
|
+
expect(mockUtils.getMigration).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
|
|
88
|
+
}));
|
|
89
|
+
it('should get migration with tenant option', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
const program = (0, getMigration_1.default)();
|
|
91
|
+
yield program.parseAsync([
|
|
92
|
+
'node',
|
|
93
|
+
'dxp-cli',
|
|
94
|
+
'--migration-id',
|
|
95
|
+
'migration-123',
|
|
96
|
+
'--asset-id',
|
|
97
|
+
'asset-456',
|
|
98
|
+
'--tenant',
|
|
99
|
+
'test-tenant',
|
|
100
|
+
]);
|
|
101
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
102
|
+
migrationId: 'migration-123',
|
|
103
|
+
assetId: 'asset-456',
|
|
104
|
+
tenant: 'test-tenant',
|
|
105
|
+
});
|
|
106
|
+
}));
|
|
107
|
+
it('should get migration with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const originalEnv = process.env.ENABLE_OVERRIDE_MIGRATION_URL;
|
|
109
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = 'true';
|
|
110
|
+
const program = (0, getMigration_1.default)();
|
|
111
|
+
yield program.parseAsync([
|
|
112
|
+
'node',
|
|
113
|
+
'dxp-cli',
|
|
114
|
+
'--migration-id',
|
|
115
|
+
'migration-123',
|
|
116
|
+
'--asset-id',
|
|
117
|
+
'asset-456',
|
|
118
|
+
'--overrideUrl',
|
|
119
|
+
'https://custom.migration.url',
|
|
120
|
+
]);
|
|
121
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
122
|
+
migrationId: 'migration-123',
|
|
123
|
+
assetId: 'asset-456',
|
|
124
|
+
overrideUrl: 'https://custom.migration.url',
|
|
125
|
+
});
|
|
126
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
|
|
127
|
+
}));
|
|
128
|
+
it('should get migration without asset-id option', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
|
+
const program = (0, getMigration_1.default)();
|
|
130
|
+
yield program.parseAsync([
|
|
131
|
+
'node',
|
|
132
|
+
'dxp-cli',
|
|
133
|
+
'--migration-id',
|
|
134
|
+
'migration-123',
|
|
135
|
+
]);
|
|
136
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
137
|
+
migrationId: 'migration-123',
|
|
138
|
+
});
|
|
139
|
+
}));
|
|
140
|
+
});
|
|
141
|
+
describe('error scenarios', () => {
|
|
142
|
+
it('should handle getMigration API error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
const apiError = new Error('Migration not found');
|
|
144
|
+
mockUtils.getMigration.mockRejectedValue(apiError);
|
|
145
|
+
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
146
|
+
const program = (0, getMigration_1.default)();
|
|
147
|
+
yield program.parseAsync([
|
|
148
|
+
'node',
|
|
149
|
+
'dxp-cli',
|
|
150
|
+
'--migration-id',
|
|
151
|
+
'migration-123',
|
|
152
|
+
'--asset-id',
|
|
153
|
+
'asset-456',
|
|
154
|
+
]);
|
|
155
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, apiError);
|
|
156
|
+
}));
|
|
157
|
+
it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
const networkError = new Error('Network connection failed');
|
|
159
|
+
mockUtils.getMigration.mockRejectedValue(networkError);
|
|
160
|
+
mockUtils.handleCommandError.mockImplementation(() => { });
|
|
161
|
+
const program = (0, getMigration_1.default)();
|
|
162
|
+
yield program.parseAsync([
|
|
163
|
+
'node',
|
|
164
|
+
'dxp-cli',
|
|
165
|
+
'--migration-id',
|
|
166
|
+
'migration-123',
|
|
167
|
+
'--asset-id',
|
|
168
|
+
'asset-456',
|
|
169
|
+
]);
|
|
170
|
+
expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, networkError);
|
|
171
|
+
}));
|
|
172
|
+
});
|
|
173
|
+
describe('required options validation', () => {
|
|
174
|
+
it('should require migration-id option', () => {
|
|
175
|
+
const program = (0, getMigration_1.default)().exitOverride();
|
|
176
|
+
expect(() => {
|
|
177
|
+
program.parse(['node', 'dxp-cli', '--asset-id', 'asset-456']);
|
|
178
|
+
}).toThrow();
|
|
179
|
+
});
|
|
180
|
+
it('should not require asset-id option', () => {
|
|
181
|
+
const program = (0, getMigration_1.default)().exitOverride();
|
|
182
|
+
expect(() => {
|
|
183
|
+
program.parse(['node', 'dxp-cli', '--migration-id', 'migration-123']);
|
|
184
|
+
}).not.toThrow();
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe('command configuration', () => {
|
|
188
|
+
it('should have correct command name and description', () => {
|
|
189
|
+
const program = (0, getMigration_1.default)();
|
|
190
|
+
expect(program.name()).toBe('get');
|
|
191
|
+
expect(program.description()).toBe('Get a migration using the AI Page migration service');
|
|
192
|
+
});
|
|
193
|
+
it('should parse options correctly', () => {
|
|
194
|
+
const program = (0, getMigration_1.default)();
|
|
195
|
+
program.parse([
|
|
196
|
+
'node',
|
|
197
|
+
'dxp-cli',
|
|
198
|
+
'--migration-id',
|
|
199
|
+
'migration-123',
|
|
200
|
+
'--asset-id',
|
|
201
|
+
'asset-456',
|
|
202
|
+
'--tenant',
|
|
203
|
+
'test-tenant',
|
|
204
|
+
]);
|
|
205
|
+
const opts = program.opts();
|
|
206
|
+
expect(opts.migrationId).toBe('migration-123');
|
|
207
|
+
expect(opts.assetId).toBe('asset-456');
|
|
208
|
+
expect(opts.tenant).toBe('test-tenant');
|
|
209
|
+
});
|
|
210
|
+
it('should parse options with kebab-case to camelCase conversion', () => {
|
|
211
|
+
const program = (0, getMigration_1.default)();
|
|
212
|
+
program.parse([
|
|
213
|
+
'node',
|
|
214
|
+
'dxp-cli',
|
|
215
|
+
'--migration-id',
|
|
216
|
+
'migration-123',
|
|
217
|
+
'--asset-id',
|
|
218
|
+
'asset-456',
|
|
219
|
+
]);
|
|
220
|
+
const opts = program.opts();
|
|
221
|
+
expect(opts.migrationId).toBe('migration-123');
|
|
222
|
+
expect(opts.assetId).toBe('asset-456');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('spinner and output behavior', () => {
|
|
226
|
+
it('should display appropriate spinner messages during execution', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
227
|
+
const program = (0, getMigration_1.default)();
|
|
228
|
+
yield program.parseAsync([
|
|
229
|
+
'node',
|
|
230
|
+
'dxp-cli',
|
|
231
|
+
'--migration-id',
|
|
232
|
+
'migration-123',
|
|
233
|
+
'--asset-id',
|
|
234
|
+
'asset-456',
|
|
235
|
+
]);
|
|
236
|
+
expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
|
|
237
|
+
expect(mockUtils.getMigration).toHaveBeenCalled();
|
|
238
|
+
}));
|
|
239
|
+
it('should format output correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
240
|
+
const program = (0, getMigration_1.default)();
|
|
241
|
+
yield program.parseAsync([
|
|
242
|
+
'node',
|
|
243
|
+
'dxp-cli',
|
|
244
|
+
'--migration-id',
|
|
245
|
+
'migration-123',
|
|
246
|
+
'--asset-id',
|
|
247
|
+
'asset-456',
|
|
248
|
+
]);
|
|
249
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
250
|
+
migrationId: 'migration-123',
|
|
251
|
+
assetId: 'asset-456',
|
|
252
|
+
});
|
|
253
|
+
}));
|
|
254
|
+
});
|
|
255
|
+
describe('override URL configuration', () => {
|
|
256
|
+
it('should work with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
+
const originalEnv = process.env.ENABLE_OVERRIDE_MIGRATION_URL;
|
|
258
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = 'true';
|
|
259
|
+
const program = (0, getMigration_1.default)();
|
|
260
|
+
yield program.parseAsync([
|
|
261
|
+
'node',
|
|
262
|
+
'dxp-cli',
|
|
263
|
+
'--migration-id',
|
|
264
|
+
'migration-123',
|
|
265
|
+
'--asset-id',
|
|
266
|
+
'asset-456',
|
|
267
|
+
'--overrideUrl',
|
|
268
|
+
'https://custom.migration.url',
|
|
269
|
+
]);
|
|
270
|
+
expect(mockUtils.getMigration).toHaveBeenCalledWith({
|
|
271
|
+
migrationId: 'migration-123',
|
|
272
|
+
assetId: 'asset-456',
|
|
273
|
+
overrideUrl: 'https://custom.migration.url',
|
|
274
|
+
});
|
|
275
|
+
process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
|
|
276
|
+
}));
|
|
277
|
+
});
|
|
278
|
+
});
|
package/lib/migration/index.js
CHANGED
|
@@ -5,8 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const commander_1 = require("commander");
|
|
7
7
|
const createMigration_1 = __importDefault(require("./create/createMigration"));
|
|
8
|
+
const getMigration_1 = __importDefault(require("./get/getMigration"));
|
|
8
9
|
const migrationCommand = new commander_1.Command('migration');
|
|
9
10
|
migrationCommand
|
|
10
11
|
.description('AI Page Migration Service Commands')
|
|
11
|
-
.addCommand((0, createMigration_1.default)())
|
|
12
|
+
.addCommand((0, createMigration_1.default)())
|
|
13
|
+
.addCommand((0, getMigration_1.default)());
|
|
12
14
|
exports.default = migrationCommand;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface CreateMigrationOptions {
|
|
2
|
+
assetId: string;
|
|
3
|
+
previewAssetId: string;
|
|
4
|
+
matrixUrl: string;
|
|
5
|
+
tenant?: string;
|
|
6
|
+
overrideUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CreateMigrationAPIResponse {
|
|
9
|
+
assetMigration: {
|
|
10
|
+
migrationId: string;
|
|
11
|
+
assetId: string;
|
|
12
|
+
xmlFilePath: string;
|
|
13
|
+
matrixUrl: string;
|
|
14
|
+
previewAssetId: string;
|
|
15
|
+
stage: string;
|
|
16
|
+
status: string;
|
|
17
|
+
created: number;
|
|
18
|
+
updated: number;
|
|
19
|
+
migrationIdAssetId: string;
|
|
20
|
+
};
|
|
21
|
+
uploadUrl: string;
|
|
22
|
+
}
|
|
23
|
+
export interface GetMigrationOptions {
|
|
24
|
+
migrationId: string;
|
|
25
|
+
assetId: string;
|
|
26
|
+
tenant?: string;
|
|
27
|
+
overrideUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface GetMigrationAPIResponse {
|
|
30
|
+
migrationId: string;
|
|
31
|
+
assetId: string;
|
|
32
|
+
stage: string;
|
|
33
|
+
status: string;
|
|
34
|
+
stageDetails?: string;
|
|
35
|
+
previewPageAssetId?: string;
|
|
36
|
+
componentsTarDownloadUrl?: string;
|
|
37
|
+
}
|
package/lib/migration/utils.d.ts
CHANGED
|
@@ -1,26 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
|
|
3
|
-
assetId: string;
|
|
4
|
-
previewAssetId: string;
|
|
5
|
-
matrixUrl: string;
|
|
6
|
-
tenant?: string;
|
|
7
|
-
overrideUrl?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface CreateMigrationAPIResponse {
|
|
10
|
-
assetMigration: {
|
|
11
|
-
migrationId: string;
|
|
12
|
-
assetId: string;
|
|
13
|
-
xmlFilePath: string;
|
|
14
|
-
matrixUrl: string;
|
|
15
|
-
previewAssetId: string;
|
|
16
|
-
stage: string;
|
|
17
|
-
status: string;
|
|
18
|
-
created: number;
|
|
19
|
-
updated: number;
|
|
20
|
-
migrationIdAssetId: string;
|
|
21
|
-
};
|
|
22
|
-
uploadUrl: string;
|
|
23
|
-
}
|
|
2
|
+
import { CreateMigrationOptions, CreateMigrationAPIResponse, GetMigrationOptions, GetMigrationAPIResponse } from './types';
|
|
24
3
|
export declare function handleCommandError(command: Command, error: Error): void;
|
|
25
4
|
export declare function throwErrorIfNotLoggedIn(command: Command): Promise<void>;
|
|
26
5
|
export declare function buildMigrationUrl(tenantID?: string, overrideUrl?: string): Promise<string>;
|
|
@@ -30,3 +9,4 @@ export declare function createTarFile(exportPath: string): Promise<string>;
|
|
|
30
9
|
export declare function getMigrationHeaders(tenantID?: string): Promise<Record<string, string>>;
|
|
31
10
|
export declare function uploadFileToS3(uploadUrl: string, filePath: string, tenantID?: string): Promise<string>;
|
|
32
11
|
export declare function createMigration(options: CreateMigrationOptions): Promise<CreateMigrationAPIResponse>;
|
|
12
|
+
export declare function getMigration(options: GetMigrationOptions): Promise<GetMigrationAPIResponse>;
|
package/lib/migration/utils.js
CHANGED
|
@@ -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.createMigration = exports.uploadFileToS3 = exports.getMigrationHeaders = exports.createTarFile = exports.validateExportFolder = exports.validateAxiosStatus = exports.buildMigrationUrl = exports.throwErrorIfNotLoggedIn = exports.handleCommandError = void 0;
|
|
15
|
+
exports.getMigration = exports.createMigration = exports.uploadFileToS3 = exports.getMigrationHeaders = exports.createTarFile = exports.validateExportFolder = exports.validateAxiosStatus = exports.buildMigrationUrl = exports.throwErrorIfNotLoggedIn = exports.handleCommandError = void 0;
|
|
16
16
|
const fs_1 = __importDefault(require("fs"));
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const chalk_1 = __importDefault(require("chalk"));
|
|
@@ -188,3 +188,38 @@ function createMigration(options) {
|
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
190
|
exports.createMigration = createMigration;
|
|
191
|
+
function getMigration(options) {
|
|
192
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
193
|
+
const apiService = new ApiService_1.ApiService({
|
|
194
|
+
validateStatus: validateAxiosStatus,
|
|
195
|
+
});
|
|
196
|
+
const migrationUrl = yield buildMigrationUrl(options.tenant, options.overrideUrl);
|
|
197
|
+
try {
|
|
198
|
+
const response = yield apiService.client.get(`${migrationUrl}/migrations/${options.migrationId}/assets/${options.assetId}`, {
|
|
199
|
+
headers: Object.assign({ 'Content-Type': 'application/json' }, (yield getMigrationHeaders(options.tenant))),
|
|
200
|
+
});
|
|
201
|
+
if (response.status !== 200) {
|
|
202
|
+
throw new Error(`Failed to get migration: ${response.status}`);
|
|
203
|
+
}
|
|
204
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
205
|
+
throw new Error('No data returned from migration service');
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
migrationId: response.data.migrationId,
|
|
209
|
+
assetId: response.data.assetId,
|
|
210
|
+
stage: response.data.stage,
|
|
211
|
+
status: response.data.status,
|
|
212
|
+
stageDetails: response.data.stageDetails,
|
|
213
|
+
previewPageAssetId: response.data.previewPageAssetId,
|
|
214
|
+
componentsTarDownloadUrl: response.data.componentsTarDownloadUrl,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error instanceof Error) {
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
throw new Error(`Failed to get migration: ${error}`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
exports.getMigration = getMigration;
|
|
@@ -408,4 +408,136 @@ describe('Migration Utils', () => {
|
|
|
408
408
|
yield expect((0, utils_1.createMigration)(mockOptions)).rejects.toThrow('Failed to create migration: Unknown error');
|
|
409
409
|
}));
|
|
410
410
|
});
|
|
411
|
+
describe('getMigration', () => {
|
|
412
|
+
let mockApiServiceInstance;
|
|
413
|
+
let mockOptions;
|
|
414
|
+
beforeEach(() => {
|
|
415
|
+
mockApiServiceInstance = {
|
|
416
|
+
client: {
|
|
417
|
+
get: jest.fn(),
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
mockApiService.mockImplementation(() => mockApiServiceInstance);
|
|
421
|
+
mockOptions = {
|
|
422
|
+
migrationId: 'migration-123',
|
|
423
|
+
assetId: 'asset-456',
|
|
424
|
+
tenant: 'test-tenant',
|
|
425
|
+
};
|
|
426
|
+
mockFetchApplicationConfig.mockResolvedValue({
|
|
427
|
+
tenant: 'test-tenant',
|
|
428
|
+
baseUrl: 'https://example.com',
|
|
429
|
+
region: 'au',
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
it('gets migration successfully', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
433
|
+
const mockResponse = {
|
|
434
|
+
status: 200,
|
|
435
|
+
data: {
|
|
436
|
+
migrationId: 'migration-123',
|
|
437
|
+
assetId: 'asset-456',
|
|
438
|
+
stage: 'completed',
|
|
439
|
+
status: 'success',
|
|
440
|
+
stageDetails: 'Migration completed successfully',
|
|
441
|
+
previewPageAssetId: 'preview-789',
|
|
442
|
+
componentsTarDownloadUrl: 'https://download.example.com/components.zip',
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
446
|
+
const result = yield (0, utils_1.getMigration)(mockOptions);
|
|
447
|
+
expect(result).toEqual({
|
|
448
|
+
migrationId: 'migration-123',
|
|
449
|
+
assetId: 'asset-456',
|
|
450
|
+
stage: 'completed',
|
|
451
|
+
status: 'success',
|
|
452
|
+
stageDetails: 'Migration completed successfully',
|
|
453
|
+
previewPageAssetId: 'preview-789',
|
|
454
|
+
componentsTarDownloadUrl: 'https://download.example.com/components.zip',
|
|
455
|
+
});
|
|
456
|
+
expect(mockApiServiceInstance.client.get).toHaveBeenCalledWith('https://example.com/__dxp/service/aiapps/migration/migrations/migration-123/assets/asset-456', {
|
|
457
|
+
headers: {
|
|
458
|
+
'Content-Type': 'application/json',
|
|
459
|
+
'x-dxp-tenant': 'test-tenant',
|
|
460
|
+
},
|
|
461
|
+
});
|
|
462
|
+
}));
|
|
463
|
+
it('gets migration with override URL', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
464
|
+
const optionsWithOverride = Object.assign(Object.assign({}, mockOptions), { overrideUrl: 'https://custom.migration.url' });
|
|
465
|
+
const mockResponse = {
|
|
466
|
+
status: 200,
|
|
467
|
+
data: {
|
|
468
|
+
migrationId: 'migration-123',
|
|
469
|
+
assetId: 'asset-456',
|
|
470
|
+
stage: 'pending',
|
|
471
|
+
status: 'processing',
|
|
472
|
+
},
|
|
473
|
+
};
|
|
474
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
475
|
+
const result = yield (0, utils_1.getMigration)(optionsWithOverride);
|
|
476
|
+
expect(result.migrationId).toBe('migration-123');
|
|
477
|
+
expect(result.assetId).toBe('asset-456');
|
|
478
|
+
expect(mockApiServiceInstance.client.get).toHaveBeenCalledWith('https://custom.migration.url/migrations/migration-123/assets/asset-456', expect.any(Object));
|
|
479
|
+
}));
|
|
480
|
+
it('handles non-success status codes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
481
|
+
const mockResponse = {
|
|
482
|
+
status: 404,
|
|
483
|
+
data: {},
|
|
484
|
+
};
|
|
485
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
486
|
+
yield expect((0, utils_1.getMigration)(mockOptions)).rejects.toThrow('Failed to get migration: 404');
|
|
487
|
+
}));
|
|
488
|
+
it('handles missing response data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
489
|
+
const mockResponse = {
|
|
490
|
+
status: 200,
|
|
491
|
+
data: null,
|
|
492
|
+
};
|
|
493
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
494
|
+
yield expect((0, utils_1.getMigration)(mockOptions)).rejects.toThrow('No data returned from migration service');
|
|
495
|
+
}));
|
|
496
|
+
it('handles API service errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
497
|
+
const error = new Error('Network error');
|
|
498
|
+
mockApiServiceInstance.client.get.mockRejectedValue(error);
|
|
499
|
+
yield expect((0, utils_1.getMigration)(mockOptions)).rejects.toThrow('Network error');
|
|
500
|
+
}));
|
|
501
|
+
it('handles unknown errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
502
|
+
mockApiServiceInstance.client.get.mockRejectedValue('Unknown error');
|
|
503
|
+
yield expect((0, utils_1.getMigration)(mockOptions)).rejects.toThrow('Failed to get migration: Unknown error');
|
|
504
|
+
}));
|
|
505
|
+
it('works without optional fields in response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
506
|
+
const mockResponse = {
|
|
507
|
+
status: 200,
|
|
508
|
+
data: {
|
|
509
|
+
migrationId: 'migration-123',
|
|
510
|
+
assetId: 'asset-456',
|
|
511
|
+
stage: 'pending',
|
|
512
|
+
status: 'processing',
|
|
513
|
+
// No optional fields: stageDetails, previewPageAssetId, componentsTarDownloadUrl
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
517
|
+
const result = yield (0, utils_1.getMigration)(mockOptions);
|
|
518
|
+
expect(result).toEqual({
|
|
519
|
+
migrationId: 'migration-123',
|
|
520
|
+
assetId: 'asset-456',
|
|
521
|
+
stage: 'pending',
|
|
522
|
+
status: 'processing',
|
|
523
|
+
stageDetails: undefined,
|
|
524
|
+
previewPageAssetId: undefined,
|
|
525
|
+
componentsTarDownloadUrl: undefined,
|
|
526
|
+
});
|
|
527
|
+
}));
|
|
528
|
+
it('constructs correct URL path', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
529
|
+
const mockResponse = {
|
|
530
|
+
status: 200,
|
|
531
|
+
data: {
|
|
532
|
+
migrationId: 'migration-123',
|
|
533
|
+
assetId: 'asset-456',
|
|
534
|
+
stage: 'completed',
|
|
535
|
+
status: 'success',
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
mockApiServiceInstance.client.get.mockResolvedValue(mockResponse);
|
|
539
|
+
yield (0, utils_1.getMigration)(mockOptions);
|
|
540
|
+
expect(mockApiServiceInstance.client.get).toHaveBeenCalledWith('https://example.com/__dxp/service/aiapps/migration/migrations/migration-123/assets/asset-456', expect.any(Object));
|
|
541
|
+
}));
|
|
542
|
+
});
|
|
411
543
|
});
|