@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.
- package/README.md +1 -0
- package/lib/__tests__/integration/main.spec.js +3 -2
- package/lib/cdp/index.js +3 -1
- package/lib/cmp/deploy.js +49 -2
- package/lib/cmp/edge-components/compiler.d.ts +13 -0
- package/lib/cmp/edge-components/compiler.js +55 -0
- package/lib/cmp/utils/definitions.d.ts +12 -0
- package/lib/cmp/utils/definitions.js +76 -0
- package/lib/datastore/index.js +1 -1
- package/lib/dxp.js +2 -0
- package/lib/porter/constants.d.ts +8 -0
- package/lib/porter/constants.js +11 -0
- package/lib/porter/index.d.ts +3 -0
- package/lib/porter/index.js +14 -0
- package/lib/porter/port/abort/abort.d.ts +3 -0
- package/lib/porter/port/abort/abort.js +77 -0
- package/lib/porter/port/abort/abort.spec.d.ts +1 -0
- package/lib/porter/port/abort/abort.spec.js +182 -0
- package/lib/porter/port/get/get.d.ts +3 -0
- package/lib/porter/port/get/get.js +94 -0
- package/lib/porter/port/get/get.spec.d.ts +1 -0
- package/lib/porter/port/get/get.spec.js +255 -0
- package/lib/porter/port/portCommand.d.ts +3 -0
- package/lib/porter/port/portCommand.js +19 -0
- package/lib/porter/port/start/start.d.ts +3 -0
- package/lib/porter/port/start/start.js +79 -0
- package/lib/porter/port/start/start.spec.d.ts +1 -0
- package/lib/porter/port/start/start.spec.js +198 -0
- package/lib/porter/project/add/add.d.ts +3 -0
- package/lib/porter/project/add/add.js +125 -0
- package/lib/porter/project/add/add.spec.d.ts +1 -0
- package/lib/porter/project/add/add.spec.js +270 -0
- package/lib/porter/project/get/get.d.ts +3 -0
- package/lib/porter/project/get/get.js +62 -0
- package/lib/porter/project/get/get.spec.d.ts +1 -0
- package/lib/porter/project/get/get.spec.js +185 -0
- package/lib/porter/project/projectCommand.d.ts +3 -0
- package/lib/porter/project/projectCommand.js +19 -0
- package/lib/porter/project/remove/remove.d.ts +3 -0
- package/lib/porter/project/remove/remove.js +66 -0
- package/lib/porter/project/remove/remove.spec.d.ts +1 -0
- package/lib/porter/project/remove/remove.spec.js +201 -0
- package/lib/porter/types.d.ts +5 -0
- package/lib/porter/types.js +2 -0
- package/lib/porter/utils/AuthUtils/CheckAuthorisation.d.ts +1 -0
- package/lib/porter/utils/AuthUtils/CheckAuthorisation.js +32 -0
- package/lib/porter/utils/AuthUtils/CheckAuthorisation.spec.d.ts +1 -0
- package/lib/porter/utils/AuthUtils/CheckAuthorisation.spec.js +77 -0
- package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.d.ts +1 -0
- package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.js +27 -0
- package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.spec.d.ts +1 -0
- package/lib/porter/utils/BuildPorterUrl/BuildPorterUrl.spec.js +59 -0
- package/lib/porter/utils/CoreUtils/CoreUtils.d.ts +2 -0
- package/lib/porter/utils/CoreUtils/CoreUtils.js +13 -0
- package/lib/porter/utils/CoreUtils/CoreUtils.spec.d.ts +1 -0
- package/lib/porter/utils/CoreUtils/CoreUtils.spec.js +36 -0
- package/lib/porter/utils/DoesPathExist/DoesPathExist.d.ts +1 -0
- package/lib/porter/utils/DoesPathExist/DoesPathExist.js +27 -0
- package/lib/porter/utils/DoesPathExist/DoesPathExist.spec.d.ts +1 -0
- package/lib/porter/utils/DoesPathExist/DoesPathExist.spec.js +40 -0
- package/lib/porter/utils/ErrorUtils/ErrorUtils.d.ts +4 -0
- package/lib/porter/utils/ErrorUtils/ErrorUtils.js +71 -0
- package/lib/porter/utils/ErrorUtils/ErrorUtils.spec.d.ts +1 -0
- package/lib/porter/utils/ErrorUtils/ErrorUtils.spec.js +190 -0
- package/lib/porter/utils/GetProjectConfig/GetProjectConfig.d.ts +2 -0
- package/lib/porter/utils/GetProjectConfig/GetProjectConfig.js +33 -0
- package/lib/porter/utils/GetProjectConfig/GetProjectConfig.spec.d.ts +1 -0
- package/lib/porter/utils/GetProjectConfig/GetProjectConfig.spec.js +50 -0
- package/lib/porter/utils/GetProjectName/GetProjectName.d.ts +4 -0
- package/lib/porter/utils/GetProjectName/GetProjectName.js +30 -0
- package/lib/porter/utils/GetProjectName/GetProjectName.spec.d.ts +1 -0
- package/lib/porter/utils/GetProjectName/GetProjectName.spec.js +91 -0
- package/lib/porter/utils/index.d.ts +7 -0
- package/lib/porter/utils/index.js +23 -0
- package/package.json +6 -3
|
@@ -0,0 +1,125 @@
|
|
|
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 dxp_porter_shared_1 = require("@squiz/dxp-porter-shared");
|
|
23
|
+
const constants_1 = require("../../constants");
|
|
24
|
+
const { version: cliVersion } = require('../../../../package.json');
|
|
25
|
+
const allPortStages = Object.values(dxp_porter_shared_1.Stage);
|
|
26
|
+
const stageDirsToCreate = allPortStages.filter(stage => stage !== dxp_porter_shared_1.Stage['component-transform'] && stage !== dxp_porter_shared_1.Stage['design-dedupe']);
|
|
27
|
+
const createAddProjectCommand = () => {
|
|
28
|
+
const addCommand = new commander_1.Command('addProject')
|
|
29
|
+
.description('Adds a new project')
|
|
30
|
+
.addOption(new commander_1.Option('--project-name <string>', 'project name')
|
|
31
|
+
.makeOptionMandatory()
|
|
32
|
+
.argParser(name => {
|
|
33
|
+
// Project name validation
|
|
34
|
+
const regex = /^[a-zA-Z0-9\-_]+$/;
|
|
35
|
+
if (!regex.test(name)) {
|
|
36
|
+
throw new commander_1.InvalidArgumentError('Project name can only contain letters, numbers, hyphen and underscore');
|
|
37
|
+
}
|
|
38
|
+
return name;
|
|
39
|
+
}))
|
|
40
|
+
.addOption(new commander_1.Option('--path <string>', 'path to store the project').makeOptionMandatory())
|
|
41
|
+
.configureOutput({
|
|
42
|
+
outputError(str, write) {
|
|
43
|
+
write(chalk_1.default.red(str));
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(addCommand);
|
|
49
|
+
const baseUrl = yield (0, utils_1.buildPorterUrl)();
|
|
50
|
+
const projectName = options.projectName;
|
|
51
|
+
const projectPath = options.path;
|
|
52
|
+
const spinner = (0, ora_1.default)();
|
|
53
|
+
const projectDir = path_1.default.resolve(projectPath);
|
|
54
|
+
try {
|
|
55
|
+
const pathExists = yield (0, utils_1.doesPathExist)(projectPath);
|
|
56
|
+
if (pathExists) {
|
|
57
|
+
throw new Error(constants_1.PORTER_ERRORS.projectAlreadyExists);
|
|
58
|
+
}
|
|
59
|
+
const parentDir = path_1.default.dirname(projectDir);
|
|
60
|
+
try {
|
|
61
|
+
yield promises_1.default.access(parentDir);
|
|
62
|
+
}
|
|
63
|
+
catch (_c) {
|
|
64
|
+
throw new Error(`Project parent directory "${parentDir}" does not exist`);
|
|
65
|
+
}
|
|
66
|
+
spinner.start('Creating a new project..');
|
|
67
|
+
yield promises_1.default.mkdir(projectDir);
|
|
68
|
+
(0, utils_1.logDebug)(`Directory created successfully at ${projectDir}`);
|
|
69
|
+
const configJsonFile = path_1.default.join(projectDir, 'config.json');
|
|
70
|
+
yield promises_1.default.writeFile(configJsonFile, JSON.stringify({
|
|
71
|
+
service: 'dxp-porter',
|
|
72
|
+
projectName,
|
|
73
|
+
version: cliVersion,
|
|
74
|
+
}, null, 2));
|
|
75
|
+
(0, utils_1.logDebug)(`File created successfully at ${configJsonFile}`);
|
|
76
|
+
const stageConfigDir = path_1.default.join(projectDir, 'stage-configs');
|
|
77
|
+
yield promises_1.default.mkdir(stageConfigDir);
|
|
78
|
+
(0, utils_1.logDebug)(`Directory created successfully at ${stageConfigDir}`);
|
|
79
|
+
yield Promise.all(stageDirsToCreate.map((stage) => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
+
const stageDir = path_1.default.join(stageConfigDir, stage);
|
|
81
|
+
yield promises_1.default.mkdir(stageDir);
|
|
82
|
+
(0, utils_1.logDebug)(`Directory created successfully at ${stageDir}`);
|
|
83
|
+
})));
|
|
84
|
+
const crawlConfigExample = path_1.default.join(stageConfigDir, 'crawl', 'config.json.example');
|
|
85
|
+
yield promises_1.default.writeFile(crawlConfigExample, JSON.stringify({
|
|
86
|
+
start_urls: ['https://...', 'https://...'],
|
|
87
|
+
exclude_patterns: ['https://...', 'https://...'],
|
|
88
|
+
max_download_size: 'MB',
|
|
89
|
+
request_delay: 'INT',
|
|
90
|
+
max_dir_depth: 'INT',
|
|
91
|
+
max_files_stored: 'INT',
|
|
92
|
+
run: true,
|
|
93
|
+
}, null, 2));
|
|
94
|
+
(0, utils_1.logDebug)(`File created successfully at ${crawlConfigExample}`);
|
|
95
|
+
// Default example configs for other stages
|
|
96
|
+
stageDirsToCreate
|
|
97
|
+
.filter(dir => dir !== dxp_porter_shared_1.Stage.crawl)
|
|
98
|
+
.map((dir) => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
|
+
const configExample = path_1.default.join(stageConfigDir, dir, 'config.json.example');
|
|
100
|
+
yield promises_1.default.writeFile(configExample, JSON.stringify({ run: true }, null, 2));
|
|
101
|
+
(0, utils_1.logDebug)(`File created successfully at ${configExample}`);
|
|
102
|
+
}));
|
|
103
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus, baseUrl);
|
|
104
|
+
const requestBody = { 'new-project': true };
|
|
105
|
+
const response = yield apiService.client.put(`/projects/${projectName}`, requestBody);
|
|
106
|
+
(0, utils_1.logDebug)(response.data);
|
|
107
|
+
spinner.succeed(`Project "${projectName}" created. Project directory initialized`);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
(0, utils_1.logDebug)(`ERROR: ${error instanceof Error ? `${error.message}` : JSON.stringify(error)}`);
|
|
111
|
+
if (spinner.isSpinning) {
|
|
112
|
+
spinner.fail();
|
|
113
|
+
}
|
|
114
|
+
if (((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.status) === 409) {
|
|
115
|
+
(0, utils_1.logDebug)(`Failed to create new project, removing project directory: "${projectDir}"`);
|
|
116
|
+
yield promises_1.default.rm(projectDir, { recursive: true });
|
|
117
|
+
const errorMessage = `Project "${projectName}" already exists. Try a different project name`;
|
|
118
|
+
return (0, utils_1.handleError)(addCommand, errorMessage);
|
|
119
|
+
}
|
|
120
|
+
(0, utils_1.handleCommandError)(addCommand, error);
|
|
121
|
+
}
|
|
122
|
+
}));
|
|
123
|
+
return addCommand;
|
|
124
|
+
};
|
|
125
|
+
exports.default = createAddProjectCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,270 @@
|
|
|
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 commander_1 = require("commander");
|
|
39
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
40
|
+
const axios_1 = require("axios");
|
|
41
|
+
const ApiService = __importStar(require("../../../ApiService"));
|
|
42
|
+
const PorterUtils = __importStar(require("../../utils"));
|
|
43
|
+
const mockCliVersion = '1.2.3';
|
|
44
|
+
jest.mock('../../../../package.json', () => {
|
|
45
|
+
return {
|
|
46
|
+
version: mockCliVersion,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
jest.mock('fs/promises', () => {
|
|
50
|
+
return {
|
|
51
|
+
access: jest.fn(),
|
|
52
|
+
mkdir: jest.fn(),
|
|
53
|
+
rm: jest.fn(),
|
|
54
|
+
writeFile: jest.fn(),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
jest.mock('../../utils');
|
|
58
|
+
describe('addProject', () => {
|
|
59
|
+
let projectName;
|
|
60
|
+
let projectPath;
|
|
61
|
+
let baseUrl;
|
|
62
|
+
let mockHandleCommandError;
|
|
63
|
+
let mockHandleError;
|
|
64
|
+
let mockBuildPorterUrl;
|
|
65
|
+
let mockResponse;
|
|
66
|
+
let mockClient;
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
jest.resetAllMocks();
|
|
69
|
+
jest.clearAllMocks();
|
|
70
|
+
projectName = 'porter-project';
|
|
71
|
+
projectPath = 'tmp/project-dir';
|
|
72
|
+
baseUrl = 'mock-url';
|
|
73
|
+
mockHandleCommandError = jest.fn(() => Promise.resolve());
|
|
74
|
+
mockHandleError = jest.fn();
|
|
75
|
+
mockBuildPorterUrl = jest.fn(() => Promise.resolve(baseUrl));
|
|
76
|
+
mockResponse = {
|
|
77
|
+
data: {},
|
|
78
|
+
status: 200,
|
|
79
|
+
};
|
|
80
|
+
mockClient = {
|
|
81
|
+
put: jest.fn().mockImplementationOnce(() => mockResponse),
|
|
82
|
+
};
|
|
83
|
+
jest.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn').mockImplementation();
|
|
84
|
+
jest
|
|
85
|
+
.spyOn(PorterUtils, 'doesPathExist')
|
|
86
|
+
.mockImplementationOnce(() => Promise.resolve(false));
|
|
87
|
+
jest
|
|
88
|
+
.spyOn(PorterUtils, 'buildPorterUrl')
|
|
89
|
+
.mockImplementationOnce(mockBuildPorterUrl);
|
|
90
|
+
jest
|
|
91
|
+
.spyOn(PorterUtils, 'handleCommandError')
|
|
92
|
+
.mockImplementationOnce(mockHandleCommandError);
|
|
93
|
+
jest
|
|
94
|
+
.spyOn(PorterUtils, 'handleError')
|
|
95
|
+
.mockImplementationOnce(mockHandleError);
|
|
96
|
+
jest.spyOn(process, 'exit').mockImplementation();
|
|
97
|
+
jest.spyOn(ApiService, 'ApiService').mockImplementationOnce(() => {
|
|
98
|
+
return {
|
|
99
|
+
client: mockClient,
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it('should throw an error if project name is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
|
+
// Project name can only contain letters, numbers, hyphens and underscores'
|
|
105
|
+
const projectNameInvalid = '!@#$';
|
|
106
|
+
const { default: createAddCommand } = require('./add');
|
|
107
|
+
const program = createAddCommand();
|
|
108
|
+
yield expect(() => program.parseAsync([
|
|
109
|
+
'project',
|
|
110
|
+
'addProject',
|
|
111
|
+
'--project-name',
|
|
112
|
+
projectNameInvalid,
|
|
113
|
+
'--path',
|
|
114
|
+
projectPath,
|
|
115
|
+
])).rejects.toThrow(commander_1.InvalidArgumentError);
|
|
116
|
+
expect(process.exit).toHaveBeenCalled();
|
|
117
|
+
}));
|
|
118
|
+
it('should throw an error if not logged in', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
119
|
+
const mockError = new Error('Error not logged in');
|
|
120
|
+
jest
|
|
121
|
+
.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn')
|
|
122
|
+
.mockImplementationOnce(() => {
|
|
123
|
+
throw mockError;
|
|
124
|
+
});
|
|
125
|
+
const { default: createAddCommand } = require('./add');
|
|
126
|
+
const program = createAddCommand();
|
|
127
|
+
yield expect(() => program.parseAsync([
|
|
128
|
+
'project',
|
|
129
|
+
'addProject',
|
|
130
|
+
'--project-name',
|
|
131
|
+
projectName,
|
|
132
|
+
'--path',
|
|
133
|
+
projectPath,
|
|
134
|
+
])).rejects.toThrow(mockError);
|
|
135
|
+
const opts = program.opts();
|
|
136
|
+
expect(opts.projectName).toEqual(projectName);
|
|
137
|
+
expect(opts.path).toEqual(projectPath);
|
|
138
|
+
expect(PorterUtils.buildPorterUrl).not.toHaveBeenCalled();
|
|
139
|
+
}));
|
|
140
|
+
it('should throw an error if project directory already exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
+
jest
|
|
142
|
+
.spyOn(PorterUtils, 'doesPathExist')
|
|
143
|
+
.mockReset()
|
|
144
|
+
.mockImplementationOnce(() => Promise.resolve(true));
|
|
145
|
+
const { default: createAddCommand } = require('./add');
|
|
146
|
+
const program = createAddCommand();
|
|
147
|
+
yield program.parseAsync([
|
|
148
|
+
'project',
|
|
149
|
+
'addProject',
|
|
150
|
+
'--project-name',
|
|
151
|
+
projectName,
|
|
152
|
+
'--path',
|
|
153
|
+
projectPath,
|
|
154
|
+
]);
|
|
155
|
+
const opts = program.opts();
|
|
156
|
+
expect(opts.projectName).toEqual(projectName);
|
|
157
|
+
expect(opts.path).toEqual(projectPath);
|
|
158
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
159
|
+
expect(PorterUtils.doesPathExist).toHaveBeenCalled();
|
|
160
|
+
expect(mockClient.put).not.toHaveBeenCalled();
|
|
161
|
+
expect(PorterUtils.handleCommandError).toHaveBeenCalled();
|
|
162
|
+
}));
|
|
163
|
+
it('should throw an error if parent directory does not exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
jest.spyOn(promises_1.default, 'access').mockImplementationOnce(() => {
|
|
165
|
+
throw new Error();
|
|
166
|
+
});
|
|
167
|
+
const { default: createAddCommand } = require('./add');
|
|
168
|
+
const program = createAddCommand();
|
|
169
|
+
yield program.parseAsync([
|
|
170
|
+
'project',
|
|
171
|
+
'addProject',
|
|
172
|
+
'--project-name',
|
|
173
|
+
projectName,
|
|
174
|
+
'--path',
|
|
175
|
+
projectPath,
|
|
176
|
+
]);
|
|
177
|
+
const opts = program.opts();
|
|
178
|
+
expect(opts.projectName).toEqual(projectName);
|
|
179
|
+
expect(opts.path).toEqual(projectPath);
|
|
180
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
181
|
+
expect(PorterUtils.doesPathExist).toHaveBeenCalled();
|
|
182
|
+
expect(promises_1.default.access).toHaveBeenCalled();
|
|
183
|
+
expect(mockClient.put).not.toHaveBeenCalled();
|
|
184
|
+
expect(PorterUtils.handleCommandError).toHaveBeenCalled();
|
|
185
|
+
}));
|
|
186
|
+
it('should clean up the directory if project already exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
+
mockClient.put = jest.fn(() => {
|
|
188
|
+
throw new axios_1.AxiosError('Project already exists', '409', undefined, undefined, {
|
|
189
|
+
data: { status: 409 },
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
const { default: createAddCommand } = require('./add');
|
|
193
|
+
const program = createAddCommand();
|
|
194
|
+
yield program.parseAsync([
|
|
195
|
+
'project',
|
|
196
|
+
'addProject',
|
|
197
|
+
'--project-name',
|
|
198
|
+
projectName,
|
|
199
|
+
'--path',
|
|
200
|
+
projectPath,
|
|
201
|
+
]);
|
|
202
|
+
const opts = program.opts();
|
|
203
|
+
expect(opts.projectName).toEqual(projectName);
|
|
204
|
+
expect(opts.path).toEqual(projectPath);
|
|
205
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
206
|
+
expect(PorterUtils.doesPathExist).toHaveBeenCalled();
|
|
207
|
+
expect(promises_1.default.access).toHaveBeenCalled();
|
|
208
|
+
// Create project dir, create "stage-configs" directory, create directories for (crawl, index, template-dedupe, validation, report)
|
|
209
|
+
expect(promises_1.default.mkdir).toHaveBeenCalledTimes(7);
|
|
210
|
+
// Create project config.json as well as 5 example config.json (for each stage)
|
|
211
|
+
expect(promises_1.default.writeFile).toHaveBeenCalledTimes(6);
|
|
212
|
+
expect(promises_1.default.writeFile).toHaveBeenNthCalledWith(1, expect.any(String), expect.stringContaining(mockCliVersion));
|
|
213
|
+
expect(mockClient.put).toHaveBeenCalled();
|
|
214
|
+
expect(promises_1.default.rm).toHaveBeenCalled();
|
|
215
|
+
expect(PorterUtils.handleError).toHaveBeenCalled();
|
|
216
|
+
expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
|
|
217
|
+
}));
|
|
218
|
+
it('should handle unexpected errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
219
|
+
const { default: createAddCommand } = require('./add');
|
|
220
|
+
const program = createAddCommand();
|
|
221
|
+
yield program.parseAsync([
|
|
222
|
+
'project',
|
|
223
|
+
'addProject',
|
|
224
|
+
'--project-name',
|
|
225
|
+
projectName,
|
|
226
|
+
'--path',
|
|
227
|
+
projectPath,
|
|
228
|
+
]);
|
|
229
|
+
const opts = program.opts();
|
|
230
|
+
expect(opts.projectName).toEqual(projectName);
|
|
231
|
+
expect(opts.path).toEqual(projectPath);
|
|
232
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
233
|
+
expect(PorterUtils.doesPathExist).toHaveBeenCalled();
|
|
234
|
+
expect(promises_1.default.access).toHaveBeenCalled();
|
|
235
|
+
// Create project dir, create "stage-configs" directory, create directories for (crawl, index, template-dedupe, validation, report)
|
|
236
|
+
expect(promises_1.default.mkdir).toHaveBeenCalledTimes(7);
|
|
237
|
+
// Create project config.json as well as 5 example config.json (for each stage)
|
|
238
|
+
expect(promises_1.default.writeFile).toHaveBeenCalledTimes(6);
|
|
239
|
+
expect(promises_1.default.writeFile).toHaveBeenNthCalledWith(1, expect.any(String), expect.stringContaining(mockCliVersion));
|
|
240
|
+
expect(mockClient.put).toHaveBeenCalled();
|
|
241
|
+
expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
|
|
242
|
+
}));
|
|
243
|
+
it('should successfully initialise the project directory and the porter project', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
244
|
+
const { default: createAddCommand } = require('./add');
|
|
245
|
+
const program = createAddCommand();
|
|
246
|
+
yield program.parseAsync([
|
|
247
|
+
'project',
|
|
248
|
+
'addProject',
|
|
249
|
+
'--project-name',
|
|
250
|
+
projectName,
|
|
251
|
+
'--path',
|
|
252
|
+
projectPath,
|
|
253
|
+
]);
|
|
254
|
+
const opts = program.opts();
|
|
255
|
+
expect(opts.projectName).toEqual(projectName);
|
|
256
|
+
expect(opts.path).toEqual(projectPath);
|
|
257
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
258
|
+
expect(PorterUtils.doesPathExist).toHaveBeenCalled();
|
|
259
|
+
expect(promises_1.default.access).toHaveBeenCalled();
|
|
260
|
+
// Create project dir, create "stage-configs" directory, create directories for (crawl, index, template-dedupe, validation, report)
|
|
261
|
+
expect(promises_1.default.mkdir).toHaveBeenCalledTimes(7);
|
|
262
|
+
// Create project config.json as well as 5 example config.json (for each stage)
|
|
263
|
+
expect(promises_1.default.writeFile).toHaveBeenCalledTimes(6);
|
|
264
|
+
expect(promises_1.default.writeFile).toHaveBeenNthCalledWith(1, expect.any(String), expect.stringContaining(mockCliVersion));
|
|
265
|
+
expect(mockClient.put).toHaveBeenCalled();
|
|
266
|
+
expect(promises_1.default.rm).not.toHaveBeenCalled();
|
|
267
|
+
expect(PorterUtils.handleError).not.toHaveBeenCalled();
|
|
268
|
+
expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
|
|
269
|
+
}));
|
|
270
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
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 createGetProjectCommand = () => {
|
|
21
|
+
const getCommand = new commander_1.Command('getProject')
|
|
22
|
+
.description('Retrieves the project')
|
|
23
|
+
.configureOutput({
|
|
24
|
+
outputError(str, write) {
|
|
25
|
+
write(chalk_1.default.red(str));
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(getCommand);
|
|
31
|
+
const baseUrl = yield (0, utils_1.buildPorterUrl)();
|
|
32
|
+
let projectName = '';
|
|
33
|
+
const spinner = (0, ora_1.default)();
|
|
34
|
+
try {
|
|
35
|
+
projectName = yield (0, utils_1.getProjectName)();
|
|
36
|
+
spinner.start('Retrieving project..');
|
|
37
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus, baseUrl);
|
|
38
|
+
const response = yield apiService.client.get(`/projects/${projectName}`);
|
|
39
|
+
const jsonResponse = response.data;
|
|
40
|
+
(0, utils_1.logDebug)(JSON.stringify(jsonResponse));
|
|
41
|
+
spinner.succeed();
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(`Project name: ${projectName}`);
|
|
44
|
+
console.log(`Download last port report: ${jsonResponse['last-report-link'] || 'Not generated'}`);
|
|
45
|
+
console.log(`Download last port artifacts: ${jsonResponse['last-artifacts-link'] || 'Not generated'}`);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
(0, utils_1.logDebug)(`ERROR: ${error instanceof Error ? `${error.message}` : JSON.stringify(error)}`);
|
|
49
|
+
if (spinner.isSpinning) {
|
|
50
|
+
spinner.fail();
|
|
51
|
+
}
|
|
52
|
+
if (((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.status) === 404) {
|
|
53
|
+
(0, utils_1.logDebug)(error.response.data);
|
|
54
|
+
const errorMessage = `Project "${projectName}" not found in DXP porter service`;
|
|
55
|
+
return (0, utils_1.handleError)(getCommand, errorMessage);
|
|
56
|
+
}
|
|
57
|
+
(0, utils_1.handleCommandError)(getCommand, error);
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
return getCommand;
|
|
61
|
+
};
|
|
62
|
+
exports.default = createGetProjectCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
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 logSpy = jest.spyOn(global.console, 'log');
|
|
39
|
+
jest.mock('../../utils');
|
|
40
|
+
describe('getProject', () => {
|
|
41
|
+
let baseUrl;
|
|
42
|
+
let projectName;
|
|
43
|
+
let mockHandleCommandError;
|
|
44
|
+
let mockHandleError;
|
|
45
|
+
let mockBuildPorterUrl;
|
|
46
|
+
let mockResponse;
|
|
47
|
+
let mockClient;
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
jest.resetAllMocks();
|
|
50
|
+
jest.clearAllMocks();
|
|
51
|
+
projectName = 'porter-project';
|
|
52
|
+
baseUrl = 'mock-url';
|
|
53
|
+
mockHandleCommandError = jest.fn(() => Promise.resolve());
|
|
54
|
+
mockHandleError = jest.fn();
|
|
55
|
+
mockBuildPorterUrl = jest.fn(() => Promise.resolve(baseUrl));
|
|
56
|
+
mockResponse = {
|
|
57
|
+
data: {},
|
|
58
|
+
status: 200,
|
|
59
|
+
};
|
|
60
|
+
mockClient = {
|
|
61
|
+
get: jest.fn().mockImplementationOnce(() => mockResponse),
|
|
62
|
+
};
|
|
63
|
+
jest.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn').mockImplementation();
|
|
64
|
+
jest
|
|
65
|
+
.spyOn(PorterUtils, 'getProjectName')
|
|
66
|
+
.mockImplementationOnce(() => Promise.resolve(projectName));
|
|
67
|
+
jest
|
|
68
|
+
.spyOn(PorterUtils, 'buildPorterUrl')
|
|
69
|
+
.mockImplementationOnce(mockBuildPorterUrl);
|
|
70
|
+
jest
|
|
71
|
+
.spyOn(PorterUtils, 'handleCommandError')
|
|
72
|
+
.mockImplementationOnce(mockHandleCommandError);
|
|
73
|
+
jest
|
|
74
|
+
.spyOn(PorterUtils, 'handleError')
|
|
75
|
+
.mockImplementationOnce(mockHandleError);
|
|
76
|
+
jest.spyOn(process, 'exit').mockImplementation();
|
|
77
|
+
jest.spyOn(ApiService, 'ApiService').mockImplementationOnce(() => {
|
|
78
|
+
return {
|
|
79
|
+
client: mockClient,
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
it('should throw an error if not logged in', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
const mockError = new Error('Error not logged in');
|
|
85
|
+
jest
|
|
86
|
+
.spyOn(PorterUtils, 'throwErrorIfNotLoggedIn')
|
|
87
|
+
.mockImplementation(() => {
|
|
88
|
+
throw mockError;
|
|
89
|
+
});
|
|
90
|
+
const { default: createGetCommand } = require('./get');
|
|
91
|
+
const program = createGetCommand();
|
|
92
|
+
yield expect(() => program.parseAsync(['project', 'getProject'])).rejects.toThrow(mockError);
|
|
93
|
+
const opts = program.opts();
|
|
94
|
+
expect(opts).toStrictEqual({});
|
|
95
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
96
|
+
expect(PorterUtils.buildPorterUrl).not.toHaveBeenCalled();
|
|
97
|
+
}));
|
|
98
|
+
it('should throw an error if project name could not be found', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
|
+
jest
|
|
100
|
+
.spyOn(PorterUtils, 'getProjectName')
|
|
101
|
+
.mockReset()
|
|
102
|
+
.mockImplementation(() => {
|
|
103
|
+
throw new Error();
|
|
104
|
+
});
|
|
105
|
+
const { default: createGetCommand } = require('./get');
|
|
106
|
+
const program = createGetCommand();
|
|
107
|
+
yield program.parseAsync(['dxp-next', 'porter', 'project', 'getProject']);
|
|
108
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
109
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
110
|
+
expect(mockClient.get).not.toHaveBeenCalled();
|
|
111
|
+
expect(PorterUtils.handleCommandError).toHaveBeenCalled();
|
|
112
|
+
}));
|
|
113
|
+
it('should throw an error if the project does not exist in the cloud', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
mockClient.get = jest.fn(() => {
|
|
115
|
+
throw new axios_1.AxiosError('Project does not exist', '404', undefined, undefined, {
|
|
116
|
+
data: { status: 404 },
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
const { default: createGetCommand } = require('./get');
|
|
120
|
+
const program = createGetCommand();
|
|
121
|
+
yield program.parseAsync(['project', 'getProject']);
|
|
122
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
123
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
124
|
+
expect(mockClient.get).toHaveBeenCalled();
|
|
125
|
+
expect(PorterUtils.handleError).toHaveBeenCalled();
|
|
126
|
+
}));
|
|
127
|
+
it('should handle unexpected errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
128
|
+
mockClient.get = jest.fn(() => {
|
|
129
|
+
throw new axios_1.AxiosError('Internal server error', '500', undefined, undefined, {
|
|
130
|
+
data: { status: 500 },
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
const { default: createGetCommand } = require('./get');
|
|
134
|
+
const program = createGetCommand();
|
|
135
|
+
yield program.parseAsync(['project', 'getProject']);
|
|
136
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
137
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
138
|
+
expect(mockClient.get).toHaveBeenCalled();
|
|
139
|
+
expect(PorterUtils.handleCommandError).toHaveBeenCalled();
|
|
140
|
+
}));
|
|
141
|
+
it('should successfully retrieve the project details (without generated links) and log this to the console', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
142
|
+
const mockGetResponse = {
|
|
143
|
+
projectid: projectName,
|
|
144
|
+
'last-artifacts-link': null,
|
|
145
|
+
'last-report-link': null,
|
|
146
|
+
};
|
|
147
|
+
mockResponse = {
|
|
148
|
+
data: mockGetResponse,
|
|
149
|
+
status: 200,
|
|
150
|
+
};
|
|
151
|
+
const { default: createGetCommand } = require('./get');
|
|
152
|
+
const program = createGetCommand();
|
|
153
|
+
yield program.parseAsync(['project', 'getProject']);
|
|
154
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
155
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
156
|
+
expect(mockClient.get).toHaveBeenCalled();
|
|
157
|
+
expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
|
|
158
|
+
expect(logSpy).toHaveBeenNthCalledWith(2, `Project name: ${projectName}`);
|
|
159
|
+
expect(logSpy).toHaveBeenNthCalledWith(3, 'Download last port report: Not generated');
|
|
160
|
+
expect(logSpy).toHaveBeenNthCalledWith(4, 'Download last port artifacts: Not generated');
|
|
161
|
+
}));
|
|
162
|
+
it('should successfully retrieve the project details and log this to the console', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
|
+
const mockReportLink = 'mock-report-link';
|
|
164
|
+
const mockArtifactsLink = 'mock-artifacts-link';
|
|
165
|
+
const mockGetResponse = {
|
|
166
|
+
projectid: '1234-5678-abcd-efgh',
|
|
167
|
+
'last-artifacts-link': mockArtifactsLink,
|
|
168
|
+
'last-report-link': mockReportLink,
|
|
169
|
+
};
|
|
170
|
+
mockResponse = {
|
|
171
|
+
data: mockGetResponse,
|
|
172
|
+
status: 200,
|
|
173
|
+
};
|
|
174
|
+
const { default: createGetCommand } = require('./get');
|
|
175
|
+
const program = createGetCommand();
|
|
176
|
+
yield program.parseAsync(['project', 'getProject']);
|
|
177
|
+
expect(PorterUtils.throwErrorIfNotLoggedIn).toHaveBeenCalled();
|
|
178
|
+
expect(PorterUtils.buildPorterUrl).toHaveBeenCalled();
|
|
179
|
+
expect(mockClient.get).toHaveBeenCalled();
|
|
180
|
+
expect(PorterUtils.handleCommandError).not.toHaveBeenCalled();
|
|
181
|
+
expect(logSpy).toHaveBeenNthCalledWith(2, `Project name: ${projectName}`);
|
|
182
|
+
expect(logSpy).toHaveBeenNthCalledWith(3, `Download last port report: ${mockReportLink}`);
|
|
183
|
+
expect(logSpy).toHaveBeenNthCalledWith(4, `Download last port artifacts: ${mockArtifactsLink}`);
|
|
184
|
+
}));
|
|
185
|
+
});
|