@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.
Files changed (73) hide show
  1. package/README.md +1 -0
  2. package/lib/migration/batch-get/batch-get.d.ts +3 -0
  3. package/lib/migration/batch-get/batch-get.js +45 -0
  4. package/lib/migration/batch-get/batch-get.spec.js +182 -0
  5. package/lib/migration/batch-next/batch-next.d.ts +3 -0
  6. package/lib/migration/batch-next/batch-next.js +60 -0
  7. package/lib/migration/batch-next/batch-next.spec.d.ts +1 -0
  8. package/lib/migration/batch-next/batch-next.spec.js +251 -0
  9. package/lib/migration/batch-revert/batch-revert.d.ts +3 -0
  10. package/lib/migration/batch-revert/batch-revert.js +45 -0
  11. package/lib/migration/batch-revert/batch-revert.spec.d.ts +1 -0
  12. package/lib/migration/batch-revert/batch-revert.spec.js +197 -0
  13. package/lib/migration/create/create.js +27 -7
  14. package/lib/migration/create/create.spec.js +48 -20
  15. package/lib/migration/get/get.js +3 -3
  16. package/lib/migration/get/get.spec.js +8 -19
  17. package/lib/migration/index.js +9 -1
  18. package/lib/migration/list/list.spec.js +7 -6
  19. package/lib/migration/mark-deployed/mark-deployed.d.ts +3 -0
  20. package/lib/migration/mark-deployed/mark-deployed.js +55 -0
  21. package/lib/migration/mark-deployed/mark-deployed.spec.d.ts +1 -0
  22. package/lib/migration/mark-deployed/mark-deployed.spec.js +217 -0
  23. package/lib/migration/next/next.spec.js +6 -5
  24. package/lib/migration/pre/pre.js +3 -3
  25. package/lib/migration/pre/pre.spec.js +8 -8
  26. package/lib/migration/revert/revert.js +1 -1
  27. package/lib/migration/revert/revert.spec.js +1 -1
  28. package/lib/migration/settings/settings.spec.js +2 -2
  29. package/lib/migration/types/common.types.d.ts +33 -2
  30. package/lib/migration/types/common.types.js +17 -0
  31. package/lib/migration/types/createMigration.types.d.ts +41 -3
  32. package/lib/migration/types/getMigration.types.d.ts +5 -1
  33. package/lib/migration/types/index.d.ts +1 -0
  34. package/lib/migration/types/index.js +1 -0
  35. package/lib/migration/types/markDeployed.types.d.ts +20 -0
  36. package/lib/migration/types/markDeployed.types.js +2 -0
  37. package/lib/migration/types/nextStage.types.d.ts +22 -1
  38. package/lib/migration/types/revert.types.d.ts +12 -0
  39. package/lib/migration/utils/common.d.ts +17 -3
  40. package/lib/migration/utils/common.js +56 -24
  41. package/lib/migration/utils/common.spec.js +73 -2
  42. package/lib/migration/utils/createMigration.d.ts +4 -21
  43. package/lib/migration/utils/createMigration.js +23 -32
  44. package/lib/migration/utils/createMigration.spec.js +19 -18
  45. package/lib/migration/utils/getMigration.d.ts +2 -1
  46. package/lib/migration/utils/getMigration.js +23 -18
  47. package/lib/migration/utils/getMigration.spec.js +146 -7
  48. package/lib/migration/utils/index.d.ts +1 -0
  49. package/lib/migration/utils/index.js +1 -0
  50. package/lib/migration/utils/listMigrations.spec.js +7 -6
  51. package/lib/migration/utils/loadAssetIdsFromFile.d.ts +9 -0
  52. package/lib/migration/utils/loadAssetIdsFromFile.js +40 -0
  53. package/lib/migration/utils/loadAssetIdsFromFile.spec.d.ts +1 -0
  54. package/lib/migration/utils/{loadCctIdsFromFile.spec.js → loadAssetIdsFromFile.spec.js} +13 -13
  55. package/lib/migration/utils/loadStageOptionsFromFile.d.ts +2 -1
  56. package/lib/migration/utils/markComponentsDeployed.d.ts +2 -0
  57. package/lib/migration/utils/markComponentsDeployed.js +37 -0
  58. package/lib/migration/utils/markComponentsDeployed.spec.d.ts +1 -0
  59. package/lib/migration/utils/markComponentsDeployed.spec.js +222 -0
  60. package/lib/migration/utils/nextStage.d.ts +2 -1
  61. package/lib/migration/utils/nextStage.js +32 -22
  62. package/lib/migration/utils/nextStage.spec.js +179 -7
  63. package/lib/migration/utils/options.d.ts +4 -1
  64. package/lib/migration/utils/options.js +32 -2
  65. package/lib/migration/utils/revertMigration.d.ts +2 -1
  66. package/lib/migration/utils/revertMigration.js +21 -1
  67. package/lib/migration/utils/revertMigration.spec.js +115 -0
  68. package/lib/page/utils/definitions.js +1 -1
  69. package/lib/page/utils/definitions.spec.js +19 -8
  70. package/package.json +1 -1
  71. package/lib/migration/utils/loadCctIdsFromFile.d.ts +0 -1
  72. package/lib/migration/utils/loadCctIdsFromFile.js +0 -32
  73. /package/lib/migration/{utils/loadCctIdsFromFile.spec.d.ts → batch-get/batch-get.spec.d.ts} +0 -0
