@tangelo/tangelo-configuration-toolkit 1.9.1 → 1.10.0
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/package.json +2 -2
- package/src/cli.js +1 -0
- package/src/lib/gulp-sftp.js +1 -1
- package/src/modules/deploy/execute.js +3 -2
- package/src/modules/deploy/index.js +12 -5
- package/src/modules/fonto/commands.js +59 -2
- package/src/modules/fonto/index.js +1 -0
- package/src/modules/migrate/steps.js +7 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangelo/tangelo-configuration-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"tct": "bin/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"node-ssh": "^12.0.2",
|
|
42
42
|
"object-assign-deep": "^0.4.0",
|
|
43
43
|
"p-limit": "^3.1.0",
|
|
44
|
-
"replace-in-file": "^3.
|
|
44
|
+
"replace-in-file": "^6.3.2",
|
|
45
45
|
"sass": "^1.43.5",
|
|
46
46
|
"saxon-js": "^2.3.0",
|
|
47
47
|
"ssh2-sftp-client": "^7.2.2",
|
package/src/cli.js
CHANGED
|
@@ -72,6 +72,7 @@ module.exports = function cli () {
|
|
|
72
72
|
init: {alias: 'i', desc: `Initialize editor (optionally pass version number or 'latest')`},
|
|
73
73
|
schema: {alias: 's', desc: 'Compile schemas to json'},
|
|
74
74
|
elements: {alias: 'e', desc: 'List schema elements not having a default configuration'},
|
|
75
|
+
attributes: {alias: 'a', desc: 'List schema attributes not having a default configuration'},
|
|
75
76
|
localize: {alias: 'l', desc: 'Update localization file'},
|
|
76
77
|
build: {alias: 'b', desc: 'Build the editor instance'},
|
|
77
78
|
run: {alias: 'r', desc: 'Start editor instance on localhost and watch changes'}
|
package/src/lib/gulp-sftp.js
CHANGED
|
@@ -25,7 +25,7 @@ module.exports = function(ftpConfig, remotedir) {
|
|
|
25
25
|
if (!files[0]) cb();
|
|
26
26
|
|
|
27
27
|
const paths = [...new Set(files.map(({destination}) => path.dirname(destination)))] // collect unique paths
|
|
28
|
-
.filter((p1, i, a) => !a.find(p2 => p1 != p2 && p2.includes(p1))) // remove paths being part of others
|
|
28
|
+
.filter((p1, i, a) => !a.find(p2 => p1 != p2 && p2.includes(p1+'/'))) // remove paths being part of others
|
|
29
29
|
;
|
|
30
30
|
|
|
31
31
|
sftp.connect(ftpConfig)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const babel_pe = require('@babel/preset-env');
|
|
1
2
|
const execGitCommand = require('../../lib/exec-git-command');
|
|
2
3
|
const fs = require('fs-extra');
|
|
3
4
|
const globby = require('globby');
|
|
@@ -6,7 +7,7 @@ const {NodeSSH} = require('node-ssh');
|
|
|
6
7
|
const through2 = require('through2');
|
|
7
8
|
const {spawnSync} = require('child_process');
|
|
8
9
|
|
|
9
|
-
const g_babel = require('gulp-babel')
|
|
10
|
+
const g_babel = require('gulp-babel');
|
|
10
11
|
const g_eol = require('gulp-eol');
|
|
11
12
|
const g_filter = require('gulp-filter');
|
|
12
13
|
const g_plumber = require('gulp-plumber');
|
|
@@ -155,7 +156,7 @@ const transfer = (paths, lrServer) => {
|
|
|
155
156
|
.pipe(xpsF.restore)
|
|
156
157
|
.pipe(jsF)
|
|
157
158
|
.pipe(g_sourcemaps.init())
|
|
158
|
-
.pipe(g_babel)
|
|
159
|
+
.pipe(g_babel({presets: [[babel_pe, {modules: false}]], comments: false, minified: true})) // function must be executed here, otherwise second execution during watch fails
|
|
159
160
|
.pipe(g_sourcemaps.write('.'))
|
|
160
161
|
.pipe(jsF.restore)
|
|
161
162
|
.pipe(sassF)
|
|
@@ -49,15 +49,17 @@ module.exports = function deploy (argv) {
|
|
|
49
49
|
const transfers = {
|
|
50
50
|
queue: [],
|
|
51
51
|
do () {
|
|
52
|
+
this.queue = this.queue.map(p => p.replace(/(fonto.)(dist|dev|packages.sx-shell-.*.src)(.assets.schemas)/, '$1dist$3')) // fonto schema changes can be detected in different paths at the same time
|
|
52
53
|
this.queue = [...new Set(this.queue)]; // remove duplicates
|
|
53
54
|
this.queue.forEach(v => s.addToCache(v));
|
|
54
55
|
transfer(this.queue, lrServer);
|
|
55
56
|
this.queue = [];
|
|
56
57
|
},
|
|
57
58
|
add (fp) {
|
|
59
|
+
const delay = !fp.match(/fonto/) ? 500 : 1500; // longer delay for fonto build files
|
|
58
60
|
this.queue.push(fp);
|
|
59
61
|
clearTimeout(this.delayedExec);
|
|
60
|
-
this.delayedExec = setTimeout(()=>transfers.do(),
|
|
62
|
+
this.delayedExec = setTimeout(()=>transfers.do(), delay);
|
|
61
63
|
}
|
|
62
64
|
};
|
|
63
65
|
|
|
@@ -67,12 +69,17 @@ module.exports = function deploy (argv) {
|
|
|
67
69
|
sftp.connect(c.server.ftpConfig).then(() => sftp.end()).catch(err => _error(`Could not connect to server${err ? ': '+err.message : ''}`));
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
gulp.watch([...c.transferPatterns, `!**/fonto/!(${c.envDev?'dev|':''}dist)/**`])
|
|
72
|
+
gulp.watch(c.transferPatterns)
|
|
72
73
|
.on('all', (event, filepath) => {
|
|
73
74
|
|
|
74
|
-
if ((event=='add' || event=='change') &&
|
|
75
|
-
|
|
75
|
+
if ((event=='add' || event=='change') && (
|
|
76
|
+
// within fonto, transfer build files only, but also schema files, because
|
|
77
|
+
// the "dist" folder isn't watched properly: it does not detect "assets" anymore after building once
|
|
78
|
+
!/fonto[\\\/]/.test(filepath) ||
|
|
79
|
+
/fonto[\\\/]dist/.test(filepath) ||
|
|
80
|
+
(/fonto[\\\/]dev/.test(filepath) && c.envDev) ||
|
|
81
|
+
/fonto[\\\/]packages[\\\/]sx-shell-.*?[\\\/]assets[\\\/]schemas[\\\/]/.test(filepath)
|
|
82
|
+
)
|
|
76
83
|
) {
|
|
77
84
|
transfers.add(filepath);
|
|
78
85
|
}
|
|
@@ -92,6 +92,7 @@ module.exports = {
|
|
|
92
92
|
|
|
93
93
|
const {rootSchemas} = fs.readJsonSync('../schema/fonto.json');
|
|
94
94
|
const fontoManifest = fs.readJsonSync('config/fonto-manifest.json');
|
|
95
|
+
let jsonPaths = [];
|
|
95
96
|
|
|
96
97
|
// remove all schema packages (sx-shell-*) from fonto-manifest.json
|
|
97
98
|
Object.keys(fontoManifest.dependencies).filter(k => k.includes('sx-shell-')).forEach(k => {
|
|
@@ -100,13 +101,14 @@ module.exports = {
|
|
|
100
101
|
|
|
101
102
|
// add dependency for sx-module to each package fonto-manifest.json
|
|
102
103
|
// add schema packages in fonto.json to config/fonto-manifest.json
|
|
103
|
-
Object.entries(rootSchemas).forEach(([
|
|
104
|
+
Object.entries(rootSchemas).forEach(([xsdPath, obj]) => {
|
|
104
105
|
const pckPath = 'packages/' + obj.packageName;
|
|
105
106
|
const pckFontoManifest = fs.readJsonSync(pckPath + '/fonto-manifest.json', {throws: false}) || {dependencies: {}};
|
|
106
107
|
pckFontoManifest.dependencies['sx-module'] = 'packages/sx-module';
|
|
107
108
|
fs.outputJsonSync(pckPath + '/fonto-manifest.json', pckFontoManifest, {spaces: 2});
|
|
108
109
|
_write(`${pckPath}/fonto-manifest.json`);
|
|
109
110
|
fontoManifest.dependencies[obj.packageName] = pckPath;
|
|
111
|
+
jsonPaths.push(`${pckPath}/src/assets/schemas/${obj.packageName}.json`);
|
|
110
112
|
});
|
|
111
113
|
|
|
112
114
|
fs.outputJsonSync('config/fonto-manifest.json', fontoManifest, {spaces: 2});
|
|
@@ -119,6 +121,13 @@ module.exports = {
|
|
|
119
121
|
_write('config/schemaExperienceResolver.js');
|
|
120
122
|
|
|
121
123
|
_write();
|
|
124
|
+
_info('Copying schema json files to build folders:');
|
|
125
|
+
// deploy-watch copies schema's to server directly, so update local builds to keep integrity
|
|
126
|
+
jsonPaths.forEach(jsonPath => {
|
|
127
|
+
fs.copySync(jsonPath, 'dev/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
|
|
128
|
+
fs.copySync(jsonPath, 'dist/assets/schemas/' + jsonPath.match(/[^//]*$/)[0]);
|
|
129
|
+
})
|
|
130
|
+
_write('Done.\n');
|
|
122
131
|
})
|
|
123
132
|
;
|
|
124
133
|
},
|
|
@@ -133,7 +142,7 @@ module.exports = {
|
|
|
133
142
|
let ignoreElements = [];
|
|
134
143
|
fs.readdirSync(tdiXsdPath).forEach(filename => {
|
|
135
144
|
const file = fs.readFileSync(tdiXsdPath + filename, {encoding: 'UTF-8'});
|
|
136
|
-
ignoreElements.push(...file.match(/(?<=xs:element name=")[^"]+(?=")/g));
|
|
145
|
+
ignoreElements.push(...(file.match(/(?<=xs:element name=")[^"]+(?=")/g)||[]));
|
|
137
146
|
});
|
|
138
147
|
ignoreElements = [...new Set(ignoreElements)]; // remove duplicates
|
|
139
148
|
|
|
@@ -169,6 +178,54 @@ module.exports = {
|
|
|
169
178
|
);
|
|
170
179
|
},
|
|
171
180
|
|
|
181
|
+
attributes () {
|
|
182
|
+
_info('Attributes requiring custom configuration:');
|
|
183
|
+
|
|
184
|
+
const findAttributes = ({rootSchemas, tdiXsdPath}) => { // cannot use variables from outside this function
|
|
185
|
+
const {execSync} = require('child_process'), fs = require('fs');
|
|
186
|
+
|
|
187
|
+
// get all attributes defined in default schema
|
|
188
|
+
let ignoreAttributes = [];
|
|
189
|
+
fs.readdirSync(tdiXsdPath).forEach(filename => {
|
|
190
|
+
const file = fs.readFileSync(tdiXsdPath + filename, {encoding: 'UTF-8'});
|
|
191
|
+
ignoreAttributes.push(...(file.match(/(?<=xs:attribute name=")[^"]+(?=")/g)||[]));
|
|
192
|
+
});
|
|
193
|
+
ignoreAttributes = [...new Set(ignoreAttributes)]; // remove duplicates
|
|
194
|
+
|
|
195
|
+
// execute "fdt attributes" for each schema package, ignore default attributes, and combine results
|
|
196
|
+
const schemasPerAttribute = {};
|
|
197
|
+
Object.entries(rootSchemas).forEach(([path, obj]) => {
|
|
198
|
+
const data = execSync(`fdt attributes --schema ${obj.packageName}`, {encoding: 'UTF-8'});
|
|
199
|
+
const attributes = data.replace(/^.*?Default value\s+|\s+Printed name\*.*$/gs, '').split(/\n\s+/).map(a => a.split(/\s+/)).map(a =>
|
|
200
|
+
a[0] + (a[2]=='required' ? ' (required)' : '') + (a[3]=='-' ? ' (no default)' : '')
|
|
201
|
+
);
|
|
202
|
+
const customAttributes = [...new Set(attributes)].filter(e => e && !ignoreAttributes.includes(e.replace(/ .*/, '')));
|
|
203
|
+
|
|
204
|
+
customAttributes.forEach(e => {
|
|
205
|
+
if (schemasPerAttribute[e]) schemasPerAttribute[e] = [...schemasPerAttribute[e], obj.packageName];
|
|
206
|
+
else schemasPerAttribute[e] = [obj.packageName];
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const result = [];
|
|
211
|
+
Object.entries(schemasPerAttribute).forEach(([e, s]) => result.push([e, s])); // convert object to array
|
|
212
|
+
return result[0] ? result : 'No results.';
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
return wws(
|
|
216
|
+
'searching',
|
|
217
|
+
findAttributes,
|
|
218
|
+
{
|
|
219
|
+
rootSchemas: fs.readJsonSync('../schema/fonto.json').rootSchemas,
|
|
220
|
+
tdiXsdPath: path.join(_paths.repo, _paths.tdi, 'src/config/cmscustom/[customer]/[project]/schema/xsd/')
|
|
221
|
+
},
|
|
222
|
+
result => {
|
|
223
|
+
if (Array.isArray(result)) result.forEach(([e, s]) => _write(e, s, '\n'));
|
|
224
|
+
else _write(result, '\n');
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
},
|
|
228
|
+
|
|
172
229
|
localize () {
|
|
173
230
|
const templateFile = 'messages-template-packages.json';
|
|
174
231
|
const messagesFile = 'packages/localization/src/messages.nl.json';
|
|
@@ -31,6 +31,7 @@ module.exports = function fonto (argv) {
|
|
|
31
31
|
.then(argv.init && (()=>commands.init(argv.init)))
|
|
32
32
|
.then(argv.schema && commands.schema)
|
|
33
33
|
.then(argv.elements && commands.elements)
|
|
34
|
+
.then(argv.attributes && commands.attributes)
|
|
34
35
|
.then(argv.localize && commands.localize)
|
|
35
36
|
.then(argv.build && commands.build)
|
|
36
37
|
.then(argv.run && commands.run)
|
|
@@ -2,10 +2,10 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const globby = require('globby');
|
|
3
3
|
const minimatch = require('minimatch');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const rif
|
|
5
|
+
const rif = require('replace-in-file');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
const getPaths
|
|
8
|
+
const getPaths = (search, filter) =>
|
|
9
9
|
globby
|
|
10
10
|
.sync(search, {dot: true, ignore: [_paths.tdi + '/**','**/cmscustom/tdi/**']})
|
|
11
11
|
.filter(p => !filter || minimatch(p, filter)
|
|
@@ -47,9 +47,11 @@ module.exports = function steps (step, dry, filter) {
|
|
|
47
47
|
r.to = r.fromtoPairs.map(p => p[1]);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
let filesModCount = 0;
|
|
51
|
+
for (let i=0; i<20 && !dry && r.files[0]; i++) { // execute repeatedly for modified files only (with safety limit of 20)
|
|
52
|
+
r.files = rif.sync(r).filter(f => f.hasChanged).map(f => f.file);
|
|
53
|
+
if (i==0) filesModCount = r.files.length; // save count only after first run (after this only subsets are processed)
|
|
54
|
+
}
|
|
53
55
|
|
|
54
56
|
_write('Files modified:', filesModCount);
|
|
55
57
|
});
|