@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
@@ -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, options) {
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, injectionConfig = {}) {
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, options = {}) {
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
- async _resolveGlobTargets(globPattern, targetConfig, variables) {
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));