@@ -0,0 +1,197 @@
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 batch_revert_1 = __importDefault(require("./batch-revert"));
40
+ const utils = __importStar(require("../utils/common"));
41
+ const ApplicationStore = __importStar(require("../../ApplicationStore"));
42
+ const revertMigrationModule = __importStar(require("../utils/revertMigration"));
43
+ jest.mock('../utils/common');
44
+ jest.mock('../utils/revertMigration');
45
+ jest.mock('../../ApplicationStore');
46
+ const mockUtils = utils;
47
+ const mockRevertMigration = revertMigrationModule;
48
+ const mockApplicationStore = ApplicationStore;
49
+ describe('batchRevertMigrationCommand', () => {
50
+ let logSpy;
51
+ let mockBatchRevertMigrationResponse;
52
+ beforeEach(() => {
53
+ nock_1.default.cleanAll();
54
+ jest.clearAllMocks();
55
+ jest.resetAllMocks();
56
+ logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
57
+ mockApplicationStore.getApplicationFile.mockResolvedValue('session-cookie');
58
+ mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
59
+ mockBatchRevertMigrationResponse = {
60
+ success: [{ assetIds: ['asset-1', 'asset-2'], message: 'Reverted' }],
61
+ failed: [],
62
+ };
63
+ mockRevertMigration.batchRevertMigration.mockResolvedValue(mockBatchRevertMigrationResponse);
64
+ });
65
+ afterEach(() => {
66
+ logSpy.mockRestore();
67
+ });
68
+ describe('successful batch revert execution', () => {
69
+ it('should execute batch revert successfully with required options', () => __awaiter(void 0, void 0, void 0, function* () {
70
+ const program = (0, batch_revert_1.default)();
71
+ yield program.parseAsync([
72
+ 'node',
73
+ 'dxp-cli',
74
+ '--migration-id',
75
+ 'migration-123',
76
+ ]);
77
+ expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
78
+ expect(mockRevertMigration.batchRevertMigration).toHaveBeenCalledWith({
79
+ migrationId: 'migration-123',
80
+ });
81
+ expect(mockRevertMigration.batchRevertMigration).toHaveBeenCalledTimes(1);
82
+ expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
83
+ }));
84
+ it('should execute batch revert with tenant option', () => __awaiter(void 0, void 0, void 0, function* () {
85
+ const program = (0, batch_revert_1.default)();
86
+ yield program.parseAsync([
87
+ 'node',
88
+ 'dxp-cli',
89
+ '--migration-id',
90
+ 'migration-123',
91
+ '--tenant',
92
+ 'test-tenant',
93
+ ]);
94
+ expect(mockRevertMigration.batchRevertMigration).toHaveBeenCalledWith({
95
+ migrationId: 'migration-123',
96
+ tenant: 'test-tenant',
97
+ });
98
+ }));
99
+ it('should execute batch revert with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
100
+ const originalEnv = process.env.ENABLE_OVERRIDE_MIGRATION_URL;
101
+ process.env.ENABLE_OVERRIDE_MIGRATION_URL = 'true';
102
+ const program = (0, batch_revert_1.default)();
103
+ yield program.parseAsync([
104
+ 'node',
105
+ 'dxp-cli',
106
+ '--migration-id',
107
+ 'migration-123',
108
+ '--overrideUrl',
109
+ 'https://custom.migration.url',
110
+ ]);
111
+ expect(mockRevertMigration.batchRevertMigration).toHaveBeenCalledWith({
112
+ migrationId: 'migration-123',
113
+ overrideUrl: 'https://custom.migration.url',
114
+ });
115
+ process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
116
+ }));
117
+ it('should handle mixed success and failure response', () => __awaiter(void 0, void 0, void 0, function* () {
118
+ mockBatchRevertMigrationResponse = {
119
+ success: [{ assetIds: ['asset-1'], message: 'Reverted' }],
120
+ failed: [{ assetIds: ['asset-2'], error: 'Cannot revert' }],
121
+ };
122
+ mockRevertMigration.batchRevertMigration.mockResolvedValue(mockBatchRevertMigrationResponse);
123
+ const program = (0, batch_revert_1.default)();
124
+ yield program.parseAsync([
125
+ 'node',
126
+ 'dxp-cli',
127
+ '--migration-id',
128
+ 'migration-123',
129
+ ]);
130
+ expect(mockRevertMigration.batchRevertMigration).toHaveBeenCalledTimes(1);
131
+ expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
132
+ }));
133
+ });
134
+ describe('error scenarios', () => {
135
+ it('should handle batchRevertMigration API error', () => __awaiter(void 0, void 0, void 0, function* () {
136
+ const apiError = new Error('Failed to revert migration');
137
+ mockRevertMigration.batchRevertMigration.mockRejectedValue(apiError);
138
+ mockUtils.handleCommandError.mockImplementation((() => { }));
139
+ const program = (0, batch_revert_1.default)();
140
+ yield program.parseAsync([
141
+ 'node',
142
+ 'dxp-cli',
143
+ '--migration-id',
144
+ 'migration-123',
145
+ ]);
146
+ expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, apiError);
147
+ }));
148
+ it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
149
+ const networkError = new Error('Network connection failed');
150
+ mockRevertMigration.batchRevertMigration.mockRejectedValue(networkError);
151
+ mockUtils.handleCommandError.mockImplementation((() => { }));
152
+ const program = (0, batch_revert_1.default)();
153
+ yield program.parseAsync([
154
+ 'node',
155
+ 'dxp-cli',
156
+ '--migration-id',
157
+ 'migration-123',
158
+ ]);
159
+ expect(mockUtils.handleCommandError).toHaveBeenCalledWith(program, networkError);
160
+ }));
161
+ });
162
+ describe('required options validation', () => {
163
+ it('should require migration-id option', () => {
164
+ const program = (0, batch_revert_1.default)().exitOverride();
165
+ expect(() => {
166
+ program.parse(['node', 'dxp-cli']);
167
+ }).toThrow();
168
+ });
169
+ it('should not require tenant option', () => {
170
+ const program = (0, batch_revert_1.default)().exitOverride();
171
+ expect(() => {
172
+ program.parse(['node', 'dxp-cli', '--migration-id', 'migration-123']);
173
+ }).not.toThrow();
174
+ });
175
+ });
176
+ describe('command configuration', () => {
177
+ it('should have correct command name and description', () => {
178
+ const program = (0, batch_revert_1.default)();
179
+ expect(program.name()).toBe('batch-revert');
180
+ expect(program.description()).toBe('Revert all assets with stage "morph" and status "awaiting-confirmation" in a migration batch using the AI Page migration service');
181
+ });
182
+ it('should parse options correctly', () => {
183
+ const program = (0, batch_revert_1.default)();
184
+ program.parse([
185
+ 'node',
186
+ 'dxp-cli',
187
+ '--migration-id',
188
+ 'migration-123',
189
+ '--tenant',
190
+ 'test-tenant',
191
+ ]);
192
+ const opts = program.opts();
193
+ expect(opts.migrationId).toBe('migration-123');
194
+ expect(opts.tenant).toBe('test-tenant');
195
+ });
196
+ });
197
+ });
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
24
  };
