@squiz/dxp-cli-next 5.14.0 → 5.15.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.
Files changed (75) hide show
  1. package/README.md +1 -0
  2. package/lib/__tests__/integration/main.spec.js +3 -2
  3. package/lib/cdp/index.js +3 -1
  4. package/lib/cmp/deploy.js +49 -2
  5. package/lib/cmp/edge-components/compiler.d.ts +13 -0
  6. package/lib/cmp/edge-components/compiler.js +55 -0
  7. package/lib/cmp/utils/definitions.d.ts +12 -0
  8. package/lib/cmp/utils/definitions.js +76 -0
  9. package/lib/datastore/index.js +1 -1
  10. package/lib/dxp.js +2 -0
  11. package/lib/porter/constants.d.ts +8 -0
  12. package/lib/porter/constants.js +11 -0
  13. package/lib/porter/index.d.ts +3 -0
  14. package/lib/porter/index.js +14 -0
  15. package/lib/porter/port/abort/abort.d.ts +3 -0
  16. package/lib/porter/port/abort/abort.js +77 -0
  17. package/lib/porter/port/abort/abort.spec.d.ts +1 -0
  18. package/lib/porter/port/abort/abort.spec.js +182 -0
  19. package/lib/porter/port/get/get.d.ts +3 -0
  20. package/lib/porter/port/get/get.js +94 -0
  21. package/lib/porter/port/get/get.spec.d.ts +1 -0
  22. package/lib/porter/port/get/get.spec.js +255 -0
  23. package/lib/porter/port/portCommand.d.ts +3 -0
  24. package/lib/porter/port/portCommand.js +19 -0
  25. package/lib/porter/port/start/start.d.ts +3 -0
  26. package/lib/porter/port/start/start.js +79 -0
  27. package/lib/porter/port/start/start.spec.d.ts +1 -0
  28. package/lib/porter/port/start/start.spec.js +198 -0
  29. package/lib/porter/project/add/add.d.ts +3 -0
  30. package/lib/porter/project/add/add.js +125 -0
  31. package/lib/porter/project/add/add.spec.d.ts +1 -0
  32. package/lib/porter/project/add/add.spec.js +270 -0
  33. package/lib/porter/project/get/get.d.ts +3 -0
  34. package/lib/porter/project/get/get.js +62 -0
  35. package/lib/porter/project/get/get.spec.d.ts +1 -0
  36. package/lib/porter/project/get/get.spec.js +185 -0
  37. package/lib/porter/project/projectCommand.d.ts +3 -0
  38. package/lib/porter/project/projectCommand.js +19 -0
  39. package/lib/porter/project/remove/remove.d.ts +3 -0
  40. package/lib/porter/project/remove/remove.js +66 -0
  41. package/lib/porter/project/remove/remove.spec.d.ts +1 -0
  42. package/lib/porter/project/remove/remove.spec.js +201 -0
  43. package/lib/porter/types.d.ts +5 -0
  44. package/lib/porter/types.js +2 -0
  45. package/lib/porter/utils/AuthUtils/CheckAuthorisation.d.ts +1 -0
  46. package/lib/porter/utils/AuthUtils/CheckAuthorisation.js +32 -0
  47. package/lib/porter/utils/AuthUtils/CheckAuthorisation.spec.d.ts +1 -0
  48. package/lib/porter/utils/AuthUtils/CheckAuthorisation.spec.js +77 -0
  49. package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.d.ts +1 -0
  50. package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.js +27 -0
  51. package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.spec.d.ts +1 -0
  52. package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.spec.js +59 -0
  53. package/lib/porter/utils/CoreUtils/CoreUtils.d.ts +2 -0
  54. package/lib/porter/utils/CoreUtils/CoreUtils.js +13 -0
  55. package/lib/porter/utils/CoreUtils/CoreUtils.spec.d.ts +1 -0
  56. package/lib/porter/utils/CoreUtils/CoreUtils.spec.js +36 -0
  57. package/lib/porter/utils/DoesPathExist/DoesPathExist.d.ts +1 -0
  58. package/lib/porter/utils/DoesPathExist/DoesPathExist.js +27 -0
  59. package/lib/porter/utils/DoesPathExist/DoesPathExist.spec.d.ts +1 -0
  60. package/lib/porter/utils/DoesPathExist/DoesPathExist.spec.js +40 -0
  61. package/lib/porter/utils/ErrorUtils/ErrorUtils.d.ts +4 -0
  62. package/lib/porter/utils/ErrorUtils/ErrorUtils.js +71 -0
  63. package/lib/porter/utils/ErrorUtils/ErrorUtils.spec.d.ts +1 -0
  64. package/lib/porter/utils/ErrorUtils/ErrorUtils.spec.js +190 -0
  65. package/lib/porter/utils/GetProjectConfig/GetProjectConfig.d.ts +2 -0
  66. package/lib/porter/utils/GetProjectConfig/GetProjectConfig.js +33 -0
  67. package/lib/porter/utils/GetProjectConfig/GetProjectConfig.spec.d.ts +1 -0
  68. package/lib/porter/utils/GetProjectConfig/GetProjectConfig.spec.js +50 -0
  69. package/lib/porter/utils/GetProjectName/GetProjectName.d.ts +4 -0
  70. package/lib/porter/utils/GetProjectName/GetProjectName.js +30 -0
  71. package/lib/porter/utils/GetProjectName/GetProjectName.spec.d.ts +1 -0
  72. package/lib/porter/utils/GetProjectName/GetProjectName.spec.js +91 -0
  73. package/lib/porter/utils/index.d.ts +7 -0
  74. package/lib/porter/utils/index.js +23 -0
  75. package/package.json +6 -3
