@tangelo/tangelo-configuration-toolkit 1.17.1 → 1.19.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/README.md CHANGED
@@ -60,3 +60,35 @@ The `build -x` commands set projects transformation scenarios and masterfiles in
60
60
  - Will try to preserve manually added entries in the transformation scenarios and masterfiles
61
61
  - Will remove non existing masterfiles or masterfiles that start with a '_'
62
62
  - No masterfiles / scenarios will be added if their path match with oXygens hidden directory patterns
63
+
64
+
65
+ ## Debug
66
+
67
+ Save this in the root of your local clone as `tct-dev.cmd`:
68
+
69
+ ```
70
+ @ECHO off
71
+ SETLOCAL
72
+ CALL :find_dp0
73
+
74
+ IF EXIST "%dp0%\node.exe" (
75
+ SET "_prog=%dp0%\node.exe"
76
+ ) ELSE (
77
+ SET "_prog=node"
78
+ SET PATHEXT=%PATHEXT:;.JS;=;%
79
+ )
80
+
81
+ "%_prog%" "%dp0%\index.js" %*
82
+ ENDLOCAL
83
+ EXIT /b %errorlevel%
84
+ :find_dp0
85
+ SET dp0=%~dp0
86
+ EXIT
87
+ ```
88
+
89
+ Then:
90
+
91
+ - open a 'Javascript Debug Terminal' in VSCode
92
+ - jump to a customer folder ( you can use `tan-cust` for this)
93
+ - set a breakpoint
94
+ - type (for instance): `tct-dev d -c`
package/index.js CHANGED
@@ -1,8 +1,7 @@
1
- require('./src/lib/style-string-getters');
1
+ global._appStartTime = new Date();
2
2
 
3
- String.prototype.toFws = function(){
4
- return this.replace(/\\/g, '/');
5
- };
3
+ require('./src/lib/set-string-getters.js');
4
+ require('./src/lib/set-global-functions.js');
6
5
 
7
6
 
8
7
  const {execSync} = require('child_process');
@@ -12,48 +11,13 @@ const homedir = require('os').homedir();
12
11
  const path = require('path');
13
12
 
14
13
  const execGitCommand = require('./src/lib/exec-git-command');
14
+ const memoize = require('./src/lib/memoize');
15
15
 
16
16
 
17
- const appname = 'tangelo-configuration-toolkit';
18
-
19
-
20
- global._write = (...msg) => {
21
- msg = msg.map(m => typeof m == 'object' ? JSON.stringify(m, null, 2).cyan : m);
22
- console.log(msg.join(' ').replace(/^/gm, ' ')); // indent each line
23
- };
24
-
25
- global._info = (msg, time = false) => {
26
- if (time) {
27
- const tzDiff = new Date().getTimezoneOffset() * 60000;
28
- const time = new Date(Date.now() - tzDiff).toISOString().match(/\d\d:\d\d:\d\d/)[0];
29
- msg = `[${time}] ${msg}`;
30
- }
31
- console.log(msg.lgreen);
32
- };
17
+ global._package = require('./package.json');
33
18
 
34
- global._warn = msg => {
35
- console.log(msg.lyellow);
36
- };
37
19
 
38
- global._error = msg => {
39
- console.log(msg.red, '\n');
40
- process.exit();
41
- };
42
-
43
- global._perf = t1 => {
44
- const t2 = new Date();
45
- console.log(`\nExecution time: ${t2 - t1}ms`.blue);
46
- };
47
-
48
- global._formatDate = date =>
49
- date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'})
50
- ;
51
-
52
-
53
- global._packages = {
54
- TCT: {name: '@tangelo/tangelo-configuration-toolkit', version: require('./package.json')?.version},
55
- FDT: {name: '@fontoxml/fontoxml-development-tools'}
56
- };
20
+ global._devmode = !__dirname.includes('node_modules');
57
21
 
58
22
 