@@ -16,32 +27,41 @@ const commander_1 = require("commander");
16
27
  const chalk_1 = __importDefault(require("chalk"));
17
28
  const ora_1 = __importDefault(require("ora"));
18
29
  const utils_1 = require("../utils");
19
- const loadCctIdsFromFile_1 = require("../utils/loadCctIdsFromFile");
30
+ const loadAssetIdsFromFile_1 = require("../utils/loadAssetIdsFromFile");
20
31
  const createMigrationCommand = () => {
21
32
  const createCommand = new commander_1.Command('create')
22
33
  .name('create')
23
34
  .description('Create a new migration using the AI Page Migration service')
24
- .addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID))
25
- .addOption((0, utils_1.getParamOption)(utils_1.OptionName.PREVIEW_ASSET_ID))
35
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID, false))
36
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_IDS, false))
37
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.PREVIEW_ASSET_ID, false))
26
38
  .addOption((0, utils_1.getParamOption)(utils_1.OptionName.MATRIX_URL))
27
39
  .addOption((0, utils_1.getParamOption)(utils_1.OptionName.CCT_IDS, false))
40
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.STAGE_OPTIONS, false))
41
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.TRIGGER_NEXT_STAGE, false))
28
42
  .addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
29
43
  .configureOutput({
30
44
  outputError(str, write) {
31
45
  write(chalk_1.default.red(str));
32
46
  },
33
47
  })
