@squiz/dxp-cli-next 5.9.0-develop.43 → 5.9.0-develop.44
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.
|
@@ -0,0 +1,174 @@
|
|
|
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 chalk_1 = __importDefault(require("chalk"));
|
|
40
|
+
const ora_1 = __importDefault(require("ora"));
|
|
41
|
+
const ApiService_1 = require("../../ApiService");
|
|
42
|
+
const utils_1 = require("../utils");
|
|
43
|
+
const fs_1 = require("fs");
|
|
44
|
+
const path_1 = require("path");
|
|
45
|
+
const YAML = __importStar(require("yaml"));
|
|
46
|
+
const createBundleCommand = () => {
|
|
47
|
+
const datastoreBundleCommand = new commander_1.Command('bundle')
|
|
48
|
+
.name('bundle')
|
|
49
|
+
.description('Datastore Bundle Commands')
|
|
50
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
51
|
+
.addOption(new commander_1.Option('-blueprint, --blueprint <string>', 'Path to your blueprint API yaml file e.g. documents/inputs/blueprint.yaml').makeOptionMandatory())
|
|
52
|
+
.addOption(new commander_1.Option('-name, --name <string>', 'Name for your blueprint e.g. MyFirstBlueprint'))
|
|
53
|
+
.addOption(new commander_1.Option('-output, --output <string>', 'Output for your output file path').makeOptionMandatory())
|
|
54
|
+
.configureOutput({
|
|
55
|
+
outputError(str, write) {
|
|
56
|
+
write(chalk_1.default.red(str));
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
if (options.name) {
|
|
61
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(datastoreBundleCommand);
|
|
62
|
+
}
|
|
63
|
+
console.log('');
|
|
64
|
+
const path = options.blueprint;
|
|
65
|
+
const blueprintPath = (0, path_1.resolve)(path);
|
|
66
|
+
const outputPath = (0, path_1.resolve)(options.output);
|
|
67
|
+
const outputDirectory = (0, path_1.dirname)(outputPath);
|
|
68
|
+
let blueprintFile;
|
|
69
|
+
const spinner = (0, ora_1.default)('Please wait while we bundle your blueprint.').start();
|
|
70
|
+
let input;
|
|
71
|
+
try {
|
|
72
|
+
if ((0, fs_1.existsSync)(blueprintPath) === false) {
|
|
73
|
+
throw new Error('No blueprint exists at that path, please specify a correct path.');
|
|
74
|
+
}
|
|
75
|
+
if ((0, fs_1.existsSync)(outputDirectory) === false) {
|
|
76
|
+
throw new Error("Output directory doesn't exist.");
|
|
77
|
+
}
|
|
78
|
+
let outputExt = (0, path_1.extname)(outputPath);
|
|
79
|
+
if (outputExt.indexOf('.') === 0) {
|
|
80
|
+
outputExt = outputExt.replace('.', '');
|
|
81
|
+
}
|
|
82
|
+
const allowedExtensions = ['yaml', 'yml'];
|
|
83
|
+
if (allowedExtensions.includes(outputExt) === false) {
|
|
84
|
+
const errorMsg = 'Please specify a valid output file. Valid extensions are: ' +
|
|
85
|
+
allowedExtensions.join(', ');
|
|
86
|
+
throw new Error(errorMsg);
|
|
87
|
+
}
|
|
88
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus);
|
|
89
|
+
let datastoreInstance;
|
|
90
|
+
if (options.name) {
|
|
91
|
+
(0, utils_1.logDebug)('Checking current blueprints');
|
|
92
|
+
// Check if we are at the blueprint limit.
|
|
93
|
+
const datastoreInstancesResp = yield apiService.client.get(yield (0, utils_1.buildDatastoreInstancesUrl)(options.tenant, options.overrideUrl));
|
|
94
|
+
(0, utils_1.logDebug)(`Finding blueprint with name: ${options.name}`);
|
|
95
|
+
const datastoreInstances = datastoreInstancesResp.data.filter((instance) => {
|
|
96
|
+
return instance.name === options.name;
|
|
97
|
+
});
|
|
98
|
+
if (datastoreInstances.length > 1) {
|
|
99
|
+
throw new Error('Unexpected error. Ask for help in our support forums.');
|
|
100
|
+
}
|
|
101
|
+
datastoreInstance = datastoreInstances[0];
|
|
102
|
+
}
|
|
103
|
+
// Bundle the blueprint.
|
|
104
|
+
input = yield (0, utils_1.bundleBlueprint)(path, true);
|
|
105
|
+
const blueprintFile = input;
|
|
106
|
+
const blueprint = YAML.parse(blueprintFile, { maxAliasCount: -1 });
|
|
107
|
+
if (options.name &&
|
|
108
|
+
datastoreInstance &&
|
|
109
|
+
datastoreInstance.deploymentUrl) {
|
|
110
|
+
// Add the servers tag to the blueprint if not already there.
|
|
111
|
+
if (blueprint.servers) {
|
|
112
|
+
const currentDatastoreServer = blueprint.servers.filter((server) => server.description === 'Datastore production');
|
|
113
|
+
if (currentDatastoreServer.length === 0) {
|
|
114
|
+
blueprint.servers.push({
|
|
115
|
+
description: 'Datastore production',
|
|
116
|
+
url: datastoreInstance.deploymentUrl,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
blueprint.servers = [
|
|
122
|
+
{
|
|
123
|
+
description: 'Datastore production',
|
|
124
|
+
url: datastoreInstance.deploymentUrl,
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (!blueprint.components) {
|
|
130
|
+
blueprint.components = {};
|
|
131
|
+
}
|
|
132
|
+
if (!blueprint.components.securitySchemes) {
|
|
133
|
+
blueprint.components.securitySchemes = {};
|
|
134
|
+
}
|
|
135
|
+
if (!blueprint.components.securitySchemes.bearerAuth) {
|
|
136
|
+
blueprint.components.securitySchemes.bearerAuth = {
|
|
137
|
+
bearerFormat: 'JWT',
|
|
138
|
+
scheme: 'bearer',
|
|
139
|
+
type: 'http',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// Check that the paths that need a JWT have the bearerAuth added.
|
|
143
|
+
for (const i in blueprint.paths) {
|
|
144
|
+
for (const j in blueprint.paths[i]) {
|
|
145
|
+
if (blueprint.paths[i][j]['x-datastore-acl'] &&
|
|
146
|
+
blueprint.paths[i][j]['x-datastore-acl'].toLowerCase() !==
|
|
147
|
+
'public') {
|
|
148
|
+
if (!blueprint.paths[i][j].security) {
|
|
149
|
+
blueprint.paths[i][j].security = [{ bearerAuth: [] }];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const updatedBlueprint = YAML.stringify(blueprint);
|
|
155
|
+
(0, fs_1.writeFile)(`${outputPath}`, updatedBlueprint, err => {
|
|
156
|
+
if (err) {
|
|
157
|
+
throw new Error(`Error: ${err.message}`);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
spinner.succeed(`Blueprint bundled at: ${outputPath}`);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
(0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
|
|
165
|
+
spinner.fail();
|
|
166
|
+
(0, utils_1.handleCommandError)(datastoreBundleCommand, error);
|
|
167
|
+
}
|
|
168
|
+
}));
|
|
169
|
+
if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
|
|
170
|
+
datastoreBundleCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
|
|
171
|
+
}
|
|
172
|
+
return datastoreBundleCommand;
|
|
173
|
+
};
|
|
174
|
+
exports.default = createBundleCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
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 nock_1 = __importDefault(require("nock"));
|
|
16
|
+
const bundle_1 = __importDefault(require("./bundle"));
|
|
17
|
+
const utils_1 = require("../utils");
|
|
18
|
+
const logSpy = jest.spyOn(global.console, 'log');
|
|
19
|
+
describe('bundleJobContexts', () => {
|
|
20
|
+
process.env.ENABLE_OVERRIDE_DATASTORE_URL = 'true';
|
|
21
|
+
it('correctly bundles a blueprint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
23
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances?type=datastore')
|
|
24
|
+
.reply(200, [
|
|
25
|
+
{
|
|
26
|
+
status: {
|
|
27
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
28
|
+
},
|
|
29
|
+
deploymentUrl: 'https://au-asdfghj.datastore.squiz.cloud',
|
|
30
|
+
secretKey: 'secretKey',
|
|
31
|
+
region: 'au',
|
|
32
|
+
name: 'secondBlueprint',
|
|
33
|
+
instanceId: '1234',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
status: {
|
|
37
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
38
|
+
},
|
|
39
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
40
|
+
secretKey: 'secretKey',
|
|
41
|
+
region: 'au',
|
|
42
|
+
name: 'myBlueprint',
|
|
43
|
+
instanceId: 'mock-instance-id',
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
47
|
+
.patch('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id', {
|
|
48
|
+
name: 'myRenamedBlueprint',
|
|
49
|
+
})
|
|
50
|
+
.reply(200, {
|
|
51
|
+
instanceId: 'mock-instance-id',
|
|
52
|
+
});
|
|
53
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
54
|
+
.post('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id/_deploy')
|
|
55
|
+
.reply(200, {
|
|
56
|
+
instanceId: 'mock-instance-id',
|
|
57
|
+
});
|
|
58
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
59
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id')
|
|
60
|
+
.reply(200, {
|
|
61
|
+
status: {
|
|
62
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
63
|
+
},
|
|
64
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
65
|
+
secretKey: 'secretKey',
|
|
66
|
+
region: 'au',
|
|
67
|
+
});
|
|
68
|
+
const program = (0, bundle_1.default)();
|
|
69
|
+
yield program.parseAsync([
|
|
70
|
+
'node',
|
|
71
|
+
'dxp-cli',
|
|
72
|
+
'datastore',
|
|
73
|
+
'bundle',
|
|
74
|
+
'-t',
|
|
75
|
+
'myTenant',
|
|
76
|
+
'-blueprint',
|
|
77
|
+
'./src/__tests__/datastore/blueprints/blueprint.yaml',
|
|
78
|
+
'-name',
|
|
79
|
+
'myRenamedBlueprint',
|
|
80
|
+
'-output',
|
|
81
|
+
'./src/__tests__/datastore/blueprints.yaml',
|
|
82
|
+
'-ou',
|
|
83
|
+
'http://localhost:9999',
|
|
84
|
+
]);
|
|
85
|
+
const opts = program.opts();
|
|
86
|
+
expect(opts.tenant).toEqual('myTenant');
|
|
87
|
+
expect(opts.overrideUrl).toEqual('http://localhost:9999');
|
|
88
|
+
expect(logSpy).toHaveBeenCalledTimes(1);
|
|
89
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
90
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
91
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
92
|
+
}));
|
|
93
|
+
});
|
package/lib/datastore/index.js
CHANGED
|
@@ -5,8 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const commander_1 = require("commander");
|
|
7
7
|
const blueprintCommand_1 = __importDefault(require("./blueprint/blueprintCommand"));
|
|
8
|
+
const bundle_1 = __importDefault(require("./bundle/bundle"));
|
|
8
9
|
const datastoreCommand = new commander_1.Command('datastore');
|
|
9
10
|
datastoreCommand
|
|
10
11
|
.description('Datastore Commands')
|
|
11
|
-
.addCommand((0, blueprintCommand_1.default)())
|
|
12
|
+
.addCommand((0, blueprintCommand_1.default)())
|
|
13
|
+
.addCommand((0, bundle_1.default)());
|
|
12
14
|
exports.default = datastoreCommand;
|