@lde/docgen 0.6.14 → 0.6.15

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/README.md CHANGED
@@ -32,9 +32,9 @@ npx @lde/docgen@latest from-shacl <shacl-file> <template-file> [options]
32
32
 
33
33
  ### Options
34
34
 
35
- | Option | Description | Default |
36
- | -------------------- | ---------------------------- | ------------------------------------ |
37
- | `-f, --frame <file>` | Path to a JSON-LD Frame file | Built-in `frames/shacl.frame.jsonld` |
35
+ | Option | Description | Default |
36
+ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
37
+ | `-f, --frame <file>` | Path to a JSON-LD Frame file. Deep-merged on top of the built-in default frame, so it only needs to contain your additions (e.g. extra `@context` entries). | Built-in `frames/shacl.frame.jsonld` |
38
38
 
39
39
  ### Example
40
40
 
@@ -108,8 +108,20 @@ Property shapes with the same `sh:path` are common in SHACL (e.g. one for cardin
108
108
 
109
109
  ## Custom frames
110
110
 
111
- The default frame selects all `sh:NodeShape` resources. To customise which shapes are selected or how they are nested, pass a custom [JSON-LD Frame](https://www.w3.org/TR/json-ld11-framing/):
111
+ The default frame selects all `sh:NodeShape` resources and provides type coercions for common SHACL terms (`targetClass`, `path`, `severity`, etc.). To extend it, pass a partial [JSON-LD Frame](https://www.w3.org/TR/json-ld11-framing/) – it is **deep-merged** on top of the default, so you only need to specify your additions:
112
+
113
+ ```json
114
+ {
115
+ "@context": {
116
+ "nde": "https://def.nde.nl#",
117
+ "nde:futureChange": {},
118
+ "nde:version": {}
119
+ }
120
+ }
121
+ ```
112
122
 
113
123
  ```sh
114
124
  npx @lde/docgen@latest from-shacl shapes.ttl template.liquid -f my-frame.jsonld
115
125
  ```
126
+
127
+ Plain objects are merged key-by-key, with user values winning; arrays and primitives in your frame replace the default. To override a built-in coercion (e.g. change `severity` from `@vocab` to `@id`), redefine the same key in your `@context`.
package/dist/cli.js CHANGED
@@ -2,9 +2,6 @@
2
2
  import { Command } from 'commander';
3
3
  import { generateDocumentation } from './index.js';
4
4
  import packageJson from '../package.json' with { type: 'json' };
5
- import { dirname } from 'path';
6
- import { fileURLToPath } from 'url';
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
5
  const program = new Command();
9
6
  program
10
7
  .name('docgen')
@@ -15,7 +12,7 @@ program
15
12
  .description('Generate documentation from a SHACL shapes file')
16
13
  .argument('<shacl-file>', 'Path to SHACL shapes file (in any RDF serialization format)')
17
14
  .argument('<template-file>', 'Path to Liquid template file')
18
- .option('-f --frame <json-ld-frame-file>', 'Path to a JSON-LD Frame file', __dirname + '/../frames/shacl.frame.jsonld')
15
+ .option('-f --frame <json-ld-frame-file>', 'Path to a JSON-LD Frame file. Deep-merged on top of the built-in default frame, so it only needs to contain your additions.')
19
16
  .addHelpText('after', `
20
17
  Example:
21
18
  $ npx @lde/docgen@latest from-shacl shacl.ttl template.liquid
package/dist/frame.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { JsonLdArray } from 'jsonld/jsonld-spec.js';
2
- import jsonld from 'jsonld';
3
- export declare function frame(document: JsonLdArray, frame: string): Promise<jsonld.NodeObject>;
2
+ import type { NodeObject } from 'jsonld';
3
+ export declare function frame(document: JsonLdArray, userFramePath?: string): Promise<NodeObject>;
4
4
  //# sourceMappingURL=frame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,wBAAsB,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,8BAS/D"}
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAUzC,wBAAsB,KAAK,CACzB,QAAQ,EAAE,WAAW,EACrB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,UAAU,CAAC,CAUrB"}
package/dist/frame.js CHANGED
@@ -1,8 +1,41 @@
1
1
  import jsonld from 'jsonld';
2
2
  import { readFile } from 'node:fs/promises';
3
- export async function frame(document, frame) {
4
- return await jsonld.frame(document, JSON.parse(await readFile(frame, 'utf8')), {
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const defaultFramePath = join(__dirname, '../frames/shacl.frame.jsonld');
7
+ export async function frame(document, userFramePath) {
8
+ const defaultFrame = await readFrame(defaultFramePath);
9
+ const mergedFrame = userFramePath
10
+ ? deepMerge(defaultFrame, await readFrame(userFramePath))
11
+ : defaultFrame;
12
+ return await jsonld.frame(document, mergedFrame, {
5
13
  omitGraph: false,
6
14
  embed: '@always',
7
15
  });
8
16
  }
17
+ async function readFrame(path) {
18
+ return JSON.parse(await readFile(path, 'utf8'));
19
+ }
20
+ /**
21
+ * Recursively merges `source` into `target`, returning a new object. Plain
22
+ * objects are merged key-by-key; arrays and primitives in `source` replace
23
+ * those in `target`. Used to compose a user-supplied JSON-LD frame on top of
24
+ * docgen’s built-in default so consumers only need to specify their additions.
25
+ */
26
+ function deepMerge(target, source) {
27
+ const result = { ...target };
28
+ for (const [key, sourceValue] of Object.entries(source)) {
29
+ const targetValue = result[key];
30
+ if (isPlainObject(targetValue) && isPlainObject(sourceValue)) {
31
+ result[key] = deepMerge(targetValue, sourceValue);
32
+ }
33
+ else {
34
+ result[key] = sourceValue;
35
+ }
36
+ }
37
+ return result;
38
+ }
39
+ function isPlainObject(value) {
40
+ return (typeof value === 'object' && value !== null && !Array.isArray(value));
41
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,11 @@
1
- export declare function generateDocumentation(rdfPath: string, templatePath: string, framePath: string): Promise<string>;
1
+ /**
2
+ * Generate documentation from a SHACL shapes file using a Liquid template.
3
+ *
4
+ * @param rdfPath Path to a SHACL shapes file in any RDF serialization.
5
+ * @param templatePath Path to a Liquid template.
6
+ * @param framePath Optional path to a JSON-LD frame. When provided, it is
7
+ * deep-merged on top of docgen’s built-in default frame, so consumers only
8
+ * need to specify their additions (e.g. extra `@context` entries).
9
+ */
10
+ export declare function generateDocumentation(rdfPath: string, templatePath: string, framePath?: string): Promise<string>;
2
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
package/dist/index.js CHANGED
@@ -1,6 +1,15 @@
1
1
  import { parseRdfToJsonLd } from './parse.js';
2
2
  import { frame } from './frame.js';
3
3
  import { render } from './render.js';
4
+ /**
5
+ * Generate documentation from a SHACL shapes file using a Liquid template.
6
+ *
7
+ * @param rdfPath Path to a SHACL shapes file in any RDF serialization.
8
+ * @param templatePath Path to a Liquid template.
9
+ * @param framePath Optional path to a JSON-LD frame. When provided, it is
10
+ * deep-merged on top of docgen’s built-in default frame, so consumers only
11
+ * need to specify their additions (e.g. extra `@context` entries).
12
+ */
4
13
  export async function generateDocumentation(rdfPath, templatePath, framePath) {
5
14
  const jsonld = await parseRdfToJsonLd(rdfPath);
6
15
  const framed = await frame(jsonld, framePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/docgen",
3
- "version": "0.6.14",
3
+ "version": "0.6.15",
4
4
  "description": "Generate documentation from SHACL shapes",
5
5
  "keywords": [
6
6
  "shacl",