@ixon-cdk/core 1.0.0 → 1.1.0-next.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/config/config.service.js +4 -8
- package/package.json +8 -8
- package/server/index.js +25 -14
- package/template/template.service.js +218 -34
- package/utils.js +18 -1
package/config/config.service.js
CHANGED
|
@@ -6,9 +6,9 @@ const { getRootDir, logFileCrudMessage, logErrorMessage } = require('../utils');
|
|
|
6
6
|
module.exports = class ConfigService {
|
|
7
7
|
_config = { components: {} };
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
constructor(configFile = 'config.json') {
|
|
10
|
+
this._path = path.join(getRootDir(), configFile);
|
|
10
11
|
|
|
11
|
-
constructor() {
|
|
12
12
|
let config;
|
|
13
13
|
|
|
14
14
|
if (!fs.existsSync(this._path)) {
|
|
@@ -19,7 +19,7 @@ module.exports = class ConfigService {
|
|
|
19
19
|
try {
|
|
20
20
|
config = require(this._path);
|
|
21
21
|
} catch {
|
|
22
|
-
logErrorMessage(
|
|
22
|
+
logErrorMessage("Couldn't parse config file.");
|
|
23
23
|
process.exit();
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -60,11 +60,7 @@ module.exports = class ConfigService {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
extendComponent(name, config) {
|
|
63
|
-
this._config.components[name] = merge(
|
|
64
|
-
{},
|
|
65
|
-
this._config.components[name],
|
|
66
|
-
config,
|
|
67
|
-
);
|
|
63
|
+
this._config.components[name] = merge({}, this._config.components[name], config);
|
|
68
64
|
this._sync();
|
|
69
65
|
}
|
|
70
66
|
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixon-cdk/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.1.0-next.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "ISC",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"app-root-dir": "^1.0.2",
|
|
10
|
-
"archiver": "^5.3.
|
|
11
|
-
"axios": "^0.
|
|
10
|
+
"archiver": "^5.3.1",
|
|
11
|
+
"axios": "^0.26.1",
|
|
12
12
|
"chalk": "^4.1.2",
|
|
13
|
-
"chokidar": "^3.5.
|
|
13
|
+
"chokidar": "^3.5.3",
|
|
14
14
|
"crypto-js": "^4.1.1",
|
|
15
|
-
"express": "^4.17.
|
|
16
|
-
"glob": "^
|
|
15
|
+
"express": "^4.17.3",
|
|
16
|
+
"glob": "^8.0.1",
|
|
17
17
|
"livereload": "^0.9.3",
|
|
18
18
|
"lodash": "^4.17.21",
|
|
19
19
|
"opener": "^1.5.2",
|
|
20
|
-
"prompts": "^2.4.
|
|
20
|
+
"prompts": "^2.4.2",
|
|
21
21
|
"rimraf": "^3.0.2",
|
|
22
|
-
"yargs": "^17.
|
|
22
|
+
"yargs": "^17.4.1"
|
|
23
23
|
}
|
|
24
24
|
}
|
package/server/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const express = require('express');
|
|
3
|
+
const liveReload = require('livereload');
|
|
3
4
|
const ConfigService = require('../config/config.service');
|
|
4
5
|
|
|
6
|
+
const LR_PORT_DEFAULT = 35729;
|
|
7
|
+
|
|
5
8
|
module.exports = class Server {
|
|
6
9
|
constructor(opts) {
|
|
7
10
|
this._configSrv = new ConfigService();
|
|
@@ -25,10 +28,7 @@ module.exports = class Server {
|
|
|
25
28
|
// CORS
|
|
26
29
|
app.use((_, res, next) => {
|
|
27
30
|
res.header('Access-Control-Allow-Origin', '*');
|
|
28
|
-
res.header(
|
|
29
|
-
'Access-Control-Allow-Headers',
|
|
30
|
-
'Origin, X-Requested-With, Content-Type, Accept',
|
|
31
|
-
);
|
|
31
|
+
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
|
32
32
|
next();
|
|
33
33
|
});
|
|
34
34
|
|
|
@@ -38,16 +38,15 @@ module.exports = class Server {
|
|
|
38
38
|
const outputDir = this._getOutputDir(name);
|
|
39
39
|
if (outputDir) {
|
|
40
40
|
const dir = path.resolve(this._rootDir, outputDir);
|
|
41
|
-
app.use(
|
|
42
|
-
`/${this._opts.componentBasePath}/${name}`,
|
|
43
|
-
express.static(dir),
|
|
44
|
-
);
|
|
41
|
+
app.use(`/${this._opts.componentBasePath}/${name}`, express.static(dir));
|
|
45
42
|
}
|
|
46
43
|
});
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
// Adds live reload watchers
|
|
50
|
-
const lrServer =
|
|
47
|
+
const lrServer = liveReload.createServer({
|
|
48
|
+
port: this._opts.liveReloadPort,
|
|
49
|
+
});
|
|
51
50
|
const _refresh = () => lrServer.refresh('/');
|
|
52
51
|
const _debouncedRefresh = require('lodash/debounce')(_refresh, 250);
|
|
53
52
|
names
|
|
@@ -55,7 +54,9 @@ module.exports = class Server {
|
|
|
55
54
|
[path.join(this._rootDir, this._getOutput(name)), 100],
|
|
56
55
|
[path.join(this._rootDir, `dist/${name}/manifest.json`), 500],
|
|
57
56
|
])
|
|
58
|
-
.forEach(([filename, interval]) =>
|
|
57
|
+
.forEach(([filename, interval]) =>
|
|
58
|
+
require('fs').watchFile(filename, { interval }, _debouncedRefresh),
|
|
59
|
+
);
|
|
59
60
|
|
|
60
61
|
// Simulator app
|
|
61
62
|
const appDir = path.dirname(require.resolve('@ixon-cdk/simulator'));
|
|
@@ -76,17 +77,27 @@ module.exports = class Server {
|
|
|
76
77
|
res.status(200).sendFile('/index.html', { root: appDir });
|
|
77
78
|
});
|
|
78
79
|
|
|
79
|
-
app.listen(this._opts.port);
|
|
80
|
+
this.server = app.listen(this._opts.port);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
openSimulator(name = null) {
|
|
83
84
|
const url = this._getComponentUrl(name);
|
|
84
|
-
const
|
|
85
|
-
|
|
85
|
+
const lrPort = this._opts.liveReloadPort;
|
|
86
|
+
const params = new URLSearchParams();
|
|
87
|
+
if (url) {
|
|
88
|
+
params.set('pct-url', url);
|
|
89
|
+
}
|
|
90
|
+
if (lrPort !== LR_PORT_DEFAULT) {
|
|
91
|
+
params.set('lr-port', lrPort);
|
|
92
|
+
}
|
|
93
|
+
const queryString = params.toString();
|
|
94
|
+
const openUrl = `${this._getBaseUrl()}/?${queryString}`;
|
|
95
|
+
require('opener')(openUrl);
|
|
86
96
|
}
|
|
87
97
|
|
|
88
98
|
_getBaseUrl() {
|
|
89
|
-
|
|
99
|
+
const address = this.server.address();
|
|
100
|
+
return `http://localhost:${address.port}`;
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
_getComponentUrl(name) {
|
|
@@ -3,8 +3,10 @@ const path = require('path');
|
|
|
3
3
|
const prompts = require('prompts');
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
+
getFiles,
|
|
6
7
|
getRootDir,
|
|
7
8
|
ensureModule,
|
|
9
|
+
logErrorMessage,
|
|
8
10
|
logFileCrudMessage,
|
|
9
11
|
pascalCase,
|
|
10
12
|
} = require('../utils');
|
|
@@ -13,12 +15,131 @@ const ConfigService = require('../config/config.service');
|
|
|
13
15
|
module.exports = class TemplateService {
|
|
14
16
|
_configSrv = new ConfigService();
|
|
15
17
|
|
|
18
|
+
_rootDir = getRootDir();
|
|
19
|
+
|
|
16
20
|
_schemas = {};
|
|
17
21
|
|
|
18
22
|
constructor() {
|
|
19
23
|
this._discover();
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
async addFromExample(componentName, componentPrefix) {
|
|
27
|
+
const examplesRoot = path.join(this._rootDir, 'node_modules/component-examples');
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(examplesRoot)) {
|
|
30
|
+
logErrorMessage("Package 'ixoncloud/component-examples' is not installed.");
|
|
31
|
+
process.exit();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const examplesConfigSrv = new ConfigService('node_modules/component-examples/config.json');
|
|
35
|
+
const { components } = examplesConfigSrv._config;
|
|
36
|
+
|
|
37
|
+
if (!Object.keys(components).length) {
|
|
38
|
+
logErrorMessage('No examples found.');
|
|
39
|
+
process.exit();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const exampleComponentRoot = examplesConfigSrv.getNewComponentRoot();
|
|
43
|
+
const examplePrefix = examplesConfigSrv.getPrefix();
|
|
44
|
+
|
|
45
|
+
const result = await prompts({
|
|
46
|
+
type: 'select',
|
|
47
|
+
name: 'name',
|
|
48
|
+
message: 'Pick a template',
|
|
49
|
+
choices: Object.keys(components).map((name) => ({ title: name, value: name })),
|
|
50
|
+
initial: 0,
|
|
51
|
+
});
|
|
52
|
+
const exampleName = result.name;
|
|
53
|
+
|
|
54
|
+
if (!exampleName) {
|
|
55
|
+
process.exit();
|
|
56
|
+
} else if (!components[exampleName]) {
|
|
57
|
+
logErrorMessage(`Example '${exampleName}' is not configured.`);
|
|
58
|
+
process.exit();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const { build } = components[exampleName].runner;
|
|
62
|
+
const { builder } = build;
|
|
63
|
+
const isVue = builder.startsWith('@ixon-cdk/vue-builder');
|
|
64
|
+
const isStatic = builder.startsWith('@ixon-cdk/static-builder');
|
|
65
|
+
const isSvelte = builder.startsWith('@ixon-cdk/svelte-builder');
|
|
66
|
+
|
|
67
|
+
// find source files, read and replace.
|
|
68
|
+
const exampleDir = path.join(examplesRoot, exampleComponentRoot, exampleName);
|
|
69
|
+
const inputFilePath = path.join(exampleDir, build.input);
|
|
70
|
+
let inputFileContents = fs.readFileSync(inputFilePath, { encoding: 'utf-8' });
|
|
71
|
+
|
|
72
|
+
if (isVue) {
|
|
73
|
+
inputFileContents = this._findAndReplaceVueInputFile(inputFileContents, componentName);
|
|
74
|
+
} else if (isStatic) {
|
|
75
|
+
inputFileContents = this._findAndReplaceStaticInputFile(
|
|
76
|
+
inputFileContents,
|
|
77
|
+
examplePrefix,
|
|
78
|
+
exampleName,
|
|
79
|
+
componentPrefix,
|
|
80
|
+
componentName,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// find manifest file, read and replace.
|
|
85
|
+
const manifestFilePath = path.join(path.dirname(inputFilePath), 'manifest.json');
|
|
86
|
+
const manifestFileContents = JSON.parse(fs.readFileSync(manifestFilePath));
|
|
87
|
+
manifestFileContents.main = `${this._getTag(componentPrefix, componentName)}.min.js`;
|
|
88
|
+
manifestFileContents.version = '1';
|
|
89
|
+
|
|
90
|
+
let input;
|
|
91
|
+
if (isVue) {
|
|
92
|
+
input = `${componentName}.vue`;
|
|
93
|
+
} else if (isStatic) {
|
|
94
|
+
input = `${componentName}.js`;
|
|
95
|
+
} else if (isSvelte) {
|
|
96
|
+
input = `${componentName}.svelte`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const files = await getFiles(exampleDir).catch(logErrorMessage);
|
|
100
|
+
|
|
101
|
+
// find and install any missing dependencies.
|
|
102
|
+
files.forEach((file) => {
|
|
103
|
+
if (/\.(jsx?|tsx?|svelte|vue)$/i.test(file)) {
|
|
104
|
+
const fileContents = fs.readFileSync(file);
|
|
105
|
+
const { dependencies } = require(path.join(examplesRoot, 'package.json'));
|
|
106
|
+
this._checkDependencies(fileContents, dependencies || {});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// else start copying input, and menifest files
|
|
111
|
+
const componentRoot = this._configSrv.getNewComponentRoot();
|
|
112
|
+
const dir = path.join(this._rootDir, componentRoot, componentName);
|
|
113
|
+
const _logCreatedInDir = (fileName) => {
|
|
114
|
+
logFileCrudMessage('CREATE', path.join(componentRoot, componentName, fileName));
|
|
115
|
+
};
|
|
116
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
117
|
+
|
|
118
|
+
files
|
|
119
|
+
.map((file) => file.slice(exampleDir.length + 1))
|
|
120
|
+
.forEach((file) => {
|
|
121
|
+
// create directory if it doesn't exist.
|
|
122
|
+
const _dir = path.dirname(path.join(dir, file));
|
|
123
|
+
if (!fs.existsSync(_dir)) {
|
|
124
|
+
fs.mkdirSync(_dir, { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
// for the input-file and manifest use the replaced file contents.
|
|
127
|
+
if (file === build.input) {
|
|
128
|
+
fs.writeFileSync(path.join(dir, input), inputFileContents, { encoding: 'utf-8' });
|
|
129
|
+
_logCreatedInDir(input);
|
|
130
|
+
} else if (file === 'manifest.json') {
|
|
131
|
+
const json = `${JSON.stringify(manifestFileContents, null, 2)}\n`;
|
|
132
|
+
fs.writeFileSync(path.join(dir, file), json, { encoding: 'utf-8' });
|
|
133
|
+
_logCreatedInDir(file);
|
|
134
|
+
} else {
|
|
135
|
+
fs.copyFileSync(path.join(exampleDir, file), path.join(dir, file));
|
|
136
|
+
_logCreatedInDir(file);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return Promise.resolve({ config: { runner: { build: { builder, input } } } });
|
|
141
|
+
}
|
|
142
|
+
|
|
22
143
|
async add(componentName, componentPrefix) {
|
|
23
144
|
let schema;
|
|
24
145
|
|
|
@@ -33,16 +154,12 @@ module.exports = class TemplateService {
|
|
|
33
154
|
initial: 0,
|
|
34
155
|
});
|
|
35
156
|
|
|
36
|
-
const tag = componentPrefix
|
|
37
|
-
? `${componentPrefix}-${componentName}`
|
|
38
|
-
: componentName;
|
|
39
|
-
|
|
40
157
|
if (result) {
|
|
41
158
|
schema = this._schemas[result.templateName];
|
|
42
159
|
}
|
|
43
160
|
|
|
44
161
|
if (schema) {
|
|
45
|
-
const context = { name: componentName, tag };
|
|
162
|
+
const context = { name: componentName, tag: this._getTag(componentPrefix, componentName) };
|
|
46
163
|
let variantIdx = null;
|
|
47
164
|
|
|
48
165
|
if (schema.variants) {
|
|
@@ -65,31 +182,28 @@ module.exports = class TemplateService {
|
|
|
65
182
|
schema = this._interpolateSchema(schema, context);
|
|
66
183
|
|
|
67
184
|
if (schema.config.runner) {
|
|
68
|
-
const modulesNames = Object.keys(schema.config.runner).reduce(
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return [...names, name];
|
|
74
|
-
}
|
|
185
|
+
const modulesNames = Object.keys(schema.config.runner).reduce((names, cmd) => {
|
|
186
|
+
if (schema.config.runner[cmd].builder) {
|
|
187
|
+
const name = schema.config.runner[cmd].builder.split(':')[0];
|
|
188
|
+
if (!names.includes(name)) {
|
|
189
|
+
return [...names, name];
|
|
75
190
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
191
|
+
}
|
|
192
|
+
return names;
|
|
193
|
+
}, []);
|
|
80
194
|
modulesNames.forEach((name) => ensureModule(name));
|
|
81
195
|
}
|
|
82
196
|
|
|
83
|
-
const
|
|
197
|
+
const componentRoot = this._configSrv.getNewComponentRoot();
|
|
84
198
|
|
|
85
199
|
schema.files.forEach((file) => {
|
|
86
|
-
file.dest = `${
|
|
200
|
+
file.dest = `${componentRoot}/${componentName}/${file.dest}`;
|
|
87
201
|
this.createFile(file, context);
|
|
88
202
|
});
|
|
89
203
|
|
|
90
204
|
if (variantIdx !== null) {
|
|
91
205
|
schema.variants[variantIdx].files.forEach((file) => {
|
|
92
|
-
file.dest = `${
|
|
206
|
+
file.dest = `${componentRoot}/${componentName}/${file.dest}`;
|
|
93
207
|
this.createFile(file, context);
|
|
94
208
|
});
|
|
95
209
|
}
|
|
@@ -99,34 +213,100 @@ module.exports = class TemplateService {
|
|
|
99
213
|
}
|
|
100
214
|
|
|
101
215
|
createFile(file, ctx) {
|
|
102
|
-
|
|
103
|
-
fs.mkdirSync(path.dirname(path.join(rootDir, file.dest)), {
|
|
216
|
+
fs.mkdirSync(path.dirname(path.join(this._rootDir, file.dest)), {
|
|
104
217
|
recursive: true,
|
|
105
218
|
});
|
|
106
219
|
if (file.interpolateContent) {
|
|
107
220
|
const text = fs.readFileSync(
|
|
108
|
-
path.join(
|
|
109
|
-
path.dirname(require.resolve('@ixon-cdk/templates')),
|
|
110
|
-
file.source,
|
|
111
|
-
),
|
|
221
|
+
path.join(path.dirname(require.resolve('@ixon-cdk/templates')), file.source),
|
|
112
222
|
{ encoding: 'utf-8' },
|
|
113
223
|
);
|
|
114
224
|
const data = this._interpolateText(text, ctx);
|
|
115
|
-
fs.writeFileSync(path.join(
|
|
225
|
+
fs.writeFileSync(path.join(this._rootDir, file.dest), data, {
|
|
116
226
|
encoding: 'utf-8',
|
|
117
227
|
});
|
|
118
228
|
} else {
|
|
119
229
|
fs.copyFileSync(
|
|
120
|
-
path.join(
|
|
121
|
-
|
|
122
|
-
file.source,
|
|
123
|
-
),
|
|
124
|
-
path.join(rootDir, file.dest),
|
|
230
|
+
path.join(path.dirname(require.resolve('@ixon-cdk/templates')), file.source),
|
|
231
|
+
path.join(this._rootDir, file.dest),
|
|
125
232
|
);
|
|
126
233
|
}
|
|
127
234
|
logFileCrudMessage('CREATE', file.dest);
|
|
128
235
|
}
|
|
129
236
|
|
|
237
|
+
/**
|
|
238
|
+
* This script loops over a dependencies object and will check if the provided file contents is
|
|
239
|
+
* importing any. When that is the case, it will first check for that package whether it could
|
|
240
|
+
* already be a depencency in your workspace. If not, the package will get installed and saved.
|
|
241
|
+
*/
|
|
242
|
+
_checkDependencies(fileContents, dependencies) {
|
|
243
|
+
const rootDeps = require(path.join(this._rootDir, 'package.json')).dependencies || {};
|
|
244
|
+
Object.keys(dependencies).forEach((pkg) => {
|
|
245
|
+
const matcher = new RegExp(`^\\s*import.*\\s['"]${pkg}\\S*['"]`, 'gm');
|
|
246
|
+
if (matcher.test(fileContents) && !(pkg in rootDeps)) {
|
|
247
|
+
const version = dependencies[pkg];
|
|
248
|
+
console.log(`Installing package '${pkg}'...`);
|
|
249
|
+
require('child_process').execSync(`npm i ${pkg}@${version} --save`);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* This script will find and replace the component name definition in a vue (SFC) input file.
|
|
256
|
+
*/
|
|
257
|
+
_findAndReplaceVueInputFile(fileContents, componentName) {
|
|
258
|
+
const matcher = /export\s+default\s+{\s+name:\s+['"](\S+)['"]/gm;
|
|
259
|
+
return fileContents.replaceAll(matcher, (match, p1) => match.replace(p1, componentName));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* This script will find and replace the component class definition and the arguments for the
|
|
264
|
+
* custom element define method in a static input file.
|
|
265
|
+
*
|
|
266
|
+
* Given the example input file has the follwing contents:
|
|
267
|
+
*
|
|
268
|
+
* ```js
|
|
269
|
+
* class PctExample extends HTMLElement {
|
|
270
|
+
* ...
|
|
271
|
+
* }
|
|
272
|
+
*
|
|
273
|
+
* customElements.define('pct-example', PctExample);
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* ...if your workspace prefix is "abc" and your component name is "from-example", the content
|
|
277
|
+
* will be transformed into:
|
|
278
|
+
*
|
|
279
|
+
* ```js
|
|
280
|
+
* class AbcFromExample extends HTMLElement {
|
|
281
|
+
* ...
|
|
282
|
+
* }
|
|
283
|
+
*
|
|
284
|
+
* customElements.define('abc-from-example', AbcFromExample);
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
_findAndReplaceStaticInputFile(
|
|
288
|
+
fileContents,
|
|
289
|
+
searchPrefix,
|
|
290
|
+
searchName,
|
|
291
|
+
replacementPrefix,
|
|
292
|
+
replacementName,
|
|
293
|
+
) {
|
|
294
|
+
const searchTag = this._getTag(searchPrefix, searchName);
|
|
295
|
+
const replacementTag = this._getTag(replacementPrefix, replacementName);
|
|
296
|
+
return fileContents
|
|
297
|
+
.replaceAll(new RegExp(`class\\s+(${pascalCase(searchTag)})`, 'gm'), (match, p1) =>
|
|
298
|
+
match.replace(p1, pascalCase(replacementTag)),
|
|
299
|
+
)
|
|
300
|
+
.replaceAll(
|
|
301
|
+
new RegExp(
|
|
302
|
+
`define\\s*\\(\\s*['"](${searchTag})['"]\\s*,\\s+(${pascalCase(searchTag)})\\)`,
|
|
303
|
+
'gm',
|
|
304
|
+
),
|
|
305
|
+
(match, p1, p2) =>
|
|
306
|
+
match.replace(p1, replacementTag).replace(p2, pascalCase(replacementTag)),
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
130
310
|
_discover() {
|
|
131
311
|
const dir = path.dirname(require.resolve('@ixon-cdk/templates'));
|
|
132
312
|
const files = fs.readdirSync(dir);
|
|
@@ -141,14 +321,18 @@ module.exports = class TemplateService {
|
|
|
141
321
|
});
|
|
142
322
|
}
|
|
143
323
|
|
|
324
|
+
_getTag(prefix, name) {
|
|
325
|
+
return prefix ? `${prefix}-${name}` : name;
|
|
326
|
+
}
|
|
327
|
+
|
|
144
328
|
_interpolateSchema(schema, params) {
|
|
145
329
|
return JSON.parse(this._interpolateText(JSON.stringify(schema), params));
|
|
146
330
|
}
|
|
147
331
|
|
|
148
332
|
_interpolateText(text, params) {
|
|
149
333
|
return text
|
|
150
|
-
.replace(
|
|
151
|
-
.replace(
|
|
152
|
-
.replace(
|
|
334
|
+
.replace(/<%=\s*name\s*%>/g, params.name)
|
|
335
|
+
.replace(/<%=\s*tag\s*%>/g, params.tag)
|
|
336
|
+
.replace(/<%=\s*classify\(\s*tag\s*\)\s*%>/g, pascalCase(params.tag));
|
|
153
337
|
}
|
|
154
338
|
};
|
package/utils.js
CHANGED
|
@@ -61,7 +61,12 @@ function ensureModule(moduleName) {
|
|
|
61
61
|
}
|
|
62
62
|
if (!moduleExists(moduleName)) {
|
|
63
63
|
console.log(`Installing package '${moduleName}'...`);
|
|
64
|
-
|
|
64
|
+
if (moduleName.startsWith('@ixon-cdk/')) {
|
|
65
|
+
const cdkVersion = require('./package.json').version;
|
|
66
|
+
require('child_process').execSync(`npm install --save-dev ${moduleName}@${cdkVersion}`);
|
|
67
|
+
} else {
|
|
68
|
+
require('child_process').execSync(`npm install --save-dev ${moduleName}`);
|
|
69
|
+
}
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
|
|
@@ -114,10 +119,22 @@ function generatePreviewHash(templateId, templateName, versionId, versionNumber,
|
|
|
114
119
|
return require('crypto-js').AES.encrypt(JSON.stringify(ref), salt).toString();
|
|
115
120
|
}
|
|
116
121
|
|
|
122
|
+
async function getFiles(dir) {
|
|
123
|
+
const dirents = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
124
|
+
const files = await Promise.all(
|
|
125
|
+
dirents.map((dirent) => {
|
|
126
|
+
const res = path.resolve(dir, dirent.name);
|
|
127
|
+
return dirent.isDirectory() ? getFiles(res) : res;
|
|
128
|
+
}),
|
|
129
|
+
);
|
|
130
|
+
return Array.prototype.concat(...files);
|
|
131
|
+
}
|
|
132
|
+
|
|
117
133
|
module.exports = {
|
|
118
134
|
getArgv,
|
|
119
135
|
getRootDir,
|
|
120
136
|
logErrorMessage,
|
|
137
|
+
getFiles,
|
|
121
138
|
logFileCrudMessage,
|
|
122
139
|
logSuccessMessage,
|
|
123
140
|
moduleExists,
|