59
23
  global._paths = {
@@ -65,8 +29,7 @@ global._paths = {
65
29
  };
66
30
  _paths.appdata = path.join(_paths.apphome, 'appdata.json');
67
31
  _paths.appconfig = path.join(_paths.apphome, 'appconfig.json');
68
- _paths.repoconfig = path.join(_paths.repo, appname+'-repoconfig.json');
69
- _paths.apply = process.cwd().replace(_paths.repo, '').substr(1);
32
+ _paths.apply = process.cwd().replace(_paths.repo, '').slice(1);
70
33
 
71
34
 
72
35
  global._appdata = fs.readJsonSync(_paths.appdata, {throws: false}) || {};
@@ -76,15 +39,6 @@ if (!_appdata.npmPath) {
76
39
  }
77
40
 
78
41
 
79
- if (!fs.existsSync(_paths.appconfig)) { // try to find old appconfig (TCT-162 => remove code block in next version)
80
- fs.ensureDirSync(_paths.apphome);
81
- const oldPathAppconfig = findUp.sync(appname+'-appconfig.json');
82
- if (oldPathAppconfig) {
83
- fs.renameSync(oldPathAppconfig, _paths.appconfig);
84
- _info(`${appname}-appconfig.json moved to ${_paths.apphome}`);
85
- }
86
- }
87
-
88
42
  global._appconfig = { // default appconfig if file not found
89
43
  'sharedConfigPath': path.join(homedir, 'Dropbox (Tangelo Software)/Product Distribution/tooling'),
90
44
  'servers': [],
@@ -105,7 +59,11 @@ catch({code, message}) {
105
59
  }
106
60
 
107
61
 
108
- _appconfig.sharedConfigPath = path.resolve(_paths.appconfig, '..', _appconfig.sharedConfigPath || '', appname+'-appconfig.json');
62
+ global._repoconfig = require('./src/lib/get-repoconfig')(_paths.repo);
63
+
64
+
65
+ const filenameSC = _package.name.split('/').pop() + '-appconfig.json';
66
+ _appconfig.sharedConfigPath = path.resolve(_paths.appconfig, '..', _appconfig.sharedConfigPath || '', filenameSC);
109
67
  _appconfig.shared = fs.readJsonSync(_appconfig.sharedConfigPath, {throws: false}) || {};
110
68
 
111
69
 
@@ -114,49 +72,20 @@ global._git = {
114
72
  if (!_appdata.gitUser) _appdata._update({gitUser: execGitCommand(`config --get user.email`, _paths.repo)});
115
73
  return _appdata.gitUser;
116
74
  },
117
- commitLocal (clearcache) {
118
- if (clearcache) delete this.cache;
119
- this.cache ??= execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, _paths.repo, ['branch', 'hash', 'date']);
120
- return this.cache;
121
- },
122
- commitRemote () {
123
- this.cache ??= execGitCommand('log -1 --format=%cd --date=iso-strict origin/'+_git.commitLocal().branch, _paths.repo, ['date']);
124
- return this.cache;
125
- },
75
+ commitLocal: memoize(() => execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, _paths.repo, ['branch', 'hash', 'date'])),
76
+ commitRemote: memoize(() => execGitCommand('log -1 --format=%cd --date=iso-strict origin/' + _git.commitLocal().branch, _paths.repo, ['date'])),
126
77
  commitTdi: {
127
- local (clearcache) {
128
- if (clearcache) delete this.cache;
129
- this.cache ??= execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, path.join(_paths.repo, _paths.tdi), ['tags', 'hash', 'date']);
130
- return this.cache;
131
- },
132
- after (commitHash) {
133
- this['cache-'+commitHash] ??= execGitCommand(`merge-base --is-ancestor ${commitHash} ${_git.commitTdi.local().hash}`, path.join(_paths.repo, _paths.tdi), null, 0);
134
- return this['cache-'+commitHash];
135
- },
78
+ local: memoize(() => execGitCommand(`log -1 --format=%D;%H;%cd --date=iso-strict`, path.join(_paths.repo, _paths.tdi), ['tags', 'hash', 'date'])),
79
+ after: memoize(commitHash => execGitCommand(`merge-base --is-ancestor ${commitHash} ${_git.commitTdi.local().hash}`, path.join(_paths.repo, _paths.tdi), null, 0)),
136
80
  fontoVersions: [ // latest commits first
137
81
  {commitHash: 'e599766', regex: /^7\.1[45]\./},
138
82
  {commitHash: '77b8ea9', regex: /^7\.14\./}, // 7.14.x
139
83
  {commitHash: '8066c44', regex: /^7\.13\./}, // 7.13.x
140
84
  {commitHash: 'a2b2d4e', regex: /^7\.12\./} // 7.12.x
141
- ],
142
- stopUsingRepoconfigFile: '1f12bff' // release/5.1 10-05-2021
85
+ ]
143
86
  }