34
- .action((options) => __awaiter(void 0, void 0, void 0, function* () {
48
+ .action((_a) => __awaiter(void 0, void 0, void 0, function* () {
49
+ var { stageOptions: stageOptionsPath, cctIds: cctIdsPath, assetIds: assetIdsPath, assetId } = _a, options = __rest(_a, ["stageOptions", "cctIds", "assetIds", "assetId"]);
35
50
  yield (0, utils_1.throwErrorIfNotLoggedIn)(createCommand);
36
51
  const spinner = (0, ora_1.default)('Creating migration').start();
37
52
  try {
38
- const cctIds = (0, loadCctIdsFromFile_1.loadCctIdsFromFile)(options.cctIds);
53
+ const cctIds = (0, loadAssetIdsFromFile_1.loadAssetIdsFromFile)(cctIdsPath, 'cct');
54
+ const assetIds = (0, loadAssetIdsFromFile_1.loadAssetIdsFromFile)(assetIdsPath, 'asset');
55
+ const stageOptions = (0, utils_1.loadStageOptionsFromFile)(stageOptionsPath);
56
+ if ((assetIds === null || assetIds === void 0 ? void 0 : assetIds.length) && assetId) {
57
+ throw new Error('Can only provide either asset-ids or asset-id, not both');
58
+ }
39
59
  // Create migration
40
- const response = yield (0, utils_1.createMigration)(Object.assign(Object.assign({}, options), { cctIds }));
60
+ const response = yield (0, utils_1.createMigration)(Object.assign(Object.assign({}, options), { cctIds, assetIds: assetIds !== null && assetIds !== void 0 ? assetIds : [assetId], stageOptions }));
41
61
  if (!response) {
42
62
  throw new Error('Migration creation failed');
43
63
  }
44
- spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('migration', response.assetMigration));
64
+ spinner.succeed((0, utils_1.buildMigrationSuccessMessage)('migration', response));
45
65
  }
46
66
  catch (error) {
47
67
  spinner.fail();
@@ -39,10 +39,19 @@ const nock_1 = __importDefault(require("nock"));
39
39
  const create_1 = __importDefault(require("./create"));
40
40
  const utils = __importStar(require("../utils/common"));
41
41
  const createMigration = __importStar(require("../utils/createMigration"));
42
+ const ApplicationStore = __importStar(require("../../ApplicationStore"));
43
+ const loadAssetIdsModule = __importStar(require("../utils/loadAssetIdsFromFile"));
44
+ const loadStageOptionsModule = __importStar(require("../utils/loadStageOptionsFromFile"));
42
45
  jest.mock('../utils/common');
43
46
  jest.mock('../utils/createMigration');
47
+ jest.mock('../../ApplicationStore');
48
+ jest.mock('../utils/loadAssetIdsFromFile');
49
+ jest.mock('../utils/loadStageOptionsFromFile');
44
50
  const mockUtils = utils;
45
51
  const mockCreateMigration = createMigration;
52
+ const mockApplicationStore = ApplicationStore;
53
+ const mockLoadAssetIds = loadAssetIdsModule;
54
+ const mockLoadStageOptions = loadStageOptionsModule;
46
55
  describe('createMigrationCommand', () => {
47
56
  let logSpy;
48
57
  let mockCreateMigrationResponse;
@@ -51,8 +60,11 @@ describe('createMigrationCommand', () => {
51
60
  jest.clearAllMocks();
52
61
  jest.resetAllMocks();
53
62
  logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
63
+ mockApplicationStore.getApplicationFile.mockResolvedValue('session-cookie');
54
64
  mockUtils.throwErrorIfNotLoggedIn.mockResolvedValue(undefined);
55
65
  mockUtils.buildMigrationSuccessMessage.mockReturnValue('Migration created successfully');
66
+ mockLoadAssetIds.loadAssetIdsFromFile.mockReturnValue(undefined);
67
+ mockLoadStageOptions.loadStageOptionsFromFile.mockReturnValue(undefined);
56
68
  mockCreateMigrationResponse = {
57
69
  assetMigration: {
58
70
  migrationId: 'migration-123',
@@ -87,9 +99,11 @@ describe('createMigrationCommand', () => {
87
99
  ]);
88
100
  expect(mockUtils.throwErrorIfNotLoggedIn).toHaveBeenCalledWith(program);
89
101
  expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
90
- assetId: 'asset-123',
102
+ assetIds: ['asset-123'],
91
103
  previewAssetId: 'preview-456',
92
104
  matrixUrl: 'https://matrix.example.com',
105
+ cctIds: undefined,
106
+ stageOptions: undefined,
93
107
  });
94
108
  expect(mockCreateMigration.createMigration).toHaveBeenCalledTimes(1);
95
109
  expect(mockUtils.handleCommandError).not.toHaveBeenCalled();
@@ -109,10 +123,12 @@ describe('createMigrationCommand', () => {
109
123
  'test-tenant',
110
124
  ]);
111
125
  expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
112
- assetId: 'asset-123',
126
+ assetIds: ['asset-123'],
113
127
  previewAssetId: 'preview-456',
114
128
  matrixUrl: 'https://matrix.example.com',
115
129
  tenant: 'test-tenant',
130
+ cctIds: undefined,
131
+ stageOptions: undefined,
116
132
  });
117
133
  }));
118
134
  it('should create migration with override URL when environment variable is set', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -132,10 +148,12 @@ describe('createMigrationCommand', () => {
132
148
  'https://custom.migration.url',
133
149
  ]);
134
150
  expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
135
- assetId: 'asset-123',
151
+ assetIds: ['asset-123'],
136
152
  previewAssetId: 'preview-456',
137
153
  matrixUrl: 'https://matrix.example.com',
138
154
  overrideUrl: 'https://custom.migration.url',
155
+ cctIds: undefined,
156
+ stageOptions: undefined,
139
157
  });
140
158
  process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
141
159
  }));
@@ -143,7 +161,7 @@ describe('createMigrationCommand', () => {
143
161
  describe('error scenarios', () => {
144
162
  it('should handle migration creation failure', () => __awaiter(void 0, void 0, void 0, function* () {
145
163
  mockCreateMigration.createMigration.mockResolvedValue(null);
146
- mockUtils.handleCommandError.mockImplementation(() => { });
164
+ mockUtils.handleCommandError.mockImplementation((() => { }));
147
165
  const program = (0, create_1.default)();
148
166
  yield program.parseAsync([
149
167
  'node',
@@ -160,7 +178,7 @@ describe('createMigrationCommand', () => {
160
178
  it('should handle migration API error', () => __awaiter(void 0, void 0, void 0, function* () {
161
179
  const apiError = new Error('Migration API failed');
162
180
  mockCreateMigration.createMigration.mockRejectedValue(apiError);
163
- mockUtils.handleCommandError.mockImplementation(() => { });
181
+ mockUtils.handleCommandError.mockImplementation((() => { }));
164
182
  const program = (0, create_1.default)();
165
183
  yield program.parseAsync([
166
184
  'node',
@@ -194,20 +212,30 @@ describe('createMigrationCommand', () => {
194
212
  }));
195
213
  });
196
214
  describe('required options validation', () => {
197
- it('should require assetid option', () => {
198
- const program = (0, create_1.default)().exitOverride();
199
- expect(() => {
200
- program.parse([
201
- 'node',
202
- 'dxp-cli',
203
- '--preview-asset-id',
204
- 'preview-456',
205
- '--matrix-url',
206
- 'https://matrix.example.com',
207
- ]);
208
- }).toThrow();
209
- });
210
- it('should require previewAssetid option', () => {
215
+ it('should allow assetId to be optional at command level for pre-migrations', () => __awaiter(void 0, void 0, void 0, function* () {
216
+ // When creating a migration without assetId or assetIds, cctIds must be provided.
217
+ // This is called a "pre-migration" which converts CCTs before the actual migration.
218
+ // The command-level validation allows this, with the API handling the validation.
219
+ const program = (0, create_1.default)();
220
+ yield program.parseAsync([
221
+ 'node',
222
+ 'dxp-cli',
223
+ '--preview-asset-id',
224
+ 'preview-456',
225
+ '--matrix-url',
226
+ 'https://matrix.example.com',
227
+ ]);
228
+ // When neither assetId nor assetIds is provided, createMigration is called with [undefined]
229
+ // In a real pre-migration scenario, cctIds would be provided instead
230
+ expect(mockCreateMigration.createMigration).toHaveBeenCalledWith({
231
+ assetIds: [undefined],
232
+ previewAssetId: 'preview-456',
233
+ matrixUrl: 'https://matrix.example.com',
234
+ cctIds: undefined,
235
+ stageOptions: undefined,
236
+ });
237
+ }));
238
+ it('should not require previewAssetId option', () => {
211
239
  const program = (0, create_1.default)().exitOverride();
212
240
  expect(() => {
213
241
  program.parse([
@@ -218,7 +246,7 @@ describe('createMigrationCommand', () => {
218
246
  '--matrix-url',
219
247
  'https://matrix.example.com',
220
248
  ]);
221
- }).toThrow();
249
+ }).not.toThrow();
222
250
  });
223
251
  it('should require matrixUrl option', () => {
224
252
  const program = (0, create_1.default)().exitOverride();
@@ -19,9 +19,9 @@ const ora_1 = __importDefault(require("ora"));
19
19
  const getMigrationCommand = () => {
20
20
  const getCommand = new commander_1.Command('get')
21
21
  .name('get')
22
- .description('Get a migration using the AI Page migration service')
22
+ .description('Get a migration for a given asset using the AI Page migration service')
23
23
  .addOption((0, utils_1.getParamOption)(utils_1.OptionName.MIGRATION_ID))
24
- .addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID, false))
24
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.ASSET_ID))
25
25
  .addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
26
26
  .configureOutput({
27
27
  outputError(str, write) {
@@ -29,8 +29,8 @@ const getMigrationCommand = () => {
29
29
  },
30
30
  })
31
31
  .action((options) => __awaiter(void 0, void 0, void 0, function* () {
32
- const spinner = (0, ora_1.default)('Getting migration').start();
33
32
  yield (0, utils_1.throwErrorIfNotLoggedIn)(getCommand);
33
+ const spinner = (0, ora_1.default)('Getting migration').start();
34
34
  try {
35
35
  const response = yield (0, utils_1.getMigration)(options);
36
36
  spinner.succeed(`Migration details: ${JSON.stringify(response, null, 2)}`);
@@ -40,6 +40,7 @@ const get_1 = __importDefault(require("./get"));
40
40
  const utils = __importStar(require("../utils/common"));
41
41
  const ApplicationStore = __importStar(require("../../ApplicationStore"));
42
42
  const getMigration = __importStar(require("../utils/getMigration"));
43
+ const types_1 = require("../types");
43
44
  jest.mock('../utils/common');
44
45
  jest.mock('../utils/getMigration');
45
46
  jest.mock('../../ApplicationStore');
@@ -65,8 +66,8 @@ describe('getMigrationCommand', () => {
65
66
  created: 1718230800,
66
67
  updated: 1718230800,
67
68
  migrationIdAssetId: 'migration-123-asset-456',
68
- stage: 'completed',
69
- status: 'success',
69
+ stage: types_1.MigrationStage.create,
70
+ status: types_1.MigrationStatus.complete,
70
71
  stageDetails: 'Migration completed successfully',
71
72
  previewPageAssetId: 'preview-789',
72
73
  componentsTarDownloadUrl: 'https://download.example.com/components.zip',
@@ -134,24 +135,12 @@ describe('getMigrationCommand', () => {
134
135
  });
135
136
  process.env.ENABLE_OVERRIDE_MIGRATION_URL = originalEnv;
136
137
  }));
137
- it('should get migration without asset-id option', () => __awaiter(void 0, void 0, void 0, function* () {
138
- const program = (0, get_1.default)();
139
- yield program.parseAsync([
140
- 'node',
141
- 'dxp-cli',
142
- '--migration-id',
143
- 'migration-123',
144
- ]);
145
- expect(mockGetMigration.getMigration).toHaveBeenCalledWith({
146
- migrationId: 'migration-123',
147
- });
148
- }));
149
138
  });
150
139
  describe('error scenarios', () => {
151
140
  it('should handle getMigration API error', () => __awaiter(void 0, void 0, void 0, function* () {
152
141
  const apiError = new Error('Migration not found');
153
142
  mockGetMigration.getMigration.mockRejectedValue(apiError);
154
- mockUtils.handleCommandError.mockImplementation(() => { });
143
+ mockUtils.handleCommandError.mockImplementation((() => { }));
155
144
  const program = (0, get_1.default)();
156
145
  yield program.parseAsync([
157
146
  'node',
@@ -166,7 +155,7 @@ describe('getMigrationCommand', () => {
166
155
  it('should handle network error', () => __awaiter(void 0, void 0, void 0, function* () {
167
156
  const networkError = new Error('Network connection failed');
168
157
  mockGetMigration.getMigration.mockRejectedValue(networkError);
169
- mockUtils.handleCommandError.mockImplementation(() => { });
158
+ mockUtils.handleCommandError.mockImplementation((() => { }));
170
159
  const program = (0, get_1.default)();
171
160
  yield program.parseAsync([
172
161
  'node',
@@ -186,18 +175,18 @@ describe('getMigrationCommand', () => {
186
175
  program.parse(['node', 'dxp-cli', '--asset-id', 'asset-456']);
187
176
  }).toThrow();
188
177
  });
189
- it('should not require asset-id option', () => {
178
+ it('should require asset-id option', () => {
190
179
  const program = (0, get_1.default)().exitOverride();
191
180
  expect(() => {
192
181
  program.parse(['node', 'dxp-cli', '--migration-id', 'migration-123']);
193
- }).not.toThrow();
182
+ }).toThrow();
194
183
  });
195
184
  });
196
185
  describe('command configuration', () => {
197
186
  it('should have correct command name and description', () => {
198
187
  const program = (0, get_1.default)();
199
188
  expect(program.name()).toBe('get');
200
- expect(program.description()).toBe('Get a migration using the AI Page migration service');
189
+ expect(program.description()).toBe('Get a migration for a given asset using the AI Page migration service');
201
190
  });
202
191
  it('should parse options correctly', () => {
203
192
  const program = (0, get_1.default)();
@@ -6,19 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const commander_1 = require("commander");
7
7
  const create_1 = __importDefault(require("./create/create"));
8
8
  const get_1 = __importDefault(require("./get/get"));
9
+ const batch_get_1 = __importDefault(require("./batch-get/batch-get"));
9
10
  const next_1 = __importDefault(require("./next/next"));
11
+ const batch_next_1 = __importDefault(require("./batch-next/batch-next"));
10
12
  const pre_1 = __importDefault(require("./pre/pre"));
11
13
  const settings_1 = __importDefault(require("./settings/settings"));
12
14
  const revert_1 = __importDefault(require("./revert/revert"));
15
+ const batch_revert_1 = __importDefault(require("./batch-revert/batch-revert"));
13
16
  const list_1 = __importDefault(require("./list/list"));
17
+ const mark_deployed_1 = __importDefault(require("./mark-deployed/mark-deployed"));
14
18
  const migrationCommand = new commander_1.Command('migration');
15
19
  migrationCommand
16
20
  .description('AI Page Migration Service Commands')
17
21
  .addCommand((0, create_1.default)())
18
22
  .addCommand((0, get_1.default)())
23
+ .addCommand((0, batch_get_1.default)())
19
24
  .addCommand((0, list_1.default)())
20
25
  .addCommand((0, next_1.default)())
26
+ .addCommand((0, batch_next_1.default)())
21
27
  .addCommand((0, pre_1.default)())
22
28
  .addCommand((0, settings_1.default)())
23
- .addCommand((0, revert_1.default)());
29
+ .addCommand((0, revert_1.default)())
30
+ .addCommand((0, batch_revert_1.default)())
31
+ .addCommand((0, mark_deployed_1.default)());
24
32
  exports.default = migrationCommand;
@@ -39,6 +39,7 @@ const mockListMigrations = jest.fn();
39
39
  const nock_1 = __importDefault(require("nock"));
40
40
  const list_1 = __importDefault(require("./list"));
41
41
  const utils = __importStar(require("../utils/common"));
42
+ const types_1 = require("../types");
42
43
  jest.mock('../utils/common');
43
44
  jest.mock('../utils/listMigrations', () => ({
44
45
  listMigrations: mockListMigrations,
@@ -51,24 +52,24 @@ describe('listMigrationsCommand', () => {
51
52
  {
52
53
  migrationId: 'migration-1',
53
54
  assetId: 'asset-1',
54
- stage: 'completed',
55
- status: 'success',
55
+ stage: types_1.MigrationStage.morph,
56
+ status: types_1.MigrationStatus.complete,
56
57
  created: 100,
57
58
  updated: 200,
58
59
  },
59
60
  {
60
61
  migrationId: 'migration-2',
61
62
  assetId: 'asset-2',
62
- stage: 'completed',
63
- status: 'success',
63
+ stage: types_1.MigrationStage.morph,
64
+ status: types_1.MigrationStatus.complete,
64
65
  created: 100,
65
66
  updated: 200,
66
67
  },
67
68
  {
68
69
  migrationId: 'migration-3',
69
70
  assetId: 'asset-3',
70
- stage: 'completed',
71
- status: 'success',
71
+ stage: types_1.MigrationStage.morph,
72
+ status: types_1.MigrationStatus.complete,
72
73
  created: 100,
73
74
  updated: 200,
74
75
  },
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const markDeployedCommand: () => Command;
3
+ export default markDeployedCommand;
@@ -0,0 +1,55 @@
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 loadAssetIdsFromFile_1 = require("../utils/loadAssetIdsFromFile");
20
+ function formatMarkDeployedResult(success, failed) {
21
+ return (0, utils_1.formatBatchOperationResult)(success.length > 0
22
+ ? [{ assetIds: success, message: 'marked as deployed' }]
23
+ : [], failed.map(({ cctId, error }) => ({ assetIds: [cctId], error })));
24
+ }
25
+ const markDeployedCommand = () => {
26
+ const markCommand = new commander_1.Command('mark-deployed')
27
+ .name('mark-deployed')
28
+ .description('Mark components as deployed in the AI Page Migration service')
29
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.CCT_IDS))
30
+ .addOption((0, utils_1.getParamOption)(utils_1.OptionName.TENANT, false))
31
+ .configureOutput({
32
+ outputError(str, write) {
33
+ write(chalk_1.default.red(str));
34
+ },
35
+ })
36
+ .action((options) => __awaiter(void 0, void 0, void 0, function* () {
37
+ yield (0, utils_1.throwErrorIfNotLoggedIn)(markCommand);
38
+ const spinner = (0, ora_1.default)('Marking components as deployed').start();
39
+ try {
40
+ const cctIds = (0, loadAssetIdsFromFile_1.loadAssetIdsFromFile)(options.cctIds);
41
+ if (!cctIds || cctIds.length === 0) {
42
+ throw new Error('No CCT IDs provided');
43
+ }
44
+ const response = yield (0, utils_1.markComponentsDeployed)(Object.assign(Object.assign({}, options), { cctIds }));
45
+ spinner.succeed(formatMarkDeployedResult(response.success, response.failed));
46
+ }
47
+ catch (error) {
48
+ spinner.fail();
49
+ (0, utils_1.handleCommandError)(markCommand, error);
50
+ }
51
+ }));
52
+ (0, utils_1.addOverrideUrlOption)(markCommand);
53
+ return markCommand;
54
+ };
55
+ exports.default = markDeployedCommand;