@squiz/dxp-cli-next 5.9.0 → 5.10.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 (45) hide show
  1. package/lib/__tests__/integration/main.spec.js +1 -0
  2. package/lib/datastore/blueprint/add/add.d.ts +3 -0
  3. package/lib/datastore/blueprint/add/add.js +109 -0
  4. package/lib/datastore/blueprint/add/add.spec.d.ts +1 -0
  5. package/lib/datastore/blueprint/add/add.spec.js +82 -0
  6. package/lib/datastore/blueprint/blueprintCommand.d.ts +3 -0
  7. package/lib/datastore/blueprint/blueprintCommand.js +21 -0
  8. package/lib/datastore/blueprint/list/list.d.ts +3 -0
  9. package/lib/datastore/blueprint/list/list.js +74 -0
  10. package/lib/datastore/blueprint/list/list.spec.d.ts +1 -0
  11. package/lib/datastore/blueprint/list/list.spec.js +50 -0
  12. package/lib/datastore/blueprint/rename/rename.d.ts +3 -0
  13. package/lib/datastore/blueprint/rename/rename.js +83 -0
  14. package/lib/datastore/blueprint/rename/rename.spec.d.ts +1 -0
  15. package/lib/datastore/blueprint/rename/rename.spec.js +92 -0
  16. package/lib/datastore/blueprint/update/update.d.ts +3 -0
  17. package/lib/datastore/blueprint/update/update.js +87 -0
  18. package/lib/datastore/blueprint/update/update.spec.d.ts +1 -0
  19. package/lib/datastore/blueprint/update/update.spec.js +99 -0
  20. package/lib/datastore/bundle/bundle.d.ts +3 -0
  21. package/lib/datastore/bundle/bundle.js +174 -0
  22. package/lib/datastore/bundle/bundle.spec.d.ts +1 -0
  23. package/lib/datastore/bundle/bundle.spec.js +93 -0
  24. package/lib/datastore/index.d.ts +3 -0
  25. package/lib/datastore/index.js +16 -0
  26. package/lib/datastore/simulator/add/add.d.ts +3 -0
  27. package/lib/datastore/simulator/add/add.js +138 -0
  28. package/lib/datastore/simulator/add/add.spec.d.ts +1 -0
  29. package/lib/datastore/simulator/add/add.spec.js +123 -0
  30. package/lib/datastore/simulator/remove/remove.d.ts +3 -0
  31. package/lib/datastore/simulator/remove/remove.js +68 -0
  32. package/lib/datastore/simulator/remove/remove.spec.d.ts +1 -0
  33. package/lib/datastore/simulator/remove/remove.spec.js +224 -0
  34. package/lib/datastore/simulator/simulatorCommand.d.ts +3 -0
  35. package/lib/datastore/simulator/simulatorCommand.js +17 -0
  36. package/lib/datastore/simulator/utils.d.ts +22 -0
  37. package/lib/datastore/simulator/utils.js +197 -0
  38. package/lib/datastore/simulator/utils.spec.d.ts +1 -0
  39. package/lib/datastore/simulator/utils.spec.js +165 -0
  40. package/lib/datastore/utils.d.ts +18 -0
  41. package/lib/datastore/utils.js +229 -0
  42. package/lib/datastore/utils.spec.d.ts +1 -0
  43. package/lib/datastore/utils.spec.js +92 -0
  44. package/lib/dxp.js +1 -0
  45. package/package.json +6 -4