144
87
  };
145
88
 
146
-
147
- if (_git.commitTdi.after(_git.commitTdi.stopUsingRepoconfigFile)) {
148
- global._repoconfig = require('./src/lib/get-repoconfig')(_paths.repo);
149
- }
150
- else {
151
- try { global._repoconfig = fs.existsSync(_paths.repoconfig) && fs.readJsonSync(_paths.repoconfig) || {}; }
152
- catch ({message}) { _error('Error in '+message); }
153
- global._repoconfig.update = obj => {
154
- global._repoconfig = Object.assign(_repoconfig, obj);
155
- fs.writeJsonSync(_paths.repoconfig, _repoconfig, {spaces: 2});
156
- };
157
- }
158
-
159
-
160
89
  global._tdiSubmoduleExists = () => fs.existsSync(path.join(_paths.repo, _paths.tdi));
161
90
  global._isPre42 = () => fs.existsSync(path.join(_paths.repo, _paths.tdi, 'create_new_project')); // folder changed in 4.2
162
91
  global._isPre51 = () => !fs.existsSync(path.join(_paths.repo, _paths.tdi, 'src')); // folder changed in 5.1 (check new folder because old one could still exist after branch switch)
@@ -174,18 +103,21 @@ global._modulesTdi = {
174
103
  }
175
104
  this.depsUpToDate = true;
176
105
  },
177
- require(module) {
178
- this.ensureDepsUpToDate();
179
- _info(`Loading ${path.join(_paths.tdi, 'tct', module)}\n`);
106
+ require(module, {throws = true, message = true} = {}) {
107
+ if (path.extname(module) !== '.json') this.ensureDepsUpToDate();
108
+ if (message) _info(`Loading ${path.join(_paths.tdi, 'tct', module)}\n`);
180
109
  try {
181
110
  return require(path.join(this.absolutePathTdi, 'tct', module));
182
111
  }
183
112
  catch (e) {
184
- _error('Module could not be loaded');
113
+ if (throws) _error('Module could not be loaded: ' + module);
114
+ else return undefined;
185
115
  }
186
116
  }
187
117
  };
188
118
 
119
+ global._settingsTdi = memoize(() => Object.assign(_package.settingsTdiDefault, _modulesTdi.require('settings.json', {throws: false, message: false}) ?? {}));
120
+
189
121
 
190
122
  process.on('beforeExit', () => {
191
123
  _write(); // print empty line before and after update check
@@ -198,7 +130,9 @@ process.on('beforeExit', () => {
198
130
  fs.writeJsonSync(_paths.appdata, _appdata, {spaces: 2});
199
131
  }
200
132
 
133
+ if (_devmode) _perf(_appStartTime); // output execution time in dev mode
134
+
201
135
  });
202
136
 
203
137
 
204
- require('./src/cli.js')();
138
+ require('./src/cli.js')();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangelo/tangelo-configuration-toolkit",
3
- "version": "1.17.1",
3
+ "version": "1.19.0",
4
4
  "engines": {
5
5
  "node": ">=14.0.0"
6
6
  },
@@ -56,5 +56,9 @@
56
56
  "type": "git",
57
57
  "url": "git+ssh://git@bitbucket.org/tangelosoftware/tangelo-configuration-toolkit.git"
58
58
  },
