@squiz/dxp-cli-next 5.24.0-develop.4 → 5.25.0-develop.1
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/instance/activate/activate.js +2 -10
- package/lib/cdp/instance/activate/activate.spec.js +18 -17
- package/lib/page/layouts/dev/dev.d.ts +5 -0
- package/lib/page/layouts/dev/dev.js +70 -0
- package/lib/page/layouts/dev/dev.spec.d.ts +1 -0
- package/lib/page/layouts/dev/dev.spec.js +162 -0
- package/lib/page/layouts/layouts.js +3 -1
- package/lib/page/layouts/layouts.spec.js +7 -0
- package/lib/page/utils/definitions.d.ts +1 -0
- package/lib/page/utils/definitions.js +2 -1
- package/lib/page/utils/parse-args.d.ts +28 -0
- package/lib/page/utils/parse-args.js +84 -0
- package/lib/page/utils/parse-args.spec.d.ts +1 -0
- package/lib/page/utils/parse-args.spec.js +146 -0
- package/lib/page/utils/render.d.ts +33 -0
- package/lib/page/utils/render.js +58 -0
- package/lib/page/utils/render.spec.d.ts +1 -0
- package/lib/page/utils/render.spec.js +134 -0
- package/lib/page/utils/server.d.ts +12 -0
- package/lib/page/utils/server.js +201 -0
- package/lib/page/utils/server.spec.d.ts +1 -0
- package/lib/page/utils/server.spec.js +275 -0
- package/package.json +2 -1
|
@@ -32,10 +32,6 @@ const createActivateCommand = () => {
|
|
|
32
32
|
const activateCommand = new commander_1.Command('deploy')
|
|
33
33
|
.name('activate')
|
|
34
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
35
|
.configureOutput({
|
|
40
36
|
outputError(str, write) {
|
|
41
37
|
write(chalk_1.default.red(str));
|
|
@@ -51,7 +47,7 @@ const createActivateCommand = () => {
|
|
|
51
47
|
return status < 400 || status === 404;
|
|
52
48
|
},
|
|
53
49
|
});
|
|
54
|
-
const scvDeployBaseUrl = yield (0, utils_1.buildDXPUrl)(constants_1.SCV_DEPLOY_SERVICE_NAME,
|
|
50
|
+
const scvDeployBaseUrl = yield (0, utils_1.buildDXPUrl)(constants_1.SCV_DEPLOY_SERVICE_NAME, undefined, options.overrideUrl, undefined);
|
|
55
51
|
const apiUrl = `${scvDeployBaseUrl.dxpUrl}/${scvDeployBaseUrl.tenant}`;
|
|
56
52
|
const getDeployResponse = (yield apiService.client
|
|
57
53
|
.get(apiUrl)
|
|
@@ -66,11 +62,7 @@ const createActivateCommand = () => {
|
|
|
66
62
|
}
|
|
67
63
|
(0, utils_1.logDebug)(`PUT ${apiUrl}`);
|
|
68
64
|
const activateInstanceAndDeploySchemaResponse = (yield apiService.client
|
|
69
|
-
.put(apiUrl
|
|
70
|
-
headers: {
|
|
71
|
-
'Content-Type': 'application/json',
|
|
72
|
-
},
|
|
73
|
-
})
|
|
65
|
+
.put(apiUrl)
|
|
74
66
|
.catch((err) => {
|
|
75
67
|
(0, utils_1.logDebug)(`RAW ERROR: ${JSON.stringify(err)}`);
|
|
76
68
|
if (err.response) {
|
|
@@ -40,21 +40,10 @@ const activate_1 = __importStar(require("./activate"));
|
|
|
40
40
|
const deploy_const_1 = require("../../schema/deploy/deploy.const");
|
|
41
41
|
const utils_1 = require("../../utils");
|
|
42
42
|
const activate = __importStar(require("./activate"));
|
|
43
|
+
const utils = __importStar(require("../../utils"));
|
|
43
44
|
const mockDomainWithPath = 'http://localhost:9999/__dxp/us/scv-deploy/myTenant';
|
|
44
|
-
function createMockArgs(
|
|
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
|
-
];
|
|
45
|
+
function createMockArgs() {
|
|
46
|
+
return ['node', 'dxp-cli', 'cdp', 'instance', 'activate'];
|
|
58
47
|
}
|
|
59
48
|
describe('cdpInstanceCommand', () => {
|
|
60
49
|
let mockTenant;
|
|
@@ -86,16 +75,24 @@ describe('cdpInstanceCommand', () => {
|
|
|
86
75
|
nock_1.default.cleanAll(); // Clear all HTTP mocks
|
|
87
76
|
});
|
|
88
77
|
it('should throw error when tenant exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
jest.spyOn(utils, 'buildDXPUrl').mockResolvedValue({
|
|
79
|
+
dxpUrl: `${mockDomain}/__dxp/us/scv-deploy`,
|
|
80
|
+
tenant: mockTenant,
|
|
81
|
+
});
|
|
89
82
|
const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
|
|
90
83
|
expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
|
|
91
84
|
(0, nock_1.default)(mockDomain)
|
|
92
85
|
.get(mockPath)
|
|
93
86
|
.reply(200, { status: deploy_const_1.CDP_DEPLOY_STATUS_ERROR });
|
|
94
87
|
const program = (0, activate_1.default)();
|
|
95
|
-
yield program.parseAsync(createMockArgs(
|
|
88
|
+
yield program.parseAsync(createMockArgs());
|
|
96
89
|
expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining(activate_1.errorMessage));
|
|
97
90
|
}));
|
|
98
91
|
it('should throw error when get tenant returns 403', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
jest.spyOn(utils, 'buildDXPUrl').mockResolvedValue({
|
|
93
|
+
dxpUrl: `${mockDomain}/__dxp/us/scv-deploy`,
|
|
94
|
+
tenant: mockTenant,
|
|
95
|
+
});
|
|
99
96
|
const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
|
|
100
97
|
expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
|
|
101
98
|
(0, nock_1.default)(mockDomain).get(mockPath).reply(403, {
|
|
@@ -103,13 +100,17 @@ describe('cdpInstanceCommand', () => {
|
|
|
103
100
|
status: 403,
|
|
104
101
|
});
|
|
105
102
|
const program = (0, activate_1.default)();
|
|
106
|
-
yield program.parseAsync(createMockArgs(
|
|
103
|
+
yield program.parseAsync(createMockArgs());
|
|
107
104
|
expect(activateErrorSpy).toHaveBeenCalledWith(403, {
|
|
108
105
|
status: 403,
|
|
109
106
|
title: 'Forbidden',
|
|
110
107
|
});
|
|
111
108
|
}));
|
|
112
109
|
it('deploys a default schema and activate an instance', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
jest.spyOn(utils, 'buildDXPUrl').mockResolvedValue({
|
|
111
|
+
dxpUrl: `${mockDomain}/__dxp/us/scv-deploy`,
|
|
112
|
+
tenant: mockTenant,
|
|
113
|
+
});
|
|
113
114
|
const mockPath = (0, utils_1.createMockUrl)(mockRegion, mockTenant);
|
|
114
115
|
expect(`${mockDomain}${mockPath}`).toEqual(mockDomainWithPath);
|
|
115
116
|
(0, nock_1.default)(mockDomain)
|
|
@@ -129,7 +130,7 @@ describe('cdpInstanceCommand', () => {
|
|
|
129
130
|
status: deploy_const_1.CDP_DEPLOY_STATUS_DEPLOYED,
|
|
130
131
|
});
|
|
131
132
|
const program = (0, activate_1.default)();
|
|
132
|
-
yield program.parseAsync(createMockArgs(
|
|
133
|
+
yield program.parseAsync(createMockArgs());
|
|
133
134
|
// Note the output from the spinner doesn't seem to appear here but this still tests that it
|
|
134
135
|
// ran without displaying an error.
|
|
135
136
|
expect(logSpy).toHaveBeenNthCalledWith(1, '');
|
|
@@ -0,0 +1,70 @@
|
|
|
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.logger = void 0;
|
|
16
|
+
const commander_1 = require("commander");
|
|
17
|
+
const dx_logger_lib_1 = require("@squiz/dx-logger-lib");
|
|
18
|
+
const definitions_1 = require("../../utils/definitions");
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const server_1 = require("../../utils/server");
|
|
21
|
+
const parse_args_1 = require("../../utils/parse-args");
|
|
22
|
+
exports.logger = (0, dx_logger_lib_1.getLogger)({
|
|
23
|
+
name: 'layout-dev',
|
|
24
|
+
format: 'human',
|
|
25
|
+
});
|
|
26
|
+
const createDevCommand = () => {
|
|
27
|
+
const devCommand = new commander_1.Command()
|
|
28
|
+
.name('dev')
|
|
29
|
+
.description('Start a development server for page layouts')
|
|
30
|
+
.option('--config <string>', 'File path to the page layout config file', './page-layout.yaml')
|
|
31
|
+
.option('--port <number>', 'Port to run the development server on', '4040')
|
|
32
|
+
.option('--no-open', 'Do not automatically open browser')
|
|
33
|
+
.option('--stylesheet <path>', 'Path to CSS file to include')
|
|
34
|
+
.option('--zones <items>', 'Zone content mappings', parse_args_1.parseZonesList, {})
|
|
35
|
+
.option('--options <items>', 'Layout options', parse_args_1.parseOptionsList, {})
|
|
36
|
+
.allowUnknownOption(true)
|
|
37
|
+
.allowExcessArguments(true)
|
|
38
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
try {
|
|
40
|
+
// Load layout definition
|
|
41
|
+
exports.logger.info(`Loading layout definition from ${options.config}`);
|
|
42
|
+
const rawLayoutDefinition = yield (0, definitions_1.loadLayoutDefinition)(options.config);
|
|
43
|
+
if (!rawLayoutDefinition) {
|
|
44
|
+
throw new Error(`Failed to load layout definition from ${options.config}`);
|
|
45
|
+
}
|
|
46
|
+
// Confirm for entry property
|
|
47
|
+
const layoutDefinition = Object.assign({}, rawLayoutDefinition);
|
|
48
|
+
exports.logger.info('Starting development server...');
|
|
49
|
+
yield (0, server_1.startDevServer)({
|
|
50
|
+
configPath: path_1.default.resolve(options.config),
|
|
51
|
+
layoutDefinition,
|
|
52
|
+
zoneContent: options.zones,
|
|
53
|
+
layoutOptions: options.options,
|
|
54
|
+
stylesheet: options.stylesheet
|
|
55
|
+
? path_1.default.resolve(options.stylesheet)
|
|
56
|
+
: undefined,
|
|
57
|
+
port: parseInt(options.port) || 4040,
|
|
58
|
+
openBrowser: options.open !== false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error.stack && process.env.DEBUG) {
|
|
63
|
+
console.error(error.stack);
|
|
64
|
+
}
|
|
65
|
+
exports.logger.error(error.message || 'An unknown error occurred');
|
|
66
|
+
}
|
|
67
|
+
}));
|
|
68
|
+
return devCommand;
|
|
69
|
+
};
|
|
70
|
+
exports.default = createDevCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
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
|
+
jest.mock('../../utils/definitions');
|
|
16
|
+
jest.mock('../../utils/server');
|
|
17
|
+
jest.mock('@squiz/dx-logger-lib', () => ({
|
|
18
|
+
getLogger: () => {
|
|
19
|
+
return {
|
|
20
|
+
info: mockLoggerInfoFn,
|
|
21
|
+
error: mockLoggerErrorFn,
|
|
22
|
+
warn: jest.fn(),
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
const mockLoggerInfoFn = jest.fn();
|
|
27
|
+
const mockLoggerErrorFn = jest.fn();
|
|
28
|
+
const dev_1 = __importDefault(require("./dev"));
|
|
29
|
+
const definitions_1 = require("../../utils/definitions");
|
|
30
|
+
const server_1 = require("../../utils/server");
|
|
31
|
+
const path_1 = __importDefault(require("path"));
|
|
32
|
+
const originalProcessArgv = process.argv;
|
|
33
|
+
function createMockArgs(opts) {
|
|
34
|
+
const args = ['node', 'dxp-cli', 'dev'];
|
|
35
|
+
if (opts.config)
|
|
36
|
+
args.push('--config', opts.config);
|
|
37
|
+
if (opts.port)
|
|
38
|
+
args.push('--port', opts.port.toString());
|
|
39
|
+
if (opts.open === false)
|
|
40
|
+
args.push('--no-open');
|
|
41
|
+
if (opts.stylesheet)
|
|
42
|
+
args.push('--stylesheet', opts.stylesheet);
|
|
43
|
+
if (opts.zoneContent) {
|
|
44
|
+
Object.entries(opts.zoneContent).forEach(([zoneName, filePaths]) => {
|
|
45
|
+
filePaths.forEach(filePath => {
|
|
46
|
+
args.push(`--zones=${zoneName}=${filePath}`);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (opts.layoutOptions) {
|
|
51
|
+
Object.entries(opts.layoutOptions).forEach(([optionName, value]) => {
|
|
52
|
+
args.push(`--options=${optionName}=${value}`);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return args;
|
|
56
|
+
}
|
|
57
|
+
describe('devCommand', () => {
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
jest.clearAllMocks();
|
|
60
|
+
process.argv = originalProcessArgv;
|
|
61
|
+
});
|
|
62
|
+
it('correctly handles command option defaults', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
const program = (0, dev_1.default)();
|
|
64
|
+
const args = createMockArgs({});
|
|
65
|
+
process.argv = args;
|
|
66
|
+
yield program.parseAsync(args);
|
|
67
|
+
const opts = program.opts();
|
|
68
|
+
expect(opts.config).toEqual('./page-layout.yaml');
|
|
69
|
+
expect(opts.port).toEqual('4040');
|
|
70
|
+
expect(opts.open).toEqual(true);
|
|
71
|
+
expect(opts.stylesheet).toBeUndefined();
|
|
72
|
+
}));
|
|
73
|
+
it('correctly handles command arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const config = './src/__tests__/layout.yaml';
|
|
75
|
+
const port = '3000';
|
|
76
|
+
const open = false;
|
|
77
|
+
const stylesheet = './src/__tests__/styles.css';
|
|
78
|
+
const program = (0, dev_1.default)();
|
|
79
|
+
const args = createMockArgs({
|
|
80
|
+
config,
|
|
81
|
+
port,
|
|
82
|
+
open,
|
|
83
|
+
stylesheet,
|
|
84
|
+
});
|
|
85
|
+
process.argv = args;
|
|
86
|
+
yield program.parseAsync(args);
|
|
87
|
+
const opts = program.opts();
|
|
88
|
+
expect(opts.config).toEqual(config);
|
|
89
|
+
expect(opts.port).toEqual(port);
|
|
90
|
+
expect(opts.open).toEqual(open);
|
|
91
|
+
expect(opts.stylesheet).toEqual(stylesheet);
|
|
92
|
+
}));
|
|
93
|
+
it('loads the layout definition and starts the server', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
+
const config = './src/__tests__/layout.yaml';
|
|
95
|
+
const mockLayout = { name: 'Test Layout' };
|
|
96
|
+
definitions_1.loadLayoutDefinition.mockResolvedValue(mockLayout);
|
|
97
|
+
const program = (0, dev_1.default)();
|
|
98
|
+
const args = createMockArgs({ config });
|
|
99
|
+
process.argv = args;
|
|
100
|
+
yield program.parseAsync(args);
|
|
101
|
+
expect(definitions_1.loadLayoutDefinition).toHaveBeenCalledWith(config);
|
|
102
|
+
expect(mockLoggerInfoFn).toHaveBeenNthCalledWith(1, `Loading layout definition from ${config}`);
|
|
103
|
+
expect(mockLoggerInfoFn).toHaveBeenNthCalledWith(2, 'Starting development server...');
|
|
104
|
+
expect(server_1.startDevServer).toHaveBeenCalledWith(expect.objectContaining({
|
|
105
|
+
configPath: path_1.default.resolve(config),
|
|
106
|
+
layoutDefinition: mockLayout,
|
|
107
|
+
}));
|
|
108
|
+
}));
|
|
109
|
+
it('parses and passes zone content to the server', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
const mockLayout = { name: 'Test Layout' };
|
|
111
|
+
definitions_1.loadLayoutDefinition.mockResolvedValue(mockLayout);
|
|
112
|
+
const zoneContent = {
|
|
113
|
+
main: ['./example.main.0.html', './example.main.1.html'],
|
|
114
|
+
aside: ['./example.aside.html'],
|
|
115
|
+
};
|
|
116
|
+
const program = (0, dev_1.default)();
|
|
117
|
+
const args = createMockArgs({ zoneContent });
|
|
118
|
+
process.argv = args;
|
|
119
|
+
yield program.parseAsync(args);
|
|
120
|
+
expect(server_1.startDevServer).toHaveBeenCalledWith(expect.objectContaining({
|
|
121
|
+
zoneContent,
|
|
122
|
+
}));
|
|
123
|
+
}));
|
|
124
|
+
it('parses and passes layout options to the server', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
const mockLayout = { name: 'Test Layout' };
|
|
126
|
+
definitions_1.loadLayoutDefinition.mockResolvedValue(mockLayout);
|
|
127
|
+
const layoutOptions = {
|
|
128
|
+
sizing: 'large',
|
|
129
|
+
theme: 'dark',
|
|
130
|
+
};
|
|
131
|
+
const program = (0, dev_1.default)();
|
|
132
|
+
const args = createMockArgs({ layoutOptions });
|
|
133
|
+
process.argv = args;
|
|
134
|
+
yield program.parseAsync(args);
|
|
135
|
+
expect(server_1.startDevServer).toHaveBeenCalledWith(expect.objectContaining({
|
|
136
|
+
layoutOptions,
|
|
137
|
+
}));
|
|
138
|
+
}));
|
|
139
|
+
it('handles failure to load layout definition', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
140
|
+
const config = './src/__tests__/layout.yaml';
|
|
141
|
+
definitions_1.loadLayoutDefinition.mockResolvedValue(undefined);
|
|
142
|
+
const originalError = mockLoggerErrorFn;
|
|
143
|
+
mockLoggerErrorFn.mockClear();
|
|
144
|
+
const program = (0, dev_1.default)();
|
|
145
|
+
const args = createMockArgs({ config });
|
|
146
|
+
process.argv = args;
|
|
147
|
+
yield program.parseAsync(args);
|
|
148
|
+
expect(mockLoggerErrorFn).toHaveBeenCalledWith(expect.stringContaining(`Failed to load layout definition from ${config}`));
|
|
149
|
+
}));
|
|
150
|
+
it('handles server startup error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
+
const mockLayout = { name: 'Test Layout' };
|
|
152
|
+
definitions_1.loadLayoutDefinition.mockResolvedValue(mockLayout);
|
|
153
|
+
server_1.startDevServer.mockRejectedValue(new Error('Server start failed'));
|
|
154
|
+
const originalError = mockLoggerErrorFn;
|
|
155
|
+
mockLoggerErrorFn.mockClear();
|
|
156
|
+
const program = (0, dev_1.default)();
|
|
157
|
+
const args = createMockArgs({});
|
|
158
|
+
process.argv = args;
|
|
159
|
+
yield program.parseAsync(args);
|
|
160
|
+
expect(mockLoggerErrorFn).toHaveBeenCalledWith(expect.stringContaining('Server start failed'));
|
|
161
|
+
}));
|
|
162
|
+
});
|
|
@@ -5,11 +5,13 @@ 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 deploy_1 = __importDefault(require("./deploy/deploy"));
|
|
8
|
+
const dev_1 = __importDefault(require("./dev/dev"));
|
|
8
9
|
const createLayoutsCommand = () => {
|
|
9
10
|
const layoutsCommand = new commander_1.Command('layouts');
|
|
10
11
|
layoutsCommand
|
|
11
12
|
.description('Page Contents Layouts Commands')
|
|
12
|
-
.addCommand((0, deploy_1.default)())
|
|
13
|
+
.addCommand((0, deploy_1.default)())
|
|
14
|
+
.addCommand((0, dev_1.default)());
|
|
13
15
|
return layoutsCommand;
|
|
14
16
|
};
|
|
15
17
|
exports.default = createLayoutsCommand;
|
|
@@ -6,10 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const commander_1 = require("commander");
|
|
7
7
|
const layouts_1 = __importDefault(require("./layouts"));
|
|
8
8
|
const deploy_1 = __importDefault(require("./deploy/deploy"));
|
|
9
|
+
const dev_1 = __importDefault(require("./dev/dev"));
|
|
9
10
|
jest.mock('./deploy/deploy');
|
|
10
11
|
deploy_1.default.mockImplementation(() => {
|
|
11
12
|
return new commander_1.Command('mock-deploy');
|
|
12
13
|
});
|
|
14
|
+
jest.mock('./dev/dev');
|
|
15
|
+
dev_1.default.mockImplementation(() => {
|
|
16
|
+
return new commander_1.Command('mock-dev');
|
|
17
|
+
});
|
|
13
18
|
describe('createLayoutsCommand', () => {
|
|
14
19
|
it('should create a layouts command with deploy subcommand', () => {
|
|
15
20
|
const layoutsCommand = (0, layouts_1.default)();
|
|
@@ -18,5 +23,7 @@ describe('createLayoutsCommand', () => {
|
|
|
18
23
|
expect(layoutsCommand.description()).toBe('Page Contents Layouts Commands');
|
|
19
24
|
expect(deploy_1.default).toHaveBeenCalled();
|
|
20
25
|
expect(layoutsCommand.commands.map(cmd => cmd.name())).toContain('mock-deploy');
|
|
26
|
+
expect(dev_1.default).toHaveBeenCalled();
|
|
27
|
+
expect(layoutsCommand.commands.map(cmd => cmd.name())).toContain('mock-dev');
|
|
21
28
|
});
|
|
22
29
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare function loadLayoutDefinition(layoutFile: string): Promise<LayoutDefinition>;
|
|
3
|
+
export declare function loadLayoutFromFile(layoutFile: string): Promise<InputLayoutDefinition>;
|
|
3
4
|
export declare const BaseLayoutDefinition: z.ZodObject<{
|
|
4
5
|
/**
|
|
5
6
|
* User defined identifier for a Page Layout
|
|
@@ -43,7 +43,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
43
43
|
return t;
|
|
44
44
|
};
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.LayoutDefinition = exports.InputLayoutDefinition = exports.BaseLayoutDefinition = exports.loadLayoutDefinition = void 0;
|
|
46
|
+
exports.LayoutDefinition = exports.InputLayoutDefinition = exports.BaseLayoutDefinition = exports.loadLayoutFromFile = exports.loadLayoutDefinition = void 0;
|
|
47
47
|
const fs = __importStar(require("node:fs/promises"));
|
|
48
48
|
const path = __importStar(require("node:path"));
|
|
49
49
|
const zod_1 = require("zod");
|
|
@@ -82,6 +82,7 @@ function loadLayoutFromFile(layoutFile) {
|
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
+
exports.loadLayoutFromFile = loadLayoutFromFile;
|
|
85
86
|
function loadTemplate(layoutDirectory, templateFile) {
|
|
86
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
88
|
try {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse zones list from command line
|
|
3
|
+
* Supports multiple formats:
|
|
4
|
+
* - Single pair: 'main=./main.html' or 'main:./main.html'
|
|
5
|
+
* - Comma-separated list: 'main=./main.html,aside=./aside.html' or 'main:./main.html,aside:./aside.html'
|
|
6
|
+
* - Multiple --zones flags: merged together
|
|
7
|
+
*
|
|
8
|
+
* @param value Current value being processed
|
|
9
|
+
* @param previous Previously processed value (used for multiple flags)
|
|
10
|
+
* @returns Record of zone names to file paths
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseZonesList(value: string, previous: Record<string, string[]>): {
|
|
13
|
+
[x: string]: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Parse options list from command line
|
|
17
|
+
* Supports multiple formats:
|
|
18
|
+
* - Single pair: 'key=value' or 'key:value'
|
|
19
|
+
* - Comma-separated list: 'key1=value1,key2=value2' or 'key1:value1,key2:value2'
|
|
20
|
+
* - Multiple --options flags: later values override earlier ones
|
|
21
|
+
*
|
|
22
|
+
* @param value Current value being processed
|
|
23
|
+
* @param previous Previously processed value (used for multiple flags)
|
|
24
|
+
* @returns Record of option names to values
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseOptionsList(value: string, previous: Record<string, string>): {
|
|
27
|
+
[x: string]: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseOptionsList = exports.parseZonesList = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Parse zones list from command line
|
|
6
|
+
* Supports multiple formats:
|
|
7
|
+
* - Single pair: 'main=./main.html' or 'main:./main.html'
|
|
8
|
+
* - Comma-separated list: 'main=./main.html,aside=./aside.html' or 'main:./main.html,aside:./aside.html'
|
|
9
|
+
* - Multiple --zones flags: merged together
|
|
10
|
+
*
|
|
11
|
+
* @param value Current value being processed
|
|
12
|
+
* @param previous Previously processed value (used for multiple flags)
|
|
13
|
+
* @returns Record of zone names to file paths
|
|
14
|
+
*/
|
|
15
|
+
function parseZonesList(value, previous) {
|
|
16
|
+
const result = Object.assign({}, previous);
|
|
17
|
+
if (!value)
|
|
18
|
+
return result;
|
|
19
|
+
// Split comma-separated values if present
|
|
20
|
+
const parts = value.includes(',') ? value.split(',') : [value];
|
|
21
|
+
for (const part of parts) {
|
|
22
|
+
let zoneName;
|
|
23
|
+
let filePath;
|
|
24
|
+
// Handle both colon and equals separators
|
|
25
|
+
if (part.includes('=')) {
|
|
26
|
+
[zoneName, filePath] = part.split('=');
|
|
27
|
+
}
|
|
28
|
+
else if (part.includes(':')) {
|
|
29
|
+
[zoneName, filePath] = part.split(':');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
continue; // Skip invalid format
|
|
33
|
+
}
|
|
34
|
+
// Skip empty zone names or file paths
|
|
35
|
+
if (!zoneName || !filePath) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (!result[zoneName]) {
|
|
39
|
+
result[zoneName] = [];
|
|
40
|
+
}
|
|
41
|
+
result[zoneName].push(filePath);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
exports.parseZonesList = parseZonesList;
|
|
46
|
+
/**
|
|
47
|
+
* Parse options list from command line
|
|
48
|
+
* Supports multiple formats:
|
|
49
|
+
* - Single pair: 'key=value' or 'key:value'
|
|
50
|
+
* - Comma-separated list: 'key1=value1,key2=value2' or 'key1:value1,key2:value2'
|
|
51
|
+
* - Multiple --options flags: later values override earlier ones
|
|
52
|
+
*
|
|
53
|
+
* @param value Current value being processed
|
|
54
|
+
* @param previous Previously processed value (used for multiple flags)
|
|
55
|
+
* @returns Record of option names to values
|
|
56
|
+
*/
|
|
57
|
+
function parseOptionsList(value, previous) {
|
|
58
|
+
const result = Object.assign({}, previous);
|
|
59
|
+
if (!value)
|
|
60
|
+
return result;
|
|
61
|
+
// Split comma-separated values if present
|
|
62
|
+
const parts = value.includes(',') ? value.split(',') : [value];
|
|
63
|
+
for (const part of parts) {
|
|
64
|
+
let optionName;
|
|
65
|
+
let optionValue;
|
|
66
|
+
// Handle both colon and equals separators
|
|
67
|
+
if (part.includes('=')) {
|
|
68
|
+
[optionName, optionValue] = part.split('=');
|
|
69
|
+
}
|
|
70
|
+
else if (part.includes(':')) {
|
|
71
|
+
[optionName, optionValue] = part.split(':');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
continue; // Skip invalid format
|
|
75
|
+
}
|
|
76
|
+
// Skip empty option names or values
|
|
77
|
+
if (!optionName || !optionValue) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
result[optionName] = optionValue;
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
exports.parseOptionsList = parseOptionsList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|