@xpack/xpm-lib 3.1.2 → 4.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/README.md +16 -212
- package/dist/classes/actions.d.ts +58 -0
- package/dist/classes/actions.d.ts.map +1 -0
- package/dist/classes/actions.js +250 -0
- package/dist/classes/actions.js.map +1 -0
- package/dist/classes/build-configurations.d.ts +78 -0
- package/dist/classes/build-configurations.d.ts.map +1 -0
- package/dist/classes/build-configurations.js +489 -0
- package/dist/classes/build-configurations.js.map +1 -0
- package/dist/classes/combinations-generator.d.ts +19 -0
- package/dist/classes/combinations-generator.d.ts.map +1 -0
- package/dist/classes/combinations-generator.js +48 -0
- package/dist/classes/combinations-generator.js.map +1 -0
- package/dist/classes/data-model.d.ts +21 -0
- package/dist/classes/data-model.d.ts.map +1 -0
- package/dist/classes/data-model.js +47 -0
- package/dist/classes/data-model.js.map +1 -0
- package/dist/classes/errors.d.ts +13 -0
- package/dist/classes/errors.d.ts.map +1 -0
- package/dist/classes/errors.js +13 -0
- package/dist/classes/errors.js.map +1 -0
- package/dist/classes/init-template-base.d.ts +47 -0
- package/dist/classes/init-template-base.d.ts.map +1 -0
- package/dist/classes/init-template-base.js +358 -0
- package/dist/classes/init-template-base.js.map +1 -0
- package/dist/classes/liquid-drop.d.ts +28 -0
- package/dist/classes/liquid-drop.d.ts.map +1 -0
- package/dist/classes/liquid-drop.js +70 -0
- package/dist/classes/liquid-drop.js.map +1 -0
- package/dist/classes/liquid-engine.d.ts +7 -0
- package/dist/classes/liquid-engine.d.ts.map +1 -0
- package/dist/classes/liquid-engine.js +72 -0
- package/dist/classes/liquid-engine.js.map +1 -0
- package/dist/classes/package.d.ts +31 -0
- package/dist/classes/package.d.ts.map +1 -0
- package/dist/classes/package.js +268 -0
- package/dist/classes/package.js.map +1 -0
- package/dist/classes/platform-detector.d.ts +14 -0
- package/dist/classes/platform-detector.d.ts.map +1 -0
- package/dist/classes/platform-detector.js +26 -0
- package/dist/classes/platform-detector.js.map +1 -0
- package/dist/classes/policies.d.ts +14 -0
- package/dist/classes/policies.d.ts.map +1 -0
- package/dist/classes/policies.js +20 -0
- package/dist/classes/policies.js.map +1 -0
- package/dist/classes/template-expander.d.ts +29 -0
- package/dist/classes/template-expander.d.ts.map +1 -0
- package/dist/classes/template-expander.js +62 -0
- package/dist/classes/template-expander.js.map +1 -0
- package/dist/data/substitutions-variables.d.ts +43 -0
- package/dist/data/substitutions-variables.d.ts.map +1 -0
- package/dist/{lib → data}/substitutions-variables.js +1 -16
- package/dist/data/substitutions-variables.js.map +1 -0
- package/dist/functions/chmod-recursively.d.ts +9 -0
- package/dist/functions/chmod-recursively.d.ts.map +1 -0
- package/dist/functions/chmod-recursively.js +66 -0
- package/dist/functions/chmod-recursively.js.map +1 -0
- package/dist/functions/filter-paths.d.ts +5 -0
- package/dist/functions/filter-paths.d.ts.map +1 -0
- package/dist/functions/filter-paths.js +16 -0
- package/dist/functions/filter-paths.js.map +1 -0
- package/dist/functions/is-something.d.ts +9 -0
- package/dist/functions/is-something.d.ts.map +1 -0
- package/dist/functions/is-something.js +25 -0
- package/dist/functions/is-something.js.map +1 -0
- package/dist/functions/matrix-expander.d.ts +17 -0
- package/dist/functions/matrix-expander.d.ts.map +1 -0
- package/dist/functions/matrix-expander.js +52 -0
- package/dist/functions/matrix-expander.js.map +1 -0
- package/dist/functions/perform-substitutions.d.ts +12 -0
- package/dist/functions/perform-substitutions.d.ts.map +1 -0
- package/dist/functions/perform-substitutions.js +76 -0
- package/dist/functions/perform-substitutions.js.map +1 -0
- package/dist/functions/utils.d.ts +8 -0
- package/dist/functions/utils.d.ts.map +1 -0
- package/dist/functions/utils.js +16 -0
- package/dist/functions/utils.js.map +1 -0
- package/dist/index.d.ts +22 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -29
- package/dist/index.js.map +1 -1
- package/dist/{lib/types.d.ts → types/json.d.ts} +31 -22
- package/dist/types/json.d.ts.map +1 -0
- package/dist/types/json.js +2 -0
- package/dist/types/json.js.map +1 -0
- package/dist/types/xpm-init-template.d.ts +21 -0
- package/dist/types/xpm-init-template.d.ts.map +1 -0
- package/dist/types/xpm-init-template.js +2 -0
- package/dist/types/xpm-init-template.js.map +1 -0
- package/dist/types/xpm.d.ts +16 -0
- package/dist/types/xpm.d.ts.map +1 -0
- package/dist/types/xpm.js +2 -0
- package/dist/types/xpm.js.map +1 -0
- package/package.json +53 -44
- package/src/CODE-REVIEW.md +2167 -0
- package/src/README.md +393 -6
- package/src/classes/actions.ts +1157 -0
- package/src/classes/build-configurations.ts +2127 -0
- package/src/classes/combinations-generator.ts +331 -0
- package/src/classes/data-model.ts +337 -0
- package/src/classes/errors.ts +105 -0
- package/src/classes/init-template-base.ts +1028 -0
- package/src/classes/liquid-drop.ts +376 -0
- package/src/classes/liquid-engine.ts +249 -0
- package/src/classes/package.ts +765 -0
- package/src/classes/platform-detector.ts +237 -0
- package/src/classes/policies.ts +200 -0
- package/src/classes/template-expander.ts +330 -0
- package/src/data/substitutions-variables.ts +390 -0
- package/src/functions/chmod-recursively.ts +195 -0
- package/src/functions/filter-paths.ts +126 -0
- package/src/functions/is-something.ts +223 -0
- package/src/functions/matrix-expander.ts +172 -0
- package/src/functions/perform-substitutions.ts +253 -0
- package/src/functions/utils.ts +151 -0
- package/src/index.ts +72 -19
- package/src/types/json.ts +519 -0
- package/src/types/xpm-init-template.ts +282 -0
- package/src/types/xpm.ts +162 -0
- package/dist/lib/chmod-recursive.d.ts +0 -7
- package/dist/lib/chmod-recursive.d.ts.map +0 -1
- package/dist/lib/chmod-recursive.js +0 -81
- package/dist/lib/chmod-recursive.js.map +0 -1
- package/dist/lib/errors.d.ts +0 -11
- package/dist/lib/errors.d.ts.map +0 -1
- package/dist/lib/errors.js +0 -26
- package/dist/lib/errors.js.map +0 -1
- package/dist/lib/functions/chmod-recursive.d.ts +0 -7
- package/dist/lib/functions/chmod-recursive.d.ts.map +0 -1
- package/dist/lib/functions/chmod-recursive.js +0 -81
- package/dist/lib/functions/chmod-recursive.js.map +0 -1
- package/dist/lib/functions/perform-substitutions.d.ts +0 -20
- package/dist/lib/functions/perform-substitutions.d.ts.map +0 -1
- package/dist/lib/functions/perform-substitutions.js +0 -85
- package/dist/lib/functions/perform-substitutions.js.map +0 -1
- package/dist/lib/functions/utils.d.ts +0 -30
- package/dist/lib/functions/utils.d.ts.map +0 -1
- package/dist/lib/functions/utils.js +0 -70
- package/dist/lib/functions/utils.js.map +0 -1
- package/dist/lib/init-template-base.d.ts +0 -46
- package/dist/lib/init-template-base.d.ts.map +0 -1
- package/dist/lib/init-template-base.js +0 -281
- package/dist/lib/init-template-base.js.map +0 -1
- package/dist/lib/liquid-actions.d.ts +0 -37
- package/dist/lib/liquid-actions.d.ts.map +0 -1
- package/dist/lib/liquid-actions.js +0 -148
- package/dist/lib/liquid-actions.js.map +0 -1
- package/dist/lib/liquid-build-configurations.d.ts +0 -47
- package/dist/lib/liquid-build-configurations.d.ts.map +0 -1
- package/dist/lib/liquid-build-configurations.js +0 -282
- package/dist/lib/liquid-build-configurations.js.map +0 -1
- package/dist/lib/liquid-drop.d.ts +0 -13
- package/dist/lib/liquid-drop.d.ts.map +0 -1
- package/dist/lib/liquid-drop.js +0 -56
- package/dist/lib/liquid-drop.js.map +0 -1
- package/dist/lib/liquid-engine.d.ts +0 -5
- package/dist/lib/liquid-engine.d.ts.map +0 -1
- package/dist/lib/liquid-engine.js +0 -85
- package/dist/lib/liquid-engine.js.map +0 -1
- package/dist/lib/liquid-package.d.ts +0 -17
- package/dist/lib/liquid-package.d.ts.map +0 -1
- package/dist/lib/liquid-package.js +0 -70
- package/dist/lib/liquid-package.js.map +0 -1
- package/dist/lib/package.d.ts +0 -66
- package/dist/lib/package.d.ts.map +0 -1
- package/dist/lib/package.js +0 -700
- package/dist/lib/package.js.map +0 -1
- package/dist/lib/perform-substitutions.d.ts +0 -20
- package/dist/lib/perform-substitutions.d.ts.map +0 -1
- package/dist/lib/perform-substitutions.js +0 -85
- package/dist/lib/perform-substitutions.js.map +0 -1
- package/dist/lib/policies.d.ts +0 -14
- package/dist/lib/policies.d.ts.map +0 -1
- package/dist/lib/policies.js +0 -33
- package/dist/lib/policies.js.map +0 -1
- package/dist/lib/substitutions-variables.d.ts +0 -117
- package/dist/lib/substitutions-variables.d.ts.map +0 -1
- package/dist/lib/substitutions-variables.js.map +0 -1
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js +0 -13
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/utils.d.ts +0 -30
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/utils.js +0 -70
- package/dist/lib/utils.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/lib/errors.ts +0 -29
- package/src/lib/functions/chmod-recursive.ts +0 -103
- package/src/lib/functions/perform-substitutions.ts +0 -116
- package/src/lib/functions/utils.ts +0 -88
- package/src/lib/init-template-base.ts +0 -408
- package/src/lib/liquid-actions.ts +0 -223
- package/src/lib/liquid-build-configurations.ts +0 -433
- package/src/lib/liquid-drop.ts +0 -99
- package/src/lib/liquid-engine.ts +0 -135
- package/src/lib/liquid-package.ts +0 -108
- package/src/lib/package.ts +0 -947
- package/src/lib/policies.ts +0 -51
- package/src/lib/substitutions-variables.ts +0 -177
- package/src/lib/types.ts +0 -109
- package/src/package.json +0 -3
- package/src/tsconfig.json +0 -10
|
@@ -0,0 +1,390 @@
|
|
|
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
|
+
// ----------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
import * as os from 'node:os'
|
|
15
|
+
import * as path from 'node:path'
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Represents a map of substitution values used by Liquid templates.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Values can be strings for simple substitutions or arrays for multi-line
|
|
24
|
+
* content. Array values are typically joined with newlines when rendered.
|
|
25
|
+
*
|
|
26
|
+
* Common use cases:
|
|
27
|
+
*
|
|
28
|
+
* <ul>
|
|
29
|
+
* <li><b>Properties:</b> User-defined configuration values from
|
|
30
|
+
* <code>xpack.properties.</code></li>
|
|
31
|
+
* <li><b>Matrix parameters:</b> Template expansion variables from
|
|
32
|
+
* <code>matrix</code> definitions.</li>
|
|
33
|
+
* <li><b>Configuration data:</b> Build-specific settings and metadata.</li>
|
|
34
|
+
* </ul>
|
|
35
|
+
*
|
|
36
|
+
* Templates access these values via namespaces like `properties.foo`,
|
|
37
|
+
* `matrix.arch`, etc., with the Liquid Drop pattern providing lazy
|
|
38
|
+
* evaluation and nested substitution support.
|
|
39
|
+
*/
|
|
40
|
+
export type LiquidSubstitutionsStrings = Record<string, string | string[]>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Defines the substitution variables available to Liquid templates.
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* This interface mirrors a subset of Node.js environment, operating
|
|
47
|
+
* system, and path information, along with package-specific configuration
|
|
48
|
+
* values.
|
|
49
|
+
*
|
|
50
|
+
* Variable hierarchy and scoping:
|
|
51
|
+
*
|
|
52
|
+
* <ol>
|
|
53
|
+
* <li><b>Base variables</b> (<code>env</code>, <code>os</code>,
|
|
54
|
+
* <code>path</code>): Available globally, initialized once
|
|
55
|
+
* from Node.js runtime at startup.</li>
|
|
56
|
+
* <li><b>Package variables:</b> Added when processing
|
|
57
|
+
* <code>package.json</code>, contains
|
|
58
|
+
* package metadata accessible via <code>package.name</code>,
|
|
59
|
+
* <code>package.version</code>,
|
|
60
|
+
* etc.</li>
|
|
61
|
+
* <li><b>Properties:</b> User-defined values from
|
|
62
|
+
* <code>xpack.properties</code>, accessible via
|
|
63
|
+
* <code>properties.key</code>.</li>
|
|
64
|
+
* <li><b>Configuration:</b> Build configuration metadata, available when
|
|
65
|
+
* processing configuration-specific templates via
|
|
66
|
+
* <code>configuration.name</code>,
|
|
67
|
+
* etc.</li>
|
|
68
|
+
* <li><b>Matrix:</b> Template expansion parameters, scoped to individual
|
|
69
|
+
* expanded instances, accessible via <code>matrix.key</code>.</li>
|
|
70
|
+
* </ol>
|
|
71
|
+
*
|
|
72
|
+
* Variables are inherited and extended through the hierarchy:
|
|
73
|
+
*
|
|
74
|
+
* <ul>
|
|
75
|
+
* <li>package actions use package properties</li>
|
|
76
|
+
* <li>configuration actions use:
|
|
77
|
+
* <ul>
|
|
78
|
+
* <li>package actions</li>
|
|
79
|
+
* <li>actions inherited from parent configurations, recursively,
|
|
80
|
+
* in order of inheritance</li>
|
|
81
|
+
* <li>configuration properties</li>
|
|
82
|
+
* </ul>
|
|
83
|
+
* </li>
|
|
84
|
+
* </ul>
|
|
85
|
+
*
|
|
86
|
+
* This ensures templates have access to appropriate
|
|
87
|
+
* context without exposing unrelated data.
|
|
88
|
+
*/
|
|
89
|
+
export interface LiquidSubstitutionsVariables {
|
|
90
|
+
/**
|
|
91
|
+
* Process environment variables from the current execution context.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* Provides access to all environment variables via `env.VARIABLE_NAME`
|
|
95
|
+
* in templates. Common uses include accessing `PATH`, `HOME`, `USER`, or
|
|
96
|
+
* custom variables set by build scripts.
|
|
97
|
+
*
|
|
98
|
+
* See {@link https://nodejs.org/dist/latest-v16.x/docs/api/process.html#process_process_env | Node.js process.env documentation}
|
|
99
|
+
*/
|
|
100
|
+
env: NodeJS.ProcessEnv
|
|
101
|
+
/**
|
|
102
|
+
* Operating system information from Node.js os module.
|
|
103
|
+
*
|
|
104
|
+
* @remarks
|
|
105
|
+
* Provides platform detection and system information for cross-platform
|
|
106
|
+
* template logic. Common uses include conditional compilation, path
|
|
107
|
+
* construction, and platform-specific configuration.
|
|
108
|
+
*
|
|
109
|
+
* Key properties for cross-platform templates:
|
|
110
|
+
*
|
|
111
|
+
* <ul>
|
|
112
|
+
* <li><code>os.platform</code>: Detect OS ('darwin', 'linux', 'win32').</li>
|
|
113
|
+
* <li><code>os.arch</code>: Detect CPU architecture ('x64', 'arm64',
|
|
114
|
+
* etc.).</li>
|
|
115
|
+
* <li><code>os.EOL</code>: Use correct line endings for generated files.</li>
|
|
116
|
+
* <li><code>os.homedir</code>: Reference user's home folder portably.</li>
|
|
117
|
+
* </ul>
|
|
118
|
+
*
|
|
119
|
+
* See {@link https://nodejs.org/dist/latest-v16.x/docs/api/os.html | Node.js os module documentation}
|
|
120
|
+
*/
|
|
121
|
+
os: {
|
|
122
|
+
/**
|
|
123
|
+
* The operating system-specific end-of-line marker.
|
|
124
|
+
* <ul>
|
|
125
|
+
* <li><code>\\n</code> on POSIX</li>
|
|
126
|
+
* <li><code>\\r\\n</code> on Windows</li>
|
|
127
|
+
* </ul>
|
|
128
|
+
*/
|
|
129
|
+
EOL: string
|
|
130
|
+
/**
|
|
131
|
+
* Possible values are 'arm', 'arm64', 'ia32', 'mips', 'mipsel',
|
|
132
|
+
* 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'.
|
|
133
|
+
*/
|
|
134
|
+
arch: string
|
|
135
|
+
/**
|
|
136
|
+
* Contains commonly used operating system-specific constants
|
|
137
|
+
* for error codes, process signals, and so on. The specific
|
|
138
|
+
* constants defined are described in
|
|
139
|
+
* {@link https://nodejs.org/dist/latest-v16.x/docs/api/os.html#os_os_constants_1 | OS constants}
|
|
140
|
+
*/
|
|
141
|
+
constants: {
|
|
142
|
+
signals: Record<string, number>
|
|
143
|
+
errno: Record<string, number>
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* An array of objects containing information about
|
|
147
|
+
* each logical CPU core.
|
|
148
|
+
*/
|
|
149
|
+
cpus: os.CpuInfo[]
|
|
150
|
+
/**
|
|
151
|
+
* A string identifying the endianness of the CPU
|
|
152
|
+
* for which the Node.js binary was compiled.
|
|
153
|
+
*
|
|
154
|
+
* Possible values are 'BE' for big endian and 'LE' for little endian.
|
|
155
|
+
*/
|
|
156
|
+
endianness: 'BE' | 'LE'
|
|
157
|
+
/**
|
|
158
|
+
* The string path of the current user's home folder.
|
|
159
|
+
*/
|
|
160
|
+
homedir: string
|
|
161
|
+
/**
|
|
162
|
+
* The host name of the operating system as a string.
|
|
163
|
+
*/
|
|
164
|
+
hostname: string
|
|
165
|
+
/**
|
|
166
|
+
* A string identifying the operating system platform.
|
|
167
|
+
* Possible values are 'aix', 'darwin', 'freebsd', 'linux', 'openbsd',
|
|
168
|
+
* 'sunos', and 'win32'.
|
|
169
|
+
*/
|
|
170
|
+
platform: NodeJS.Platform
|
|
171
|
+
/**
|
|
172
|
+
* The operating system as a string.
|
|
173
|
+
*/
|
|
174
|
+
release: string
|
|
175
|
+
/**
|
|
176
|
+
* Returns the operating system's default folder for
|
|
177
|
+
* temporary files as a string.
|
|
178
|
+
*/
|
|
179
|
+
tmpdir: string
|
|
180
|
+
/**
|
|
181
|
+
* Returns the operating system name as returned by uname(3).
|
|
182
|
+
* For example, it returns 'Linux' on Linux, 'Darwin' on macOS,
|
|
183
|
+
* and 'Windows_NT' on Windows.
|
|
184
|
+
*/
|
|
185
|
+
type: string
|
|
186
|
+
/**
|
|
187
|
+
* Returns a string identifying the kernel version.
|
|
188
|
+
*
|
|
189
|
+
* On POSIX systems, the operating system release is determined
|
|
190
|
+
* by calling `uname(3)`. On Windows, `RtlGetVersion()` is used,
|
|
191
|
+
* and if it is not available, `GetVersionExW()` will be used.
|
|
192
|
+
*/
|
|
193
|
+
version: string
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Path separators and delimiters from Node.js path module.
|
|
197
|
+
*
|
|
198
|
+
* @remarks
|
|
199
|
+
* Provides platform-specific path constants for building file paths in
|
|
200
|
+
* templates. Use these to construct paths that work correctly on all
|
|
201
|
+
* platforms.
|
|
202
|
+
*
|
|
203
|
+
* Available constants:
|
|
204
|
+
*
|
|
205
|
+
* <ul>
|
|
206
|
+
* <li><code>path.sep</code>: Platform-specific path separator (/ or \).</li>
|
|
207
|
+
* <li><code>path.delimiter</code>: Platform-specific PATH delimiter
|
|
208
|
+
* (; or :).</li>
|
|
209
|
+
* <li><code>path.posix.*</code>: Force POSIX conventions regardless
|
|
210
|
+
of platform.</li>
|
|
211
|
+
* <li><code>path.win32.*</code>: Force Windows conventions regardless
|
|
212
|
+
of platform.</li>
|
|
213
|
+
* </ul>
|
|
214
|
+
*
|
|
215
|
+
* Note: For path manipulation, prefer using Liquid filters like
|
|
216
|
+
* `path_join`, `path_dirname`, etc., which handle cross-platform concerns
|
|
217
|
+
* automatically.
|
|
218
|
+
*
|
|
219
|
+
* See [Node.js path module documentation](https://nodejs.org/dist/latest-v16.x/docs/api/path.html)
|
|
220
|
+
*/
|
|
221
|
+
path: {
|
|
222
|
+
/**
|
|
223
|
+
* Provides the platform-specific path delimiter:
|
|
224
|
+
* <ul>
|
|
225
|
+
* <li><code>;</code> for Windows</li>
|
|
226
|
+
* <li><code>:</code> for POSIX</li>
|
|
227
|
+
* </ul>
|
|
228
|
+
*/
|
|
229
|
+
delimiter: string
|
|
230
|
+
/**
|
|
231
|
+
* Provides the platform-specific path segment separator:
|
|
232
|
+
* <ul>
|
|
233
|
+
* <li><code>\\</code> on Windows</li>
|
|
234
|
+
* <li><code>/</code> on POSIX</li>
|
|
235
|
+
* </ul>
|
|
236
|
+
*/
|
|
237
|
+
sep: string
|
|
238
|
+
win32: {
|
|
239
|
+
delimiter: string
|
|
240
|
+
sep: string
|
|
241
|
+
}
|
|
242
|
+
posix: {
|
|
243
|
+
delimiter: string
|
|
244
|
+
sep: string
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The package metadata exposed to Liquid templates.
|
|
249
|
+
*
|
|
250
|
+
* @remarks
|
|
251
|
+
* Contains the entire `package.json` content, allowing templates to access
|
|
252
|
+
* package name, version, description, dependencies, and xpack-specific
|
|
253
|
+
* metadata.
|
|
254
|
+
*
|
|
255
|
+
* Common template patterns:
|
|
256
|
+
*
|
|
257
|
+
* <ul>
|
|
258
|
+
* <li><code>\{\{ package.name \}\}</code>: Package name for generated
|
|
259
|
+
* files.</li>
|
|
260
|
+
* <li><code>\{\{ package.version \}\}</code>: Version string for
|
|
261
|
+
* documentation.</li>
|
|
262
|
+
* <li><code>\{\{ package.xpack.properties.key \}\}</code>: Access xpack
|
|
263
|
+
* properties.</li>
|
|
264
|
+
* </ul>
|
|
265
|
+
*
|
|
266
|
+
* Undefined when processing templates outside of a package context.
|
|
267
|
+
*/
|
|
268
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
269
|
+
package?: any
|
|
270
|
+
/**
|
|
271
|
+
* The build configuration exposed to Liquid templates.
|
|
272
|
+
*
|
|
273
|
+
* @remarks
|
|
274
|
+
* Available only when processing templates within a build configuration
|
|
275
|
+
* context (actions, dependencies, properties belonging to a specific
|
|
276
|
+
* configuration).
|
|
277
|
+
*
|
|
278
|
+
* Contains the configuration name and all configuration properties,
|
|
279
|
+
* allowing templates to reference the current build context:
|
|
280
|
+
*
|
|
281
|
+
* <ul>
|
|
282
|
+
* <li><code>\{\{ configuration.name \}\}</code>: The build configuration
|
|
283
|
+
* name.</li>
|
|
284
|
+
* <li><code>\{\{ configuration.properties.key \}\}</code>:
|
|
285
|
+
* Configuration-specific
|
|
286
|
+
* settings.</li>
|
|
287
|
+
* </ul>
|
|
288
|
+
*
|
|
289
|
+
* Undefined when processing package-level templates.
|
|
290
|
+
*/
|
|
291
|
+
configuration?: {
|
|
292
|
+
name: string
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
294
|
+
[key: string]: any
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* The properties map used for substitutions.
|
|
298
|
+
*
|
|
299
|
+
* @remarks
|
|
300
|
+
* User-defined configuration values from `xpack.properties`
|
|
301
|
+
* in `package.json`.
|
|
302
|
+
* Provides a namespace for custom template variables without polluting
|
|
303
|
+
* the global scope.
|
|
304
|
+
*
|
|
305
|
+
* Properties support nested substitutions: a property value can reference
|
|
306
|
+
* other properties, package metadata, or system variables using Liquid
|
|
307
|
+
* syntax. The Liquid Drop pattern ensures recursive evaluation.
|
|
308
|
+
*
|
|
309
|
+
* Access via `{{ properties.key }}` in templates.
|
|
310
|
+
*/
|
|
311
|
+
properties: LiquidSubstitutionsStrings
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Optional matrix parameters used for template expansion.
|
|
315
|
+
*
|
|
316
|
+
* @remarks
|
|
317
|
+
* Available only for actions or configurations generated from templates
|
|
318
|
+
* with matrix definitions. Each expanded instance receives a specific
|
|
319
|
+
* combination of matrix values.
|
|
320
|
+
*
|
|
321
|
+
* Matrix parameters enable generating multiple similar actions or
|
|
322
|
+
* configurations from a single template definition. For example, a matrix
|
|
323
|
+
* with `arch: ['x64', 'arm64']` and `os: ['linux', 'darwin']` generates
|
|
324
|
+
* 4 instances (x64-linux, x64-darwin, arm64-linux, arm64-darwin).
|
|
325
|
+
*
|
|
326
|
+
* Access via `{{ matrix.key }}` in templates. Scoped to the individual
|
|
327
|
+
* expanded instance, ensuring isolation between generated items.
|
|
328
|
+
*/
|
|
329
|
+
matrix?: LiquidSubstitutionsStrings
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* The base substitution variables initialised from the current environment.
|
|
334
|
+
*
|
|
335
|
+
* @remarks
|
|
336
|
+
* This constant provides the foundation for all Liquid template processing,
|
|
337
|
+
* capturing the runtime environment once at module load time.
|
|
338
|
+
*
|
|
339
|
+
* Initialization strategy:
|
|
340
|
+
*
|
|
341
|
+
* <ol>
|
|
342
|
+
* <li><b>Environment variables:</b> Snapshot of process.env at load time.</li>
|
|
343
|
+
* <li><b>OS information:</b> OS specific definitions (platform, arch,
|
|
344
|
+
* etc.).</li>
|
|
345
|
+
* <li><b>Path constants:</b> Platform-specific separators and delimiters.</li>
|
|
346
|
+
* <li><b>Properties:</b> Placeholder for package-specific additions.</li>
|
|
347
|
+
* </ol>
|
|
348
|
+
*
|
|
349
|
+
* These base variables are shared across all template processing within the
|
|
350
|
+
* application and extended with package, configuration, and matrix variables
|
|
351
|
+
* as needed. The base object is typically spread into new contexts rather
|
|
352
|
+
* than mutated, preserving the original snapshot.
|
|
353
|
+
*/
|
|
354
|
+
|
|
355
|
+
export const liquidSubstitutionsVariablesBase: LiquidSubstitutionsVariables = {
|
|
356
|
+
env: process.env,
|
|
357
|
+
os: {
|
|
358
|
+
EOL: os.EOL,
|
|
359
|
+
arch: os.arch(),
|
|
360
|
+
constants: {
|
|
361
|
+
signals: os.constants.signals,
|
|
362
|
+
errno: os.constants.errno,
|
|
363
|
+
},
|
|
364
|
+
cpus: os.cpus(),
|
|
365
|
+
endianness: os.endianness(),
|
|
366
|
+
homedir: os.homedir(),
|
|
367
|
+
hostname: os.hostname(),
|
|
368
|
+
platform: os.platform(),
|
|
369
|
+
release: os.release(),
|
|
370
|
+
tmpdir: os.tmpdir(),
|
|
371
|
+
type: os.type(),
|
|
372
|
+
// os.version() available since 12.x
|
|
373
|
+
version: os.version(),
|
|
374
|
+
},
|
|
375
|
+
path: {
|
|
376
|
+
delimiter: path.delimiter,
|
|
377
|
+
sep: path.sep,
|
|
378
|
+
win32: {
|
|
379
|
+
delimiter: path.win32.delimiter,
|
|
380
|
+
sep: path.win32.sep,
|
|
381
|
+
},
|
|
382
|
+
posix: {
|
|
383
|
+
delimiter: path.posix.delimiter,
|
|
384
|
+
sep: path.posix.sep,
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
properties: {},
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ----------------------------------------------------------------------------
|
|
@@ -0,0 +1,195 @@
|
|
|
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
|
+
// ----------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
// https://nodejs.org/docs/latest/api/
|
|
15
|
+
import assert from 'node:assert'
|
|
16
|
+
import * as fs from 'node:fs/promises'
|
|
17
|
+
import * as path from 'node:path'
|
|
18
|
+
|
|
19
|
+
import { Logger } from '@xpack/logger'
|
|
20
|
+
import { ConfigurationError } from '../index.js'
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Maximum recursion depth for file system operations.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* This limit protects against extremely deep directory trees that could
|
|
29
|
+
* cause stack overflow or performance issues. A limit of 1000 levels is
|
|
30
|
+
* more than sufficient for typical use cases whilst preventing pathological
|
|
31
|
+
* scenarios.
|
|
32
|
+
*/
|
|
33
|
+
const CHMOD_RECURSIVELY_MAX_DEPTH = 42
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Recursively changes file permissions within a folder tree.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* This function modifies file system permissions recursively, handling both
|
|
42
|
+
* files and directories with special logic to avoid permission conflicts.
|
|
43
|
+
*
|
|
44
|
+
* Processing strategy:
|
|
45
|
+
*
|
|
46
|
+
* <ol>
|
|
47
|
+
* <li><b>Symbolic links:</b> Ignored because links permissions
|
|
48
|
+
* cannot be reliably changed across platforms.</li>
|
|
49
|
+
* <li><b>Read-only mode:</b> Process folder contents first (recursively),
|
|
50
|
+
* then set
|
|
51
|
+
* the folder itself to read-only. This prevents permission denied errors
|
|
52
|
+
* when trying to access a read-only folder's contents.</li>
|
|
53
|
+
* <li><b>Read-write mode:</b> Set folder to read-write first, then process
|
|
54
|
+
* contents
|
|
55
|
+
* recursively. This ensures the folder is writable before attempting to
|
|
56
|
+
* modify nested items.</li>
|
|
57
|
+
* </ol>
|
|
58
|
+
*
|
|
59
|
+
* Permission modes applied:
|
|
60
|
+
*
|
|
61
|
+
* <ul>
|
|
62
|
+
* <li><b>Read-only:</b> Removes all write bits (user, group, other)
|
|
63
|
+
* using bitwise
|
|
64
|
+
* AND with negated <code>S_IWUSR</code> | <code>S_IWGRP</code> |
|
|
65
|
+
* <code>S_IWOTH</code>.</li>
|
|
66
|
+
* <li><b>Read-write:</b> Adds only user write bit using bitwise OR with
|
|
67
|
+
* <code>S_IWUSR</code>,
|
|
68
|
+
* preserving existing group and other permissions.</li>
|
|
69
|
+
* </ul>
|
|
70
|
+
*
|
|
71
|
+
* The function validates the result after each chmod operation and logs
|
|
72
|
+
* warnings if the expected permission state is not achieved, which can
|
|
73
|
+
* occur on filesystems with non-standard permission handling.
|
|
74
|
+
*
|
|
75
|
+
* Recursion depth is limited to `CHMOD_RECURSIVELY_MAX_DEPTH` levels to
|
|
76
|
+
* protect against extremely deep directory trees.
|
|
77
|
+
*
|
|
78
|
+
* @param inputPath - The file or folder path to process.
|
|
79
|
+
* @param readOnly - Whether to set permissions to read-only.
|
|
80
|
+
* @param log - The logger instance for output and diagnostics.
|
|
81
|
+
* @param depth - Internal parameter tracking recursion depth.
|
|
82
|
+
* @returns A promise that resolves when all permissions have been updated.
|
|
83
|
+
*
|
|
84
|
+
* @throws {@link ConfigurationError}
|
|
85
|
+
* If recursion depth exceeds the maximum limit.
|
|
86
|
+
*/
|
|
87
|
+
export async function chmodRecursively({
|
|
88
|
+
inputPath,
|
|
89
|
+
readOnly,
|
|
90
|
+
log,
|
|
91
|
+
depth = 0,
|
|
92
|
+
maxDepth = CHMOD_RECURSIVELY_MAX_DEPTH,
|
|
93
|
+
}: {
|
|
94
|
+
inputPath: string
|
|
95
|
+
readOnly: boolean
|
|
96
|
+
log: Logger
|
|
97
|
+
depth?: number
|
|
98
|
+
maxDepth?: number
|
|
99
|
+
}): Promise<void> {
|
|
100
|
+
assert(inputPath, 'inputPath is required')
|
|
101
|
+
assert(log, 'log is required')
|
|
102
|
+
assert(maxDepth > 0, 'maxDepth must be a positive integer')
|
|
103
|
+
|
|
104
|
+
/* c8 ignore start - defensive guard for pathological directory trees. */
|
|
105
|
+
if (depth > maxDepth) {
|
|
106
|
+
throw new ConfigurationError(
|
|
107
|
+
`Recursion depth limit exceeded ` +
|
|
108
|
+
`(${String(maxDepth)} levels) ` +
|
|
109
|
+
`whilst processing: ${inputPath}`
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
/* c8 ignore stop */
|
|
113
|
+
|
|
114
|
+
const stat = await fs.lstat(inputPath)
|
|
115
|
+
// log.trace(util.inspect(stat))
|
|
116
|
+
|
|
117
|
+
if (stat.isSymbolicLink()) {
|
|
118
|
+
log.trace(inputPath, 'is a symbolic link, skipping')
|
|
119
|
+
// Since it is not possible to change the modes of links (lchmod
|
|
120
|
+
// was deprecated and worked on macOS anyway), don't bother
|
|
121
|
+
// with them.
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// The order is important, process the folder before
|
|
126
|
+
// changing it to RO.
|
|
127
|
+
if (readOnly && stat.isDirectory()) {
|
|
128
|
+
log.trace(inputPath)
|
|
129
|
+
const dirents = await fs.readdir(inputPath, {
|
|
130
|
+
withFileTypes: true,
|
|
131
|
+
})
|
|
132
|
+
for (const dirent of dirents) {
|
|
133
|
+
await chmodRecursively({
|
|
134
|
+
inputPath: path.resolve(inputPath, dirent.name),
|
|
135
|
+
readOnly,
|
|
136
|
+
log,
|
|
137
|
+
depth: depth + 1,
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const mode = stat.mode
|
|
143
|
+
// For RO, remove all W bits, for RW add only user.
|
|
144
|
+
const newMode = readOnly
|
|
145
|
+
? mode &
|
|
146
|
+
~(fs.constants.S_IWUSR | fs.constants.S_IWGRP | fs.constants.S_IWOTH)
|
|
147
|
+
: mode | fs.constants.S_IWUSR
|
|
148
|
+
|
|
149
|
+
// log.trace(
|
|
150
|
+
// `set ${inputPath} from ${mode.toString(8)} to ${newMode.toString(8)}`)
|
|
151
|
+
await fs.chmod(inputPath, newMode)
|
|
152
|
+
|
|
153
|
+
const actualStat = await fs.stat(inputPath)
|
|
154
|
+
// log.trace(`actual ${inputPath} is ${actualStat.mode.toString(8)}`)
|
|
155
|
+
|
|
156
|
+
// Safety net: These validations verify that the chmod operation succeeded.
|
|
157
|
+
// Modern file systems reliably apply permission changes, so these checks
|
|
158
|
+
// rarely fail. However, they detect edge cases such as:
|
|
159
|
+
// 1. File system permission restrictions (immutable flags, ACLs)
|
|
160
|
+
// 2. Race conditions where file permissions change between chmod and stat
|
|
161
|
+
// 3. Platform-specific behaviours with symbolic links
|
|
162
|
+
// 4. Network file systems with delayed or denied permission propagation
|
|
163
|
+
// The warnings alert developers to unexpected permission inconsistencies.
|
|
164
|
+
if (readOnly) {
|
|
165
|
+
/* c8 ignore start - safety net, normally it is set. */
|
|
166
|
+
if ((actualStat.mode & fs.constants.S_IWUSR) !== 0) {
|
|
167
|
+
log.warn(`${inputPath} not set to RO`)
|
|
168
|
+
}
|
|
169
|
+
/* c8 ignore stop */
|
|
170
|
+
} else {
|
|
171
|
+
/* c8 ignore start - safety net, normally it is not set. */
|
|
172
|
+
if ((actualStat.mode & fs.constants.S_IWUSR) === 0) {
|
|
173
|
+
log.warn(`${inputPath} not set to RW`)
|
|
174
|
+
}
|
|
175
|
+
/* c8 ignore stop */
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// If RW, process the folder after changing it to RW.
|
|
179
|
+
if (!readOnly && stat.isDirectory()) {
|
|
180
|
+
log.trace(inputPath)
|
|
181
|
+
const dirents = await fs.readdir(inputPath, {
|
|
182
|
+
withFileTypes: true,
|
|
183
|
+
})
|
|
184
|
+
for (const dirent of dirents) {
|
|
185
|
+
await chmodRecursively({
|
|
186
|
+
inputPath: path.resolve(inputPath, dirent.name),
|
|
187
|
+
readOnly,
|
|
188
|
+
log,
|
|
189
|
+
depth: depth + 1,
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ----------------------------------------------------------------------------
|