@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.
Files changed (59) hide show
  1. package/dist/index.mjs +9207 -0
  2. package/package.json +33 -28
  3. package/src/base/filter-templates.js +7 -1
  4. package/src/base/index.js +15 -10
  5. package/src/base/injection-targets.js +6 -0
  6. package/src/base/macro-templates.js +6 -0
  7. package/src/base/shacl-templates.js +6 -0
  8. package/src/base/template-base.js +7 -1
  9. package/src/core/attestor.js +50 -1
  10. package/src/core/filters.js +134 -1
  11. package/src/core/index.js +8 -1
  12. package/src/core/kgen-engine.js +49 -1
  13. package/src/core/parser.js +52 -1
  14. package/src/core/post-processor.js +7 -1
  15. package/src/core/renderer.js +67 -1
  16. package/src/doc-generator/mdx-generator.mjs +1 -1
  17. package/src/doc-generator/nav-generator.mjs +1 -1
  18. package/src/doc-generator/rdf-builder.mjs +2 -2
  19. package/src/engine/index.js +9 -0
  20. package/src/engine/pipeline.js +7 -1
  21. package/src/engine/renderer.js +18 -3
  22. package/src/engine/template-engine.js +12 -3
  23. package/src/filters/array.js +14 -6
  24. package/src/filters/index.js +165 -17
  25. package/src/filters/rdf.js +3 -3
  26. package/src/{index.js → index.mjs} +46 -0
  27. package/src/index.test.mjs +40 -0
  28. package/src/inheritance/index.js +19 -1
  29. package/src/injection/atomic-writer.js +22 -1
  30. package/src/injection/idempotency-manager.js +33 -0
  31. package/src/injection/injection-engine.js +46 -1
  32. package/src/injection/integration.js +3 -3
  33. package/src/injection/modes/index.js +30 -0
  34. package/src/injection/rollback-manager.js +26 -2
  35. package/src/injection/target-resolver.js +48 -3
  36. package/src/injection/tests/injection-engine.test.js +3 -3
  37. package/src/injection/tests/integration.test.js +2 -1
  38. package/src/injection/tests/run-tests.js +3 -0
  39. package/src/injection/validation-engine.js +71 -5
  40. package/src/linter/determinism-linter.js +20 -5
  41. package/src/linter/determinism.js +8 -2
  42. package/src/linter/index.js +3 -1
  43. package/src/linter/test-doubles.js +151 -4
  44. package/src/parser/frontmatter.js +6 -0
  45. package/src/parser/variables.js +7 -1
  46. package/src/rdf/filters.js +393 -0
  47. package/src/rdf/index.js +444 -0
  48. package/src/renderer/deterministic.js +6 -0
  49. package/src/renderer/index.js +3 -1
  50. package/src/templates/rdf/DELIVERY-SUMMARY.md +266 -0
  51. package/src/templates/rdf/README.md +595 -0
  52. package/src/templates/rdf/dataset.njk +83 -0
  53. package/src/templates/rdf/index.js +106 -0
  54. package/src/templates/rdf/jsonld-context.njk +63 -0
  55. package/src/templates/rdf/ontology.njk +107 -0
  56. package/src/templates/rdf/schema.njk +79 -0
  57. package/src/templates/rdf/shapes.njk +89 -0
  58. package/src/templates/rdf/sparql-queries.njk +70 -0
  59. package/src/templates/rdf/vocabulary.njk +79 -0
@@ -12,17 +12,23 @@
12
12
  */
13
13
 
14
14
  import { createHash } from 'crypto';
15
- import { EventEmitter } from 'events';
15
+ import { EventEmitter as _EventEmitter } from 'events';
16
16
 
17
17
  /**
18
18
  * TEMPORAL TEST DOUBLES
19
19
  * Replace all time-based nondeterministic functions
20
20
  */
21
21
 
