@squiz/dxp-cli-next 5.24.0-develop.3 → 5.24.0-develop.4

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/lib/cdp/index.js CHANGED
@@ -5,8 +5,12 @@ 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 schemaCommand_1 = __importDefault(require("./schema/schemaCommand"));
8
+ const instanceCommand_1 = __importDefault(require("./instance/instanceCommand"));
8
9
  const cdpCommand = new commander_1.Command('cdp');
9
10
  cdpCommand
10
11
  .description('Customer Data Platform Service Commands')
11
12
  .addCommand((0, schemaCommand_1.default)());
13
+ if (process.env.ENABLE_CDP_ADMIN === 'true') {
14
+ cdpCommand.addCommand((0, instanceCommand_1.default)());
15
+ }
12
16
  exports.default = cdpCommand;
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+ export declare const handleActivateError: (status: number, body: any) => void;
3
+ export declare const errorMessage = "Cannot activate instance as instance is already active";
4
+ declare const createActivateCommand: () => Command | null;
5
+ export default createActivateCommand;
@@ -0,0 +1,102 @@
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
+ exports.errorMessage = exports.handleActivateError = void 0;
16
+ const commander_1 = require("commander");
17
+ const chalk_1 = __importDefault(require("chalk"));
18
+ const ora_1 = __importDefault(require("ora"));
19
+ const ApiService_1 = require("../../../ApiService");
20
+ const utils_1 = require("../../utils");
21
+ const constants_1 = require("../../constants");
22
+ const handleActivateError = (status, body) => {
23
+ const message = `Status code: ${status}\n${JSON.stringify(body, null, ' ')}`;
24
+ throw new Error(message);
25
+ };
26
+ exports.handleActivateError = handleActivateError;
27
+ exports.errorMessage = 'Cannot activate instance as instance is already active';
28
+ const createActivateCommand = () => {
29
+ if (!process.env.ENABLE_CDP_ADMIN) {
30
+ return null; // Skip command registration if the env var is not set
31
+ }
32
+ const activateCommand = new commander_1.Command('deploy')
33
+ .name('activate')
34
+ .description('Activate a CDP instance')
35
+ .addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
36
+ .addOption(new commander_1.Option('-r, --region <string>', 'Region for your instance to be activated e.g. au')
37
+ .choices(['au', 'uk', 'us'])
38
+ .makeOptionMandatory())
39
+ .configureOutput({
40
+ outputError(str, write) {
41
+ write(chalk_1.default.red(str));
42
+ },
43
+ })
44
+ .action((options) => __awaiter(void 0, void 0, void 0, function* () {
45
+ yield (0, utils_1.throwErrorIfNotLoggedIn)(activateCommand);
46
+ console.log('');
47
+ const spinner = (0, ora_1.default)('Please wait a few minutes while our cloud builds this for you.').start();
48
+ try {
49
+ const apiService = new ApiService_1.ApiService({
50
+ validateStatus: (status) => {
51
+ return status < 400 || status === 404;
52
+ },
53
+ });
54
+ const scvDeployBaseUrl = yield (0, utils_1.buildDXPUrl)(constants_1.SCV_DEPLOY_SERVICE_NAME, options.tenant, options.overrideUrl, options.region);
55
+ const apiUrl = `${scvDeployBaseUrl.dxpUrl}/${scvDeployBaseUrl.tenant}`;
56
+ const getDeployResponse = (yield apiService.client
57
+ .get(apiUrl)
58
+ .catch((err) => {
59
+ (0, utils_1.logDebug)(`RAW ERROR: ${JSON.stringify(err)}`);
60
+ if (err.response && err.response.status != 404) {
61
+ (0, exports.handleActivateError)(err.response.status, err.response.data);
62
+ }
63
+ }));
64
+ if (getDeployResponse.status === 200) {
65
+ throw new Error(exports.errorMessage);
66
+ }
67
+ (0, utils_1.logDebug)(`PUT ${apiUrl}`);
68
+ const activateInstanceAndDeploySchemaResponse = (yield apiService.client
69
+ .put(apiUrl, null, {
70
+ headers: {
71
+ 'Content-Type': 'application/json',
72
+ },
73
+ })
74
+ .catch((err) => {
75
+ (0, utils_1.logDebug)(`RAW ERROR: ${JSON.stringify(err)}`);
76
+ if (err.response) {
77
+ (0, exports.handleActivateError)(err.response.status, err.response.data);
78
+ }
79
+ }));
80
+ (0, utils_1.logDebug)(`Activate instance response: ${JSON.stringify(activateInstanceAndDeploySchemaResponse.data)}`);
81
+ if (activateInstanceAndDeploySchemaResponse.status === 409) {
82
+ throw new Error('Currently activating instance. Please try again later.');
83
+ }
84
+ yield (0, utils_1.pollForDeployedSchema)(apiUrl, apiService);
85
+ spinner.succeed('Done!');
86
+ console.log('');
87
+ console.log('Your Schema has been deployed and instance has been activated.');
88
+ console.log('');
89
+ return;
90
+ }
91
+ catch (error) {
92
+ (0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
93
+ spinner.fail();
94
+ (0, utils_1.handleCommandError)(error);
95
+ }
96
+ }));
97
+ if (process.env.ENABLE_OVERRIDE_CDP_SCHEMA_URL === 'true') {
98
+ activateCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
99
+ }
100
+ return activateCommand;
101
+ };
102
+ exports.default = createActivateCommand;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,141 @@
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 nock_1 = __importDefault(require("nock"));
39
+ const activate_1 = __importStar(require("./activate"));
40
+ const deploy_const_1 = require("../../schema/deploy/deploy.const");
41
+ const utils_1 = require("../../utils");
42
+ const activate = __importStar(require("./activate"));
43
+ const mockDomainWithPath = 'http://localhost:9999/__dxp/us/scv-deploy/myTenant';
44
+ function createMockArgs(region, tenantID, filePath, mockDomain) {
45
+ return [
46
+ 'node',
47
+ 'dxp-cli',
48
+ 'cdp',
49
+ 'instance',
50
+ 'activate',
51
+ '-t',
52
+ tenantID,
53
+ '-r',
54
+ region,
55
+ '-ou',
56
+ 'http://localhost:9999',
57
+ ];
58
+ }
59
+ describe('cdpInstanceCommand', () => {
60
+ let mockTenant;
61
+ let mockRegion;
62
+ let mockFilePath;
63
+ let mockDomain;
64
+ let logSpy;
65
+ let errorSpy;
66
+ let activateErrorSpy;
67
+ beforeEach(() => {
68
+ process.env.ENABLE_CDP_ADMIN = 'true';
69
+ process.env.ENABLE_OVERRIDE_CDP_SCHEMA_URL = 'true';
70
+ mockTenant = 'myTenant';
71
+ mockRegion = 'us';
72
+ mockFilePath = './src/__tests__/cdp/scv/schema.json';
73
+ mockDomain = 'http://localhost:9999';
74
+ logSpy = jest.spyOn(console, 'log').mockImplementation(() => { });
75
+ errorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
76
+ activateErrorSpy = jest
77
+ .spyOn(activate, 'handleActivateError')
78
+ .mockImplementation(() => { });
79
+ if (!nock_1.default.isActive()) {
80
+ nock_1.default.activate();
81
+ }
82
+ nock_1.default.cleanAll(); // Ensures each test runs in isolation
83
+ });
84
+ afterEach(() => {
85
+ jest.clearAllMocks(); // Clear all spies after each test
86
+ nock_1.default.cleanAll(); // Clear all HTTP mocks
87
+ });
88
+ it('should throw error when tenant exists', () => __awaiter(void 0, void 0, void 0, function* () {
89
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
90
+ expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
91
+ (0, nock_1.default)(mockDomain)
92
+ .get(mockPath)
93
+ .reply(200, { status: deploy_const_1.CDP_DEPLOY_STATUS_ERROR });
94
+ const program = (0, activate_1.default)();
95
+ yield program.parseAsync(createMockArgs(mockRegion, mockTenant, mockFilePath, mockDomain));
96
+ expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining(activate_1.errorMessage));
97
+ }));
98
+ it('should throw error when get tenant returns 403', () => __awaiter(void 0, void 0, void 0, function* () {
99
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
100
+ expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
101
+ (0, nock_1.default)(mockDomain).get(mockPath).reply(403, {
102
+ title: 'Forbidden',
103
+ status: 403,
104
+ });
105
+ const program = (0, activate_1.default)();
106
+ yield program.parseAsync(createMockArgs(mockRegion, mockTenant, mockFilePath, mockDomain));
107
+ expect(activateErrorSpy).toHaveBeenCalledWith(403, {
108
+ status: 403,
109
+ title: 'Forbidden',
110
+ });
111
+ }));
112
+ it('deploys a default schema and activate an instance', () => __awaiter(void 0, void 0, void 0, function* () {
113
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
114
+ expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
115
+ (0, nock_1.default)(mockDomain)
116
+ .get(mockPath)
117
+ .reply(404, {
118
+ status: deploy_const_1.CDP_DEPLOY_STATUS_ERROR,
119
+ })
120
+ .put(mockPath)
121
+ .reply(200, {
122
+ tenantid: 'myTenant',
123
+ version: 'unknown',
124
+ stack: 'stackName',
125
+ status: deploy_const_1.CDP_DEPLOY_STATUS_DEPLOYING,
126
+ })
127
+ .get(mockPath)
128
+ .reply(200, {
129
+ status: deploy_const_1.CDP_DEPLOY_STATUS_DEPLOYED,
130
+ });
131
+ const program = (0, activate_1.default)();
132
+ yield program.parseAsync(createMockArgs(mockRegion, mockTenant, mockFilePath, mockDomain));
133
+ // Note the output from the spinner doesn't seem to appear here but this still tests that it
134
+ // ran without displaying an error.
135
+ expect(logSpy).toHaveBeenNthCalledWith(1, '');
136
+ expect(logSpy).toHaveBeenNthCalledWith(2, '');
137
+ expect(logSpy).toHaveBeenNthCalledWith(3, 'Your Schema has been deployed and instance has been activated.');
138
+ expect(logSpy).toHaveBeenNthCalledWith(4, '');
139
+ expect(errorSpy).not.toHaveBeenCalled();
140
+ }));
141
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const instanceCommand: () => Command;
3
+ export default instanceCommand;
@@ -0,0 +1,15 @@
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 activate_1 = __importDefault(require("./activate/activate"));
8
+ const instanceCommand = () => {
9
+ const cdpSchemaCommands = new commander_1.Command('instance');
10
+ cdpSchemaCommands
11
+ .description('CDP Instance Commands')
12
+ .addCommand((0, activate_1.default)());
13
+ return cdpSchemaCommands;
14
+ };
15
+ exports.default = instanceCommand;
@@ -16,9 +16,7 @@ const nock_1 = __importDefault(require("nock"));
16
16
  const deploy_1 = __importDefault(require("./deploy"));
17
17
  const deploy_const_1 = require("./deploy.const");
18
18
  const path_1 = __importDefault(require("path"));
19
- function createMockUrl(region, path) {
20
- return `/__dxp/${region}/scv-deploy/${path}`;
21
- }
19
+ const utils_1 = require("../../utils");
22
20
  function createMockArgs(region, tenantID, filePath, mockDomain) {
23
21
  return [
24
22
  'node',
@@ -62,7 +60,7 @@ describe('cdpSchemaCommand', () => {
62
60
  jest.clearAllMocks(); // Clear all spies
63
61
  });
64
62
  it('correctly handles command arguments', () => __awaiter(void 0, void 0, void 0, function* () {
65
- const mockPath = createMockUrl(mockRegion, mockTenant);
63
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
66
64
  (0, nock_1.default)(mockDomain)
67
65
  .put(mockPath, require(path_1.default.resolve(process.cwd(), './src/__tests__/cdp/scv/schema.json')))
68
66
  .reply(200, {
@@ -83,7 +81,7 @@ describe('cdpSchemaCommand', () => {
83
81
  }));
84
82
  it('presents a formatted invalid schema message', () => __awaiter(void 0, void 0, void 0, function* () {
85
83
  const schemaFileContent = require(path_1.default.resolve(process.cwd(), mockFilePath));
86
- const mockPath = createMockUrl(mockRegion, mockTenant);
84
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
87
85
  expect(`${mockDomain}${mockPath}`).toEqual('http://localhost:9999/__dxp/us/scv-deploy/myTenant');
88
86
  (0, nock_1.default)(mockDomain)
89
87
  .get(mockPath)
@@ -112,7 +110,7 @@ describe('cdpSchemaCommand', () => {
112
110
  }));
113
111
  it('deploys a schema', () => __awaiter(void 0, void 0, void 0, function* () {
114
112
  const schemaFileContent = require(path_1.default.resolve(process.cwd(), mockFilePath));
115
- const mockPath = createMockUrl(mockRegion, mockTenant);
113
+ const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
116
114
  expect(`${mockDomain}${mockPath}`).toEqual('http://localhost:9999/__dxp/us/scv-deploy/myTenant');
117
115
  (0, nock_1.default)(mockDomain)
118
116
  .get(mockPath)
@@ -14,6 +14,7 @@ export declare function buildDXPUrl(serviceName: string, tenantID?: string, over
14
14
  tenant: string | undefined;
15
15
  }>;
16
16
  export declare function handleCommandError(error: Error): void;
17
+ export declare function createMockUrl(region: string, path: string): string;
17
18
  /**
18
19
  * Poll the schema to be deployed.
19
20
  */
package/lib/cdp/utils.js CHANGED
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.pollForDeployedSchema = exports.handleCommandError = exports.buildDXPUrl = exports.throwErrorIfNotLoggedIn = exports.logDebug = void 0;
15
+ exports.pollForDeployedSchema = exports.createMockUrl = exports.handleCommandError = exports.buildDXPUrl = exports.throwErrorIfNotLoggedIn = exports.logDebug = void 0;
16
16
  const ApplicationStore_1 = require("../ApplicationStore");
17
17
  const chalk_1 = __importDefault(require("chalk"));
18
18
  const ApplicationConfig_1 = require("../ApplicationConfig");
@@ -82,6 +82,10 @@ function handleCommandError(error) {
82
82
  }
83
83
  }
84
84
  exports.handleCommandError = handleCommandError;
85
+ function createMockUrl(region, path) {
86
+ return `/__dxp/${region}/scv-deploy/${path}`;
87
+ }
88
+ exports.createMockUrl = createMockUrl;
85
89
  /**
86
90
  * Poll the schema to be deployed.
87
91
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/dxp-cli-next",
3
- "version": "5.24.0-develop.3",
3
+ "version": "5.24.0-develop.4",
4
4
  "repository": {
5
5
  "url": "https://gitlab.squiz.net/dxp/dxp-cli-next"
6
6
  },