@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.
Files changed (202) hide show
  1. package/README.md +16 -212
  2. package/dist/classes/actions.d.ts +58 -0
  3. package/dist/classes/actions.d.ts.map +1 -0
  4. package/dist/classes/actions.js +250 -0
  5. package/dist/classes/actions.js.map +1 -0
  6. package/dist/classes/build-configurations.d.ts +78 -0
  7. package/dist/classes/build-configurations.d.ts.map +1 -0
  8. package/dist/classes/build-configurations.js +489 -0
  9. package/dist/classes/build-configurations.js.map +1 -0
  10. package/dist/classes/combinations-generator.d.ts +19 -0
  11. package/dist/classes/combinations-generator.d.ts.map +1 -0
  12. package/dist/classes/combinations-generator.js +48 -0
  13. package/dist/classes/combinations-generator.js.map +1 -0
  14. package/dist/classes/data-model.d.ts +21 -0
  15. package/dist/classes/data-model.d.ts.map +1 -0
  16. package/dist/classes/data-model.js +47 -0
  17. package/dist/classes/data-model.js.map +1 -0
  18. package/dist/classes/errors.d.ts +13 -0
  19. package/dist/classes/errors.d.ts.map +1 -0
  20. package/dist/classes/errors.js +13 -0
  21. package/dist/classes/errors.js.map +1 -0
  22. package/dist/classes/init-template-base.d.ts +47 -0
  23. package/dist/classes/init-template-base.d.ts.map +1 -0
  24. package/dist/classes/init-template-base.js +358 -0
  25. package/dist/classes/init-template-base.js.map +1 -0
  26. package/dist/classes/liquid-drop.d.ts +28 -0
  27. package/dist/classes/liquid-drop.d.ts.map +1 -0
  28. package/dist/classes/liquid-drop.js +70 -0
  29. package/dist/classes/liquid-drop.js.map +1 -0
  30. package/dist/classes/liquid-engine.d.ts +7 -0
  31. package/dist/classes/liquid-engine.d.ts.map +1 -0
  32. package/dist/classes/liquid-engine.js +72 -0
  33. package/dist/classes/liquid-engine.js.map +1 -0
  34. package/dist/classes/package.d.ts +31 -0
  35. package/dist/classes/package.d.ts.map +1 -0
  36. package/dist/classes/package.js +268 -0
  37. package/dist/classes/package.js.map +1 -0
  38. package/dist/classes/platform-detector.d.ts +14 -0
  39. package/dist/classes/platform-detector.d.ts.map +1 -0
  40. package/dist/classes/platform-detector.js +26 -0
  41. package/dist/classes/platform-detector.js.map +1 -0
  42. package/dist/classes/policies.d.ts +14 -0
  43. package/dist/classes/policies.d.ts.map +1 -0
  44. package/dist/classes/policies.js +20 -0
  45. package/dist/classes/policies.js.map +1 -0
  46. package/dist/classes/template-expander.d.ts +29 -0
  47. package/dist/classes/template-expander.d.ts.map +1 -0
  48. package/dist/classes/template-expander.js +62 -0
  49. package/dist/classes/template-expander.js.map +1 -0
  50. package/dist/data/substitutions-variables.d.ts +43 -0
  51. package/dist/data/substitutions-variables.d.ts.map +1 -0
  52. package/dist/{lib → data}/substitutions-variables.js +1 -16
  53. package/dist/data/substitutions-variables.js.map +1 -0
  54. package/dist/functions/chmod-recursively.d.ts +9 -0
  55. package/dist/functions/chmod-recursively.d.ts.map +1 -0
  56. package/dist/functions/chmod-recursively.js +66 -0
  57. package/dist/functions/chmod-recursively.js.map +1 -0
  58. package/dist/functions/filter-paths.d.ts +5 -0
  59. package/dist/functions/filter-paths.d.ts.map +1 -0
  60. package/dist/functions/filter-paths.js +16 -0
  61. package/dist/functions/filter-paths.js.map +1 -0
  62. package/dist/functions/is-something.d.ts +9 -0
  63. package/dist/functions/is-something.d.ts.map +1 -0
  64. package/dist/functions/is-something.js +25 -0
  65. package/dist/functions/is-something.js.map +1 -0
  66. package/dist/functions/matrix-expander.d.ts +17 -0
  67. package/dist/functions/matrix-expander.d.ts.map +1 -0
  68. package/dist/functions/matrix-expander.js +52 -0
  69. package/dist/functions/matrix-expander.js.map +1 -0
  70. package/dist/functions/perform-substitutions.d.ts +12 -0
  71. package/dist/functions/perform-substitutions.d.ts.map +1 -0
  72. package/dist/functions/perform-substitutions.js +76 -0
  73. package/dist/functions/perform-substitutions.js.map +1 -0
  74. package/dist/functions/utils.d.ts +8 -0
  75. package/dist/functions/utils.d.ts.map +1 -0
  76. package/dist/functions/utils.js +16 -0
  77. package/dist/functions/utils.js.map +1 -0
  78. package/dist/index.d.ts +22 -15
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +22 -29
  81. package/dist/index.js.map +1 -1
  82. package/dist/{lib/types.d.ts → types/json.d.ts} +31 -22
  83. package/dist/types/json.d.ts.map +1 -0
  84. package/dist/types/json.js +2 -0
  85. package/dist/types/json.js.map +1 -0
  86. package/dist/types/xpm-init-template.d.ts +21 -0
  87. package/dist/types/xpm-init-template.d.ts.map +1 -0
  88. package/dist/types/xpm-init-template.js +2 -0
  89. package/dist/types/xpm-init-template.js.map +1 -0
  90. package/dist/types/xpm.d.ts +16 -0
  91. package/dist/types/xpm.d.ts.map +1 -0
  92. package/dist/types/xpm.js +2 -0
  93. package/dist/types/xpm.js.map +1 -0
  94. package/package.json +53 -44
  95. package/src/CODE-REVIEW.md +2167 -0
  96. package/src/README.md +393 -6
  97. package/src/classes/actions.ts +1157 -0
  98. package/src/classes/build-configurations.ts +2127 -0
  99. package/src/classes/combinations-generator.ts +331 -0
  100. package/src/classes/data-model.ts +337 -0
  101. package/src/classes/errors.ts +105 -0
  102. package/src/classes/init-template-base.ts +1028 -0
  103. package/src/classes/liquid-drop.ts +376 -0
  104. package/src/classes/liquid-engine.ts +249 -0
  105. package/src/classes/package.ts +765 -0
  106. package/src/classes/platform-detector.ts +237 -0
  107. package/src/classes/policies.ts +200 -0
  108. package/src/classes/template-expander.ts +330 -0
  109. package/src/data/substitutions-variables.ts +390 -0
  110. package/src/functions/chmod-recursively.ts +195 -0
  111. package/src/functions/filter-paths.ts +126 -0
  112. package/src/functions/is-something.ts +223 -0
  113. package/src/functions/matrix-expander.ts +172 -0
  114. package/src/functions/perform-substitutions.ts +253 -0
  115. package/src/functions/utils.ts +151 -0
  116. package/src/index.ts +72 -19
  117. package/src/types/json.ts +519 -0
  118. package/src/types/xpm-init-template.ts +282 -0
  119. package/src/types/xpm.ts +162 -0
  120. package/dist/lib/chmod-recursive.d.ts +0 -7
  121. package/dist/lib/chmod-recursive.d.ts.map +0 -1
  122. package/dist/lib/chmod-recursive.js +0 -81
  123. package/dist/lib/chmod-recursive.js.map +0 -1
  124. package/dist/lib/errors.d.ts +0 -11
  125. package/dist/lib/errors.d.ts.map +0 -1
  126. package/dist/lib/errors.js +0 -26
  127. package/dist/lib/errors.js.map +0 -1
  128. package/dist/lib/functions/chmod-recursive.d.ts +0 -7
  129. package/dist/lib/functions/chmod-recursive.d.ts.map +0 -1
  130. package/dist/lib/functions/chmod-recursive.js +0 -81
  131. package/dist/lib/functions/chmod-recursive.js.map +0 -1
  132. package/dist/lib/functions/perform-substitutions.d.ts +0 -20
  133. package/dist/lib/functions/perform-substitutions.d.ts.map +0 -1
  134. package/dist/lib/functions/perform-substitutions.js +0 -85
  135. package/dist/lib/functions/perform-substitutions.js.map +0 -1
  136. package/dist/lib/functions/utils.d.ts +0 -30
  137. package/dist/lib/functions/utils.d.ts.map +0 -1
  138. package/dist/lib/functions/utils.js +0 -70
  139. package/dist/lib/functions/utils.js.map +0 -1
  140. package/dist/lib/init-template-base.d.ts +0 -46
  141. package/dist/lib/init-template-base.d.ts.map +0 -1
  142. package/dist/lib/init-template-base.js +0 -281
  143. package/dist/lib/init-template-base.js.map +0 -1
  144. package/dist/lib/liquid-actions.d.ts +0 -37
  145. package/dist/lib/liquid-actions.d.ts.map +0 -1
  146. package/dist/lib/liquid-actions.js +0 -148
  147. package/dist/lib/liquid-actions.js.map +0 -1
  148. package/dist/lib/liquid-build-configurations.d.ts +0 -47
  149. package/dist/lib/liquid-build-configurations.d.ts.map +0 -1
  150. package/dist/lib/liquid-build-configurations.js +0 -282
  151. package/dist/lib/liquid-build-configurations.js.map +0 -1
  152. package/dist/lib/liquid-drop.d.ts +0 -13
  153. package/dist/lib/liquid-drop.d.ts.map +0 -1
  154. package/dist/lib/liquid-drop.js +0 -56
  155. package/dist/lib/liquid-drop.js.map +0 -1
  156. package/dist/lib/liquid-engine.d.ts +0 -5
  157. package/dist/lib/liquid-engine.d.ts.map +0 -1
  158. package/dist/lib/liquid-engine.js +0 -85
  159. package/dist/lib/liquid-engine.js.map +0 -1
  160. package/dist/lib/liquid-package.d.ts +0 -17
  161. package/dist/lib/liquid-package.d.ts.map +0 -1
  162. package/dist/lib/liquid-package.js +0 -70
  163. package/dist/lib/liquid-package.js.map +0 -1
  164. package/dist/lib/package.d.ts +0 -66
  165. package/dist/lib/package.d.ts.map +0 -1
  166. package/dist/lib/package.js +0 -700
  167. package/dist/lib/package.js.map +0 -1
  168. package/dist/lib/perform-substitutions.d.ts +0 -20
  169. package/dist/lib/perform-substitutions.d.ts.map +0 -1
  170. package/dist/lib/perform-substitutions.js +0 -85
  171. package/dist/lib/perform-substitutions.js.map +0 -1
  172. package/dist/lib/policies.d.ts +0 -14
  173. package/dist/lib/policies.d.ts.map +0 -1
  174. package/dist/lib/policies.js +0 -33
  175. package/dist/lib/policies.js.map +0 -1
  176. package/dist/lib/substitutions-variables.d.ts +0 -117
  177. package/dist/lib/substitutions-variables.d.ts.map +0 -1
  178. package/dist/lib/substitutions-variables.js.map +0 -1
  179. package/dist/lib/types.d.ts.map +0 -1
  180. package/dist/lib/types.js +0 -13
  181. package/dist/lib/types.js.map +0 -1
  182. package/dist/lib/utils.d.ts +0 -30
  183. package/dist/lib/utils.d.ts.map +0 -1
  184. package/dist/lib/utils.js +0 -70
  185. package/dist/lib/utils.js.map +0 -1
  186. package/dist/tsconfig.tsbuildinfo +0 -1
  187. package/src/lib/errors.ts +0 -29
  188. package/src/lib/functions/chmod-recursive.ts +0 -103
  189. package/src/lib/functions/perform-substitutions.ts +0 -116
  190. package/src/lib/functions/utils.ts +0 -88
  191. package/src/lib/init-template-base.ts +0 -408
  192. package/src/lib/liquid-actions.ts +0 -223
  193. package/src/lib/liquid-build-configurations.ts +0 -433
  194. package/src/lib/liquid-drop.ts +0 -99
  195. package/src/lib/liquid-engine.ts +0 -135
  196. package/src/lib/liquid-package.ts +0 -108
  197. package/src/lib/package.ts +0 -947
  198. package/src/lib/policies.ts +0 -51
  199. package/src/lib/substitutions-variables.ts +0 -177
  200. package/src/lib/types.ts +0 -109
  201. package/src/package.json +0 -3
  202. package/src/tsconfig.json +0 -10
