@unrdf/kgn 5.0.1 → 26.4.2
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/dist/index.mjs +9207 -0
- package/package.json +33 -28
- package/src/base/filter-templates.js +7 -1
- package/src/base/index.js +15 -10
- package/src/base/injection-targets.js +6 -0
- package/src/base/macro-templates.js +6 -0
- package/src/base/shacl-templates.js +6 -0
- package/src/base/template-base.js +7 -1
- package/src/core/attestor.js +50 -1
- package/src/core/filters.js +134 -1
- package/src/core/index.js +8 -1
- package/src/core/kgen-engine.js +49 -1
- package/src/core/parser.js +52 -1
- package/src/core/post-processor.js +7 -1
- package/src/core/renderer.js +67 -1
- package/src/doc-generator/mdx-generator.mjs +1 -1
- package/src/doc-generator/nav-generator.mjs +1 -1
- package/src/doc-generator/rdf-builder.mjs +2 -2
- package/src/engine/index.js +9 -0
- package/src/engine/pipeline.js +7 -1
- package/src/engine/renderer.js +18 -3
- package/src/engine/template-engine.js +12 -3
- package/src/filters/array.js +14 -6
- package/src/filters/index.js +165 -17
- package/src/filters/rdf.js +3 -3
- package/src/{index.js → index.mjs} +46 -0
- package/src/index.test.mjs +40 -0
- package/src/inheritance/index.js +19 -1
- package/src/injection/atomic-writer.js +22 -1
- package/src/injection/idempotency-manager.js +33 -0
- package/src/injection/injection-engine.js +46 -1
- package/src/injection/integration.js +3 -3
- package/src/injection/modes/index.js +30 -0
- package/src/injection/rollback-manager.js +26 -2
- package/src/injection/target-resolver.js +48 -3
- package/src/injection/tests/injection-engine.test.js +3 -3
- package/src/injection/tests/integration.test.js +2 -1
- package/src/injection/tests/run-tests.js +3 -0
- package/src/injection/validation-engine.js +71 -5
- package/src/linter/determinism-linter.js +20 -5
- package/src/linter/determinism.js +8 -2
- package/src/linter/index.js +3 -1
- package/src/linter/test-doubles.js +151 -4
- package/src/parser/frontmatter.js +6 -0
- package/src/parser/variables.js +7 -1
- package/src/rdf/filters.js +393 -0
- package/src/rdf/index.js +444 -0
- package/src/renderer/deterministic.js +6 -0
- package/src/renderer/index.js +3 -1
- package/src/templates/rdf/DELIVERY-SUMMARY.md +266 -0
- package/src/templates/rdf/README.md +595 -0
- package/src/templates/rdf/dataset.njk +83 -0
- package/src/templates/rdf/index.js +106 -0
- package/src/templates/rdf/jsonld-context.njk +63 -0
- package/src/templates/rdf/ontology.njk +107 -0
- package/src/templates/rdf/schema.njk +79 -0
- package/src/templates/rdf/shapes.njk +89 -0
- package/src/templates/rdf/sparql-queries.njk +70 -0
- package/src/templates/rdf/vocabulary.njk +79 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { promises as fs } from 'fs';
|
|
9
|
-
import { join, dirname, resolve, relative } from 'path';
|
|
9
|
+
import { join as _join, dirname, resolve as _resolve, relative as _relative } from 'path';
|
|
10
10
|
import { createHash } from 'crypto';
|
|
11
11
|
|
|
12
12
|
import { TargetResolver } from './target-resolver.js';
|
|
@@ -23,7 +23,13 @@ import {
|
|
|
23
23
|
OPERATION_METADATA
|
|
24
24
|
} from './constants.js';
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
26
29
|
export class InjectionEngine {
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
27
33
|
constructor(config = {}) {
|
|
28
34
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
29
35
|
|
|
@@ -127,6 +133,9 @@ export class InjectionEngine {
|
|
|
127
133
|
* Private Methods
|
|
128
134
|
*/
|
|
129
135
|
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
*/
|
|
130
139
|
_generateOperationId(templateConfig, content) {
|
|
131
140
|
const hash = createHash('sha256');
|
|
132
141
|
hash.update(JSON.stringify(templateConfig, null, 0));
|
|
@@ -135,6 +144,9 @@ export class InjectionEngine {
|
|
|
135
144
|
return `injection-${hash.digest('hex').substring(0, 16)}`;
|
|
136
145
|
}
|
|
137
146
|
|
|
147
|
+
/**
|
|
148
|
+
*
|
|
149
|
+
*/
|
|
138
150
|
async _beginOperation(operationId, templateConfig) {
|
|
139
151
|
this.activeOperations.set(operationId, {
|
|
140
152
|
id: operationId,
|
|
@@ -146,6 +158,9 @@ export class InjectionEngine {
|
|
|
146
158
|
});
|
|
147
159
|
}
|
|
148
160
|
|
|
161
|
+
/**
|
|
162
|
+
*
|
|
163
|
+
*/
|
|
149
164
|
async _validateAllTargets(targets, throwOnError = true) {
|
|
150
165
|
const results = [];
|
|
151
166
|
|
|
@@ -166,6 +181,9 @@ export class InjectionEngine {
|
|
|
166
181
|
return results;
|
|
167
182
|
}
|
|
168
183
|
|
|
184
|
+
/**
|
|
185
|
+
*
|
|
186
|
+
*/
|
|
169
187
|
async _filterIdempotentTargets(targets, content, variables) {
|
|
170
188
|
const filtered = [];
|
|
171
189
|
|
|
@@ -184,6 +202,9 @@ export class InjectionEngine {
|
|
|
184
202
|
return filtered;
|
|
185
203
|
}
|
|
186
204
|
|
|
205
|
+
/**
|
|
206
|
+
*
|
|
207
|
+
*/
|
|
187
208
|
async _checkIdempotency(targets, content, variables) {
|
|
188
209
|
const results = [];
|
|
189
210
|
|
|
@@ -197,6 +218,9 @@ export class InjectionEngine {
|
|
|
197
218
|
return results;
|
|
198
219
|
}
|
|
199
220
|
|
|
221
|
+
/**
|
|
222
|
+
*
|
|
223
|
+
*/
|
|
200
224
|
async _executeAtomicInjection(targets, content, variables, operationId) {
|
|
201
225
|
const operation = this.activeOperations.get(operationId);
|
|
202
226
|
operation.phase = 'executing';
|
|
@@ -211,6 +235,9 @@ export class InjectionEngine {
|
|
|
211
235
|
return await this._executeTransaction(targets, content, variables, operationId);
|
|
212
236
|
}
|
|
213
237
|
|
|
238
|
+
/**
|
|
239
|
+
*
|
|
240
|
+
*/
|
|
214
241
|
async _injectSingleTarget(target, content, variables, operationId) {
|
|
215
242
|
// Read current file content
|
|
216
243
|
const currentContent = await this._readTargetFile(target);
|
|
@@ -247,6 +274,9 @@ export class InjectionEngine {
|
|
|
247
274
|
};
|
|
248
275
|
}
|
|
249
276
|
|
|
277
|
+
/**
|
|
278
|
+
*
|
|
279
|
+
*/
|
|
250
280
|
async _executeTransaction(targets, content, variables, operationId) {
|
|
251
281
|
const transaction = await this.atomicWriter.beginTransaction(operationId);
|
|
252
282
|
|
|
@@ -290,6 +320,9 @@ export class InjectionEngine {
|
|
|
290
320
|
}
|
|
291
321
|
}
|
|
292
322
|
|
|
323
|
+
/**
|
|
324
|
+
*
|
|
325
|
+
*/
|
|
293
326
|
async _readTargetFile(target) {
|
|
294
327
|
if (target.mode === INJECTION_MODES.CREATE && target.createIfMissing) {
|
|
295
328
|
try {
|
|
@@ -309,6 +342,9 @@ export class InjectionEngine {
|
|
|
309
342
|
return await fs.readFile(target.resolvedPath, 'utf8');
|
|
310
343
|
}
|
|
311
344
|
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
*/
|
|
312
348
|
async _commitOperation(operationId, results) {
|
|
313
349
|
const operation = this.activeOperations.get(operationId);
|
|
314
350
|
operation.phase = 'committed';
|
|
@@ -329,6 +365,9 @@ export class InjectionEngine {
|
|
|
329
365
|
this.activeOperations.delete(operationId);
|
|
330
366
|
}
|
|
331
367
|
|
|
368
|
+
/**
|
|
369
|
+
*
|
|
370
|
+
*/
|
|
332
371
|
async _rollbackOperation(operationId, error) {
|
|
333
372
|
const operation = this.activeOperations.get(operationId);
|
|
334
373
|
|
|
@@ -353,6 +392,9 @@ export class InjectionEngine {
|
|
|
353
392
|
}
|
|
354
393
|
}
|
|
355
394
|
|
|
395
|
+
/**
|
|
396
|
+
*
|
|
397
|
+
*/
|
|
356
398
|
_wrapError(error, operationId) {
|
|
357
399
|
return new InjectionError(
|
|
358
400
|
error.message,
|
|
@@ -367,6 +409,9 @@ export class InjectionEngine {
|
|
|
367
409
|
* Custom error class for injection operations
|
|
368
410
|
*/
|
|
369
411
|
export class InjectionError extends Error {
|
|
412
|
+
/**
|
|
413
|
+
*
|
|
414
|
+
*/
|
|
370
415
|
constructor(message, code, operationId, originalError = null) {
|
|
371
416
|
super(message);
|
|
372
417
|
this.name = 'InjectionError';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Provides seamless injection support for template processing.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { inject, dryRun, processTemplate, initializeInjection } from './api.js';
|
|
8
|
+
import { inject, dryRun, processTemplate as _processTemplate, initializeInjection } from './api.js';
|
|
9
9
|
import { DEFAULT_CONFIG, INJECTION_MODES } from './constants.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -147,7 +147,7 @@ async function processInjectionTemplate(template, data, options, injectionEngine
|
|
|
147
147
|
/**
|
|
148
148
|
* Render template content (without injection)
|
|
149
149
|
*/
|
|
150
|
-
async function renderTemplateContent(content, data,
|
|
150
|
+
async function renderTemplateContent(content, data, _options) {
|
|
151
151
|
// Simple variable interpolation - in production use proper template engine
|
|
152
152
|
return content.replace(/\{\{(\w+)\}\}/g, (match, variable) => {
|
|
153
153
|
return data[variable] || match;
|
|
@@ -219,7 +219,7 @@ function parseFrontmatter(text) {
|
|
|
219
219
|
/**
|
|
220
220
|
* Create injection-aware template loader
|
|
221
221
|
*/
|
|
222
|
-
export function createInjectionTemplateLoader(baseLoader,
|
|
222
|
+
export function createInjectionTemplateLoader(baseLoader, _injectionConfig = {}) {
|
|
223
223
|
return {
|
|
224
224
|
...baseLoader,
|
|
225
225
|
|
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import { INJECTION_MODES, LINE_ENDINGS } from '../constants.js';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
10
13
|
export class InjectionModes {
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
11
17
|
constructor(config = {}) {
|
|
12
18
|
this.config = config;
|
|
13
19
|
}
|
|
@@ -241,6 +247,9 @@ export class InjectionModes {
|
|
|
241
247
|
* Helper Methods
|
|
242
248
|
*/
|
|
243
249
|
|
|
250
|
+
/**
|
|
251
|
+
*
|
|
252
|
+
*/
|
|
244
253
|
_normalizeContent(content) {
|
|
245
254
|
if (!content) return '';
|
|
246
255
|
|
|
@@ -253,6 +262,9 @@ export class InjectionModes {
|
|
|
253
262
|
return content;
|
|
254
263
|
}
|
|
255
264
|
|
|
265
|
+
/**
|
|
266
|
+
*
|
|
267
|
+
*/
|
|
256
268
|
_normalizeInjectionContent(content, variables) {
|
|
257
269
|
// Variable interpolation
|
|
258
270
|
let result = content.replace(/\{\{(\w+)\}\}/g, (match, variable) => {
|
|
@@ -267,12 +279,18 @@ export class InjectionModes {
|
|
|
267
279
|
return result;
|
|
268
280
|
}
|
|
269
281
|
|
|
282
|
+
/**
|
|
283
|
+
*
|
|
284
|
+
*/
|
|
270
285
|
_detectLineEnding(content) {
|
|
271
286
|
if (content.includes('\r\n')) return LINE_ENDINGS.CRLF;
|
|
272
287
|
if (content.includes('\r')) return LINE_ENDINGS.CR;
|
|
273
288
|
return LINE_ENDINGS.LF;
|
|
274
289
|
}
|
|
275
290
|
|
|
291
|
+
/**
|
|
292
|
+
*
|
|
293
|
+
*/
|
|
276
294
|
_findTargetLine(lines, pattern, target) {
|
|
277
295
|
if (target.regex) {
|
|
278
296
|
const flags = target.regexFlags || 'gm';
|
|
@@ -284,15 +302,24 @@ export class InjectionModes {
|
|
|
284
302
|
return lines.findIndex(line => line.includes(pattern));
|
|
285
303
|
}
|
|
286
304
|
|
|
305
|
+
/**
|
|
306
|
+
*
|
|
307
|
+
*/
|
|
287
308
|
_getLineIndentation(line) {
|
|
288
309
|
const match = line.match(/^(\s*)/);
|
|
289
310
|
return match ? match[1] : '';
|
|
290
311
|
}
|
|
291
312
|
|
|
313
|
+
/**
|
|
314
|
+
*
|
|
315
|
+
*/
|
|
292
316
|
_looksLikeImports(content) {
|
|
293
317
|
return /^import\s+.*from\s+['"][^'"]+['"];?\s*$/m.test(content);
|
|
294
318
|
}
|
|
295
319
|
|
|
320
|
+
/**
|
|
321
|
+
*
|
|
322
|
+
*/
|
|
296
323
|
_sortImports(content) {
|
|
297
324
|
const lineEnding = this._detectLineEnding(content);
|
|
298
325
|
const lines = content.split(lineEnding);
|
|
@@ -334,6 +361,9 @@ export class InjectionModes {
|
|
|
334
361
|
return content;
|
|
335
362
|
}
|
|
336
363
|
|
|
364
|
+
/**
|
|
365
|
+
*
|
|
366
|
+
*/
|
|
337
367
|
_extractImportSource(importLine) {
|
|
338
368
|
const match = importLine.match(/from\s+['"]([^'"]+)['"]/);
|
|
339
369
|
return match ? match[1] : '';
|
|
@@ -6,12 +6,18 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { promises as fs } from 'fs';
|
|
9
|
-
import { join, dirname, basename } from 'path';
|
|
9
|
+
import { join as _join, dirname, basename as _basename } from 'path';
|
|
10
10
|
import { createHash } from 'crypto';
|
|
11
11
|
|
|
12
|
-
import { ERROR_CODES, CHECKSUM_ALGORITHMS } from './constants.js';
|
|
12
|
+
import { ERROR_CODES as _ERROR_CODES, CHECKSUM_ALGORITHMS } from './constants.js';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
14
17
|
export class RollbackManager {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
15
21
|
constructor(config = {}) {
|
|
16
22
|
this.config = config;
|
|
17
23
|
this.rollbackHistory = new Map();
|
|
@@ -215,6 +221,9 @@ export class RollbackManager {
|
|
|
215
221
|
* Private Methods
|
|
216
222
|
*/
|
|
217
223
|
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
*/
|
|
218
227
|
async _restoreFromBackup(targetPath, backupPath) {
|
|
219
228
|
// Verify backup exists
|
|
220
229
|
try {
|
|
@@ -254,6 +263,9 @@ export class RollbackManager {
|
|
|
254
263
|
}
|
|
255
264
|
}
|
|
256
265
|
|
|
266
|
+
/**
|
|
267
|
+
*
|
|
268
|
+
*/
|
|
257
269
|
async _cleanupTemporaryFiles(operationData) {
|
|
258
270
|
// Clean up any temporary files created during operation
|
|
259
271
|
if (operationData.tempFiles) {
|
|
@@ -267,6 +279,9 @@ export class RollbackManager {
|
|
|
267
279
|
}
|
|
268
280
|
}
|
|
269
281
|
|
|
282
|
+
/**
|
|
283
|
+
*
|
|
284
|
+
*/
|
|
270
285
|
async _releaseLocks(operationData) {
|
|
271
286
|
// Release any locks held by the operation
|
|
272
287
|
if (operationData.locks) {
|
|
@@ -280,6 +295,9 @@ export class RollbackManager {
|
|
|
280
295
|
}
|
|
281
296
|
}
|
|
282
297
|
|
|
298
|
+
/**
|
|
299
|
+
*
|
|
300
|
+
*/
|
|
283
301
|
_getOperationHistory(operationId) {
|
|
284
302
|
// This would normally come from the injection engine's history
|
|
285
303
|
// For now, return a mock structure
|
|
@@ -291,10 +309,16 @@ export class RollbackManager {
|
|
|
291
309
|
};
|
|
292
310
|
}
|
|
293
311
|
|
|
312
|
+
/**
|
|
313
|
+
*
|
|
314
|
+
*/
|
|
294
315
|
_findOperationBackups(operationId) {
|
|
295
316
|
return this.operationBackups.get(operationId) || [];
|
|
296
317
|
}
|
|
297
318
|
|
|
319
|
+
/**
|
|
320
|
+
*
|
|
321
|
+
*/
|
|
298
322
|
async _calculateFileChecksum(filePath, algorithm = CHECKSUM_ALGORITHMS.SHA256) {
|
|
299
323
|
const content = await fs.readFile(filePath);
|
|
300
324
|
const hash = createHash(algorithm);
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { promises as fs } from 'fs';
|
|
9
|
-
import { resolve, join, relative, dirname, basename } from 'path';
|
|
9
|
+
import { resolve, join as _join, relative, dirname as _dirname, basename } from 'path';
|
|
10
10
|
// Simple glob implementation for basic pattern matching
|
|
11
11
|
// In production, use a proper glob library like 'glob' or 'fast-glob'
|
|
12
|
-
function simpleGlob(pattern,
|
|
12
|
+
function simpleGlob(pattern, _options = {}) {
|
|
13
13
|
// Very basic glob implementation for demo purposes
|
|
14
14
|
return Promise.resolve([]);
|
|
15
15
|
}
|
|
@@ -17,7 +17,13 @@ const glob = simpleGlob;
|
|
|
17
17
|
|
|
18
18
|
import { ERROR_CODES, DEFAULT_CONFIG } from './constants.js';
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
20
23
|
export class TargetResolver {
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
21
27
|
constructor(config = {}) {
|
|
22
28
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
23
29
|
this.projectRoot = config.projectRoot || process.cwd();
|
|
@@ -57,6 +63,9 @@ export class TargetResolver {
|
|
|
57
63
|
* Private Methods
|
|
58
64
|
*/
|
|
59
65
|
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
60
69
|
async _resolveSingleTarget(targetConfig, variables) {
|
|
61
70
|
let targetPath = targetConfig.to;
|
|
62
71
|
|
|
@@ -97,7 +106,10 @@ export class TargetResolver {
|
|
|
97
106
|
return target;
|
|
98
107
|
}
|
|
99
108
|
|
|
100
|
-
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
*/
|
|
112
|
+
async _resolveGlobTargets(globPattern, targetConfig, _variables) {
|
|
101
113
|
// Use glob to find matching files
|
|
102
114
|
const matches = await glob(globPattern, {
|
|
103
115
|
cwd: this.projectRoot,
|
|
@@ -143,6 +155,9 @@ export class TargetResolver {
|
|
|
143
155
|
return targets;
|
|
144
156
|
}
|
|
145
157
|
|
|
158
|
+
/**
|
|
159
|
+
*
|
|
160
|
+
*/
|
|
146
161
|
_interpolateVariables(template, variables) {
|
|
147
162
|
return template.replace(/\{\{(\w+)\}\}/g, (match, variable) => {
|
|
148
163
|
const value = variables[variable];
|
|
@@ -153,10 +168,16 @@ export class TargetResolver {
|
|
|
153
168
|
});
|
|
154
169
|
}
|
|
155
170
|
|
|
171
|
+
/**
|
|
172
|
+
*
|
|
173
|
+
*/
|
|
156
174
|
_isGlobPattern(path) {
|
|
157
175
|
return /[*?{}\[\]]/.test(path);
|
|
158
176
|
}
|
|
159
177
|
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
*/
|
|
160
181
|
_resolvePath(targetPath) {
|
|
161
182
|
// Convert to absolute path
|
|
162
183
|
if (!targetPath.startsWith('/')) {
|
|
@@ -165,6 +186,9 @@ export class TargetResolver {
|
|
|
165
186
|
return resolve(targetPath);
|
|
166
187
|
}
|
|
167
188
|
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
*/
|
|
168
192
|
_validatePath(resolvedPath) {
|
|
169
193
|
// Security: Prevent path traversal
|
|
170
194
|
if (this.config.preventPathTraversal) {
|
|
@@ -183,6 +207,9 @@ export class TargetResolver {
|
|
|
183
207
|
}
|
|
184
208
|
}
|
|
185
209
|
|
|
210
|
+
/**
|
|
211
|
+
*
|
|
212
|
+
*/
|
|
186
213
|
_applyExclusions(matches, exclusions) {
|
|
187
214
|
const exclusionPatterns = Array.isArray(exclusions) ? exclusions : [exclusions];
|
|
188
215
|
|
|
@@ -201,6 +228,9 @@ export class TargetResolver {
|
|
|
201
228
|
});
|
|
202
229
|
}
|
|
203
230
|
|
|
231
|
+
/**
|
|
232
|
+
*
|
|
233
|
+
*/
|
|
204
234
|
_matchesGlob(path, pattern) {
|
|
205
235
|
// Simple glob matching - in production, use minimatch or similar
|
|
206
236
|
const regex = pattern
|
|
@@ -211,6 +241,9 @@ export class TargetResolver {
|
|
|
211
241
|
return new RegExp(`^${regex}$`).test(path);
|
|
212
242
|
}
|
|
213
243
|
|
|
244
|
+
/**
|
|
245
|
+
*
|
|
246
|
+
*/
|
|
214
247
|
async _evaluateTargetCondition(target, condition) {
|
|
215
248
|
try {
|
|
216
249
|
// Check if file exists first
|
|
@@ -254,6 +287,9 @@ export class TargetResolver {
|
|
|
254
287
|
}
|
|
255
288
|
}
|
|
256
289
|
|
|
290
|
+
/**
|
|
291
|
+
*
|
|
292
|
+
*/
|
|
257
293
|
async _evaluateComplexCondition(target, content, condition) {
|
|
258
294
|
const { pattern, size, lines, encoding } = condition;
|
|
259
295
|
|
|
@@ -287,6 +323,9 @@ export class TargetResolver {
|
|
|
287
323
|
return true;
|
|
288
324
|
}
|
|
289
325
|
|
|
326
|
+
/**
|
|
327
|
+
*
|
|
328
|
+
*/
|
|
290
329
|
async _fileExists(filePath) {
|
|
291
330
|
try {
|
|
292
331
|
await fs.access(filePath);
|
|
@@ -296,12 +335,18 @@ export class TargetResolver {
|
|
|
296
335
|
}
|
|
297
336
|
}
|
|
298
337
|
|
|
338
|
+
/**
|
|
339
|
+
*
|
|
340
|
+
*/
|
|
299
341
|
_getFileExtension(filePath) {
|
|
300
342
|
const name = basename(filePath);
|
|
301
343
|
const dotIndex = name.lastIndexOf('.');
|
|
302
344
|
return dotIndex === -1 ? '' : name.slice(dotIndex);
|
|
303
345
|
}
|
|
304
346
|
|
|
347
|
+
/**
|
|
348
|
+
*
|
|
349
|
+
*/
|
|
305
350
|
_detectEncoding(content) {
|
|
306
351
|
// Simple encoding detection - in production use a proper library
|
|
307
352
|
try {
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* atomic operations, idempotency, and error handling.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
8
|
+
import { describe, test, expect, beforeEach, afterEach, vi as _vi } from 'vitest';
|
|
9
9
|
import { promises as fs } from 'fs';
|
|
10
|
-
import { join, dirname } from 'path';
|
|
10
|
+
import { join, dirname as _dirname } from 'path';
|
|
11
11
|
import { tmpdir } from 'os';
|
|
12
12
|
|
|
13
13
|
import { InjectionEngine } from '../injection-engine.js';
|
|
14
|
-
import { INJECTION_MODES, ERROR_CODES } from '../constants.js';
|
|
14
|
+
import { INJECTION_MODES, ERROR_CODES as _ERROR_CODES } from '../constants.js';
|
|
15
15
|
|
|
16
16
|
describe('InjectionEngine', () => {
|
|
17
17
|
let tempDir;
|
|
@@ -232,8 +232,9 @@ export default router;`;
|
|
|
232
232
|
};
|
|
233
233
|
|
|
234
234
|
const content = 'test content';
|
|
235
|
+
const variables = {};
|
|
235
236
|
|
|
236
|
-
await expect(inject(templateConfig, content, variables
|
|
237
|
+
await expect(inject(templateConfig, content, variables))
|
|
237
238
|
.rejects.toThrow(/Unknown injection mode/);
|
|
238
239
|
});
|
|
239
240
|
|
|
@@ -16,6 +16,9 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
16
16
|
const __dirname = dirname(__filename);
|
|
17
17
|
const rootDir = join(__dirname, '../../..');
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
19
22
|
async function runTests() {
|
|
20
23
|
console.log('🚀 Starting KGEN Injection System Tests');
|
|
21
24
|
console.log('=' .repeat(50));
|