59
- "homepage": "https://bitbucket.org/tangelosoftware/tangelo-configuration-toolkit#readme"
59
+ "homepage": "https://bitbucket.org/tangelosoftware/tangelo-configuration-toolkit#readme",
60
+ "settingsTdiDefault": {
61
+ "#": "Defaults for tangelo-default-implementation/tct/settings.json",
62
+ "transpileToES5": true
63
+ }
60
64
  }
package/src/cli.js CHANGED
@@ -6,7 +6,7 @@ module.exports = function cli () {
6
6
  _write();
7
7
 
8
8
  const txtTitle = 'Tangelo Configuration Toolkit'.bold.underline.cyan;
9
- const txtVersion = `v${_packages.TCT.version}`.lblack;
9
+ const txtVersion = `v${_package.version}`.lblack;
10
10
 
11
11
  yargs
12
12
  .scriptName('tct')
@@ -34,7 +34,6 @@ module.exports = function cli () {
34
34
  init: {alias: 'i', desc: 'Create repository content structure', conflicts: ['p', 's', 'c']},
35
35
  project: {alias: 'p', desc: 'Create project configuration', conflicts: ['i', 's', 'c']},
36
36
  symlinks: {alias: 's', desc: 'Recreate symlinks to TDI', conflicts: ['p', 'i', 'c']},
37
- config: {alias: 'c', desc: 'Create repo-config file', conflicts: ['p', 'i', 's'], hidden: true},
38
37
  oxygen: {alias: 'x', desc: 'Create or update oXygen project file (.xpr)', conflicts: ['p', 'i', 'c']}
39
38
  },
40
39
  handler: require('./modules/build')
@@ -76,8 +75,9 @@ module.exports = function cli () {
76
75
  init: {alias: 'i', desc: 'Initialize repository and add submodule', conflicts: ['r', 'c', 'u']},
77
76
  reset: {alias: 'r', desc: 'Reset repository to last commit', conflicts: ['i', 'c', 'u']},
78
77
  clone: {alias: 'c', desc: 'Clone a client repository and do basic setup', conflicts: ['i', 'r', 'u']},
79
- update: {alias: 'u', desc: 'Update repository or TDI submodule', conflicts: ['i', 'r', 'c']},
80
- branch: {alias: 'b', desc: 'Pass tdi release branch, e.g. "5.4"', conflicts: ['i', 'r', 'c']}
78
+ 'update-repo': {alias: 'ur', desc: 'Update repository', conflicts: ['i', 'r', 'c']},
79
+ 'update-submodule': {alias: 'us', desc: 'Update TDI submodule, optionally pass release branch (without "release/")', conflicts: ['i', 'r', 'c']},
80
+ dates: {alias: 'd', desc: '[hidden] Use i.c.w. update-submodule, pass 2 dates in format yyyy-mm-dd', conflicts: ['i', 'r', 'c'], implies: 'update-submodule', requiresArg: true, array: true, hidden: !_devmode}
81
81
  },
82
82
  handler: require('./modules/git')
83
83
  })
@@ -123,9 +123,9 @@ module.exports = function cli () {
123
123
  ['$0 deploy --copy --server demo', 'Copy files to server "demo"'],
124
124
  ['$0 d -c -s demo', 'Same as above'],
125
125
  ['$0 f -sb && $0 d -c', 'Compile schema and build Fonto, then deploy to default server'],
126
- ['$0 git --update', 'Pull git repository and submodule to latest repository commit'],
127
- ['$0 git --update tdi', 'Update TDI submodule to latest within current TDI branch'],
128
- ['$0 git --update tdi --branch 5.4', 'Update TDI submodule to latest in specified branch']
126
+ ['$0 git --update-repo', 'Pull git repository and submodule to latest repository commit'],
127
+ ['$0 git --update-submodule', 'Update TDI submodule to latest within current TDI branch'],
128
+ ['$0 git --update-submodule 5.4', 'Update TDI submodule to latest in specified branch']
129
129
  ])
