@xpack/xpm-lib 3.0.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/LICENSE +21 -0
- package/README.md +223 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/chmod-recursive.d.ts +7 -0
- package/dist/lib/chmod-recursive.d.ts.map +1 -0
- package/dist/lib/chmod-recursive.js +81 -0
- package/dist/lib/chmod-recursive.js.map +1 -0
- package/dist/lib/errors.d.ts +11 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +26 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/functions/chmod-recursive.d.ts +7 -0
- package/dist/lib/functions/chmod-recursive.d.ts.map +1 -0
- package/dist/lib/functions/chmod-recursive.js +81 -0
- package/dist/lib/functions/chmod-recursive.js.map +1 -0
- package/dist/lib/functions/perform-substitutions.d.ts +20 -0
- package/dist/lib/functions/perform-substitutions.d.ts.map +1 -0
- package/dist/lib/functions/perform-substitutions.js +85 -0
- package/dist/lib/functions/perform-substitutions.js.map +1 -0
- package/dist/lib/functions/utils.d.ts +30 -0
- package/dist/lib/functions/utils.d.ts.map +1 -0
- package/dist/lib/functions/utils.js +70 -0
- package/dist/lib/functions/utils.js.map +1 -0
- package/dist/lib/init-template-base.d.ts +46 -0
- package/dist/lib/init-template-base.d.ts.map +1 -0
- package/dist/lib/init-template-base.js +275 -0
- package/dist/lib/init-template-base.js.map +1 -0
- package/dist/lib/liquid-actions.d.ts +32 -0
- package/dist/lib/liquid-actions.d.ts.map +1 -0
- package/dist/lib/liquid-actions.js +113 -0
- package/dist/lib/liquid-actions.js.map +1 -0
- package/dist/lib/liquid-build-configurations.d.ts +49 -0
- package/dist/lib/liquid-build-configurations.d.ts.map +1 -0
- package/dist/lib/liquid-build-configurations.js +267 -0
- package/dist/lib/liquid-build-configurations.js.map +1 -0
- package/dist/lib/liquid-drop.d.ts +13 -0
- package/dist/lib/liquid-drop.d.ts.map +1 -0
- package/dist/lib/liquid-drop.js +56 -0
- package/dist/lib/liquid-drop.js.map +1 -0
- package/dist/lib/liquid-engine.d.ts +5 -0
- package/dist/lib/liquid-engine.d.ts.map +1 -0
- package/dist/lib/liquid-engine.js +85 -0
- package/dist/lib/liquid-engine.js.map +1 -0
- package/dist/lib/liquid-package.d.ts +17 -0
- package/dist/lib/liquid-package.d.ts.map +1 -0
- package/dist/lib/liquid-package.js +70 -0
- package/dist/lib/liquid-package.js.map +1 -0
- package/dist/lib/package.d.ts +66 -0
- package/dist/lib/package.d.ts.map +1 -0
- package/dist/lib/package.js +700 -0
- package/dist/lib/package.js.map +1 -0
- package/dist/lib/perform-substitutions.d.ts +20 -0
- package/dist/lib/perform-substitutions.d.ts.map +1 -0
- package/dist/lib/perform-substitutions.js +85 -0
- package/dist/lib/perform-substitutions.js.map +1 -0
- package/dist/lib/policies.d.ts +13 -0
- package/dist/lib/policies.d.ts.map +1 -0
- package/dist/lib/policies.js +31 -0
- package/dist/lib/policies.js.map +1 -0
- package/dist/lib/substitutions-variables.d.ts +117 -0
- package/dist/lib/substitutions-variables.d.ts.map +1 -0
- package/dist/lib/substitutions-variables.js +51 -0
- package/dist/lib/substitutions-variables.js.map +1 -0
- package/dist/lib/types.d.ts +70 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +13 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +30 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +70 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +102 -0
- package/src/README.md +10 -0
- package/src/index.ts +35 -0
- package/src/lib/errors.ts +29 -0
- package/src/lib/functions/chmod-recursive.ts +103 -0
- package/src/lib/functions/perform-substitutions.ts +116 -0
- package/src/lib/functions/utils.ts +88 -0
- package/src/lib/init-template-base.ts +401 -0
- package/src/lib/liquid-actions.ts +179 -0
- package/src/lib/liquid-build-configurations.ts +410 -0
- package/src/lib/liquid-drop.ts +99 -0
- package/src/lib/liquid-engine.ts +135 -0
- package/src/lib/liquid-package.ts +108 -0
- package/src/lib/package.ts +946 -0
- package/src/lib/policies.ts +49 -0
- package/src/lib/substitutions-variables.ts +177 -0
- package/src/lib/types.ts +109 -0
- package/src/package.json +3 -0
- package/src/tsconfig.json +10 -0
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xpack/xpm-lib",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A Node.js ES6 module with the xpm library utilities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"typings": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"src/"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"compile-watch": "tsc --build --verbose --watch src",
|
|
20
|
+
"prettier": "prettier src --write",
|
|
21
|
+
"fix": "eslint --fix src",
|
|
22
|
+
"compile": "tsc --build --verbose src",
|
|
23
|
+
"fix-compile": "npm run prettier && npm run fix && npm run compile",
|
|
24
|
+
"npm-install": "npm install",
|
|
25
|
+
"npm-link": "npm link",
|
|
26
|
+
"npm-link-deps": "npm link @xpack/logger",
|
|
27
|
+
"npm-outdated": "npm outdated",
|
|
28
|
+
"npm-update": "npm update",
|
|
29
|
+
"npm-version-patch": "npm version patch",
|
|
30
|
+
"npm-version-minor": "npm version minor",
|
|
31
|
+
"postversion": "git push origin --all && git push origin --tags",
|
|
32
|
+
"npm-pack": "npm pack",
|
|
33
|
+
"git-log": "git log --pretty='%cd * %h %s' --date=short",
|
|
34
|
+
"lint": "eslint src",
|
|
35
|
+
"prepare": "npm run compile && npm run lint",
|
|
36
|
+
"pretest": "npm run lint",
|
|
37
|
+
"test": "npm run test-tap-run",
|
|
38
|
+
"test-ci": "npm run test-tap-run",
|
|
39
|
+
"test-tap-run": "tap run",
|
|
40
|
+
"test-tap-config-list": "tap config list",
|
|
41
|
+
"dev-cycle": "npm run fix && npm run compile && npm run test-100-c8",
|
|
42
|
+
"clean": "del-cli dist 'tests/**/cjs' 'src/**/*.d.ts' 'src/**/*.d.ts.map' 'src/**/*.js' 'src/**/*.js.map' 'tests/**/*.d.ts' 'tests/**/*.d.ts.map' 'tests/**/*.js' 'tests/**/*.js.map' '**/tsconfig.tsbuildinfo' .nyc_output coverage",
|
|
43
|
+
"deep-clean": "npm run clean && rm -rf node_modules package-lock.json",
|
|
44
|
+
"npm-version": "echo $(which node) $(node --version) && echo $(which npm) $(npm --version)"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/xpack/xpm-lib-ts.git"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"xpm",
|
|
52
|
+
"liquid",
|
|
53
|
+
"liquidjs"
|
|
54
|
+
],
|
|
55
|
+
"author": {
|
|
56
|
+
"name": "Liviu Ionescu",
|
|
57
|
+
"email": "ilg@livius.net",
|
|
58
|
+
"url": "https://github.com/ilg-ul"
|
|
59
|
+
},
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/xpack/xpm-lib-ts/issues"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://xpack.github.io/xpm-lib-ts/",
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@npmcli/arborist": "^9.1.9",
|
|
67
|
+
"@xpack/logger": "^6.0.0",
|
|
68
|
+
"cacache": "^18.0.2",
|
|
69
|
+
"cp-file": "^10.0.0",
|
|
70
|
+
"decompress": "^4.2.1",
|
|
71
|
+
"del": "^8.0.1",
|
|
72
|
+
"https-proxy-agent": "^7.0.6",
|
|
73
|
+
"liquidjs": "^10.24.0",
|
|
74
|
+
"make-dir": "^5.1.0",
|
|
75
|
+
"node-fetch": "^3.3.2",
|
|
76
|
+
"pacote": "^17.0.6",
|
|
77
|
+
"proxy-from-env": "^1.1.0",
|
|
78
|
+
"semver": "^7.7.3"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@eslint/js": "^9.31.0",
|
|
82
|
+
"@tsconfig/node20": "^20.1.6",
|
|
83
|
+
"@types/decompress": "^4.2.7",
|
|
84
|
+
"@types/node": "^25.0.3",
|
|
85
|
+
"@types/npmcli__arborist": "^6.3.1",
|
|
86
|
+
"@types/pacote": "^11.1.8",
|
|
87
|
+
"@types/proxy-from-env": "^1.0.4",
|
|
88
|
+
"@types/semver": "^7.7.1",
|
|
89
|
+
"@types/tap": "^15.0.11",
|
|
90
|
+
"del-cli": "^7.0.0",
|
|
91
|
+
"eslint": "^9.31.0",
|
|
92
|
+
"eslint-config-prettier": "^10.1.8",
|
|
93
|
+
"prettier": "^3.7.4",
|
|
94
|
+
"tap": "^21.5.0",
|
|
95
|
+
"ts-node": "^10.9.2",
|
|
96
|
+
"typescript": "^5.8.3",
|
|
97
|
+
"typescript-eslint": "^8.38.0"
|
|
98
|
+
},
|
|
99
|
+
"engines": {
|
|
100
|
+
"node": " >=20.0"
|
|
101
|
+
}
|
|
102
|
+
}
|
package/src/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# src
|
|
2
|
+
|
|
3
|
+
This folder includes the main TypeScript source files, that provide
|
|
4
|
+
the project functionality.
|
|
5
|
+
|
|
6
|
+
They are compiled by `tsc` into the top `dist` folder as ES6 code.
|
|
7
|
+
|
|
8
|
+
## CommonJS backward compatibility
|
|
9
|
+
|
|
10
|
+
Starting with version 3.x, compatibility with CommonJS was removed.
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the xPack project (http://xpack.github.io).
|
|
3
|
+
* Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
6
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* If a copy of the license was not distributed with this file, it can
|
|
9
|
+
* be obtained from https://opensource.org/license/mit.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint max-len: [ "error", 80, { "ignoreUrls": true } ] */
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
// Re-export all library definitions.
|
|
17
|
+
export * from './lib/functions/chmod-recursive.js'
|
|
18
|
+
export * from './lib/functions/perform-substitutions.js'
|
|
19
|
+
export * from './lib/functions/utils.js'
|
|
20
|
+
|
|
21
|
+
export * from './lib/errors.js'
|
|
22
|
+
export * from './lib/init-template-base.js'
|
|
23
|
+
export * from './lib/liquid-actions.js'
|
|
24
|
+
export * from './lib/liquid-build-configurations.js'
|
|
25
|
+
export * from './lib/liquid-drop.js'
|
|
26
|
+
export * from './lib/liquid-engine.js'
|
|
27
|
+
export * from './lib/liquid-package.js'
|
|
28
|
+
export * from './lib/package.js'
|
|
29
|
+
export * from './lib/policies.js'
|
|
30
|
+
export * from './lib/substitutions-variables.js'
|
|
31
|
+
export * from './lib/types.js'
|
|
32
|
+
|
|
33
|
+
export * from 'liquidjs'
|
|
34
|
+
|
|
35
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the xPack project (http://xpack.github.io).
|
|
3
|
+
* Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
6
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* If a copy of the license was not distributed with this file, it can
|
|
9
|
+
* be obtained from https://opensource.org/license/mit.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint max-len: [ "error", 80, { "ignoreUrls": true } ] */
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
// Application errors
|
|
17
|
+
export class XpmError extends Error {}
|
|
18
|
+
|
|
19
|
+
export class XpmPrerequisitesError extends Error {}
|
|
20
|
+
|
|
21
|
+
export class XpmInputError extends Error {}
|
|
22
|
+
|
|
23
|
+
export class XpmSyntaxError extends Error {}
|
|
24
|
+
|
|
25
|
+
export class XpmOutputError extends Error {}
|
|
26
|
+
|
|
27
|
+
// Other errors: Child.
|
|
28
|
+
|
|
29
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the xPack project (http://xpack.github.io).
|
|
3
|
+
* Copyright (c) 2017-2026 Liviu Ionescu. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
6
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* If a copy of the license was not distributed with this file, it can
|
|
9
|
+
* be obtained from https://opensource.org/license/mit.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint max-len: [ "error", 80, { "ignoreUrls": true } ] */
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
// https://nodejs.org/docs/latest/api/
|
|
17
|
+
import assert from 'node:assert'
|
|
18
|
+
import * as fs from 'node:fs/promises'
|
|
19
|
+
import path from 'node:path'
|
|
20
|
+
|
|
21
|
+
import { Logger } from '@xpack/logger'
|
|
22
|
+
|
|
23
|
+
// ----------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
export async function chmodRecursive({
|
|
26
|
+
inputPath,
|
|
27
|
+
readOnly,
|
|
28
|
+
log,
|
|
29
|
+
}: {
|
|
30
|
+
inputPath: string
|
|
31
|
+
readOnly: boolean
|
|
32
|
+
log: Logger
|
|
33
|
+
}): Promise<void> {
|
|
34
|
+
assert(inputPath, 'mandatory inputPath')
|
|
35
|
+
assert(log, 'mandatory log')
|
|
36
|
+
|
|
37
|
+
const stat = await fs.lstat(inputPath)
|
|
38
|
+
// log.trace(util.inspect(stat))
|
|
39
|
+
|
|
40
|
+
if (stat.isSymbolicLink()) {
|
|
41
|
+
// Since it is not possible to change the modes of links (lchmod
|
|
42
|
+
// was deprecated and worked on macOS anyway), don't bother
|
|
43
|
+
// with them.
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// The order is important, process the folder before
|
|
48
|
+
// changing it to RO.
|
|
49
|
+
if (readOnly && stat.isDirectory()) {
|
|
50
|
+
log.trace(inputPath)
|
|
51
|
+
const dirents = await fs.readdir(inputPath, {
|
|
52
|
+
withFileTypes: true,
|
|
53
|
+
})
|
|
54
|
+
for (const dirent of dirents) {
|
|
55
|
+
await chmodRecursive({
|
|
56
|
+
inputPath: path.resolve(inputPath, dirent.name),
|
|
57
|
+
readOnly,
|
|
58
|
+
log,
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const mode = stat.mode
|
|
64
|
+
// For RO, remove all W bits, for RW add only user.
|
|
65
|
+
const newMode = readOnly
|
|
66
|
+
? mode &
|
|
67
|
+
~(fs.constants.S_IWUSR | fs.constants.S_IWGRP | fs.constants.S_IWOTH)
|
|
68
|
+
: mode | fs.constants.S_IWUSR
|
|
69
|
+
|
|
70
|
+
// log.trace(
|
|
71
|
+
// `set ${inputPath} from ${mode.toString(8)} to ${newMode.toString(8)}`)
|
|
72
|
+
await fs.chmod(inputPath, newMode)
|
|
73
|
+
|
|
74
|
+
const actualStat = await fs.stat(inputPath)
|
|
75
|
+
// log.trace(`actual ${inputPath} is ${actualStat.mode.toString(8)}`)
|
|
76
|
+
|
|
77
|
+
if (readOnly) {
|
|
78
|
+
if ((actualStat.mode & fs.constants.S_IWUSR) !== 0) {
|
|
79
|
+
log.warn(`${inputPath} not set to RO`)
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
if ((actualStat.mode & fs.constants.S_IWUSR) === 0) {
|
|
83
|
+
log.warn(`${inputPath} not set to RW`)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// If RW, process the folder after changing it to RW.
|
|
88
|
+
if (!readOnly && stat.isDirectory()) {
|
|
89
|
+
log.trace(inputPath)
|
|
90
|
+
const dirents = await fs.readdir(inputPath, {
|
|
91
|
+
withFileTypes: true,
|
|
92
|
+
})
|
|
93
|
+
for (const dirent of dirents) {
|
|
94
|
+
await chmodRecursive({
|
|
95
|
+
inputPath: path.resolve(inputPath, dirent.name),
|
|
96
|
+
readOnly,
|
|
97
|
+
log,
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the xPack project (http://xpack.github.io).
|
|
3
|
+
* Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
6
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* If a copy of the license was not distributed with this file, it can
|
|
9
|
+
* be obtained from https://opensource.org/license/mit.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint max-len: [ "error", 80, { "ignoreUrls": true } ] */
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
import assert from 'node:assert'
|
|
17
|
+
|
|
18
|
+
import { Context } from 'liquidjs'
|
|
19
|
+
|
|
20
|
+
import { Logger } from '@xpack/logger'
|
|
21
|
+
|
|
22
|
+
import { XpmLiquidEngine } from '../liquid-engine.js'
|
|
23
|
+
import { XpmLiquidPropertiesDrop } from '../liquid-drop.js'
|
|
24
|
+
import { XpmLiquidSubstitutionsVariables } from '../substitutions-variables.js'
|
|
25
|
+
|
|
26
|
+
// ----------------------------------------------------------------------------
|
|
27
|
+
/**
|
|
28
|
+
* Perform substitution on the input string.
|
|
29
|
+
* Repeat until no more Liquid variables or tags are identified.
|
|
30
|
+
*
|
|
31
|
+
* @param input - The input string, possibly with substitutions.
|
|
32
|
+
* @param map - The substitution map.
|
|
33
|
+
* @returns The substituted string.
|
|
34
|
+
*
|
|
35
|
+
* @throws Liquid exceptions
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
export async function performSubstitutions({
|
|
39
|
+
log,
|
|
40
|
+
engine,
|
|
41
|
+
input,
|
|
42
|
+
substitutionsVariables,
|
|
43
|
+
}: {
|
|
44
|
+
log: Logger
|
|
45
|
+
engine: XpmLiquidEngine
|
|
46
|
+
input: string
|
|
47
|
+
substitutionsVariables: XpmLiquidSubstitutionsVariables
|
|
48
|
+
}): Promise<string> {
|
|
49
|
+
assert(substitutionsVariables)
|
|
50
|
+
|
|
51
|
+
if (input.trim() === '') {
|
|
52
|
+
// Spare it the trouble for empty strings.
|
|
53
|
+
return input
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let context
|
|
57
|
+
// Wrap properties into a liquid drop (a mechanism to process
|
|
58
|
+
// substitutions immediately).
|
|
59
|
+
if (Object.keys(substitutionsVariables.properties).length > 0) {
|
|
60
|
+
context = new Context({
|
|
61
|
+
...substitutionsVariables,
|
|
62
|
+
properties: new XpmLiquidPropertiesDrop({
|
|
63
|
+
log,
|
|
64
|
+
engine,
|
|
65
|
+
properties: substitutionsVariables.properties,
|
|
66
|
+
}),
|
|
67
|
+
})
|
|
68
|
+
} else {
|
|
69
|
+
context = new Context(substitutionsVariables)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
log.trace(`performSubstitutions('${input}')`)
|
|
73
|
+
|
|
74
|
+
let current: string = input
|
|
75
|
+
let substituted: string = current
|
|
76
|
+
let count = 0
|
|
77
|
+
|
|
78
|
+
// Iterate until all substitutions are done.
|
|
79
|
+
while (current.includes('{{') || current.includes('{%')) {
|
|
80
|
+
++count
|
|
81
|
+
// May throw.
|
|
82
|
+
try {
|
|
83
|
+
substituted = (await engine.parseAndRender(current, context)) as string
|
|
84
|
+
|
|
85
|
+
/* c8 ignore start */ /* istanbul ignore next */
|
|
86
|
+
if (substituted === current) {
|
|
87
|
+
// If nothing changed, we're done.
|
|
88
|
+
// This test is just a safety net, normally should not get there.
|
|
89
|
+
log.warn(
|
|
90
|
+
`performSubstitutions() ${String(count)} => |`,
|
|
91
|
+
substituted,
|
|
92
|
+
'| did not change'
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
break
|
|
96
|
+
} /* c8 ignore stop */
|
|
97
|
+
} catch (ex) {
|
|
98
|
+
if (ex instanceof Error) {
|
|
99
|
+
// log.error(ex)
|
|
100
|
+
log.error(ex.message)
|
|
101
|
+
} else {
|
|
102
|
+
log.error(new Error(String(ex)))
|
|
103
|
+
}
|
|
104
|
+
// Return the current (unsubstituted) value.
|
|
105
|
+
substituted = current
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
log.trace(`performSubstitutions() ${String(count)} => |`, substituted, '|')
|
|
110
|
+
current = substituted
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return substituted
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the xPack project (http://xpack.github.io).
|
|
3
|
+
* Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
6
|
+
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
7
|
+
*
|
|
8
|
+
* If a copy of the license was not distributed with this file, it can
|
|
9
|
+
* be obtained from https://opensource.org/license/mit.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* eslint max-len: [ "error", 80, { "ignoreUrls": true } ] */
|
|
13
|
+
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
import * as os from 'node:os'
|
|
17
|
+
|
|
18
|
+
// ----------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
export function isPrimitive(value: unknown): boolean {
|
|
21
|
+
return (
|
|
22
|
+
(typeof value !== 'object' && typeof value !== 'function') || value === null
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isJsonObject(value: unknown): boolean {
|
|
27
|
+
return value !== undefined && !isPrimitive(value) && !Array.isArray(value)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isJsonArray(value: unknown): boolean {
|
|
31
|
+
return value !== undefined && Array.isArray(value)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isNonEmptyJsonObject(value: unknown): boolean {
|
|
35
|
+
return isJsonObject(value) && Object.keys(value as object).length > 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function isString(value: unknown): value is string {
|
|
39
|
+
return typeof value === 'string'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Replace non alphanumeric chars with dashes to make the paths
|
|
44
|
+
* comply with filesystem names.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} input A path candidate.
|
|
47
|
+
* @returns {string} A validated path.
|
|
48
|
+
*/
|
|
49
|
+
export function filterPath(input: string): string {
|
|
50
|
+
/* c8 ignore start */ /* istanbul ignore next */
|
|
51
|
+
const fixed =
|
|
52
|
+
os.platform() === 'win32'
|
|
53
|
+
? input.replace(/[^a-zA-Z0-9\\:]+/g, '-')
|
|
54
|
+
: input.replace(/[^a-zA-Z0-9/]+/g, '-')
|
|
55
|
+
/* c8 ignore stop */
|
|
56
|
+
|
|
57
|
+
return fixed.replace(/--/g, '-')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Replace non alphanumeric chars with dashes to make the paths
|
|
62
|
+
* comply with Posix filesystem names.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} input A path candidate.
|
|
65
|
+
* @returns {string} A validated path.
|
|
66
|
+
*/
|
|
67
|
+
export function filterPosixPath(input: string): string {
|
|
68
|
+
/* istanbul ignore next */
|
|
69
|
+
const fixed = input.replace(/[^a-zA-Z0-9/]+/g, '-')
|
|
70
|
+
|
|
71
|
+
return fixed.replace(/--/g, '-')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Replace non alphanumeric chars with dashes to make the paths
|
|
76
|
+
* comply with Windows filesystem names.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} input A path candidate.
|
|
79
|
+
* @returns {string} A validated path.
|
|
80
|
+
*/
|
|
81
|
+
export function filterWin32Path(input: string): string {
|
|
82
|
+
/* istanbul ignore next */
|
|
83
|
+
const fixed = input.replace(/[^a-zA-Z0-9\\:]+/g, '-')
|
|
84
|
+
|
|
85
|
+
return fixed.replace(/--/g, '-')
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ----------------------------------------------------------------------------
|