22
+ /**
23
+ *
24
+ */
22
25
  export class DeterministicDate extends Date {
23
26
  static FIXED_TIMESTAMP = '2025-01-01T00:00:00.000Z';
24
27
  static FIXED_TIME_MS = new Date(DeterministicDate.FIXED_TIMESTAMP).getTime();
25
28
 
29
+ /**
30
+ *
31
+ */
26
32
  constructor(...args) {
27
33
  if (args.length === 0) {
28
34
  // No arguments = current time -> use fixed time
@@ -36,28 +42,46 @@ export class DeterministicDate extends Date {
36
42
  }
37
43
  }
38
44
 
45
+ /**
46
+ *
47
+ */
39
48
  static now() {
40
49
  return DeterministicDate.FIXED_TIME_MS;
41
50
  }
42
51
 
52
+ /**
53
+ *
54
+ */
43
55
  static deterministic() {
44
56
  return DeterministicDate.FIXED_TIME_MS;
45
57
  }
46
58
  }
47
59
 
60
+ /**
61
+ *
62
+ */
48
63
  export class MockMath {
49
64
  static seed = 0.12345; // Fixed seed for deterministic "random"
50
65
 
66
+ /**
67
+ *
68
+ */
51
69
  static random() {
52
70
  // Linear congruential generator - deterministic pseudorandom
53
71
  MockMath.seed = (MockMath.seed * 9301 + 49297) % 233280;
54
72
  return MockMath.seed / 233280;
55
73
  }
56
74
 
75
+ /**
76
+ *
77
+ */
57
78
  static resetSeed() {
58
79
  MockMath.seed = 0.12345;
59
80
  }
60
81
 
82
+ /**
83
+ *
84
+ */
61
85
  static setSeed(newSeed) {
62
86
  MockMath.seed = newSeed;
63
87
  }
@@ -76,7 +100,13 @@ export class MockMath {
76
100
  * Replace UUID and random ID generation with content-based deterministic IDs
77
101
  */
78
102
 
103
+ /**
104
+ *
105
+ */
79
106
  export class DeterministicIdGenerator {
107
+ /**
108
+ *
109
+ */
80
110
  constructor(config = {}) {
81
111
  this.config = {
82
112
  defaultSalt: 'kgen-deterministic',
@@ -87,6 +117,9 @@ export class DeterministicIdGenerator {
87
117
  this.counter = 0;
88
118
  }
89
119
 
120
+ /**
121
+ *
122
+ */
90
123
  generateId(content, salt = null) {
91
124
  const actualSalt = salt || this.config.defaultSalt;
92
125
  const hash = createHash(this.config.hashAlgorithm);
@@ -103,12 +136,18 @@ export class DeterministicIdGenerator {
103
136
  return hash.digest('hex').substring(0, this.config.idLength);
104
137
  }
105
138
 
139
+ /**
140
+ *
141
+ */
106
142
  generateUUID(content, salt = null) {
107
143
  const hash = this.generateId(content, salt);
108
144
  // Format as UUID v4 structure (but deterministic)
109
145
  return `${hash.substring(0, 8)}-${hash.substring(8, 12)}-4${hash.substring(12, 15)}-8${hash.substring(15, 18)}-${hash.substring(18, 30)}000000`.substring(0, 36);
110
146
  }
111
147
 
148
+ /**
149
+ *
150
+ */
112
151
  reset() {
113
152
  this.counter = 0;
114
153
  }
@@ -119,6 +158,9 @@ export class DeterministicIdGenerator {
119
158
  * Replace process.env and system information with deterministic alternatives
120
159
  */
121
160
 
161
+ /**
162
+ *
163
+ */
122
164
  export class MockProcessEnv {
123
165
  static FIXED_ENV = {
124
166
  NODE_ENV: 'test',
@@ -130,23 +172,38 @@ export class MockProcessEnv {
130
172
  HOST: '0.0.0.0'
131
173
  };
132
174
 
175
+ /**
176
+ *
177
+ */
133
178
  static get(key) {
134
179
  return MockProcessEnv.FIXED_ENV[key];
135
180
  }
136
181
 
182
+ /**
183
+ *
184
+ */
137
185
  static set(key, value) {
138
186
  MockProcessEnv.FIXED_ENV[key] = value;
139
187
  }
140
188
 
189
+ /**
190
+ *
191
+ */
141
192
  static reset() {
142
193
  MockProcessEnv.FIXED_ENV = { ...MockProcessEnv.FIXED_ENV };
143
194
  }
144
195
 
196
+ /**
197
+ *
198
+ */
145
199
  static toObject() {
146
200
  return { ...MockProcessEnv.FIXED_ENV };
147
201
  }
148
202
  }
149
203
 
204
+ /**
205
+ *
206
+ */
150
207
  export class MockOS {
151
208
  static FIXED_INFO = {
152
209
  hostname: 'test-hostname',
@@ -163,26 +220,44 @@ export class MockOS {
163
220
  }
164
221
  };
165
222
 
223
+ /**
224
+ *
225
+ */
166
226
  static hostname() {
167
227
  return MockOS.FIXED_INFO.hostname;
168
228
  }
169
229
 
230
+ /**
231
+ *
232
+ */
170
233
  static platform() {
171
234
  return MockOS.FIXED_INFO.platform;
172
235
  }
173
236
 
237
+ /**
238
+ *
239
+ */
174
240
  static arch() {
175
241
  return MockOS.FIXED_INFO.arch;
176
242
  }
177
243
 
244
+ /**
245
+ *
246
+ */
178
247
  static version() {
179
248
  return MockOS.FIXED_INFO.version;
180
249
  }
181
250
 
251
+ /**
252
+ *
253
+ */
182
254
  static tmpdir() {
183
255
  return MockOS.FIXED_INFO.tmpdir;
184
256
  }
185
257
 
258
+ /**
259
+ *
260
+ */
186
261
  static userInfo() {
187
262
  return { ...MockOS.FIXED_INFO.userInfo };
188
263
  }
@@ -193,11 +268,17 @@ export class MockOS {
193
268
  * Replace filesystem operations with deterministic alternatives
194
269
  */
195
270
 
271
+ /**
272
+ *
273
+ */
196
274
  export class MockFS {
197
275
  static sortFiles = true;
198
276
  static fixedFiles = new Map();
199
277
 
200
- static async readdir(path, options = {}) {
278
+ /**
279
+ *
280
+ */
281
+ static async readdir(path, _options = {}) {
201
282
  // Simulate async operation
202
283
  await new Promise(resolve => setTimeout(resolve, 0));
203
284
 
@@ -210,7 +291,10 @@ export class MockFS {
210
291
  return MockFS.sortFiles ? files.sort() : files;
211
292
  }
212
293
 
213
- static async readFile(path, encoding = 'utf8') {
294
+ /**
295
+ *
296
+ */
297
+ static async readFile(path, _encoding = 'utf8') {
214
298
  await new Promise(resolve => setTimeout(resolve, 0));
215
299
 
216
300
  const content = MockFS.fixedFiles.get(`content:${path}`) ||
@@ -219,24 +303,39 @@ export class MockFS {
219
303
  return content;
220
304
  }
221
305
 
306
+ /**
307
+ *
308
+ */
222
309
  static setFixedFiles(path, files) {
223
310
  MockFS.fixedFiles.set(path, files);
224
311
  }
225
312
 
313
+ /**
314
+ *
315
+ */
226
316
  static setFixedContent(path, content) {
227
317
  MockFS.fixedFiles.set(`content:${path}`, content);
228
318
  }
229
319
 
320
+ /**
321
+ *
322
+ */
230
323
  static reset() {
231
324
  MockFS.fixedFiles.clear();
232
325
  MockFS.sortFiles = true;
233
326
  }
234
327
  }
235
328
 
329
+ /**
330
+ *
331
+ */
236
332
  export class MockGlob {
237
333
  static patterns = new Map();
238
334
 
239
- static async glob(pattern, options = {}) {
335
+ /**
336
+ *
337
+ */
338
+ static async glob(pattern, _options = {}) {
240
339
  await new Promise(resolve => setTimeout(resolve, 0));
241
340
 
242
341
  const matches = MockGlob.patterns.get(pattern) || [
@@ -248,10 +347,16 @@ export class MockGlob {
248
347
  return matches.sort(); // Always sorted for determinism
249
348
  }
250
349
 
350
+ /**
351
+ *
352
+ */
251
353
  static setFixedMatches(pattern, matches) {
252
354
  MockGlob.patterns.set(pattern, matches);
253
355
  }
254
356
 
357
+ /**
358
+ *
359
+ */
255
360
  static reset() {
256
361
  MockGlob.patterns.clear();
257
362
  }
@@ -262,6 +367,9 @@ export class MockGlob {
262
367
  * Replace network operations with deterministic responses
263
368
  */
264
369
 
370
+ /**
371
+ *
372
+ */
265
373
  export class MockFetch {
266
374
  static responses = new Map();
267
375
  static defaultResponse = {
@@ -272,6 +380,9 @@ export class MockFetch {
272
380
  text: async () => 'deterministic text response'
273
381
  };
274
382
 
383
+ /**
384
+ *
385
+ */
275
386
  static async fetch(url, options = {}) {
276
387
  await new Promise(resolve => setTimeout(resolve, 10)); // Simulate network delay
277
388
 
@@ -285,11 +396,17 @@ export class MockFetch {
285
396
  };
286
397
  }
287
398
 
399
+ /**
400
+ *
401
+ */
288
402
  static setResponse(method, url, response) {
289
403
  const key = `${method} ${url}`;
290
404
  MockFetch.responses.set(key, response);
291
405
  }
292
406
 
407
+ /**
408
+ *
409
+ */
293
410
  static reset() {
294
411
  MockFetch.responses.clear();
295
412
  }
@@ -300,13 +417,22 @@ export class MockFetch {
300
417
  * Replace all nondeterministic globals with deterministic alternatives
301
418
  */
302
419
 
420
+ /**
421
+ *
422
+ */
303
423
  export class DeterministicTestEnvironment {
424
+ /**
425
+ *
426
+ */
304
427
  constructor() {
305
428
  this.originalGlobals = {};
306
429
  this.idGenerator = new DeterministicIdGenerator();
307
430
  this.isActive = false;
308
431
  }
309
432
 
433
+ /**
434
+ *
435
+ */
310
436
  activate() {
311
437
  if (this.isActive) return;
312
438
 
@@ -340,6 +466,9 @@ export class DeterministicTestEnvironment {
340
466
  this.isActive = true;
341
467
  }
342
468
 
469
+ /**
470
+ *
471
+ */
343
472
  deactivate() {
344
473
  if (!this.isActive) return;
345
474
 
@@ -348,6 +477,9 @@ export class DeterministicTestEnvironment {
348
477
  this.isActive = false;
349
478
  }
350
479
 
480
+ /**
481
+ *
482
+ */
351
483
  reset() {
352
484
  MockMath.resetSeed();
353
485
  MockProcessEnv.reset();
@@ -357,6 +489,9 @@ export class DeterministicTestEnvironment {
357
489
  this.idGenerator.reset();
358
490
  }
359
491
 
492
+ /**
493
+ *
494
+ */
360
495
  generateDeterministicData(schema) {
361
496
  const data = {};
362
497
 
@@ -391,7 +526,13 @@ export class DeterministicTestEnvironment {
391
526
  * Behavior-driven development helpers for deterministic testing
392
527
  */
393
528
 
529
+ /**
530
+ *
531
+ */
394
532
  export class BDDTestHelpers {
533
+ /**
534
+ *
535
+ */
395
536
  static createDeterministicFixture(name, schema) {
396
537
  const env = new DeterministicTestEnvironment();
397
538
  env.activate();
@@ -403,6 +544,9 @@ export class BDDTestHelpers {
403
544
  return fixture;
404
545
  }
405
546
 
547
+ /**
548
+ *
549
+ */
406
550
  static async verifyDeterministicBehavior(testFunction, iterations = 3) {
407
551
  const results = [];
408
552
  const env = new DeterministicTestEnvironment();
@@ -428,6 +572,9 @@ export class BDDTestHelpers {
428
572
  return JSON.parse(firstResult);
429
573
  }
430
574
 
575
+ /**
576
+ *
577
+ */
431
578
  static createMockContext(overrides = {}) {
432
579
  return {
433
580
  metadata: {
@@ -6,7 +6,13 @@
6
6
  import matter from 'gray-matter';
7
7
  import { parse as parseYAML, stringify as stringifyYAML } from 'yaml';
8
8
 
9
+ /**
10
+ *
11
+ */
9
12
  export class FrontmatterParser {
13
+ /**
14
+ *
15
+ */
10
16
  constructor(options = {}) {
11
17
  this.strict = options.strict !== false;
12
18
  this.allowEmpty = options.allowEmpty !== false;
@@ -3,7 +3,13 @@
3
3
  * Migrated from ~/unjucks with enhanced pattern matching
4
4
  */
5
5
 
6
+ /**
7
+ *
8
+ */
6
9
  export class VariableExtractor {
10
+ /**
11
+ *
12
+ */
7
13
  constructor(options = {}) {
8
14
  this.includeFilters = options.includeFilters !== false;
9
15
  this.includeFunctions = options.includeFunctions !== false;
@@ -67,7 +73,7 @@ export class VariableExtractor {
67
73
  let match;
68
74
 
69
75
  while ((match = forPattern.exec(content)) !== null) {
70
- const [, itemVar, indexVar, collection] = match;
76
+ const [, _itemVar, _indexVar, collection] = match;
71
77
 
72
78
  // Collection is a variable we need
73
79
  const collectionVar = collection.trim().split('.')[0].split('|')[0].trim();