130
130
  .check((argv, options) => {
131
131
  const nonDefaultOptions = Object.keys(options.key).filter(o => !Object.keys(options.default).includes(o));
@@ -133,7 +133,7 @@ module.exports = function cli () {
133
133
  else throw new Error('Pass a non-default option');
134
134
  })
135
135
  .strict()
136
- .wrap(100)
136
+ .wrap(120)
137
137
  .parse()
138
138
  ;
139
139
 
@@ -4,11 +4,9 @@ const globby = require('globby');
4
4
 
5
5
  module.exports = function getRepoconfig(repoPath) {
6
6
 
7
- const repoconfig = [];
8
-
9
- globby
7
+ return globby
10
8
  .sync('database/config/**/txd_document_types.sql', {cwd: repoPath, absolute: true})
11
- .forEach(p => {
9
+ .map(p => {
12
10
  const dtSqlInsert = fs.readFileSync(p).toString().match(/select(.*?)from/s)[1];
13
11
  const ntSqlInsert = fs.readFileSync(p.replace('txd_document_types', 'txd_node_types')).toString().match(/select(.*?)from/s)[1];
14
12
 
@@ -21,7 +19,7 @@ module.exports = function getRepoconfig(repoPath) {
21
19
  const dnRegex = [path_cmscustom[0].replace(/[_'"]/g, '.'), path_dbconfig[0].replace(/[_'"]/g, '.')].sort((a, b) => b.length - a.length).join('|');
22
20
  const customer_name = (dtDisplayName.match(RegExp(dnRegex, 'i')) || dtDisplayName.split(/ (.+)/))[0];
23
21
 
24
- repoconfig.push({
22
+ return {
25
23
  customer_name,
26
24
  customer_abbr: ntName.split('_')[0],
27
25
  project_name: dtDisplayName.split(RegExp(customer_name.replace(/(\W)/g, '\\$1')))[1].trim() || '',
@@ -29,9 +27,7 @@ module.exports = function getRepoconfig(repoPath) {
29
27
  path_cmscustom,
30
28
  path_dbconfig,
31
29
  id_range: dtSqlInsert.match(/(\d+)\d{3} id/)[1]
32
- });
30
+ };
33
31
  });
34
32
 
35
- return repoconfig;
36
-
37
33
  };
@@ -2,22 +2,24 @@ const execGitCommand = require('./exec-git-command');
2
2
  const path = require('path');
3
3
 
4
4
  module.exports = function getTdiBranch(toBranchName) {
5
+ const tdiPath = path.join(_paths.repo, _paths.tdi);
5
6
  const tdiBranch = {};
7
+
6
8
  // Fetch all
7
9
  _info(`Fetch TDI submodule`);
8
- const cmdFetch = execGitCommand('fetch -pf --all', path.join(_paths.repo, _paths.tdi));
10
+ const cmdFetch = execGitCommand('fetch -pf --all', tdiPath);
9
11
  if (cmdFetch.error) _warn(`Fetch failed\n${cmdFetch.error}`);
10
12
 
11
13
  let toBranch;
12
14
  if (toBranchName) {
13
15
  // Check if specified branch exists; we will update to this branch
14
16
  toBranch = String(toBranchName).replace(/(?:release\/)?(\d+(?:\.[\dxt]+)*)/, `release/$1`);
15
- const branchExists = execGitCommand(`branch --remote`, path.join(_paths.repo, _paths.tdi)).match(`origin/${toBranch}`);
17
+ const branchExists = execGitCommand(`branch --remote`, tdiPath).match(`origin/${toBranch}`);
16
18
  if (!branchExists) _error(`TDI branch "${toBranch}" does not exist. Note that TCT can only update to a release branch.`);
17
19
  }
18
20
 
19
21
  // Get remote release branches containing TDI HEAD commit
20
- const releaseBranches = execGitCommand(`branch --all --contains ${_git.commitTdi.local().hash}`, path.join(_paths.repo, _paths.tdi)).match(/remotes\/origin\/release\/[^\s]+/gsm);
22
+ const releaseBranches = execGitCommand(`branch --all --contains ${_git.commitTdi.local().hash}`, tdiPath).match(/remotes\/origin\/release\/[^\s]+/gsm);
21
23
  if (!releaseBranches || releaseBranches.error) _error(`Could not retrieve TDI release branches`);
22
24
 
23
25
  // Get the first possible branch; prefer release/5.1 over release/5.2:
@@ -32,13 +34,13 @@ module.exports = function getTdiBranch(toBranchName) {
32
34
  tdiBranch.from = {name: tdiBranch.name};
33
35
  tdiBranch.name = toBranch;
34
36
 
35
- const branchHash = execGitCommand(`rev-parse origin/${toBranch}`, path.join(_paths.repo, _paths.tdi));
36
- const commonAncestorHash = execGitCommand(`merge-base ${_git.commitTdi.local().hash} ${branchHash}`, path.join(_paths.repo, _paths.tdi));
37
- const commonAncestorDate = execGitCommand(`show ${commonAncestorHash} --no-patch --format=%cd --date=iso-strict `, path.join(_paths.repo, _paths.tdi), ['date']).date;
37
+ const branchHash = execGitCommand(`rev-parse origin/${toBranch}`, tdiPath);
38
+ const commonAncestorHash = execGitCommand(`merge-base ${_git.commitTdi.local().hash} ${branchHash}`, tdiPath);
39
+ const commonAncestorDate = execGitCommand(`show ${commonAncestorHash} --no-patch --format=%cd --date=iso-strict `, tdiPath, ['date']).date;
38
40
  tdiBranch.commonAncestor = {date: new Date(commonAncestorDate)};
39
41
  }
40
42
 
41
43
  // Get number of commits behind
42
- tdiBranch.commitsBehind = execGitCommand(`rev-list HEAD...origin/${tdiBranch.name} --count`, path.join(_paths.repo, _paths.tdi));
44
+ tdiBranch.commitsBehind = execGitCommand(`rev-list HEAD...origin/${tdiBranch.name} --count`, tdiPath);
43
45
  return tdiBranch;
44
46
  };
@@ -4,15 +4,15 @@ const es = require('event-stream'), minimatch = require('minimatch'), istextorbi
4
4
 
5
5
  const execReplace = (c, s, r) => Buffer.from(s instanceof RegExp ? String(c).replace(s, r) : String(c).split(s).join(r));
6
6
 
7
- module.exports = (arr) => {
7
+ module.exports = arr => {
8
8
  return es.map((file, callback) => {
9
9
  if(file.contents instanceof Buffer) {
10
- arr.forEach(e => {
10
+ for (const e of arr) {
11
11
  // exec if no glob is passed or if glob matches, and it's a text file
12
12
  if ((!e[2] || minimatch(file.path, e[2])) && istextorbinary.isText(file.path, file)) {
13
13
  file.contents = execReplace(file.contents, e[0], e[1]);
14
14
  }
15
- });
15
+ }
16
16
  }
17
17
  callback(null, file);
18
18
  });
@@ -16,7 +16,7 @@ module.exports = function(ftpConfig, remotedir) {
16
16
  if (file.isStream()) return cb(new Error('Streaming not supported.'));
17
17
  if (file.stat.isDirectory()) return cb();
18
18
 
19
- file.destination = path.join(remotedir, file.relative).toFws();
19
+ file.destination = path.join(remotedir, file.relative).toFws;
20
20
  files.push(file); // collect all files in array
21
21
  return cb();
22
22
  },
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Memoizes a function by caching its results based on the arguments.
3
+ * @param {Function} fn - The function to be memoized.
4
+ * @returns {Function} - The memoized function.
5
+ */
6
+ module.exports = function memoize(fn) {
7
+ let cache = {};
8
+
9
+ /**
10
+ * The memoized function that caches the results of the original function based on its arguments.
11
+ * @param {...*} args - The arguments to be passed to the original function.
12
+ * @returns {*} - The result of the original function.
13
+ */
14
+ const cachedfn = (...args) => {
15
+ const key = JSON.stringify(args);
16
+ cache[key] ??= fn(...args);
17
+ return cache[key];
18
+ };
19
+
20
+ /**
21
+ * Clears the cache of the memoized function.
22
+ */
23
+ cachedfn.clear = () => {
24
+ cache = {};
25
+ };
26
+
27
+ return cachedfn;
28
+ };
@@ -2,12 +2,14 @@ const {compare} = require('compare-versions');
2
2
  const exec = require('util').promisify(require('child_process').exec);
3
3
 
4
4
 
5
+ const packages = {TCT: _package};
6
+
5
7
  const doUpdateCheck = (pkg) => (
6
- exec(`npm view -g ${_packages[pkg].name} version`)
8
+ exec(`npm view -g ${packages[pkg].name} version`)
7
9
  .then(r => {
8
10
  const versionAvailable = r.stdout.match(/([\d/.]+)/)[1];
9
- if (!_packages[pkg].version) _warn(`${pkg} is not installed! Run ` + `npm i -g ${_packages[pkg].name}`.white);
10
- else if (compare(_packages[pkg].version, versionAvailable, '<')) {
11
+ if (!packages[pkg].version) _warn(`${pkg} is not installed! Run ` + `npm i -g ${packages[pkg].name}`.white);
12
+ else if (compare(packages[pkg].version, versionAvailable, '<')) {
11
13
  _appdata._update({[`updateCheck${pkg}`]: {executed: new Date(), versionAvailable}});
12
14
  return versionAvailable;
13
15
  }
@@ -25,14 +27,14 @@ module.exports = function packageUpdateCheck () {
25
27
  checkUpdatesDone = true;
26
28
 
27
29
  ['TCT'].forEach(pkg => {
28
- const updateMsg = (va) => `| Update ${pkg} to ${va} | ` + `npm i -g ${_packages[pkg].name}`.white;
30
+ const updateMsg = (va) => `| Update ${pkg} to ${va} | ` + `npm i -g ${packages[pkg].name}`.white;
29
31
  const {versionAvailable} = _appdata[`updateCheck${pkg}`] || {};
30
32
 
31
33
  if (new Date() - new Date(_appdata[`updateCheck${pkg}`]?.executed || 0) > 1000*3600*24*1) { // check every day
32
34
  doUpdateCheck(pkg).then(r => r && _warn(updateMsg(r)));
33
35
  }
34
36
  else if (versionAvailable) {
35
- if (compare(_packages[pkg].version, versionAvailable, '<')) _warn(updateMsg(versionAvailable));
37
+ if (compare(packages[pkg].version, versionAvailable, '<')) _warn(updateMsg(versionAvailable));
36
38
  else _appdata._update({[`updateCheck${pkg}`]: {executed: new Date()}});
37
39
  }
38
40
  });
@@ -0,0 +1,24 @@
1
+ global._write = (...msg) => {
2
+ msg = msg.map(m => typeof m == 'object' ? JSON.stringify(m, null, 2).cyan : m);
3
+ console.log(msg.join(' ').replace(/^/gm, ' ')); // indent each line
4
+ };
5
+ global._info = (msg, time = false) => {
6
+ if (time) {
7
+ const tzDiff = new Date().getTimezoneOffset() * 60000;
8
+ const time = new Date(Date.now() - tzDiff).toISOString().match(/\d\d:\d\d:\d\d/)[0];
9
+ msg = `[${time}] ${msg}`;
10
+ }
11
+ console.log(msg.lgreen);
12
+ };
13
+ global._warn = msg => {
14
+ console.log(msg.lyellow);
15
+ };
16
+ global._error = msg => {
17
+ console.log(msg.red, '\n');
18
+ process.exit();
19
+ };
20
+ global._perf = t1 => {
21
+ const t2 = new Date();
22
+ console.log(`\nExecution time: ${t2 - t1}ms`.blue);
23
+ };
24
+ global._formatDate = date => date?.toLocaleDateString('en-gb', {day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit'});
@@ -0,0 +1,24 @@
1
+ /* eslint-disable no-control-regex */
2
+
3
+ const styles = {bold: 1, underline: 4, black: 30, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37, lblack: 90, lred: 91, lgreen: 92, lyellow: 93, lblue: 94, lmagenta: 95, lcyan: 96, lwhite: 97};
4
+
5
+ for (const name in styles ) {
6
+ Object.defineProperty(String.prototype, name, {
7
+ get () {
8
+ const _this = this.replace(/\x1b\[0m/g, `\x1b[${styles[name]}m`); // replace reset control with color for supporting multiple colors in string
9
+ return `\x1b[${styles[name]}m${_this}\x1b[0m`;
10
+ }
11
+ });
12
+ }
13
+
14
+ Object.defineProperty(String.prototype, 'nostyle', {
15
+ get () {
16
+ return this.replace(/[\u001b\u009b][[()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
17
+ }
18
+ });
19
+
20
+ Object.defineProperty(String.prototype, 'toFws', {
21
+ get () {
22
+ return this.replace(/\\/g, '/');
23
+ }
24
+ });
@@ -70,43 +70,5 @@ module.exports = function build (argv) {
70
70
  createSymlinks();
71
71
  }
72
72
 
73
- if (argv.config) {
74
- if (_git.commitTdi.after(_git.commitTdi.stopUsingRepoconfigFile)) _error('This option only works for older repo\'s using a repoconfig file.');
75
-
76
- inquirer
77
- .prompt([{message: 'Be sure paths for projects are [customer]/[project]. Continue?', name: 'confirm', type: 'confirm'}])
78
- .then(({confirm}) => {
79
- if (!confirm) return;
80
-
81
- const customer = {}, projects = [];
82
-
83
- globby
84
- .sync('database/config/**/txd_document_types.sql')
85
- .forEach(p => {
86
- const dtSqlInsert = fs.readFileSync(p).toString().match(/select(.*?)from/s)[1];
87
- const ntSqlInsert = fs.readFileSync(p.replace('txd_document_types', 'txd_node_types')).toString().match(/select(.*?)from/s)[1];
88
-
89
- const dtDisplayName = dtSqlInsert.match(/'([^']+)' display_name/)[1];
90
- const ntName = ntSqlInsert.match(/'([^']+)' name/)[1];
91
- const xpiDir = ntSqlInsert.match(/'([^']+)' xsl_prep_inc/)[1];
92
-
93
- customer.name = dtDisplayName.split(/ (.+)/)[0];
94
- customer.abbr = ntName.split('_')[0];
95
- customer.dirname = xpiDir.split('/')[0];
96
-
97
- projects.push({
98
- name: dtDisplayName.split(/ (.+)/)[1],
99
- abbr: ntName.split('_')[1],
100
- dirname: xpiDir.split('/')[1],
101
- idrange: dtSqlInsert.match(/(\d+)\d{3} id/)[1]
102
- });
103
- });
104
-
105
- _repoconfig.update({customer, projects, applink: 'None'});
106
-
107
- _write(`\nFile '${_paths.repoconfig}' has been created.`);
108
- });
109
- }
110
-
111
73
  if (argv.oxygen) oxygen(argv.oxygen);
112
74
  };