@tangelo/tangelo-configuration-toolkit 1.19.0 → 1.20.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/index.js CHANGED
@@ -92,13 +92,13 @@ global._isPre51 = () => !fs.existsSync(path.join(_paths.repo, _paths.tdi, 'src')
92
92
 
93
93
  global._modulesTdi = {
94
94
  absolutePathTdi: path.join(_paths.repo, _paths.tdi),
95
- ensureDepsUpToDate() {
95
+ ensureDepsUpToDate(message) {
96
96
  if (this.depsUpToDate) return;
97
97
  try {
98
- _info('Checking installed dependencies in submodule');
98
+ if (message) _info('Checking installed dependencies in submodule');
99
99
  execSync('npm list', {cwd: this.absolutePathTdi, stdio: 'ignore'});
100
100
  } catch (e) {
101
- _info('Updating dependencies in submodule');
101
+ if (message) _info('Updating dependencies in submodule');
102
102
  execSync('npm update', {cwd: this.absolutePathTdi, stdio: 'ignore'});
103
103
  }
104
104
  this.depsUpToDate = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangelo/tangelo-configuration-toolkit",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "engines": {
5
5
  "node": ">=14.0.0"
6
6
  },
@@ -46,10 +46,11 @@
46
46
  "p-limit": "^3.1.0",
47
47
  "replace-in-file": "^6.3.2",
48
48
  "sass": "^1.43.5",
49
- "saxon-js": "^2.3.0",
49
+ "saxon-js": "^2.5.0",
50
50
  "ssh2-sftp-client": "^9.1.0",
51
51
  "through2": "^4.0.2",
52
52
  "tiny-lr": "^2.0.0",
53
+ "xml2js": "^0.6.2",
53
54
  "yargs": "^17.7.2"
54
55
  },
55
56
  "repository": {
@@ -14,7 +14,7 @@ module.exports = function(ftpConfig, remotedir) {
14
14
 
15
15
  function transform (file, _, cb) {
16
16
  if (file.isStream()) return cb(new Error('Streaming not supported.'));
17
- if (file.stat.isDirectory()) return cb();
17
+ if (file.stat?.isDirectory()) return cb();
18
18
 
19
19
  file.destination = path.join(remotedir, file.relative).toFws;
20
20
  files.push(file); // collect all files in array
@@ -0,0 +1,40 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const TclConfig = require('./tcl-config');
4
+ const through2 = require('through2');
5
+ const Vinyl = require('vinyl');
6
+
7
+
8
+ function createAddToStreamFn(stream) {
9
+ return (path, content) => stream.push(new Vinyl({
10
+ path: path,
11
+ contents: Buffer.from(content)
12
+ }));
13
+ }
14
+
15
+ module.exports = function() {
16
+ const tclFileDirs = [];
17
+
18
+ return through2.obj(
19
+
20
+ function transform (file, _, cb) {
21
+ if (file.isStream()) return cb(new Error('Streaming not supported.'));
22
+
23
+ if (file.extname == '.tcl') tclFileDirs.push(path.dirname(file.relative));
24
+ return cb(null, file);
25
+ },
26
+
27
+ function flush(cb) {
28
+ for (const tclFileDir of tclFileDirs) {
29
+ const tclConfig = new TclConfig(tclFileDir, createAddToStreamFn(this));
30
+ tclConfig.outputJson(path.resolve(tclFileDir, 'fonto/assets'));
31
+ tclConfig.outputCss(path.resolve(tclFileDir, 'fonto'));
32
+ const esefCssDir = path.resolve(tclFileDir, 'export/esef/esef_out/css');
33
+ if (fs.existsSync(esefCssDir)) tclConfig.outputCss(esefCssDir);
34
+ }
35
+ cb();
36
+ }
37
+
38
+ )
39
+ .resume(); // required for triggering 'end' event
40
+ };
@@ -0,0 +1,101 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const sass = require('sass');
4
+ const SaxonJS = require('saxon-js');
5
+
6
+
7
+ module.exports = class TclConfig {
8
+
9
+ static #SEF_FILE_PATH = 'tcl/configToJson.sef.json';
10
+ static #JSON_TO_SCSS_FILE_PATH = 'tcl/configJsonToScss';
11
+ static #TCL_FILE_NAME = 'project.tcl';
12
+ static #TCL_JSON_FILE_NAME = 'tcl-config.json';
13
+ static #TCL_CSS_FILE_NAME = 'tcl-styles.css';
14
+ static #FONTO_HTML_FILE_NAME = 'index.html';
15
+
16
+ static #sefFile;
17
+ static #jsonToScssFile;
18
+
19
+ static #transformTclConfigToJson(tclFilePathRel) {
20
+ this.#sefFile ??= _modulesTdi.require(this.#SEF_FILE_PATH, {message: false});
21
+
22
+ const messages = [` Warnings from transformation of ${tclFilePathRel}`];
23
+ const transformation = SaxonJS.transform({
24
+ stylesheetText: JSON.stringify(this.#sefFile),
25
+ sourceFileName: tclFilePathRel,
26
+ destination: 'raw',
27
+ deliverMessage(messageNode) {
28
+ messages.push(messageNode.textContent);
29
+ }
30
+ });
31
+
32
+ if (messages[1]) _warn(messages.join('\n '));
33
+ return transformation.principalResult ?? _error(`No result from transformation of ${tclFilePathRel}`);
34
+ }
35
+
36
+ static #transformJsonToCss(tclFilePathRel, json, moduleName) {
37
+ this.#jsonToScssFile ??= _modulesTdi.require(this.#JSON_TO_SCSS_FILE_PATH, {message: false});
38
+ const scss = this.#jsonToScssFile(json.project, moduleName);
39
+ const url = new URL(path.join('file://', path.resolve(tclFilePathRel)));
40
+ return sass.compileString(scss, {url, style: 'compressed'}).css;
41
+ }
42
+
43
+ static #addCssImportToHtml(dir) {
44
+ const filepath = path.join(dir, this.#FONTO_HTML_FILE_NAME);
45
+
46
+ if (fs.existsSync(filepath)) {
47
+ const html = fs.readFileSync(filepath).toString();
48
+
49
+ if (!RegExp(`<link[^>]*${this.#TCL_CSS_FILE_NAME}[^>]*>`).test(html)) {
50
+ const newHtml = html.replace(/((\s+<link.*")[^"]+\.css(.*))/, `$1$2${this.#TCL_CSS_FILE_NAME}$3`);
51
+ fs.outputFileSync(filepath, newHtml);
52
+ }
53
+ }
54
+ }
55
+
56
+ #outputFn;
57
+ #doModifyFontoHtml;
58
+ #tclFilePathRel;
59
+ #tclFileExists;
60
+ #resultJson;
61
+ #resultCss = {};
62
+
63
+ constructor(tclFileRelDir, addToStreamFn) {
64
+ this.#tclFilePathRel = path.join(tclFileRelDir, TclConfig.#TCL_FILE_NAME);
65
+ this.#tclFileExists = fs.existsSync(this.#tclFilePathRel);
66
+ this.#outputFn = addToStreamFn ?? fs.outputFileSync;
67
+ this.#doModifyFontoHtml = !addToStreamFn;
68
+ }
69
+
70
+ #getJson() {
71
+ return this.#resultJson ??= TclConfig.#transformTclConfigToJson(this.#tclFilePathRel);
72
+ }
73
+
74
+ #getCss(moduleName) {
75
+ return this.#resultCss[moduleName] ??= TclConfig.#transformJsonToCss(this.#tclFilePathRel, this.#getJson(), moduleName);
76
+ }
77
+
78
+ outputJson(dir) {
79
+ if (this.#tclFileExists) {
80
+ const filepath = path.join(dir, TclConfig.#TCL_JSON_FILE_NAME);
81
+ this.#outputFn(filepath, JSON.stringify(this.#getJson()));
82
+ }
83
+ return this;
84
+ }
85
+
86
+ outputCss(dir) {
87
+ if (this.#tclFileExists) {
88
+ const filepath = path.join(dir, TclConfig.#TCL_CSS_FILE_NAME);
89
+ const moduleName = dir.includes('esef') ? 'ESEF' : 'FONTO';
90
+ this.#outputFn(filepath, this.#getCss(moduleName));
91
+ this.modifyFontoHtml(dir);
92
+ }
93
+ return this;
94
+ }
95
+
96
+ modifyFontoHtml(dir) {
97
+ if (this.#tclFileExists && this.#doModifyFontoHtml) TclConfig.#addCssImportToHtml(dir);
98
+ return this;
99
+ }
100
+
101
+ };
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
4
4
  const globby = require('globby');
5
5
  const gulp = require('gulp');
6
6
  const {NodeSSH} = require('node-ssh');
7
+ const g_tcl = require('../../lib/gulp-tcl-config');
7
8
  const through2 = require('through2');
8
9
  const {spawnSync} = require('child_process');
9
10
 
@@ -160,6 +161,7 @@ const transfer = (paths, lrServer) => {
160
161
  .pipe(xpsF)
161
162
  .pipe(g_resolveIncl())
162
163
  .pipe(xpsF.restore)
164
+ .pipe(g_tcl())
163
165
  .pipe(jsF)
164
166
  .pipe(g_sourcemaps.init())
165
167
  .pipe(g_babel({presets: [[babel_pe, {modules: false}]], comments: false, minified: true})) // function must be executed here, otherwise second execution during watch fails
@@ -1,12 +1,13 @@
1
- const del = require('del');
2
- const {exec} = require('child_process');
3
- const fs = require('fs-extra');
4
- const globby = require('globby');
5
- const gulp = require('gulp');
6
- const g_print = require('gulp-print');
7
- const path = require('path');
8
- const sass = require('gulp-sass')(require('sass'));
9
- const wws = require('../../lib/worker-with-spinner');
1
+ const del = require('del');
2
+ const {exec} = require('child_process');
3
+ const fs = require('fs-extra');
4
+ const globby = require('globby');
5
+ const gulp = require('gulp');
6
+ const g_print = require('gulp-print');
7
+ const path = require('path');
8
+ const sass = require('gulp-sass')(require('sass'));
9
+ const TclConfig = require('../../lib/tcl-config');
10
+ const wws = require('../../lib/worker-with-spinner');
10
11
 
11
12
 
12
13
  g_print.setLogFunction((filepath) => _write(filepath.nostyle));
@@ -261,6 +262,11 @@ module.exports = {
261
262
  _write('Done.\n');
262
263
  })
263
264
  .then(() => cmdExec(`${fdt} editor build`))
265
+ .then(() => {
266
+ _info('Read project configuration and create json and css for Fonto:');
267
+ new TclConfig('..').outputJson('dist/assets').outputCss('dist');
268
+ _write('Done.\n');
269
+ })
264
270
  .then(() => [fdt])
265
271
  ;
266
272
  },
@@ -268,14 +274,27 @@ module.exports = {
268
274
  run ([fdt]) {
269
275
  return compileSass()
270
276
  .then(() => {
271
- _info('Starting sass watch:');
272
- gulp.watch('**/*.scss')
277
+ _info('Read project configuration and create json and css for Fonto:');
278
+ new TclConfig('..').outputJson('dev/assets').outputCss('dev');
279
+ _write('Done.\n');
280
+ })
281
+ .then(() => {
282
+ _info('Starting watch for tcl and sass files:');
283
+ gulp.watch(['**/*.scss', '../*.tcl', 'dev/index.html'])
273
284
  .on('all', (event, filepath) => {
274
285
  _write(event + ':', filepath);
275
- gulp.src('**/*.scss')
276
- .pipe(sass().on('error', sass.logError))
277
- .pipe(gulp.dest('.'))
278
- ;
286
+ if (filepath.endsWith('.scss')) {
287
+ gulp.src('**/*.scss')
288
+ .pipe(sass().on('error', sass.logError))
289
+ .pipe(gulp.dest('.'))
290
+ ;
291
+ }
292
+ else if (filepath.endsWith('.html')) {
293
+ new TclConfig('..').modifyFontoHtml('dev');
294
+ }
295
+ else if (filepath.endsWith('.tcl')) {
296
+ new TclConfig('..').outputJson('dev/assets').outputCss('dev');
297
+ }
279
298
  });
280
299
  _write('Done.\n');
281
300
  })
@@ -71,9 +71,9 @@ function init () {
71
71
  ])
72
72
  .then(() => {
73
73
  _info(`Next steps:
74
- 1. Go to https://bitbucket.org/repo/create?workspace=tangelosoftware and create a repository named "${path.basename(process.cwd()).replace(/\W/, '-')}", with options for including README/.gitignore disabled.
75
- 2. Open this folder in Sourcetree (ctrl+O), and push master branch to origin.
76
- `.replace(/^\s{8}/gm, ''));
74
+ 1. Go to https://bitbucket.org/repo/create?workspace=tangelosoftware and create a repository named "${path.basename(process.cwd()).replace(/\W/, '-')}", with options for including README/.gitignore disabled.
75
+ 2. Open this folder in Sourcetree (ctrl+O), and push master branch to origin.
76
+ `.replace(/^\s{8}/gm, ''));
77
77
  });
78
78
  });
79
79
  }
@@ -101,7 +101,7 @@ function clone ({clone: repoName}) {
101
101
  // Change directory for the next commands, it should have the same name as the clone argument from commandline at this point
102
102
  process.chdir('./' + repoName);
103
103
  cmdExec([
104
- // Retrieve TDI submodule for this client
104
+ // Retrieve TDI submodule for this client
105
105
  ['git submodule update --init', 'Fetch submodules such as TDI'],
106
106
  // Create symlinks for TDI
107
107
  ['tct b -s', 'Create TDI symlinks'],