@squiz/dxp-cli-next 5.9.0 → 5.10.0-develop.10
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 +1 -0
- package/lib/datastore/blueprint/add/add.d.ts +3 -0
- package/lib/datastore/blueprint/add/add.js +109 -0
- package/lib/datastore/blueprint/add/add.spec.d.ts +1 -0
- package/lib/datastore/blueprint/add/add.spec.js +82 -0
- package/lib/datastore/blueprint/blueprintCommand.d.ts +3 -0
- package/lib/datastore/blueprint/blueprintCommand.js +21 -0
- package/lib/datastore/blueprint/list/list.d.ts +3 -0
- package/lib/datastore/blueprint/list/list.js +74 -0
- package/lib/datastore/blueprint/list/list.spec.d.ts +1 -0
- package/lib/datastore/blueprint/list/list.spec.js +50 -0
- package/lib/datastore/blueprint/rename/rename.d.ts +3 -0
- package/lib/datastore/blueprint/rename/rename.js +83 -0
- package/lib/datastore/blueprint/rename/rename.spec.d.ts +1 -0
- package/lib/datastore/blueprint/rename/rename.spec.js +92 -0
- package/lib/datastore/blueprint/update/update.d.ts +3 -0
- package/lib/datastore/blueprint/update/update.js +87 -0
- package/lib/datastore/blueprint/update/update.spec.d.ts +1 -0
- package/lib/datastore/blueprint/update/update.spec.js +99 -0
- package/lib/datastore/bundle/bundle.d.ts +3 -0
- package/lib/datastore/bundle/bundle.js +174 -0
- package/lib/datastore/bundle/bundle.spec.d.ts +1 -0
- package/lib/datastore/bundle/bundle.spec.js +93 -0
- package/lib/datastore/index.d.ts +3 -0
- package/lib/datastore/index.js +16 -0
- package/lib/datastore/simulator/add/add.d.ts +3 -0
- package/lib/datastore/simulator/add/add.js +138 -0
- package/lib/datastore/simulator/add/add.spec.d.ts +1 -0
- package/lib/datastore/simulator/add/add.spec.js +123 -0
- package/lib/datastore/simulator/clear/clear.d.ts +3 -0
- package/lib/datastore/simulator/clear/clear.js +70 -0
- package/lib/datastore/simulator/clear/clear.spec.d.ts +1 -0
- package/lib/datastore/simulator/clear/clear.spec.js +224 -0
- package/lib/datastore/simulator/list/list.d.ts +3 -0
- package/lib/datastore/simulator/list/list.js +118 -0
- package/lib/datastore/simulator/list/list.spec.d.ts +1 -0
- package/lib/datastore/simulator/list/list.spec.js +95 -0
- package/lib/datastore/simulator/pause/pause.d.ts +3 -0
- package/lib/datastore/simulator/pause/pause.js +85 -0
- package/lib/datastore/simulator/pause/pause.spec.d.ts +1 -0
- package/lib/datastore/simulator/pause/pause.spec.js +90 -0
- package/lib/datastore/simulator/remove/remove.d.ts +3 -0
- package/lib/datastore/simulator/remove/remove.js +68 -0
- package/lib/datastore/simulator/remove/remove.spec.d.ts +1 -0
- package/lib/datastore/simulator/remove/remove.spec.js +224 -0
- package/lib/datastore/simulator/resume/resume.d.ts +3 -0
- package/lib/datastore/simulator/resume/resume.js +85 -0
- package/lib/datastore/simulator/resume/resume.spec.d.ts +1 -0
- package/lib/datastore/simulator/resume/resume.spec.js +90 -0
- package/lib/datastore/simulator/simulatorCommand.d.ts +3 -0
- package/lib/datastore/simulator/simulatorCommand.js +27 -0
- package/lib/datastore/simulator/upgrade/upgrade.d.ts +3 -0
- package/lib/datastore/simulator/upgrade/upgrade.js +160 -0
- package/lib/datastore/simulator/upgrade/upgrade.spec.d.ts +1 -0
- package/lib/datastore/simulator/upgrade/upgrade.spec.js +204 -0
- package/lib/datastore/simulator/utils.d.ts +24 -0
- package/lib/datastore/simulator/utils.js +196 -0
- package/lib/datastore/simulator/utils.spec.d.ts +1 -0
- package/lib/datastore/simulator/utils.spec.js +165 -0
- package/lib/datastore/utils.d.ts +18 -0
- package/lib/datastore/utils.js +229 -0
- package/lib/datastore/utils.spec.d.ts +1 -0
- package/lib/datastore/utils.spec.js +92 -0
- package/lib/dxp.js +2 -0
- package/package.json +6 -4
|
@@ -0,0 +1,165 @@
|
|
|
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 utils = __importStar(require("./utils"));
|
|
39
|
+
const nock_1 = __importDefault(require("nock"));
|
|
40
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
41
|
+
return undefined;
|
|
42
|
+
}); // prevent process exit on error
|
|
43
|
+
const stderrSpy = jest.spyOn(process.stderr, 'write');
|
|
44
|
+
// const logSpy = jest.spyOn(global.console, 'log');
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
jest.resetAllMocks();
|
|
47
|
+
});
|
|
48
|
+
describe('stringHashShort', () => {
|
|
49
|
+
it('should correctly hash the path for a simulated blueprint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
const path = '/path/to/my/blueprint.yaml';
|
|
51
|
+
const expectedHash = '4a3d07ac';
|
|
52
|
+
const hash = utils.stringHashShort(path);
|
|
53
|
+
expect(hash).toStrictEqual(expectedHash);
|
|
54
|
+
}));
|
|
55
|
+
});
|
|
56
|
+
describe('checkDockerInstalled', () => {
|
|
57
|
+
it('should throw error when docker -v fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
const executeCommandSpy = jest
|
|
59
|
+
.spyOn(utils, 'executeCommand')
|
|
60
|
+
.mockImplementation((cmd, opts) => {
|
|
61
|
+
expect(cmd).toStrictEqual('docker -v');
|
|
62
|
+
return Promise.reject(false);
|
|
63
|
+
});
|
|
64
|
+
yield expect(utils.checkDockerInstalled()).rejects.toThrowError(new Error('Docker not installed. Please install latest version.'));
|
|
65
|
+
}));
|
|
66
|
+
it('should not throw an error when docker -v works', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
const executeCommandSpy = jest
|
|
68
|
+
.spyOn(utils, 'executeCommand')
|
|
69
|
+
.mockImplementation((cmd, opts) => {
|
|
70
|
+
expect(cmd).toStrictEqual('docker -v');
|
|
71
|
+
return Promise.resolve(true);
|
|
72
|
+
});
|
|
73
|
+
yield expect(utils.checkDockerInstalled()).resolves.not.toThrowError(new Error('Docker not installed. Please install latest version.'));
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
76
|
+
describe('checkUpdateAvailable', () => {
|
|
77
|
+
it('should skip checking for an update if the DXP_DATASTORE_SIMULATOR_SKIP_VERSION_CHECK is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
process.env.DXP_DATASTORE_SIMULATOR_SKIP_VERSION_CHECK = 'true';
|
|
79
|
+
yield expect(utils.checkUpdateAvailable()).resolves.toStrictEqual(null);
|
|
80
|
+
delete process.env.DXP_DATASTORE_SIMULATOR_SKIP_VERSION_CHECK;
|
|
81
|
+
}));
|
|
82
|
+
it('should not prompt when no update needed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
+
(0, nock_1.default)('https://registry.hub.docker.com')
|
|
84
|
+
.get('/v2/repositories/squizdxp/datastore/tags?page_size=3')
|
|
85
|
+
.reply(200, {
|
|
86
|
+
results: [
|
|
87
|
+
{
|
|
88
|
+
images: [
|
|
89
|
+
{
|
|
90
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
name: 'latest',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
images: [
|
|
97
|
+
{
|
|
98
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
name: '4.0.1',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
images: [
|
|
105
|
+
{
|
|
106
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
name: 'c4f40b0d',
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
const promptSpy = jest
|
|
114
|
+
.spyOn(utils, 'promptForContinue')
|
|
115
|
+
.mockResolvedValue(false);
|
|
116
|
+
const executeCommandSpy = jest
|
|
117
|
+
.spyOn(utils, 'executeCommand')
|
|
118
|
+
.mockResolvedValue('[squizdxp/datastore@sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0]');
|
|
119
|
+
yield expect(utils.checkUpdateAvailable()).resolves.toStrictEqual(null);
|
|
120
|
+
expect(executeCommandSpy).toHaveBeenCalledWith('docker image inspect squizdxp/datastore:latest --format "{{ index .RepoDigests }}"');
|
|
121
|
+
expect(promptSpy).not.toHaveBeenCalled();
|
|
122
|
+
}));
|
|
123
|
+
it('should prompt when update needed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
+
(0, nock_1.default)('https://registry.hub.docker.com')
|
|
125
|
+
.get('/v2/repositories/squizdxp/datastore/tags?page_size=3')
|
|
126
|
+
.reply(200, {
|
|
127
|
+
results: [
|
|
128
|
+
{
|
|
129
|
+
images: [
|
|
130
|
+
{
|
|
131
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
name: 'latest',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
images: [
|
|
138
|
+
{
|
|
139
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
name: '4.0.1',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
images: [
|
|
146
|
+
{
|
|
147
|
+
digest: 'sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe0',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
name: 'c4f40b0d',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
const promptSpy = jest
|
|
155
|
+
.spyOn(utils, 'promptForContinue')
|
|
156
|
+
.mockResolvedValue(false);
|
|
157
|
+
const executeCommandSpy = jest
|
|
158
|
+
.spyOn(utils, 'executeCommand')
|
|
159
|
+
.mockResolvedValue('[squizdxp/datastore@sha256:bd61f8f80d9f235d81477454cf512a6edede0ae6d2d0a8c0508956db2418dbe1]');
|
|
160
|
+
yield expect(utils.checkUpdateAvailable()).resolves.toStrictEqual(null);
|
|
161
|
+
expect(executeCommandSpy).toHaveBeenNthCalledWith(1, 'docker image inspect squizdxp/datastore:latest --format "{{ index .RepoDigests }}"');
|
|
162
|
+
expect(executeCommandSpy).toHaveBeenNthCalledWith(2, 'docker image inspect squizdxp/datastore:latest --format \'{{ or (index .Config.Labels "squiz.datastore.version") (printf "Unknown") }}\'');
|
|
163
|
+
expect(promptSpy).toHaveBeenCalled();
|
|
164
|
+
}));
|
|
165
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { ApiService } from '../ApiService';
|
|
3
|
+
export declare const CONSOLE_STATUS_CODE_LIVE = "Live";
|
|
4
|
+
export declare const CONSOLE_STATUS_CODE_ERROR = "Error";
|
|
5
|
+
export declare function logDebug(message: string): void;
|
|
6
|
+
export declare function bundleBlueprint(filePath: string, asYaml?: boolean): Promise<string>;
|
|
7
|
+
export declare function handleCommandError(command: Command, error: Error): void;
|
|
8
|
+
export declare function throwErrorIfNotLoggedIn(command: Command): Promise<void>;
|
|
9
|
+
export declare function writeLineSeparator(): void;
|
|
10
|
+
export declare function validateAxiosStatus(status: number): boolean;
|
|
11
|
+
export declare function buildDXPUrl(tenantID?: string, override?: string): Promise<{
|
|
12
|
+
dxpUrl: string;
|
|
13
|
+
tenant: string | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function buildOrganisationUrl(tenantID?: string, override?: string): Promise<string>;
|
|
16
|
+
export declare function buildInstanceUrl(tenantID?: string, instanceID?: string, override?: string, isDeploy?: boolean): Promise<string>;
|
|
17
|
+
export declare function buildDatastoreInstancesUrl(tenantID?: string, override?: string): Promise<string>;
|
|
18
|
+
export declare function checkDeploymentStatus(apiService: ApiService, tenantID?: string, instanceID?: string, override?: string): Promise<any>;
|
|
@@ -0,0 +1,229 @@
|
|
|
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
|
+
exports.checkDeploymentStatus = exports.buildDatastoreInstancesUrl = exports.buildInstanceUrl = exports.buildOrganisationUrl = exports.buildDXPUrl = exports.validateAxiosStatus = exports.writeLineSeparator = exports.throwErrorIfNotLoggedIn = exports.handleCommandError = exports.bundleBlueprint = exports.logDebug = exports.CONSOLE_STATUS_CODE_ERROR = exports.CONSOLE_STATUS_CODE_LIVE = void 0;
|
|
39
|
+
const path_1 = __importDefault(require("path"));
|
|
40
|
+
const fs_1 = __importDefault(require("fs"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const ApplicationConfig_1 = require("../ApplicationConfig");
|
|
43
|
+
const axios_1 = __importDefault(require("axios"));
|
|
44
|
+
const ApplicationStore_1 = require("../ApplicationStore");
|
|
45
|
+
const swagger_parser_1 = __importDefault(require("@apidevtools/swagger-parser"));
|
|
46
|
+
const YAML = __importStar(require("yaml"));
|
|
47
|
+
exports.CONSOLE_STATUS_CODE_LIVE = 'Live';
|
|
48
|
+
exports.CONSOLE_STATUS_CODE_ERROR = 'Error';
|
|
49
|
+
/* istanbul ignore next */
|
|
50
|
+
const sleep = (ms) => {
|
|
51
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
52
|
+
};
|
|
53
|
+
/* istanbul ignore next */
|
|
54
|
+
function logDebug(message) {
|
|
55
|
+
if (!!process.env.DEBUG) {
|
|
56
|
+
console.log(message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.logDebug = logDebug;
|
|
60
|
+
function bundleBlueprint(filePath, asYaml = true) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const inputPath = path_1.default.resolve(filePath);
|
|
63
|
+
let bundle;
|
|
64
|
+
if (fs_1.default.existsSync(inputPath)) {
|
|
65
|
+
try {
|
|
66
|
+
logDebug(`Bundling ${inputPath}`);
|
|
67
|
+
bundle = yield swagger_parser_1.default.dereference(inputPath, {
|
|
68
|
+
dereference: {
|
|
69
|
+
circular: 'ignore',
|
|
70
|
+
},
|
|
71
|
+
parse: {
|
|
72
|
+
json: {
|
|
73
|
+
order: 2,
|
|
74
|
+
},
|
|
75
|
+
yaml: {
|
|
76
|
+
order: 1,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
resolve: {
|
|
80
|
+
external: true,
|
|
81
|
+
file: {
|
|
82
|
+
canRead: true,
|
|
83
|
+
order: 1,
|
|
84
|
+
},
|
|
85
|
+
http: {
|
|
86
|
+
canRead: true,
|
|
87
|
+
order: 1,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
validate: {
|
|
91
|
+
spec: true,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (asYaml) {
|
|
95
|
+
bundle = YAML.stringify(bundle);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
bundle = JSON.stringify(bundle);
|
|
99
|
+
}
|
|
100
|
+
return bundle;
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
throw new Error(`Unable to read file ${inputPath} - ${e.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw new Error('Input could not be found');
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
exports.bundleBlueprint = bundleBlueprint;
|
|
112
|
+
function handleCommandError(command, error) {
|
|
113
|
+
var _a, _b, _c, _d;
|
|
114
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
115
|
+
let message = `${error.message}`;
|
|
116
|
+
if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) {
|
|
117
|
+
message += `: ${error.response.data.message}`;
|
|
118
|
+
}
|
|
119
|
+
if ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.details) {
|
|
120
|
+
message += ` - ${error.response.data.details}`;
|
|
121
|
+
}
|
|
122
|
+
command.error(chalk_1.default.red(message));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
if (!!process.env.DEBUG && error.stack) {
|
|
126
|
+
command.error(error.stack);
|
|
127
|
+
}
|
|
128
|
+
if (error.message) {
|
|
129
|
+
command.error(chalk_1.default.red(error.message));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
command.error(chalk_1.default.red('An unknown error occurred'));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.handleCommandError = handleCommandError;
|
|
137
|
+
function throwErrorIfNotLoggedIn(command) {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
if (!(yield (0, ApplicationStore_1.getApplicationFile)(ApplicationStore_1.STORE_FILES.sessionCookie))) {
|
|
140
|
+
command.error(chalk_1.default.red('You must login to interact with the job runner. See `dxp-next auth login`'));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
exports.throwErrorIfNotLoggedIn = throwErrorIfNotLoggedIn;
|
|
145
|
+
function writeLineSeparator() {
|
|
146
|
+
console.log(chalk_1.default.cyan('------------------------------'));
|
|
147
|
+
}
|
|
148
|
+
exports.writeLineSeparator = writeLineSeparator;
|
|
149
|
+
function validateAxiosStatus(status) {
|
|
150
|
+
return status < 400;
|
|
151
|
+
}
|
|
152
|
+
exports.validateAxiosStatus = validateAxiosStatus;
|
|
153
|
+
function buildDXPUrl(tenantID, override) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
if (!override) {
|
|
156
|
+
const existingConfig = yield (0, ApplicationConfig_1.fetchApplicationConfig)(tenantID);
|
|
157
|
+
logDebug(`existingConfig: ${JSON.stringify(existingConfig)}`);
|
|
158
|
+
return {
|
|
159
|
+
dxpUrl: `${existingConfig.baseUrl}/__dxp/${existingConfig.region}/dxp`,
|
|
160
|
+
tenant: existingConfig.tenant,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
logDebug(`Using override URL: ${override}`);
|
|
165
|
+
return {
|
|
166
|
+
dxpUrl: `${override}/__dxp/au/dxp`,
|
|
167
|
+
tenant: tenantID,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
exports.buildDXPUrl = buildDXPUrl;
|
|
173
|
+
function buildOrganisationUrl(tenantID, override) {
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
const dxpUrlConfig = yield buildDXPUrl(tenantID, override);
|
|
176
|
+
return `${dxpUrlConfig.dxpUrl}/tenants/${dxpUrlConfig.tenant}`;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
exports.buildOrganisationUrl = buildOrganisationUrl;
|
|
180
|
+
function buildInstanceUrl(tenantID, instanceID, override, isDeploy = false) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
const dxpUrlConfig = yield buildDXPUrl(tenantID, override);
|
|
183
|
+
const base = `${dxpUrlConfig.dxpUrl}/tenants/${dxpUrlConfig.tenant}`;
|
|
184
|
+
if (isDeploy) {
|
|
185
|
+
return `${base}/instances/${instanceID}/_deploy`;
|
|
186
|
+
}
|
|
187
|
+
return instanceID ? `${base}/instances/${instanceID}` : `${base}/instances`;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
exports.buildInstanceUrl = buildInstanceUrl;
|
|
191
|
+
function buildDatastoreInstancesUrl(tenantID, override) {
|
|
192
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
193
|
+
const url = yield buildInstanceUrl(tenantID, undefined, override, false);
|
|
194
|
+
return `${url}?type=datastore`;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
exports.buildDatastoreInstancesUrl = buildDatastoreInstancesUrl;
|
|
198
|
+
function checkDeploymentStatus(apiService, tenantID, instanceID, override) {
|
|
199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
let lastPollStatus = '';
|
|
201
|
+
let lastPollTime = 0;
|
|
202
|
+
let pollTimeout = false;
|
|
203
|
+
let datastoreInstanceResp;
|
|
204
|
+
let datastoreInstance;
|
|
205
|
+
do {
|
|
206
|
+
datastoreInstanceResp = yield apiService.client.get(yield buildInstanceUrl(tenantID, instanceID, override, false));
|
|
207
|
+
datastoreInstance = datastoreInstanceResp.data;
|
|
208
|
+
const nowAt = Math.floor(Date.now() / 1000);
|
|
209
|
+
if (lastPollStatus !== datastoreInstance.status.message) {
|
|
210
|
+
lastPollStatus = datastoreInstance.status.message;
|
|
211
|
+
lastPollTime = nowAt;
|
|
212
|
+
}
|
|
213
|
+
else if (nowAt - lastPollTime > 600 &&
|
|
214
|
+
lastPollStatus === datastoreInstance.status.message) {
|
|
215
|
+
pollTimeout = true;
|
|
216
|
+
}
|
|
217
|
+
yield sleep(3000);
|
|
218
|
+
} while (datastoreInstance.status.code !== exports.CONSOLE_STATUS_CODE_LIVE &&
|
|
219
|
+
datastoreInstance.status.code !== exports.CONSOLE_STATUS_CODE_ERROR &&
|
|
220
|
+
!pollTimeout);
|
|
221
|
+
if (datastoreInstance.status.code === exports.CONSOLE_STATUS_CODE_LIVE) {
|
|
222
|
+
return datastoreInstance;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
throw new Error(datastoreInstance.status.message);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
exports.checkDeploymentStatus = checkDeploymentStatus;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
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 utils_1 = require("./utils");
|
|
16
|
+
const commander_1 = require("commander");
|
|
17
|
+
const axios_1 = require("axios");
|
|
18
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
21
|
+
return undefined;
|
|
22
|
+
}); // prevent process exit on error
|
|
23
|
+
const stderrSpy = jest.spyOn(process.stderr, 'write');
|
|
24
|
+
const logSpy = jest.spyOn(global.console, 'log');
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.resetAllMocks();
|
|
27
|
+
});
|
|
28
|
+
describe('handleCommandError', () => {
|
|
29
|
+
it('correctly displays the console logs for command error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const command = new commander_1.Command();
|
|
31
|
+
const message = 'Something bad happened';
|
|
32
|
+
(0, utils_1.handleCommandError)(command, new Error(message));
|
|
33
|
+
expect(stderrSpy).toHaveBeenCalledTimes(1);
|
|
34
|
+
console.log(stderrSpy.mock.calls);
|
|
35
|
+
// read the mock call strings directly otherwise colours cause test failures with .toEqual()
|
|
36
|
+
expect(stderrSpy.mock.calls[0][0]).toContain(message);
|
|
37
|
+
}));
|
|
38
|
+
it('correctly displays the console logs for axios error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
const command = new commander_1.Command();
|
|
40
|
+
const message = 'Something bad happened';
|
|
41
|
+
const responseMessage = 'I am an error response';
|
|
42
|
+
const errDetails = 'i am error details';
|
|
43
|
+
(0, utils_1.handleCommandError)(command, new axios_1.AxiosError(message, '500', undefined, undefined, {
|
|
44
|
+
data: { message: responseMessage, details: errDetails },
|
|
45
|
+
}));
|
|
46
|
+
expect(stderrSpy).toHaveBeenCalledTimes(1);
|
|
47
|
+
// read the mock call strings directly otherwise colours cause test failures with .toEqual()
|
|
48
|
+
expect(stderrSpy.mock.calls[0][0]).toContain(`${message}: ${responseMessage} - ${errDetails}`);
|
|
49
|
+
}));
|
|
50
|
+
it('correctly displays the console logs for error without a message', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
const command = new commander_1.Command();
|
|
52
|
+
(0, utils_1.handleCommandError)(command, new Error());
|
|
53
|
+
expect(stderrSpy).toHaveBeenCalledTimes(1);
|
|
54
|
+
// read the mock call strings directly otherwise colours cause test failures with .toEqual()
|
|
55
|
+
expect(stderrSpy.mock.calls[0][0]).toContain('An unknown error occurred');
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
describe('writeLineSeparator', () => {
|
|
59
|
+
it('correctly displays the console logs for line separator', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
(0, utils_1.writeLineSeparator)();
|
|
61
|
+
expect(logSpy).toHaveBeenCalledTimes(1);
|
|
62
|
+
expect(logSpy).toHaveBeenCalledWith(chalk_1.default.cyan('------------------------------'));
|
|
63
|
+
}));
|
|
64
|
+
});
|
|
65
|
+
describe('validateAxiosStatus', () => {
|
|
66
|
+
it('correctly validates the status', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
expect((0, utils_1.validateAxiosStatus)(200)).toBe(true);
|
|
68
|
+
expect((0, utils_1.validateAxiosStatus)(400)).toBe(false);
|
|
69
|
+
}));
|
|
70
|
+
});
|
|
71
|
+
describe('bundleBlueprint', () => {
|
|
72
|
+
it('should return a YAML string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const res = yield (0, utils_1.bundleBlueprint)(path_1.default.join('./src/__tests__/datastore/blueprints/blueprint.yaml'));
|
|
74
|
+
expect(res).toEqual(`openapi: 3.0.2
|
|
75
|
+
info:
|
|
76
|
+
description: A Sample Test API
|
|
77
|
+
version: 1.0.0
|
|
78
|
+
title: Unit Test
|
|
79
|
+
paths:
|
|
80
|
+
/acl-dxp-authentication-1:
|
|
81
|
+
get:
|
|
82
|
+
x-datastore-acl: public
|
|
83
|
+
responses:
|
|
84
|
+
"200":
|
|
85
|
+
description: OK
|
|
86
|
+
`);
|
|
87
|
+
}));
|
|
88
|
+
it('should return a JSON string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
+
const res = yield (0, utils_1.bundleBlueprint)(path_1.default.join('./src/__tests__/datastore/blueprints/blueprint.json'), false);
|
|
90
|
+
expect(res).toStrictEqual('{"openapi":"3.0.2","info":{"description":"A Sample Test API","version":"1.0.0","title":"Unit Test"},"paths":{"/acl-dxp-authentication-1":{"get":{"x-datastore-acl":"public","responses":{"200":{"description":"OK"}}}}}}');
|
|
91
|
+
}));
|
|
92
|
+
});
|
package/lib/dxp.js
CHANGED
|
@@ -14,6 +14,7 @@ validateNodeVersion();
|
|
|
14
14
|
const auth_1 = __importDefault(require("./auth"));
|
|
15
15
|
const cmp_1 = __importDefault(require("./cmp"));
|
|
16
16
|
const job_runner_1 = __importDefault(require("./job-runner"));
|
|
17
|
+
const datastore_1 = __importDefault(require("./datastore"));
|
|
17
18
|
const program = new commander_1.default.Command();
|
|
18
19
|
const packageJson = require('../package.json');
|
|
19
20
|
const version = packageJson.version;
|
|
@@ -24,6 +25,7 @@ program
|
|
|
24
25
|
.addCommand(auth_1.default)
|
|
25
26
|
.addCommand(cmp_1.default)
|
|
26
27
|
.addCommand(job_runner_1.default)
|
|
28
|
+
.addCommand(datastore_1.default)
|
|
27
29
|
.action(() => {
|
|
28
30
|
program.help();
|
|
29
31
|
})
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiz/dxp-cli-next",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.0-develop.10",
|
|
4
4
|
"repository": {
|
|
5
|
-
"url": "https://gitlab.squiz.net/
|
|
5
|
+
"url": "https://gitlab.squiz.net/dxp/dxp-cli-next"
|
|
6
6
|
},
|
|
7
7
|
"files": [
|
|
8
8
|
"!lib/__tests__/**/*",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"codecov"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@squiz/component-cli-lib": "1.
|
|
42
|
+
"@squiz/component-cli-lib": "1.64.0",
|
|
43
|
+
"@apidevtools/swagger-parser": "10.1.0",
|
|
43
44
|
"axios": "1.1.3",
|
|
44
45
|
"cli-color": "2.0.3",
|
|
45
46
|
"commander": "9.4.0",
|
|
@@ -49,7 +50,8 @@
|
|
|
49
50
|
"ora": "^5.4.1",
|
|
50
51
|
"prompt": "^1.3.0",
|
|
51
52
|
"tough-cookie": "4.1.2",
|
|
52
|
-
"update-notifier": "5.1.0"
|
|
53
|
+
"update-notifier": "5.1.0",
|
|
54
|
+
"yaml": "^2.3.4"
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
57
|
"@semantic-release/git": "10.0.1",
|