@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
package/src/README.md CHANGED
@@ -1,10 +1,397 @@
1
- # src
1
+ # Source Code Documentation
2
2
 
3
- This folder includes the main TypeScript source files, that provide
4
- the project functionality.
3
+ This folder contains the TypeScript source files that provide the core functionality of the xpm-lib library.
5
4
 
6
- They are compiled by `tsc` into the top `dist` folder as ES6 code.
5
+ ## Overview
7
6
 
8
- ## CommonJS backward compatibility
7
+ **Total Lines:** ~9,826 lines across 15 TypeScript files
8
+ **Build Output:** Compiled by `tsc` to ES6 modules in the `dist/` folder
9
+ **Module System:** ES modules with `.js` extensions in imports
9
10
 
10
- Starting with version 3.x, compatibility with CommonJS was removed.
11
+ ## Architecture
12
+
13
+ The library implements a sophisticated **two-phase lazy evaluation pattern** for optimal performance:
14
+
15
+ ### Phase 1: Collection Initialisation
16
+
17
+ When `Actions` or `BuildConfigurations` collections are initialised, only template names are expanded using matrix parameters. Template content remains unevaluated.
18
+
19
+ ```typescript
20
+ const buildConfigurations = new BuildConfigurations({ ... })
21
+ await buildConfigurations.initialise() // Expands names only
22
+ ```
23
+
24
+ ### Phase 2: Item Retrieval & Initialisation
25
+
26
+ Individual items are fully evaluated only when accessed and explicitly initialised:
27
+
28
+ ```typescript
29
+ const config = buildConfigurations.get('release-x64')
30
+ await config.initialise() // Now processes content, inheritance, etc.
31
+ ```
32
+
33
+ **Benefits:**
34
+
35
+ - ⚡ Performance: Only used configurations incur processing cost
36
+ - 💾 Memory: Deferred object creation until needed
37
+ - 🔄 Flexibility: Template expansion without content evaluation
38
+
39
+ ## Folder Structure
40
+
41
+ ```
42
+ src/
43
+ ├── classes/ # Core domain classes
44
+ │ ├── actions.ts # Action collections and individual actions
45
+ │ ├── build-configurations.ts # Build configuration management
46
+ │ ├── combinations-generator.ts # Cartesian product for matrices
47
+ │ ├── data-model.ts # Package data model and variable hierarchy
48
+ │ ├── errors.ts # Custom error type hierarchy
49
+ │ ├── init-template-base.ts # Base class for init templates
50
+ │ ├── liquid-drop.ts # Liquid template variable drops
51
+ │ ├── liquid-engine.ts # Custom Liquid engine with filters
52
+ │ ├── package.ts # Package.json management
53
+ │ ├── platform-detector.ts # OS and architecture detection
54
+ │ ├── policies.ts # Version compatibility policies
55
+ │ └── template-expander.ts # Generic template expansion engine
56
+
57
+ ├── data/ # Static data and constants
58
+ │ └── substitutions-variables.ts # Base substitution variables
59
+
60
+ ├── functions/ # Pure utility functions
61
+ │ ├── chmod-recursively.ts # File permission utilities
62
+ │ ├── filter-paths.ts # Path sanitisation filters
63
+ │ ├── is-something.ts # Type guard utilities
64
+ │ ├── matrix-expander.ts # Matrix parameter processing
65
+ │ ├── perform-substitutions.ts # Liquid template substitution
66
+ │ └── utils.ts # General utility functions
67
+
68
+ ├── types/ # TypeScript type definitions
69
+ │ ├── json.ts # JSON structure type definitions
70
+ │ ├── xpm-init-template.ts # Init template types
71
+ │ └── xpm.ts # Core xpm types
72
+
73
+ └── index.ts # Public API exports
74
+ ```
75
+
76
+ ## Key Components
77
+
78
+ ### Classes
79
+
80
+ #### Core Domain Classes
81
+
82
+ - **`BuildConfigurations`** / **`BuildConfiguration`** - Manages build configurations with inheritance, template expansion, and property merging
83
+ - **`Actions`** / **`Action`** - Manages executable actions with Liquid template support
84
+ - **`DataModel`** - Top-level coordinator for package processing and variable hierarchy
85
+ - **`Package`** - Package.json loading, validation, and capability detection
86
+
87
+ #### Template Processing
88
+
89
+ - **`TemplateExpander`** - Generic template expansion with matrix parameters
90
+ - **`CombinationsGenerator`** - Cartesian product computation for matrix expansion
91
+ - **`LiquidEngine`** - Custom Liquid engine with xpm-specific filters
92
+ - **`LiquidPropertiesDrop`** / **`LiquidMatrixDrop`** - Liquid variable access with strict validation
93
+
94
+ #### Utilities
95
+
96
+ - **`PlatformDetector`** - Cross-platform OS and architecture detection
97
+ - **`Policies`** - Version compatibility and feature flags
98
+ - **`InitTemplateBase`** - Abstract base for project initialisation templates
99
+
100
+ ### Functions
101
+
102
+ Pure utility functions organised by purpose:
103
+
104
+ - **Type Guards:** `isString()`, `isNumber()`, `isJsonObject()`, etc.
105
+ - **Template Detection:** `hasLiquidSyntax()`, `performSubstitutions()`
106
+ - **Path Operations:** `filterPath()`, `chmodRecursively()`
107
+ - **Matrix Processing:** `processMatrixForExpansion()`
108
+ - **Error Handling:** `getErrorMessage()`
109
+
110
+ ### Types
111
+
112
+ Comprehensive TypeScript definitions:
113
+
114
+ - **`json.ts`** - All JSON structure types for package.json and xpack section
115
+ - **`xpm.ts`** - Core xpm types (Context, etc.)
116
+ - **`xpm-init-template.ts`** - Init template property definitions
117
+
118
+ ## Error Hierarchy
119
+
120
+ Well-defined error types for semantic error handling:
121
+
122
+ ```typescript
123
+ // Parsing errors
124
+ JsonSyntaxError // Malformed JSON
125
+
126
+ // Configuration errors
127
+ ConfigurationError // Invalid configuration content
128
+ TemplateError // Template evaluation failures
129
+
130
+ // User input errors
131
+ InputError // Invalid command-line arguments or user input
132
+ PrerequisitesError // Missing dependencies or incompatible versions
133
+
134
+ // Output errors
135
+ OutputError // File generation or output failures
136
+ ```
137
+
138
+ ## Design Patterns
139
+
140
+ ### 1. Lazy Initialisation
141
+
142
+ Classes use two-step initialisation (constructor + `initialise()` method) to defer expensive operations:
143
+
144
+ ```typescript
145
+ class BuildConfigurations {
146
+ protected _isInitialised = false
147
+
148
+ async initialise(): Promise<boolean> {
149
+ if (this._isInitialised) return true
150
+ // Perform expensive operations
151
+ this._isInitialised = true
152
+ return true
153
+ }
154
+ }
155
+ ```
156
+
157
+ ### 2. Template Inheritance
158
+
159
+ Build configurations support multiple inheritance with circular reference detection:
160
+
161
+ ```typescript
162
+ {
163
+ "release-x64": {
164
+ "inherits": ["common", "release-base"],
165
+ "properties": { /* overrides */ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### 3. Matrix Expansion
171
+
172
+ Templates generate multiple concrete instances from matrix parameters:
173
+
174
+ ```typescript
175
+ {
176
+ "release-{{ matrix.arch }}": {
177
+ "matrix": {
178
+ "arch": ["x64", "arm64", "ia32"]
179
+ },
180
+ "template": { /* configuration */ }
181
+ }
182
+ }
183
+ // Generates: release-x64, release-arm64, release-ia32
184
+ ```
185
+
186
+ ### 4. Dependency Injection
187
+
188
+ All classes accept dependencies via constructor parameters:
189
+
190
+ ```typescript
191
+ constructor({
192
+ engine,
193
+ substitutionsVariables,
194
+ log,
195
+ }: BuildConfigurationsConstructorParameters) {
196
+ // No hard dependencies on singletons
197
+ }
198
+ ```
199
+
200
+ ## Variable Hierarchy
201
+
202
+ Substitution variables follow a clear hierarchy:
203
+
204
+ ```
205
+ liquidSubstitutionsVariablesBase (sealed)
206
+ ├── env: { ... } # Environment variables
207
+ ├── os: { platform, arch, ... } # Platform detection
208
+ └── path: { sep, delimiter, ... } # Path utilities
209
+
210
+ DataModel.substitutionsVariables (sealed)
211
+ ├── [base variables]
212
+ ├── package: { name, version, ... } # Package metadata
213
+ └── properties: { ... } # User-defined properties
214
+
215
+ BuildConfiguration._substitutionsVariables
216
+ ├── [package variables]
217
+ ├── configuration: { name, ... } # Configuration context
218
+ ├── properties: { ... } # Merged inherited properties
219
+ └── matrix: { ... } # Template matrix parameters
220
+ ```
221
+
222
+ ## Coding Conventions
223
+
224
+ ### TypeScript
225
+
226
+ - Use strict type checking
227
+ - Prefer interfaces for public APIs
228
+ - Use type guards for runtime validation
229
+ - Avoid `any` (use `unknown` when type is truly unknown)
230
+
231
+ ### Naming
232
+
233
+ - **Classes:** PascalCase (`BuildConfiguration`)
234
+ - **Interfaces:** PascalCase with descriptive suffixes (`BuildConfigurationConstructorParameters`)
235
+ - **Functions:** camelCase (`hasLiquidSyntax`)
236
+ - **Constants:** SCREAMING_SNAKE_CASE or descriptive names
237
+ - **Protected/Private:** Prefix with underscore (`_isInitialised`)
238
+
239
+ ### Async Patterns
240
+
241
+ - Always use `async/await` (no callbacks)
242
+ - Return `Promise<boolean>` from `initialise()` methods
243
+ - Use `Promise<void>` for operations without return values
244
+
245
+ ### Error Handling
246
+
247
+ - Use specific error types from error hierarchy
248
+ - Include context in error messages
249
+ - Throw synchronously when possible (no wrapping in Promise.reject)
250
+
251
+ ### Documentation
252
+
253
+ - Comprehensive TSDoc for all public APIs
254
+ - Use `@remarks` for detailed explanations
255
+ - Document `@throws` conditions
256
+ - Keep line length ≤80 characters in comments
257
+
258
+ ## File Size Guidelines
259
+
260
+ **Current State:**
261
+
262
+ - ✅ Most files: 200-800 lines (appropriate)
263
+ - ⚠️ `build-configurations.ts`: 2,155 lines (consider splitting)
264
+ - ⚠️ `actions.ts`: 1,160 lines (consider splitting)
265
+ - ⚠️ `init-template-base.ts`: 1,027 lines (manageable)
266
+
267
+ **Recommendations:**
268
+
269
+ - Target: <800 lines per file
270
+ - Split at: >1,000 lines
271
+ - Extract: Complex subsystems into separate files
272
+
273
+ See [CODE-REVIEW.md](./CODE-REVIEW.md) for detailed analysis and refactoring recommendations.
274
+
275
+ ## Development Workflow
276
+
277
+ ### Building
278
+
279
+ ```bash
280
+ npm run compile # Compile TypeScript to dist/
281
+ npm run compile-clean # Clean and compile
282
+ npm run watch # Watch mode for development
283
+ ```
284
+
285
+ ### Testing
286
+
287
+ ```bash
288
+ npm test # Run all tests
289
+ npm run test-coverage # Generate coverage report
290
+ ```
291
+
292
+ ### Linting
293
+
294
+ ```bash
295
+ npm run lint # ESLint check
296
+ npm run lint-fix # Auto-fix linting issues
297
+ ```
298
+
299
+ ### API Documentation
300
+
301
+ ```bash
302
+ cd website
303
+ npm run build-api # Generate API reference
304
+ ```
305
+
306
+ ## Common Tasks
307
+
308
+ ### Adding a New Class
309
+
310
+ 1. Create file in appropriate folder (`classes/`, `functions/`, etc.)
311
+ 2. Add comprehensive TSDoc comments
312
+ 3. Export from `index.ts`
313
+ 4. Add corresponding tests in `tests/tap/`
314
+ 5. Update API documentation if needed
315
+
316
+ ### Adding a Liquid Filter
317
+
318
+ In `liquid-engine.ts`:
319
+
320
+ ```typescript
321
+ this.registerFilter('filterName', (value: string, arg?: string) => {
322
+ // Implementation
323
+ return processedValue
324
+ })
325
+ ```
326
+
327
+ Then add tests in `tests/tap/classes/liquid-engine.ts`.
328
+
329
+ ### Adding Type Definitions
330
+
331
+ 1. Add types to appropriate file in `types/`
332
+ 2. Use descriptive names with `Json` prefix for JSON structures
333
+ 3. Export from type file (already re-exported by index.ts)
334
+ 4. Add type validation in runtime code
335
+
336
+ ## Performance Considerations
337
+
338
+ ### Lazy Loading ⚡
339
+
340
+ - Collections expand template names without evaluating content
341
+ - Items initialised only when accessed
342
+ - Caching of expanded names and instances
343
+
344
+ ### Efficient Data Structures
345
+
346
+ - Maps for O(1) lookups of configurations and actions
347
+ - Sets for O(1) duplicate detection
348
+ - Cached arrays for repeated access to names
349
+
350
+ ### Memory Management
351
+
352
+ - Sealed substitution variable objects (no accidental modification)
353
+ - References to parent collections (no deep cloning)
354
+ - Deferred instantiation of configurations and actions
355
+
356
+ ## Security Considerations
357
+
358
+ ### Template Injection
359
+
360
+ - Liquid templates are sourced from package.json (user's own code)
361
+ - Liquid engine is sandboxed (no filesystem access by default)
362
+ - Consider template size limits for production use
363
+
364
+ ### Path Traversal
365
+
366
+ - All paths resolved relative to package folder
367
+ - No user-provided paths accepted without validation
368
+ - Build folder paths sanitised
369
+
370
+ ### Command Execution
371
+
372
+ - Action commands are user-defined (trusted code)
373
+ - If accepting commands from external sources, sanitisation required
374
+
375
+ ## Related Documentation
376
+
377
+ - **[Code Review](./CODE-REVIEW.md)** - Comprehensive analysis with improvement recommendations
378
+ - **[API Reference](../website/docs/api/)** - Generated API documentation
379
+ - **[Test Suite](../tests/tap/README.md)** - Test organisation and conventions
380
+ - **[Main README](../README.md)** - Project overview and usage
381
+
382
+ ## Contributing
383
+
384
+ When contributing to the source code:
385
+
386
+ 1. Follow existing code style and conventions
387
+ 2. Add comprehensive TSDoc comments
388
+ 3. Write tests for all new functionality
389
+ 4. Ensure all tests pass (`npm test`)
390
+ 5. Run linter (`npm run lint-fix`)
391
+ 6. Update documentation as needed
392
+
393
+ ## Questions?
394
+
395
+ - **Issues:** https://github.com/xpack/xpm-lib-ts/issues
396
+ - **Discussions:** https://github.com/xpack/xpm-lib-ts/discussions
397
+ - **Documentation:** https://xpack.github.io/xpm-lib/