@@ -0,0 +1,99 @@
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 update_1 = __importDefault(require("./update"));
17
+ const utils_1 = require("../../utils");
18
+ const logSpy = jest.spyOn(global.console, 'log');
19
+ describe('datastoreBlueprintUpdate', () => {
20
+ process.env.ENABLE_OVERRIDE_DATASTORE_URL = 'true';
21
+ it('correctly adds 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
+ blueprintFile: /.+/i,
49
+ status: {
50
+ code: 'Deploying',
51
+ message: 'Instance is deploying',
52
+ },
53
+ })
54
+ .reply(200, {
55
+ instanceId: 'mock-instance-id',
56
+ });
57
+ (0, nock_1.default)('http://localhost:9999')
58
+ .post('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id/_deploy')
59
+ .reply(200, {
60
+ instanceId: 'mock-instance-id',
61
+ });
62
+ (0, nock_1.default)('http://localhost:9999')
63
+ .get('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id')
64
+ .reply(200, {
65
+ status: {
66
+ code: utils_1.CONSOLE_STATUS_CODE_LIVE,
67
+ },
68
+ deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
69
+ secretKey: 'secretKey',
70
+ region: 'au',
71
+ });
72
+ const program = (0, update_1.default)();
73
+ yield program.parseAsync([
74
+ 'node',
75
+ 'dxp-cli',
76
+ 'datastore',
77
+ 'blueprint',
78
+ 'update',
79
+ '-t',
80
+ 'myTenant',
81
+ '-p',
82
+ './src/__tests__/datastore/blueprints/blueprint.yaml',
83
+ '-n',
84
+ 'myBlueprint',
85
+ '-ou',
86
+ 'http://localhost:9999',
87
+ ]);
88
+ const opts = program.opts();
89
+ expect(opts.tenant).toEqual('myTenant');
90
+ expect(opts.overrideUrl).toEqual('http://localhost:9999');
91
+ expect(logSpy).toHaveBeenCalledTimes(6);
92
+ expect(logSpy).toHaveBeenCalledWith('');
93
+ expect(logSpy).toHaveBeenCalledWith('');
94
+ expect(logSpy).toHaveBeenCalledWith(' URL: https://au-12345678.datastore.squiz.cloud');
95
+ expect(logSpy).toHaveBeenCalledWith(' Secret Key: secretKey');
96
+ expect(logSpy).toHaveBeenCalledWith(' Region: au');
97
+ expect(logSpy).toHaveBeenCalledWith('');
98
+ }));
99
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const createBundleCommand: () => Command;
3
+ export default createBundleCommand;
@@ -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
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const datastoreCommand: Command;
3
+ export default datastoreCommand;
@@ -0,0 +1,16 @@
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 blueprintCommand_1 = __importDefault(require("./blueprint/blueprintCommand"));
8
+ const bundle_1 = __importDefault(require("./bundle/bundle"));
9
+ const simulatorCommand_1 = __importDefault(require("./simulator/simulatorCommand"));
10
+ const datastoreCommand = new commander_1.Command('datastore');
11
+ datastoreCommand
12
+ .description('Datastore Commands')
13
+ .addCommand((0, blueprintCommand_1.default)())
14
+ .addCommand((0, bundle_1.default)())
15
+ .addCommand((0, simulatorCommand_1.default)());
16
+ exports.default = datastoreCommand;
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const createAddCommand: () => Command;
3
+ export default createAddCommand;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const commander_1 = require("commander");
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const ora_1 = __importDefault(require("ora"));
18
+ const utils_1 = require("../../utils");
19
+ const utils_2 = require("../utils");
20
+ const path_1 = require("path");
21
+ const fs_1 = __importDefault(require("fs"));
22
+ const createAddCommand = () => {
23
+ const addCommand = new commander_1.Command('add')
24
+ .name('add')
25
+ .description('Adds a new simulator')
26
+ .addOption(new commander_1.Option('-p, --port <string>', 'Port for the Datastore simulator to run on'))
27
+ .addOption(new commander_1.Option('-b, --blueprint <string>', 'Path to your datastore API yaml file.').makeOptionMandatory())
28
+ .configureOutput({
29
+ outputError(str, write) {
30
+ write(chalk_1.default.red(str));
31
+ },
32
+ })
33
+ .action((options) => __awaiter(void 0, void 0, void 0, function* () {
34
+ console.log('');
35
+ const spinner = (0, ora_1.default)();
36
+ try {
37
+ yield (0, utils_2.checkUpdateAvailable)();
38
+ spinner.start('Creating a new simulator container.');
39
+ yield (0, utils_2.checkDockerInstalled)();
40
+ const { fullPath, dirPath, yamlFile, containerName } = (0, utils_2.getSimulatorDetails)(options.blueprint);
41
+ const fileCheck = fs_1.default.existsSync(fullPath);
42
+ let errorMsg = 'There was an error starting simulator. Ask for help in our support forums.';
43
+ if (fileCheck === false) {
44
+ throw new Error('Sorry, we could not create your simulator container. Please try again using a valid path to a blueprint.');
45
+ }
46
+ else {
47
+ let fileExt = (0, path_1.extname)(fullPath);
48
+ if (fileExt.indexOf('.') === 0) {
49
+ fileExt = fileExt.replace('.', '');
50
+ }
51
+ if (utils_2.allowedExtensions.includes(fileExt) === false) {
52
+ errorMsg = 'Sorry, we could not create your simulator container.';
53
+ errorMsg += ` Please try again using a valid path to a blueprint. Valid extensions are: ${utils_2.allowedExtensions.join(', ')}`;
54
+ throw new Error(errorMsg);
55
+ }
56
+ }
57
+ const versionDetails = {
58
+ digest: '',
59
+ version: '',
60
+ };
61
+ // Find an available port.
62
+ const usedPorts = yield (0, utils_2.executeCommand)('docker ps -a --format "~{{.Labels}}~" --filter "name=datastore-sim-*"');
63
+ let selectedPort = '';
64
+ if (options.port) {
65
+ selectedPort = options.port;
66
+ }
67
+ else {
68
+ utils_2.availablePorts.forEach(port => {
69
+ if (
70
+ // Port is stored in label, avoid using same port.
71
+ usedPorts.match(`port=${port}`) === null &&
72
+ selectedPort === '') {
73
+ selectedPort = port;
74
+ }
75
+ });
76
+ }
77
+ if (selectedPort === '') {
78
+ throw new Error('Failed to find an available Docker port. Try again with --port parameter.');
79
+ }
80
+ try {
81
+ spinner.text = 'Starting the new container.';
82
+ const startCommand = yield (0, utils_2.executeCommand)(`docker run -l "blueprint=${fullPath.replace(/(\s+)/g, '\\$1')}" -l "port=${selectedPort}" -itd --name ${containerName}\
83
+ -p ${utils_2.host}:${selectedPort}:80 \
84
+ -e MYHOST=${utils_2.host} -e MYPORT=${selectedPort} -e BLUEPRINT=${fullPath.replace(/(\s+)/g, '\\$1')} \
85
+ -v "${dirPath}":/var/www/instances \
86
+ ${utils_2.datastoreRepo}`);
87
+ }
88
+ catch (error) {
89
+ if (error.message.includes('already in use') === true) {
90
+ throw new Error('There is already a container running with this blueprint.');
91
+ }
92
+ else {
93
+ throw new Error('Failed to start Docker container. Ask for help in our support forums.');
94
+ }
95
+ }
96
+ spinner.text = 'Installing and simulating new blueprint.';
97
+ const installCommand = yield (0, utils_2.executeCommand)(`docker exec -i ${containerName} install simulator:${yamlFile} --output=json`);
98
+ const obj = JSON.parse(installCommand);
99
+ const url = obj[0].URL;
100
+ const jwtUrl = obj[0].jwtURL;
101
+ const versionDetailsCommand = yield (0, utils_2.executeCommand)(`docker image inspect ${utils_2.datastoreRepo} --format "{{ index .RepoDigests }}"`);
102
+ versionDetails.digest = versionDetailsCommand.replace(/\r?\n|\r/g, '');
103
+ versionDetails.digest = versionDetails.digest.slice(20, -1);
104
+ let simulatorVersionCmd = `docker image inspect ${utils_2.datastoreRepo}`;
105
+ simulatorVersionCmd +=
106
+ ' --format \'{{ or (index .Config.Labels "squiz.datastore.version") (printf "Unknown") }}\'';
107
+ const imageVersion = yield (0, utils_2.executeCommand)(simulatorVersionCmd);
108
+ versionDetails.version = imageVersion.replace(/\r?\n|\r/g, '');
109
+ // Store those info in a file on container, easier to fetch.
110
+ const data = {
111
+ blueprint: `${fullPath}`,
112
+ container: `${containerName}`,
113
+ imageDigest: `${versionDetails.digest}`,
114
+ imageVersion: `${versionDetails.version}`,
115
+ jwt: `${jwtUrl}`,
116
+ url: `${url}`,
117
+ };
118
+ const jsonData = JSON.stringify(data, null, 4).replace(/"/g, '\\"');
119
+ yield (0, utils_2.executeCommand)(`docker exec -i ${containerName} bash -c "echo '${jsonData}' > /var/www/data/containerData.json"`);
120
+ spinner.succeed('Done! Use these details for local querying:');
121
+ console.log('');
122
+ console.log(` URL: ${url}`);
123
+ console.log(` JWT URL: ${jwtUrl}`);
124
+ console.log('');
125
+ return;
126
+ }
127
+ catch (error) {
128
+ (0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
129
+ spinner.fail();
130
+ (0, utils_1.handleCommandError)(addCommand, error);
131
+ }
132
+ }));
133
+ if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
134
+ addCommand.addOption(new commander_1.Option('-i, --image <string>', 'Override the docker image'));
135
+ }
136
+ return addCommand;
137
+ };
138
+ exports.default = createAddCommand;
@@ -0,0 +1 @@
1
+ export {};