@@ -0,0 +1,94 @@
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 ApiService_1 = require("../../../ApiService");
19
+ const utils_1 = require("../../utils");
20
+ const constants_1 = require("../../constants");
21
+ const dxp_porter_shared_1 = require("@squiz/dxp-porter-shared");
22
+ const createGetPortCommand = () => {
23
+ const getCommand = new commander_1.Command('getPort')
24
+ .description('Gets the information about a specified website port')
25
+ .configureOutput({
26
+ outputError(str, write) {
27
+ write(chalk_1.default.red(str));
28
+ },
29
+ })
30
+ .addArgument(new commander_1.Argument('UUID', 'ID of the port').argParser((portId) => {
31
+ const trimmedPortId = portId.trim();
32
+ if (!trimmedPortId) {
33
+ throw new commander_1.InvalidArgumentError(constants_1.PORTER_ERRORS.portIdBlankError);
34
+ }
35
+ return trimmedPortId;
36
+ }))
37
+ .action((uuid) => __awaiter(void 0, void 0, void 0, function* () {
38
+ var _a, _b, _c, _d;
39
+ yield (0, utils_1.throwErrorIfNotLoggedIn)(getCommand);
40
+ const baseUrl = yield (0, utils_1.buildPorterUrl)();
41
+ const portId = uuid;
42
+ let projectName = '';
43
+ const spinner = (0, ora_1.default)();
44
+ try {
45
+ projectName = yield (0, utils_1.getProjectName)();
46
+ spinner.start('Retrieving port..');
47
+ const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus, baseUrl);
48
+ const response = yield apiService.client.get(`/projects/${projectName}/ports/${portId}`);
49
+ const jsonResponse = response.data;
50
+ (0, utils_1.logDebug)(JSON.stringify(jsonResponse));
51
+ const { portid, stages, 'stage-settings': stageSettings, status, } = jsonResponse;
52
+ const artifactsLink = (_a = jsonResponse['artifacts-link']) !== null && _a !== void 0 ? _a : 'Not generated';
53
+ const reportLink = (_b = jsonResponse['report-link']) !== null && _b !== void 0 ? _b : 'Not generated';
54
+ spinner.succeed();
55
+ console.log('');
56
+ console.log(`Port ID: ${portid}`);
57
+ console.log(`Status: ${status}`);
58
+ console.log(`Download report: ${reportLink}`);
59
+ console.log(`Download artifacts: ${artifactsLink}`);
60
+ console.log('');
61
+ for (const stage of Object.values(dxp_porter_shared_1.Stage)) {
62
+ if (stage === dxp_porter_shared_1.Stage['component-transform'] ||
63
+ stage === dxp_porter_shared_1.Stage['design-dedupe']) {
64
+ continue;
65
+ }
66
+ const stageString = stage.replace(/-/, ' ');
67
+ console.log(`Stage ${stageString} status: ${stages[stage].status}`);
68
+ }
69
+ console.log('');
70
+ for (const stage of Object.values(dxp_porter_shared_1.Stage)) {
71
+ if (stage === dxp_porter_shared_1.Stage['component-transform'] ||
72
+ stage === dxp_porter_shared_1.Stage['design-dedupe']) {
73
+ continue;
74
+ }
75
+ const stageString = stage.replace(/-/, ' ');
76
+ console.log(`Stage ${stageString} settings:`, stageSettings[stage]);
77
+ }
78
+ }
79
+ catch (error) {
80
+ (0, utils_1.logDebug)(`ERROR: ${error instanceof Error ? `${error.message}` : JSON.stringify(error)}`);
81
+ if (spinner.isSpinning) {
82
+ spinner.fail();
83
+ }
84
+ if (((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.status) === 404) {
85
+ (0, utils_1.logDebug)(error.response.data);
86
+ const errorMessage = 'Website port execution not found';
87
+ return (0, utils_1.handleError)(getCommand, errorMessage);
88
+ }
89
+ (0, utils_1.handleCommandError)(getCommand, error);
90
+ }
91
+ }));
92
+ return getCommand;
93
+ };
94
+ exports.default = createGetPortCommand;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,255 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ const axios_1 = require("axios");
36
+ const ApiService = __importStar(require("../../../ApiService"));
37
+ const PorterUtils = __importStar(require("../../utils"));
38
+ const constants_1 = require("../../constants");
39
+ const dxp_porter_shared_1 = require("@squiz/dxp-porter-shared");
40
+ const logSpy = jest.spyOn(global.console, 'log');
41
+ jest.mock('../../utils');
42
+ describe('getPort', () => {
43
+ let projectName;
44
+ let portId;
45
+ let baseUrl;
46
+ let mockHandleCommandError;
47
+ let mockHandleError;
48
+ let mockBuildPorterUrl;
49
+ let mockResponse;
50
+ let mockClient;
51
+ beforeEach(() => {
52
+ jest.resetAllMocks();
53
+ jest.clearAllMocks();
54
+ projectName = 'mock-project';
55
+ portId = '1234-5678-1234-5678';
56
+ baseUrl = 'mock-url';
57
+ mockHandleCommandError = jest.fn(() => Promise.resolve());
58
+ mockHandleError = jest.fn();
59
+ mockBuildPorterUrl = jest.fn(() => Promise.resolve(baseUrl));
60
+ mockResponse = {
61
+ data: {},
62
+ status: 200,
63
+ };
64
+ mockClient = {
65
+ get: jest.fn().mockImplementationOnce(() => mockResponse),
66
+ };
67
+ jest.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn').mockImplementation();
68
+ jest
69
+ .spyOn(PorterUtils, 'buildPorterUrl')
70
+ .mockImplementationOnce(mockBuildPorterUrl);
71
+ jest
72
+ .spyOn(PorterUtils, 'getProjectName')
73
+ .mockImplementation(() => Promise.resolve(projectName));
74
+ jest
75
+ .spyOn(PorterUtils, 'handleCommandError')
76
+ .mockImplementationOnce(mockHandleCommandError);
77
+ jest
78
+ .spyOn(PorterUtils, 'handleError')
79
+ .mockImplementationOnce(mockHandleError);
80
+ jest.spyOn(process, 'exit').mockImplementation();
81
+ jest.spyOn(ApiService, 'ApiService').mockImplementationOnce(() => {
82
+ return {
83
+ client: mockClient,
84
+ };
85
+ });
86
+ });
87
+ it('should throw an error if port id is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
88
+ const portIdInvalid = ' ';
89
+ const { default: createGetCommand } = require('./get');
90
+ const program = createGetCommand();
91
+ yield expect(() => program.parseAsync(['port', 'getPort', portIdInvalid])).rejects.toThrow(constants_1.PORTER_ERRORS.portIdBlankError);
92
+ }));
93
+ it('should throw an error if not logged in', () => __awaiter(void 0, void 0, void 0, function* () {
94
+ const mockError = new Error('Error not logged in');
95
+ jest
96
+ .spyOn(PorterUtils, 'throwErrorIfNotLoggedIn')
97
+ .mockImplementationOnce(() => {
98
+ throw mockError;
99
+ });
100
+ const { default: createGetCommand } = require('./get');
101
+ const program = createGetCommand();
102
+ yield expect(() => program.parseAsync(['port', 'getPort', portId])).rejects.toThrow(mockError);
103
+ const opts = program.opts();
104
+ expect(opts).toStrictEqual({});
105
+ expect(PorterUtils.buildPorterUrl).not.toHaveBeenCalled();
106
+ }));
107
+ it('should throw an error if project name could not be found', () => __awaiter(void 0, void 0, void 0, function* () {
108
+ jest.spyOn(PorterUtils, 'getProjectName').mockImplementationOnce(() => {
109
+ throw new Error();
110
+ });
111
+ const { default: createGetCommand } = require('./get');
112
+ const program = createGetCommand();
113
+ yield program.parseAsync(['port', 'getPort', portId]);
114
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
115
+ expect(mockClient.get).not.toHaveBeenCalled();
116
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
117
+ }));
118
+ it('should handle 404 error when port cannot be found for project', () => __awaiter(void 0, void 0, void 0, function* () {
119
+ mockClient.get = jest.fn(() => {
120
+ throw new axios_1.AxiosError('Port does not exist', '404', undefined, undefined, {
121
+ data: { status: 404 },
122
+ });
123
+ });
124
+ const { default: createGetCommand } = require('./get');
125
+ const program = createGetCommand();
126
+ yield program.parseAsync(['port', 'getPort', portId]);
127
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
128
+ expect(mockClient.get).toHaveBeenCalledWith(`/projects/${projectName}/ports/${portId}`);
129
+ expect(PorterUtils.handleError).toHaveBeenCalled();
130
+ }));
131
+ it('should handle unexpected errors', () => __awaiter(void 0, void 0, void 0, function* () {
132
+ mockClient.get = jest.fn(() => {
133
+ throw new axios_1.AxiosError('Internal server error', '500', undefined, undefined, {
134
+ data: { status: 500 },
135
+ });
136
+ });
137
+ const { default: createGetCommand } = require('./get');
138
+ const program = createGetCommand();
139
+ yield program.parseAsync(['port', 'getPort', portId]);
140
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
141
+ expect(mockClient.get).toHaveBeenCalledWith(`/projects/${projectName}/ports/${portId}`);
142
+ expect(PorterUtils.handleError).not.toHaveBeenCalled();
143
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
144
+ }));
145
+ it('should successfully retrieve the port details and log this to the console', () => __awaiter(void 0, void 0, void 0, function* () {
146
+ const mockStatus = dxp_porter_shared_1.PortStatus.complete;
147
+ const mockGetResponse = {
148
+ portid: portId,
149
+ 'artifacts-link': null,
150
+ 'report-link': null,
151
+ 'stage-settings': {
152
+ crawl: { run: true, start_urls: [] },
153
+ index: { run: false },
154
+ 'component-transform': { run: false },
155
+ 'design-dedupe': { run: false },
156
+ 'template-dedupe': { run: false },
157
+ validation: { run: false },
158
+ report: { run: false },
159
+ },
160
+ stages: {
161
+ crawl: { status: dxp_porter_shared_1.PortStatus.complete },
162
+ index: { status: dxp_porter_shared_1.PortStatus.skipped },
163
+ 'component-transform': { status: dxp_porter_shared_1.PortStatus.skipped },
164
+ 'design-dedupe': { status: dxp_porter_shared_1.PortStatus.skipped },
165
+ 'template-dedupe': { status: dxp_porter_shared_1.PortStatus.skipped },
166
+ validation: { status: dxp_porter_shared_1.PortStatus.skipped },
167
+ report: { status: dxp_porter_shared_1.PortStatus.skipped },
168
+ },
169
+ status: mockStatus,
170
+ };
171
+ mockResponse = {
172
+ data: mockGetResponse,
173
+ status: 200,
174
+ };
175
+ const { default: createGetCommand } = require('./get');
176
+ const program = createGetCommand();
177
+ yield program.parseAsync(['port', 'getPort', portId]);
178
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
179
+ expect(mockClient.get).toHaveBeenCalledWith(`/projects/${projectName}/ports/${portId}`);
180
+ expect(PorterUtils.handleError).not.toHaveBeenCalled();
181
+ expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
182
+ expect(logSpy).toHaveBeenNthCalledWith(2, `Port ID: ${portId}`);
183
+ expect(logSpy).toHaveBeenNthCalledWith(3, `Status: ${mockStatus}`);
184
+ expect(logSpy).toHaveBeenNthCalledWith(4, 'Download report: Not generated');
185
+ expect(logSpy).toHaveBeenNthCalledWith(5, 'Download artifacts: Not generated');
186
+ expect(logSpy).toHaveBeenNthCalledWith(6, '');
187
+ expect(logSpy).toHaveBeenNthCalledWith(7, 'Stage crawl status: complete');
188
+ expect(logSpy).toHaveBeenNthCalledWith(8, 'Stage index status: skipped');
189
+ expect(logSpy).toHaveBeenNthCalledWith(9, 'Stage template dedupe status: skipped');
190
+ expect(logSpy).toHaveBeenNthCalledWith(10, 'Stage validation status: skipped');
191
+ expect(logSpy).toHaveBeenNthCalledWith(11, 'Stage report status: skipped');
192
+ expect(logSpy).toHaveBeenNthCalledWith(12, '');
193
+ expect(logSpy).toHaveBeenNthCalledWith(13, 'Stage crawl settings:', mockGetResponse['stage-settings'].crawl);
194
+ expect(logSpy).toHaveBeenNthCalledWith(14, 'Stage index settings:', mockGetResponse['stage-settings'].index);
195
+ expect(logSpy).toHaveBeenNthCalledWith(15, 'Stage template dedupe settings:', mockGetResponse['stage-settings']['template-dedupe']);
196
+ expect(logSpy).toHaveBeenNthCalledWith(16, 'Stage validation settings:', mockGetResponse['stage-settings'].validation);
197
+ expect(logSpy).toHaveBeenNthCalledWith(17, 'Stage report settings:', mockGetResponse['stage-settings'].report);
198
+ }));
199
+ it('should successfully retrieve the port details and log this to the console with non-null links', () => __awaiter(void 0, void 0, void 0, function* () {
200
+ const mockStatus = dxp_porter_shared_1.PortStatus.complete;
201
+ const mockReportLink = 'report-link';
202
+ const mockArtifactsLink = 'artifacts-link';
203
+ const mockGetResponse = {
204
+ portid: portId,
205
+ 'artifacts-link': mockArtifactsLink,
206
+ 'report-link': mockReportLink,
207
+ 'stage-settings': {
208
+ crawl: { run: true, start_urls: [] },
209
+ index: { run: false },
210
+ 'component-transform': { run: false },
211
+ 'design-dedupe': { run: false },
212
+ 'template-dedupe': { run: false },
213
+ validation: { run: false },
214
+ report: { run: false },
215
+ },
216
+ stages: {
217
+ crawl: { status: dxp_porter_shared_1.PortStatus.complete },
218
+ index: { status: dxp_porter_shared_1.PortStatus.skipped },
219
+ 'component-transform': { status: dxp_porter_shared_1.PortStatus.skipped },
220
+ 'design-dedupe': { status: dxp_porter_shared_1.PortStatus.skipped },
221
+ 'template-dedupe': { status: dxp_porter_shared_1.PortStatus.skipped },
222
+ validation: { status: dxp_porter_shared_1.PortStatus.skipped },
223
+ report: { status: dxp_porter_shared_1.PortStatus.skipped },
224
+ },
225
+ status: mockStatus,
226
+ };
227
+ mockResponse = {
228
+ data: mockGetResponse,
229
+ status: 200,
230
+ };
231
+ const { default: createGetCommand } = require('./get');
232
+ const program = createGetCommand();
233
+ yield program.parseAsync(['port', 'getPort', portId]);
234
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
235
+ expect(mockClient.get).toHaveBeenCalledWith(`/projects/${projectName}/ports/${portId}`);
236
+ expect(PorterUtils.handleError).not.toHaveBeenCalled();
237
+ expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
238
+ expect(logSpy).toHaveBeenNthCalledWith(2, `Port ID: ${portId}`);
239
+ expect(logSpy).toHaveBeenNthCalledWith(3, `Status: ${mockStatus}`);
240
+ expect(logSpy).toHaveBeenNthCalledWith(4, `Download report: ${mockReportLink}`);
241
+ expect(logSpy).toHaveBeenNthCalledWith(5, `Download artifacts: ${mockArtifactsLink}`);
242
+ expect(logSpy).toHaveBeenNthCalledWith(6, '');
243
+ expect(logSpy).toHaveBeenNthCalledWith(7, 'Stage crawl status: complete');
244
+ expect(logSpy).toHaveBeenNthCalledWith(8, 'Stage index status: skipped');
245
+ expect(logSpy).toHaveBeenNthCalledWith(9, 'Stage template dedupe status: skipped');
246
+ expect(logSpy).toHaveBeenNthCalledWith(10, 'Stage validation status: skipped');
247
+ expect(logSpy).toHaveBeenNthCalledWith(11, 'Stage report status: skipped');
248
+ expect(logSpy).toHaveBeenNthCalledWith(12, '');
249
+ expect(logSpy).toHaveBeenNthCalledWith(13, 'Stage crawl settings:', mockGetResponse['stage-settings'].crawl);
250
+ expect(logSpy).toHaveBeenNthCalledWith(14, 'Stage index settings:', mockGetResponse['stage-settings'].index);
251
+ expect(logSpy).toHaveBeenNthCalledWith(15, 'Stage template dedupe settings:', mockGetResponse['stage-settings']['template-dedupe']);
252
+ expect(logSpy).toHaveBeenNthCalledWith(16, 'Stage validation settings:', mockGetResponse['stage-settings'].validation);
253
+ expect(logSpy).toHaveBeenNthCalledWith(17, 'Stage report settings:', mockGetResponse['stage-settings'].report);
254
+ }));
255
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const createPortCommand: () => Command;
3
+ export default createPortCommand;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const commander_1 = require("commander");
7
+ const abort_1 = __importDefault(require("./abort/abort"));
8
+ const get_1 = __importDefault(require("./get/get"));
9
+ const start_1 = __importDefault(require("./start/start"));
10
+ const createPortCommand = () => {
11
+ const portCommand = new commander_1.Command('port');
12
+ portCommand
13
+ .description('Porter port commands')
14
+ .addCommand((0, start_1.default)())
15
+ .addCommand((0, get_1.default)())
16
+ .addCommand((0, abort_1.default)());
17
+ return portCommand;
18
+ };
19
+ exports.default = createPortCommand;
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const createStartPortCommand: () => Command;
3
+ export default createStartPortCommand;
@@ -0,0 +1,79 @@
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 promises_1 = __importDefault(require("fs/promises"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const ora_1 = __importDefault(require("ora"));
20
+ const ApiService_1 = require("../../../ApiService");
21
+ const utils_1 = require("../../utils");
22
+ const createStartPortCommand = () => {
23
+ const getCommand = new commander_1.Command('startPort')
24
+ .description('Start porting a website using the local project configuration')
25
+ .configureOutput({
26
+ outputError(str, write) {
27
+ write(chalk_1.default.red(str));
28
+ },
29
+ })
30
+ .action((options) => __awaiter(void 0, void 0, void 0, function* () {
31
+ yield (0, utils_1.throwErrorIfNotLoggedIn)(getCommand);
32
+ const baseUrl = yield (0, utils_1.buildPorterUrl)();
33
+ let projectName = '';
34
+ const spinner = (0, ora_1.default)();
35
+ try {
36
+ projectName = yield (0, utils_1.getProjectName)();
37
+ spinner.start('Starting port..');
38
+ const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus, baseUrl);
39
+ // Read the stage directories for project configuration
40
+ const stageConfigDir = path_1.default.resolve('stage-configs');
41
+ const stageDirs = yield promises_1.default.readdir(stageConfigDir);
42
+ // Currently, skip component-transform and design-dedupe
43
+ const portSettings = {
44
+ 'component-transform': { run: false },
45
+ 'design-dedupe': { run: false },
46
+ };
47
+ // Read the config files for each stage, and construct the overall port settings
48
+ yield Promise.all(stageDirs.map((stage) => __awaiter(void 0, void 0, void 0, function* () {
49
+ const stageConfigFile = path_1.default.resolve(stageConfigDir, stage, 'config.json');
50
+ const stageConfig = yield promises_1.default.readFile(stageConfigFile, {
51
+ encoding: 'utf-8',
52
+ });
53
+ const config = JSON.parse(stageConfig);
54
+ const updatedConfig = Object.assign(Object.assign({}, portSettings[stage]), config);
55
+ portSettings[stage] = updatedConfig;
56
+ })));
57
+ (0, utils_1.logDebug)(`Port settings to use: ${JSON.stringify(portSettings)}`);
58
+ const portRequest = {
59
+ ['stage-settings']: portSettings,
60
+ };
61
+ const response = yield apiService.client.post(`/projects/${projectName}/ports`, portRequest);
62
+ const jsonResponse = response.data;
63
+ (0, utils_1.logDebug)(JSON.stringify(jsonResponse));
64
+ const { portid } = jsonResponse;
65
+ spinner.succeed();
66
+ console.log('');
67
+ console.log(`Website porting in progress with ID: ${portid}`);
68
+ }
69
+ catch (error) {
70
+ (0, utils_1.logDebug)(`ERROR: ${error instanceof Error ? `${error.message}` : JSON.stringify(error)}`);
71
+ if (spinner.isSpinning) {
72
+ spinner.fail();
73
+ }
74
+ (0, utils_1.handleCommandError)(getCommand, error);
75
+ }
76
+ }));
77
+ return getCommand;
78
+ };
79
+ exports.default = createStartPortCommand;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,198 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ const axios_1 = require("axios");
36
+ const ApiService = __importStar(require("../../../ApiService"));
37
+ const PorterUtils = __importStar(require("../../utils"));
38
+ const fsp = __importStar(require("fs/promises"));
39
+ // const logSpy = jest.spyOn(global.console, 'log');
40
+ jest.mock('../../utils');
41
+ jest.mock('fs/promises');
42
+ describe('startPort', () => {
43
+ let projectName;
44
+ let portId;
45
+ let baseUrl;
46
+ let mockHandleCommandError;
47
+ let mockHandleError;
48
+ let mockBuildPorterUrl;
49
+ let mockResponse;
50
+ let mockClient;
51
+ beforeEach(() => {
52
+ jest.resetAllMocks();
53
+ jest.clearAllMocks();
54
+ projectName = 'mock-project';
55
+ portId = '1234-5678-1234-5678';
56
+ baseUrl = 'mock-url';
57
+ mockHandleCommandError = jest.fn(() => Promise.resolve());
58
+ mockHandleError = jest.fn();
59
+ mockBuildPorterUrl = jest.fn(() => Promise.resolve(baseUrl));
60
+ mockResponse = {
61
+ data: {},
62
+ status: 200,
63
+ };
64
+ mockClient = {
65
+ post: jest.fn().mockImplementationOnce(() => mockResponse),
66
+ };
67
+ jest.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn').mockImplementation();
68
+ jest
69
+ .spyOn(PorterUtils, 'buildPorterUrl')
70
+ .mockImplementationOnce(mockBuildPorterUrl);
71
+ jest
72
+ .spyOn(PorterUtils, 'getProjectName')
73
+ .mockImplementation(() => Promise.resolve(projectName));
74
+ jest
75
+ .spyOn(fsp, 'readdir')
76
+ .mockImplementationOnce(() => Promise.resolve([
77
+ 'crawl',
78
+ 'index',
79
+ 'template-dedupe',
80
+ 'validation',
81
+ 'report',
82
+ ]));
83
+ jest
84
+ .spyOn(fsp, 'readFile')
85
+ .mockImplementation(() => Promise.resolve(JSON.stringify({ run: true })));
86
+ jest
87
+ .spyOn(PorterUtils, 'handleCommandError')
88
+ .mockImplementationOnce(mockHandleCommandError);
89
+ jest
90
+ .spyOn(PorterUtils, 'handleError')
91
+ .mockImplementationOnce(mockHandleError);
92
+ jest.spyOn(process, 'exit').mockImplementation();
93
+ jest.spyOn(ApiService, 'ApiService').mockImplementationOnce(() => {
94
+ return {
95
+ client: mockClient,
96
+ };
97
+ });
98
+ });
99
+ it('should throw an error if not logged in', () => __awaiter(void 0, void 0, void 0, function* () {
100
+ const mockError = new Error('Error not logged in');
101
+ jest
102
+ .spyOn(PorterUtils, 'throwErrorIfNotLoggedIn')
103
+ .mockImplementationOnce(() => {
104
+ throw mockError;
105
+ });
106
+ const { default: createStartCommand } = require('./start');
107
+ const program = createStartCommand();
108
+ yield expect(() => program.parseAsync(['port', 'startPort', portId])).rejects.toThrow(mockError);
109
+ const opts = program.opts();
110
+ expect(opts).toStrictEqual({});
111
+ expect(PorterUtils.buildPorterUrl).not.toHaveBeenCalled();
112
+ }));
113
+ it('should throw an error if project name could not be found', () => __awaiter(void 0, void 0, void 0, function* () {
114
+ jest.spyOn(PorterUtils, 'getProjectName').mockImplementationOnce(() => {
115
+ throw new Error();
116
+ });
117
+ const { default: createStartCommand } = require('./start');
118
+ const program = createStartCommand();
119
+ yield program.parseAsync(['port', 'startPort', portId]);
120
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
121
+ expect(mockClient.post).not.toHaveBeenCalled();
122
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
123
+ }));
124
+ it('should handle errors reading stage config files', () => __awaiter(void 0, void 0, void 0, function* () {
125
+ jest
126
+ .spyOn(fsp, 'readdir')
127
+ .mockReset()
128
+ .mockImplementationOnce(() => {
129
+ throw new Error('ENOENT: no such file or directory');
130
+ });
131
+ const { default: createStartCommand } = require('./start');
132
+ const program = createStartCommand();
133
+ yield program.parseAsync(['port', 'startPort', portId]);
134
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
135
+ expect(mockClient.post).not.toHaveBeenCalled();
136
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
137
+ }));
138
+ it('should handle 400 error from the porter service', () => __awaiter(void 0, void 0, void 0, function* () {
139
+ mockClient.post = jest.fn(() => {
140
+ throw new axios_1.AxiosError('Bad request', '400', undefined, undefined, {
141
+ data: {
142
+ status: 400,
143
+ title: 'Bad request',
144
+ 'invalid-params': [
145
+ { name: 'crawl.run', reason: 'crawl.run is required in the body' },
146
+ ],
147
+ },
148
+ });
149
+ });
150
+ const { default: createStartCommand } = require('./start');
151
+ const program = createStartCommand();
152
+ yield program.parseAsync(['port', 'startPort', portId]);
153
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
154
+ expect(mockClient.post).toHaveBeenCalled();
155
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
156
+ }));
157
+ it('should handle unexpected errors', () => __awaiter(void 0, void 0, void 0, function* () {
158
+ mockClient.post = jest.fn(() => {
159
+ throw new axios_1.AxiosError('Internal server error', '500', undefined, undefined, {
160
+ data: { status: 500 },
161
+ });
162
+ });
163
+ const { default: createStartCommand } = require('./start');
164
+ const program = createStartCommand();
165
+ yield program.parseAsync(['port', 'startPort', portId]);
166
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
167
+ expect(mockClient.post).toHaveBeenCalled();
168
+ expect(PorterUtils.handleError).not.toHaveBeenCalled();
169
+ expect(PorterUtils.handleCommandError).toHaveBeenCalled();
170
+ }));
171
+ it('should successfully start a website port and log to the console', () => __awaiter(void 0, void 0, void 0, function* () {
172
+ const uuid = '1234-1234-1234-1234';
173
+ const mockPostResponse = {
174
+ portid: uuid,
175
+ };
176
+ mockResponse = {
177
+ data: mockPostResponse,
178
+ status: 200,
179
+ };
180
+ const { default: createStartCommand } = require('./start');
181
+ const program = createStartCommand();
182
+ yield program.parseAsync(['port', 'startPort', portId]);
183
+ expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
184
+ expect(mockClient.post).toHaveBeenCalledWith(`/projects/${projectName}/ports`, {
185
+ 'stage-settings': {
186
+ crawl: { run: true },
187
+ index: { run: true },
188
+ 'component-transform': { run: false },
189
+ 'design-dedupe': { run: false },
190
+ 'template-dedupe': { run: true },
191
+ validation: { run: true },
192
+ report: { run: true },
193
+ },
194
+ });
195
+ expect(PorterUtils.handleError).not.toHaveBeenCalled();
196
+ expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
197
+ }));
198
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const createAddProjectCommand: () => Command;
3
+ export default createAddProjectCommand;