@@ -0,0 +1,237 @@
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
+ /**
15
+ * Platform information structure for runtime environment detection.
16
+ *
17
+ * @remarks
18
+ * This interface encapsulates operating system and architecture information
19
+ * used throughout the xPack library for platform-specific behaviour,
20
+ * path filtering, and binary distribution selection.
21
+ */
22
+ export interface PlatformInfo {
23
+ /**
24
+ * The operating system platform identifier.
25
+ *
26
+ * @remarks
27
+ * Common values include:
28
+ *
29
+ * <ul>
30
+ * <li><code>darwin</code> (macOS)</li>
31
+ * <li><code>linux</code> (Linux)</li>
32
+ * <li><code>win32</code> (Windows)</li>
33
+ * </ul>
34
+ *
35
+ * Corresponds to <code>process.platform</code> from Node.js.
36
+ */
37
+ platform: string
38
+
39
+ /**
40
+ * The CPU architecture identifier.
41
+ *
42
+ * @remarks
43
+ * Common values include:
44
+ *
45
+ * <ul>
46
+ * <li><code>x64</code> (64-bit Intel/AMD)</li>
47
+ * <li><code>arm64</code> (64-bit ARM)</li>
48
+ * <li><code>ia32</code> (32-bit Intel/AMD)</li>
49
+ * <li><code>arm</code> (32-bit ARM)</li>
50
+ * </ul>
51
+ *
52
+ * Corresponds to <code>process.arch</code> from Node.js.
53
+ */
54
+ arch: string
55
+ }
56
+
57
+ /**
58
+ * Options for platform information retrieval.
59
+ *
60
+ * @remarks
61
+ * This interface defines configuration options that control how platform
62
+ * information is retrieved and processed, particularly for architecture
63
+ * coercion scenarios.
64
+ */
65
+ export interface PlatformInfoOptions {
66
+ /**
67
+ * Whether to coerce 64-bit architectures to their 32-bit equivalents.
68
+ *
69
+ * @remarks
70
+ * When <code>true</code>, applies the following architecture mappings:
71
+ *
72
+ * <ul>
73
+ * <li><code>x64 → ia32</code></li>
74
+ * <li><code>arm64 → arm</code></li>
75
+ * </ul>
76
+ *
77
+ * This is useful for backward compatibility scenarios where only 32-bit
78
+ * binaries are available but can run on 64-bit systems.
79
+ *
80
+ * @defaultValue `false`
81
+ */
82
+ doForce32bit?: boolean
83
+ }
84
+
85
+ // ============================================================================
86
+
87
+ /**
88
+ * Platform detection service for runtime environment identification.
89
+ *
90
+ * @remarks
91
+ * This class encapsulates platform and architecture detection logic,
92
+ * providing a mockable abstraction over Node.js process properties.
93
+ * It enables testable platform-specific behaviour without requiring
94
+ * execution on multiple operating systems or architectures.
95
+ *
96
+ * Key features:
97
+ *
98
+ * <ol>
99
+ * <li><b>Dependency injection:</b> Accepts a custom process object via
100
+ * constructor, enabling test environments to inject mock process
101
+ * implementations.</li>
102
+ * <li><b>Architecture coercion:</b> Provides optional 64-bit to 32-bit
103
+ * architecture mapping for backward compatibility scenarios.</li>
104
+ * <li><b>Consistent interface:</b> Returns standardised
105
+ * {@link PlatformInfo} objects for use throughout the xPack library.</li>
106
+ * </ol>
107
+ *
108
+ * This abstraction eliminates direct <code>process.platform</code> and
109
+ * <code>process.arch</code> access in business logic, making platform-specific
110
+ * code paths testable via mocked platform information.
111
+ *
112
+ * @example
113
+ * Default usage with actual runtime platform:
114
+ * ```typescript
115
+ * const detector = new PlatformDetector()
116
+ * const info = detector.getPlatformInfo()
117
+ * console.log(info.platform) // 'darwin', 'linux', or 'win32'
118
+ * console.log(info.arch) // 'x64', 'arm64', etc.
119
+ * ```
120
+ *
121
+ * @example
122
+ * Testing with mocked platform:
123
+ * ```typescript
124
+ * const mockProcess = {
125
+ * platform: 'darwin',
126
+ * arch: 'arm64'
127
+ * } as NodeJS.Process
128
+ *
129
+ * const detector = new PlatformDetector(mockProcess)
130
+ * const info = detector.getPlatformInfo({ doForce32bit: true })
131
+ * // info.platform === 'darwin'
132
+ * // info.arch === 'arm' (coerced from arm64)
133
+ * ```
134
+ */
135
+ export class PlatformDetector {
136
+ // --------------------------------------------------------------------------
137
+ // Private Members.
138
+
139
+ /**
140
+ * The Node.js process object for accessing platform information.
141
+ */
142
+ private readonly process: NodeJS.Process
143
+
144
+ // --------------------------------------------------------------------------
145
+ // Constructor.
146
+
147
+ /**
148
+ * Constructs a platform detector instance.
149
+ *
150
+ * @remarks
151
+ * This constructor accepts an optional process object parameter, enabling
152
+ * dependency injection for testing scenarios. When no process object is
153
+ * provided, the global Node.js <code>process</code> is used automatically.
154
+ *
155
+ * The injected process object must implement the <code>platform</code> and
156
+ * <code>arch</code> properties from the <code>NodeJS.Process</code>
157
+ * interface.
158
+ *
159
+ * @param _process - The Node.js process object providing platform and
160
+ * architecture information. Defaults to the global <code>process</code>
161
+ * object.
162
+ */
163
+ constructor(_process: NodeJS.Process = globalThis.process) {
164
+ this.process = _process
165
+ }
166
+
167
+ // --------------------------------------------------------------------------
168
+ // Public Methods.
169
+
170
+ /**
171
+ * Retrieves current platform and architecture information.
172
+ *
173
+ * @remarks
174
+ * This method returns a {@link PlatformInfo} object containing the
175
+ * operating system platform and CPU architecture. When the
176
+ * <code>doForce32bit</code> option is enabled, 64-bit architectures
177
+ * are coerced to their 32-bit equivalents.
178
+ *
179
+ * Architecture coercion rules (when <code>doForce32bit</code> is
180
+ * <code>true</code>):
181
+ *
182
+ * <ul>
183
+ * <li><b>x64 → ia32:</b> Coerces 64-bit Intel/AMD to 32-bit.</li>
184
+ * <li><b>arm64 → arm:</b> Coerces 64-bit ARM to 32-bit.</li>
185
+ * </ul>
186
+ *
187
+ * This coercion is useful for backward compatibility scenarios where
188
+ * only 32-bit binaries are available but can run on 64-bit systems via
189
+ * compatibility layers.
190
+ *
191
+ * The platform identifier is never modified and always reflects the actual
192
+ * operating system (<code>darwin</code>, <code>linux</code>,
193
+ * <code>win32</code>).
194
+ *
195
+ * @param options - Configuration options controlling platform information
196
+ * retrieval.
197
+ * @returns Platform and architecture information.
198
+ */
199
+ getPlatformInfo(options: PlatformInfoOptions = {}): PlatformInfo {
200
+ const { doForce32bit = false } = options
201
+
202
+ let arch = this.process.arch
203
+
204
+ if (doForce32bit) {
205
+ // https://nodejs.org/docs/latest/api/process.html#processarch
206
+ if (arch === 'x64') {
207
+ arch = 'ia32'
208
+ } else if (arch === 'arm64') {
209
+ arch = 'arm'
210
+ }
211
+ }
212
+
213
+ return {
214
+ platform: this.process.platform,
215
+ arch,
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Checks whether the current platform is Windows.
221
+ *
222
+ * @remarks
223
+ * This convenience method provides a simple boolean check for Windows
224
+ * platform detection, commonly used for path handling and command
225
+ * formatting decisions.
226
+ *
227
+ * Equivalent to checking <code>platform === 'win32'</code>.
228
+ *
229
+ * @returns <code>true</code> if running on Windows,
230
+ * <code>false</code> otherwise.
231
+ */
232
+ isWindows(): boolean {
233
+ return this.process.platform === 'win32'
234
+ }
235
+ }
236
+
237
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,200 @@
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
+ // import assert from 'node:assert'
15
+
16
+ // https://nodejs.org/docs/latest/api/
17
+ import { Logger } from '@xpack/logger'
18
+
19
+ // https://www.npmjs.com/package/semver
20
+ import semver from 'semver'
21
+
22
+ // ============================================================================
23
+
24
+ /**
25
+ * Configuration parameters for constructing a policies instance.
26
+ *
27
+ * @remarks
28
+ * This interface defines the required configuration for creating an
29
+ * instance of {@link Policies}. Both properties are mandatory.
30
+ *
31
+ * The parameters provide the minimum <b>xpm</b> version for policy
32
+ * evaluation and the logger for diagnostic output.
33
+ */
34
+ export interface PoliciesConstructorParameters {
35
+ /**
36
+ * The minimum <b>xpm</b> version to evaluate.
37
+ */
38
+ minVersion: string
39
+
40
+ /**
41
+ * The logger instance for output and diagnostics.
42
+ */
43
+ log: Logger
44
+ }
45
+
46
+ /**
47
+ * Computes feature policy flags based on a minimum <b>xpm</b> version.
48
+ *
49
+ * @remarks
50
+ * This class derives compatibility flags from a specified minimum
51
+ * version to preserve legacy behaviour when required.
52
+ *
53
+ * Policy versioning allows <b>xpm</b> to evolve its behavior while maintaining
54
+ * backward compatibility for packages that specify older minimum versions.
55
+ * Each policy flag represents a breaking change introduced at a specific
56
+ * <b>xpm</b> version:
57
+ *
58
+ * <ul>
59
+ * <li>Packages with minimumXpmRequired \< version threshold get
60
+ * legacy behavior.</li>
61
+ * <li>Packages with minimumXpmRequired \>= version threshold get
62
+ * new behavior.</li>
63
+ * </ul>
64
+ *
65
+ * This approach ensures that:
66
+ *
67
+ * <ol>
68
+ * <li>Existing packages continue to work with newer <b>xpm</b> versions without
69
+ * modification.</li>
70
+ * <li>New packages can opt into modern behavior by specifying a recent
71
+ * minimumXpmRequired.</li>
72
+ * <li>Breaking changes are tied to explicit version declarations rather than
73
+ * <b>xpm</b> installation version.</li>
74
+ * </ol>
75
+ *
76
+ * Policy flags are evaluated once during initialization and cached for the
77
+ * duration of the operation.
78
+ */
79
+ export class Policies {
80
+ // --------------------------------------------------------------------------
81
+ // Public Members.
82
+
83
+ /**
84
+ * The minimum <b>xpm</b> version used to derive policy flags.
85
+ */
86
+ minVersion = '0.0.0'
87
+
88
+ /**
89
+ * Indicates whether npm dependencies are shared across installations.
90
+ *
91
+ * @remarks
92
+ * Legacy behavior (before 0.14.0): npm dependencies were shared in a global
93
+ * location, similar to how npm itself works with global `node_modules`.
94
+ *
95
+ * Modern behavior (0.14.0+): npm dependencies are installed locally per
96
+ * <b>xpm</b> package, providing better isolation and avoiding version
97
+ * conflicts.
98
+ *
99
+ * Set to `true` for packages with minimumXpmRequired \< 0.14.0.
100
+ */
101
+ shareNpmDependencies = false
102
+
103
+ /**
104
+ * Indicates whether local `xpacks` folders are non-hierarchical.
105
+ *
106
+ * @remarks
107
+ * Legacy behavior (before 0.16.0): xpacks were stored in a flat structure
108
+ * within the local `xpacks` folder.
109
+ *
110
+ * Modern behavior (0.16.0+): xpacks are organized hierarchically within
111
+ * the `xpacks` folder, mirroring the scoped package structure (e.g.,
112
+ * `xpacks/@scope/package`).
113
+ *
114
+ * Set to `true` for packages with minimumXpmRequired \< 0.16.0.
115
+ */
116
+ nonHierarchicalLocalXpacksFolder = false
117
+
118
+ /**
119
+ * Indicates whether dependencies are restricted to string-only notation.
120
+ *
121
+ * @remarks
122
+ * Legacy behavior (before 0.16.0): dependencies could only be specified as
123
+ * strings (e.g., `"@scope/package": "1.0.0"`).
124
+ *
125
+ * Modern behavior (0.16.0+): dependencies can be specified as objects with
126
+ * additional metadata (e.g., platforms, repositories), providing richer
127
+ * dependency configuration.
128
+ *
129
+ * Set to `true` for packages with minimumXpmRequired \< 0.16.0.
130
+ */
131
+ onlyStringDependencies = false
132
+
133
+ /**
134
+ * Indicates whether `xpm init` templates accept a single parameter.
135
+ *
136
+ * @remarks
137
+ * Legacy behavior (before 0.22.0): init templates accepted only a single
138
+ * parameter combining template name and optional arguments.
139
+ *
140
+ * Modern behavior (0.22.0+): init templates support multiple parameters
141
+ * for more flexible template initialization and configuration.
142
+ *
143
+ * Set to `true` for packages with minimumXpmRequired \< 0.22.0.
144
+ */
145
+ singleParameterXpmInitTemplate = false
146
+
147
+ // --------------------------------------------------------------------------
148
+ // Constructor.
149
+
150
+ /**
151
+ * Constructs policy flags based on a minimum <b>xpm</b> version.
152
+ *
153
+ * @remarks
154
+ * The constructor evaluates each policy flag by comparing the provided
155
+ * minimum version against threshold versions where behavior changed.
156
+ *
157
+ * Evaluation process:
158
+ *
159
+ * <ol>
160
+ * <li>Validate that <code>minVersion</code> is a valid semver string.</li>
161
+ * <li>If invalid, retain default values (all flags false = modern
162
+ * behavior).</li>
163
+ * <li>For each policy, use <code>semver.lt()</code> to check if
164
+ * <code>minVersion</code> is less than
165
+ * the threshold version.</li>
166
+ * <li>If <code>minVersion</code> \< threshold, enable legacy behavior
167
+ * (flag = <code>true</code>).</li>
168
+ * <li>If <code>minVersion</code> \>= threshold, use modern behavior
169
+ * (flag = <code>false</code>).</li>
170
+ * </ol>
171
+ *
172
+ * This ensures that packages explicitly declaring their minimum version
173
+ * get the behavior that was current at that version, while packages
174
+ * without a valid minimum version default to the most modern behavior.
175
+ *
176
+ * @param minVersion - The minimum <b>xpm</b> version to evaluate.
177
+ * @param log - The logger instance for output and diagnostics.
178
+ */
179
+ constructor({ minVersion, log }: PoliciesConstructorParameters) {
180
+ log.trace(`${Policies.name}({minVersion: ${minVersion})`)
181
+
182
+ if (semver.valid(minVersion) !== null) {
183
+ this.minVersion = minVersion
184
+
185
+ this.shareNpmDependencies = semver.lt(this.minVersion, '0.14.0')
186
+
187
+ this.nonHierarchicalLocalXpacksFolder = semver.lt(
188
+ this.minVersion,
189
+ '0.16.0'
190
+ )
191
+ this.onlyStringDependencies = semver.lt(this.minVersion, '0.16.0')
192
+
193
+ this.singleParameterXpmInitTemplate = semver.lt(this.minVersion, '0.22.0')
194
+ }
195
+
196
+ log.trace('policies:', this)
197
+ }
198
+ }
199
+
200
+ // ----------------------------------------------------------------------------