@twin.org/data-json-ld 0.0.3-next.2 → 0.0.3-next.20
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 +1 -1
- package/dist/es/dataTypes/jsonLdDataTypes.js +104 -131
- package/dist/es/dataTypes/jsonLdDataTypes.js.map +1 -1
- package/dist/es/helpers/jsonLdHelperTypes.js +2 -0
- package/dist/es/helpers/jsonLdHelperTypes.js.map +1 -0
- package/dist/es/index.js +1 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/jsonLdContexts.js +10 -2
- package/dist/es/models/jsonLdContexts.js.map +1 -1
- package/dist/es/schemas/JsonLdContainerType.json +17 -7
- package/dist/es/schemas/JsonLdContainerTypeArray.json +129 -142
- package/dist/es/schemas/JsonLdContextDefinition.json +76 -18
- package/dist/es/schemas/JsonLdContextDefinitionElement.json +1 -0
- package/dist/es/schemas/JsonLdContextDefinitionRoot.json +1 -0
- package/dist/es/schemas/JsonLdDocument.json +3 -3
- package/dist/es/schemas/JsonLdExpandedTermDefinition.json +101 -89
- package/dist/es/schemas/JsonLdGraphObject.json +2 -2
- package/dist/es/schemas/JsonLdIdMap.json +1 -0
- package/dist/es/schemas/JsonLdIncludedBlock.json +1 -0
- package/dist/es/schemas/JsonLdIndexMap.json +2 -1
- package/dist/es/schemas/JsonLdIndexMapItem.json +1 -0
- package/dist/es/schemas/JsonLdJsonArray.json +1 -0
- package/dist/es/schemas/JsonLdJsonObject.json +2 -8
- package/dist/es/schemas/JsonLdJsonPrimitive.json +14 -5
- package/dist/es/schemas/JsonLdJsonValue.json +1 -0
- package/dist/es/schemas/JsonLdLanguageMap.json +1 -0
- package/dist/es/schemas/JsonLdListObject.json +2 -2
- package/dist/es/schemas/JsonLdListOrSetItem.json +1 -0
- package/dist/es/schemas/JsonLdNodeObject.json +12 -72
- package/dist/es/schemas/JsonLdNodePrimitive.json +1 -0
- package/dist/es/schemas/JsonLdObject.json +3 -3
- package/dist/es/schemas/JsonLdSetObject.json +2 -2
- package/dist/es/schemas/JsonLdTypeMap.json +1 -0
- package/dist/es/schemas/JsonLdValueObject.json +99 -87
- package/dist/es/utils/jsonLdHelper.js +181 -15
- package/dist/es/utils/jsonLdHelper.js.map +1 -1
- package/dist/es/utils/jsonLdProcessor.js +122 -33
- package/dist/es/utils/jsonLdProcessor.js.map +1 -1
- package/dist/types/helpers/jsonLdHelperTypes.d.ts +127 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/models/jsonLdContexts.d.ts +10 -2
- package/dist/types/utils/jsonLdHelper.d.ts +63 -6
- package/dist/types/utils/jsonLdProcessor.d.ts +10 -7
- package/docs/changelog.md +273 -1
- package/docs/examples.md +214 -1
- package/docs/reference/classes/JsonLdDataTypes.md +1 -1
- package/docs/reference/classes/JsonLdHelper.md +249 -13
- package/docs/reference/classes/JsonLdProcessor.md +51 -58
- package/docs/reference/index.md +23 -0
- package/docs/reference/interfaces/IJsonLdContextDefinition.md +20 -20
- package/docs/reference/interfaces/IJsonLdGraphObject.md +7 -7
- package/docs/reference/interfaces/IJsonLdIdMap.md +1 -1
- package/docs/reference/interfaces/IJsonLdIndexMap.md +1 -1
- package/docs/reference/interfaces/IJsonLdJsonObject.md +1 -1
- package/docs/reference/interfaces/IJsonLdLanguageMap.md +1 -1
- package/docs/reference/interfaces/IJsonLdListObject.md +3 -3
- package/docs/reference/interfaces/IJsonLdNodeObject.md +17 -17
- package/docs/reference/interfaces/IJsonLdObject.md +16 -16
- package/docs/reference/interfaces/IJsonLdSetObject.md +3 -3
- package/docs/reference/interfaces/IJsonLdTypeMap.md +1 -1
- package/docs/reference/type-aliases/IJsonLdExpandedTermDefinition.md +7 -7
- package/docs/reference/type-aliases/IJsonLdValueObject.md +2 -2
- package/docs/reference/type-aliases/JsonLdAliasKey.md +15 -0
- package/docs/reference/type-aliases/JsonLdExistingProperty.md +19 -0
- package/docs/reference/type-aliases/JsonLdExistingPropertyEither.md +24 -0
- package/docs/reference/type-aliases/JsonLdKeys.md +11 -0
- package/docs/reference/type-aliases/JsonLdObjectWithAliases.md +16 -0
- package/docs/reference/type-aliases/JsonLdObjectWithAtId.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithAtType.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithContext.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithId.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithNoAtId.md +11 -0
- package/docs/reference/type-aliases/JsonLdObjectWithNoAtType.md +11 -0
- package/docs/reference/type-aliases/JsonLdObjectWithNoContext.md +12 -0
- package/docs/reference/type-aliases/JsonLdObjectWithNoId.md +11 -0
- package/docs/reference/type-aliases/JsonLdObjectWithNoType.md +11 -0
- package/docs/reference/type-aliases/JsonLdObjectWithOptionalAtId.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithOptionalAtType.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithOptionalContext.md +22 -0
- package/docs/reference/type-aliases/JsonLdObjectWithOptionalId.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithOptionalType.md +21 -0
- package/docs/reference/type-aliases/JsonLdObjectWithType.md +21 -0
- package/docs/reference/type-aliases/JsonLdOptionalKeys.md +11 -0
- package/docs/reference/type-aliases/JsonLdRequiredKeys.md +11 -0
- package/docs/reference/type-aliases/JsonLdWithAliases.md +17 -0
- package/docs/reference/variables/JsonLdContexts.md +15 -3
- package/docs/reference/variables/JsonLdTypes.md +26 -26
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
import { BaseError, GeneralError, Is, ObjectHelper, SharedStore } from "@twin.org/core";
|
|
4
|
-
import { FetchHelper, HeaderTypes, HttpMethod, MimeTypes } from "@twin.org/web";
|
|
4
|
+
import { FetchHelper, HeaderHelper, HeaderTypes, HttpLinkRelType, HttpMethod, HttpStatusCode, MimeTypes } from "@twin.org/web";
|
|
5
5
|
import jsonLd from "jsonld";
|
|
6
6
|
/**
|
|
7
7
|
* JSON-LD Processor.
|
|
@@ -12,6 +12,11 @@ export class JsonLdProcessor {
|
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
14
|
static CLASS_NAME = "JsonLdProcessor";
|
|
15
|
+
/**
|
|
16
|
+
* Maximum number of HTTP Link-header discovery hops (namespace URL → context document).
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
static _MAX_LINK_DISCOVERY_DEPTH = 1;
|
|
15
20
|
/**
|
|
16
21
|
* The document loader to use.
|
|
17
22
|
* @param documentLoader The document loader to use.
|
|
@@ -50,7 +55,8 @@ export class JsonLdProcessor {
|
|
|
50
55
|
return cacheLimitMs;
|
|
51
56
|
}
|
|
52
57
|
/**
|
|
53
|
-
*
|
|
58
|
+
* Replace the global redirect list (use {@link JsonLdProcessor.addRedirect} to append without replacing).
|
|
59
|
+
* Redirects run before any HTTP GET or `Link` discovery; use them for stable overrides, tests, or hosts that do not expose a suitable `Link` header.
|
|
54
60
|
* @param redirects The redirects to use.
|
|
55
61
|
*/
|
|
56
62
|
static setRedirects(redirects) {
|
|
@@ -68,6 +74,19 @@ export class JsonLdProcessor {
|
|
|
68
74
|
}
|
|
69
75
|
return redirects;
|
|
70
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Append a redirect rule (ignored if the same `RegExp.source` is already registered).
|
|
79
|
+
* Optional when the vocabulary URL supports HTTP `Link` discovery (`rel` includes `alternate`, `type` is `application/ld+json`) via the default document loader.
|
|
80
|
+
* Standards packages often expose `registerRedirects()` helpers that call this method; those are optional for the same reason.
|
|
81
|
+
* @param from The URL to redirect from.
|
|
82
|
+
* @param to The URL to redirect to.
|
|
83
|
+
*/
|
|
84
|
+
static addRedirect(from, to) {
|
|
85
|
+
const redirects = JsonLdProcessor.getRedirects();
|
|
86
|
+
if (!redirects.some(r => r.from.source === from.source)) {
|
|
87
|
+
redirects.push({ from, to });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
71
90
|
/**
|
|
72
91
|
* Compact a document according to a particular context.
|
|
73
92
|
* @param document The JSON-LD document to compact.
|
|
@@ -163,17 +182,6 @@ export class JsonLdProcessor {
|
|
|
163
182
|
throw new GeneralError(JsonLdProcessor.CLASS_NAME, "canonize", undefined, err);
|
|
164
183
|
}
|
|
165
184
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Add a redirect to use during document resolution.
|
|
168
|
-
* @param from The URL to redirect from.
|
|
169
|
-
* @param to The URL to redirect to.
|
|
170
|
-
*/
|
|
171
|
-
static addRedirect(from, to) {
|
|
172
|
-
const redirects = JsonLdProcessor.getRedirects();
|
|
173
|
-
if (!redirects.some(r => r.from.source === from.source)) {
|
|
174
|
-
redirects.push({ from, to });
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
185
|
/**
|
|
178
186
|
* Combine contexts.
|
|
179
187
|
* @param context1 The first JSON-LD context to combine.
|
|
@@ -326,33 +334,114 @@ export class JsonLdProcessor {
|
|
|
326
334
|
break;
|
|
327
335
|
}
|
|
328
336
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
337
|
+
return JsonLdProcessor.fetchRemoteJsonLdDocument(url, 0);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* True when FetchHelper failed to decode JSON from the response (e.g. HTML or plain text).
|
|
341
|
+
* @param err The error from fetchJson.
|
|
342
|
+
* @internal
|
|
343
|
+
*/
|
|
344
|
+
static isFetchJsonDecodeFailure(err) {
|
|
345
|
+
// Raw JSON.parse / response.json() failures (FetchHelper may rethrow as FetchError with cause,
|
|
346
|
+
// or propagate SyntaxError when error-response body is not JSON).
|
|
347
|
+
const error = BaseError.fromError(err);
|
|
348
|
+
if (error.name === "SyntaxError" || error.cause?.name === "SyntaxError") {
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
return error.message.includes("decodingJSON") || error.message.includes("is not valid JSON");
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Use HTTP Link (rel=alternate, type=application/ld+json) to discover a JSON-LD context URL.
|
|
355
|
+
* @param sourceUrl URL that did not yield JSON (e.g. vocabulary namespace HTML page).
|
|
356
|
+
* @returns Absolute context document URL, or undefined.
|
|
357
|
+
* @internal
|
|
358
|
+
*/
|
|
359
|
+
static async tryDiscoverAlternateJsonLdContextUrl(sourceUrl) {
|
|
360
|
+
const fetchOpts = {
|
|
361
|
+
timeoutMs: 30_000,
|
|
362
|
+
headers: {
|
|
363
|
+
[HeaderTypes.Accept]: `${MimeTypes.JsonLd},${MimeTypes.Json};q=0.9,*/*;q=0.8`
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
let response = await FetchHelper.fetch(JsonLdProcessor.CLASS_NAME, sourceUrl, HttpMethod.HEAD, undefined, fetchOpts);
|
|
367
|
+
if (response.status === HttpStatusCode.methodNotAllowed ||
|
|
368
|
+
response.status === HttpStatusCode.notImplemented) {
|
|
369
|
+
response = await FetchHelper.fetch(JsonLdProcessor.CLASS_NAME, sourceUrl, HttpMethod.GET, undefined, fetchOpts);
|
|
370
|
+
await response.arrayBuffer();
|
|
371
|
+
}
|
|
372
|
+
if (!response.ok) {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
const linkHeader = response.headers.get(HeaderTypes.Link);
|
|
376
|
+
if (Is.empty(linkHeader)) {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
// response.url is "" for many mocked/synthetic Responses; Is.empty("") is false, but
|
|
380
|
+
// new URL(absoluteHref, "") throws — use a non-empty resolved URL as base only.
|
|
381
|
+
const baseUrl = Is.stringValue(response.url) ? response.url : sourceUrl;
|
|
382
|
+
const alternateLinkHeaders = HeaderHelper.extractLinkHeaderRelations(linkHeader, HttpLinkRelType.alternate);
|
|
383
|
+
if (Is.arrayValue(alternateLinkHeaders)) {
|
|
384
|
+
for (const alternateLinkHeader of alternateLinkHeaders) {
|
|
385
|
+
if (alternateLinkHeader.params?.type === MimeTypes.JsonLd) {
|
|
386
|
+
try {
|
|
387
|
+
return new URL(alternateLinkHeader.url, baseUrl).href;
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
// Malformed URL for this segment; try the next Link segment.
|
|
391
|
+
}
|
|
334
392
|
}
|
|
335
|
-
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Fetch a remote JSON-LD document, with Accept fallbacks and optional Link-header discovery.
|
|
399
|
+
* @param url Resolved document URL.
|
|
400
|
+
* @param linkDiscoveryDepth Current discovery recursion depth.
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
static async fetchRemoteJsonLdDocument(url, linkDiscoveryDepth) {
|
|
404
|
+
const cacheTtlMs = JsonLdProcessor.getCacheLimit();
|
|
405
|
+
const fetchJsonLdOptions = {
|
|
406
|
+
cacheTtlMs,
|
|
407
|
+
headers: {
|
|
408
|
+
[HeaderTypes.Accept]: MimeTypes.JsonLd
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
const fetchJsonOptions = {
|
|
412
|
+
cacheTtlMs,
|
|
413
|
+
headers: {
|
|
414
|
+
[HeaderTypes.Accept]: MimeTypes.Json
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
try {
|
|
418
|
+
const document = await FetchHelper.fetchJson(JsonLdProcessor.CLASS_NAME, url, HttpMethod.GET, undefined, fetchJsonLdOptions);
|
|
336
419
|
return {
|
|
337
420
|
documentUrl: url,
|
|
338
|
-
document
|
|
421
|
+
document
|
|
339
422
|
};
|
|
340
423
|
}
|
|
341
|
-
catch (
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
424
|
+
catch (errLd) {
|
|
425
|
+
if (JsonLdProcessor.isFetchJsonDecodeFailure(errLd)) {
|
|
426
|
+
try {
|
|
427
|
+
const document = await FetchHelper.fetchJson(JsonLdProcessor.CLASS_NAME, url, HttpMethod.GET, undefined, fetchJsonOptions);
|
|
428
|
+
return {
|
|
429
|
+
documentUrl: url,
|
|
430
|
+
document
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
catch (errJson) {
|
|
434
|
+
if (linkDiscoveryDepth < JsonLdProcessor._MAX_LINK_DISCOVERY_DEPTH &&
|
|
435
|
+
JsonLdProcessor.isFetchJsonDecodeFailure(errJson)) {
|
|
436
|
+
const discovered = await JsonLdProcessor.tryDiscoverAlternateJsonLdContextUrl(url);
|
|
437
|
+
if (Is.stringValue(discovered) && discovered !== url) {
|
|
438
|
+
return JsonLdProcessor.fetchRemoteJsonLdDocument(discovered, linkDiscoveryDepth + 1);
|
|
439
|
+
}
|
|
348
440
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
documentUrl: url,
|
|
352
|
-
document: response
|
|
353
|
-
};
|
|
441
|
+
throw errJson;
|
|
442
|
+
}
|
|
354
443
|
}
|
|
355
|
-
throw
|
|
444
|
+
throw errLd;
|
|
356
445
|
}
|
|
357
446
|
}
|
|
358
447
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonLdProcessor.js","sourceRoot":"","sources":["../../../src/utils/jsonLdProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseError, GeneralError, Is, ObjectHelper, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { FetchHelper, HeaderTypes, HttpMethod, MimeTypes } from \"@twin.org/web\";\nimport jsonLd from \"jsonld\";\nimport type { JsonLd, RemoteDocument, Url } from \"jsonld/jsonld-spec.js\";\nimport type { IJsonLdContextDefinition } from \"../models/IJsonLdContextDefinition.js\";\nimport type { IJsonLdContextDefinitionElement } from \"../models/IJsonLdContextDefinitionElement.js\";\nimport type { IJsonLdContextDefinitionRoot } from \"../models/IJsonLdContextDefinitionRoot.js\";\nimport type { IJsonLdNodeObject } from \"../models/IJsonLdNodeObject.js\";\n\n/**\n * JSON-LD Processor.\n */\nexport class JsonLdProcessor {\n\t/**\n\t * The class name.\n\t * @internal\n\t */\n\tpublic static readonly CLASS_NAME = nameof<JsonLdProcessor>();\n\n\t/**\n\t * The document loader to use.\n\t * @param documentLoader The document loader to use.\n\t */\n\tpublic static setDocumentLoader(documentLoader: (url: Url) => Promise<RemoteDocument>): void {\n\t\tSharedStore.set(\"jsonLdDocumentLoader\", documentLoader);\n\t}\n\n\t/**\n\t * The document loader to use for retrieving JSON-LD documents.\n\t * @returns The document loader.\n\t */\n\tpublic static getDocumentLoader(): (url: Url) => Promise<RemoteDocument> {\n\t\tlet documentLoader =\n\t\t\tSharedStore.get<(url: Url) => Promise<RemoteDocument>>(\"jsonLdDocumentLoader\");\n\t\tif (!Is.function(documentLoader)) {\n\t\t\tdocumentLoader = async (url: string) => JsonLdProcessor.documentLoader(url);\n\t\t}\n\t\treturn documentLoader;\n\t}\n\n\t/**\n\t * Set the cache time limit for documents.\n\t * @param cacheLimitMs The cache limit in milliseconds.\n\t */\n\tpublic static setCacheLimit(cacheLimitMs: number): void {\n\t\tSharedStore.set(\"jsonLdDocumentCacheLimit\", cacheLimitMs);\n\t}\n\n\t/**\n\t * Get the cache limit for documents.\n\t * @returns The document loader.\n\t */\n\tpublic static getCacheLimit(): number {\n\t\tlet cacheLimitMs = SharedStore.get<number>(\"jsonLdDocumentCacheLimit\");\n\t\tif (Is.empty(cacheLimitMs)) {\n\t\t\tcacheLimitMs = 3600000;\n\t\t\tSharedStore.set(\"jsonLdDocumentCacheLimit\", cacheLimitMs);\n\t\t}\n\t\treturn cacheLimitMs;\n\t}\n\n\t/**\n\t * Set the global redirects for JSON-LD, use addRedirect for default handling.\n\t * @param redirects The redirects to use.\n\t */\n\tpublic static setRedirects(\n\t\tredirects: {\n\t\t\tfrom: RegExp;\n\t\t\tto: string;\n\t\t}[]\n\t): void {\n\t\tSharedStore.set(\"jsonLdRedirects\", redirects);\n\t}\n\n\t/**\n\t * Get the global redirects for JSON-LD.\n\t * @returns The registered redirects.\n\t */\n\tpublic static getRedirects(): {\n\t\tfrom: RegExp;\n\t\tto: string;\n\t}[] {\n\t\tlet redirects = SharedStore.get<\n\t\t\t{\n\t\t\t\tfrom: RegExp;\n\t\t\t\tto: string;\n\t\t\t}[]\n\t\t>(\"jsonLdRedirects\");\n\t\tif (Is.empty(redirects)) {\n\t\t\tredirects = [];\n\t\t\tSharedStore.set(\"jsonLdRedirects\", redirects);\n\t\t}\n\t\treturn redirects;\n\t}\n\n\t/**\n\t * Compact a document according to a particular context.\n\t * @param document The JSON-LD document to compact.\n\t * @param context The context to compact the document to, if not provided will use the one in the document.\n\t * @param options The options for compacting the document.\n\t * @param options.itemListOverride Whether to override the itemListElement context with a set, defaults to true.\n\t * @returns The compacted JSON-LD document.\n\t */\n\tpublic static async compact<T>(\n\t\tdocument: T,\n\t\tcontext?: IJsonLdContextDefinitionRoot,\n\t\toptions?: { itemListOverride: boolean }\n\t): Promise<T> {\n\t\ttry {\n\t\t\tif (Is.object<IJsonLdNodeObject>(document)) {\n\t\t\t\t// If the user didn't provide a context, use the one from the document\n\t\t\t\tif (Is.empty(context) && !Is.empty(document[\"@context\"])) {\n\t\t\t\t\tcontext = document[\"@context\"];\n\t\t\t\t}\n\n\t\t\t\tconst overrideListElementOption = options?.itemListOverride ?? true;\n\t\t\t\tlet overrideContext: IJsonLdContextDefinitionElement | undefined;\n\n\t\t\t\tif (overrideListElementOption) {\n\t\t\t\t\t// The compactArrays flag doesn't work with the current version of jsonld.js\n\t\t\t\t\t// For list results we standardise on ItemList and itemListElement\n\t\t\t\t\t// so we modify the schema.org type for itemListElement to be a set which bypasses the issue\n\t\t\t\t\t// https://github.com/digitalbazaar/jsonld.js/issues/247\n\t\t\t\t\toverrideContext = {\n\t\t\t\t\t\titemListElement: {\n\t\t\t\t\t\t\t\"@id\": \"http://schema.org/itemListElement\",\n\t\t\t\t\t\t\t\"@container\": \"@set\",\n\t\t\t\t\t\t\t\"@protected\": true\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif (Is.object(context) && \"@context\" in context) {\n\t\t\t\t\t\t// If the context is an object, we need to merge it with the override context\n\t\t\t\t\t\tcontext = JsonLdProcessor.combineContexts(\n\t\t\t\t\t\t\tcontext[\"@context\"] as IJsonLdContextDefinitionRoot,\n\t\t\t\t\t\t\toverrideContext\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the context is a string or an array, we need to merge it with the override context\n\t\t\t\t\t\tcontext = JsonLdProcessor.combineContexts(context, overrideContext);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst compacted = await jsonLd.compact(\n\t\t\t\t\tObjectHelper.removeEmptyProperties(document),\n\t\t\t\t\tcontext as IJsonLdContextDefinition,\n\t\t\t\t\t{\n\t\t\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tif (!Is.empty(overrideContext)) {\n\t\t\t\t\t// Remove the override context from the compacted document\n\t\t\t\t\tcompacted[\"@context\"] = JsonLdProcessor.removeContexts(\n\t\t\t\t\t\tcompacted[\"@context\"] as IJsonLdContextDefinitionRoot,\n\t\t\t\t\t\t[overrideContext]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn compacted as T;\n\t\t\t}\n\t\t\treturn document;\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"compact\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Expand a document, removing its context.\n\t * @param compacted The compacted JSON-LD document to expand.\n\t * @returns The expanded JSON-LD document.\n\t */\n\tpublic static async expand<T>(compacted: T): Promise<IJsonLdNodeObject[]> {\n\t\ttry {\n\t\t\tif (Is.object<IJsonLdNodeObject>(compacted)) {\n\t\t\t\tconst expanded = await jsonLd.expand(ObjectHelper.removeEmptyProperties(compacted), {\n\t\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t\t});\n\t\t\t\treturn expanded;\n\t\t\t}\n\t\t\treturn [];\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"expand\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Canonize a document.\n\t * @param document The document to canonize.\n\t * @param options The options for canonization.\n\t * @param options.algorithm The algorithm to use for canonization, defaults to URDNA2015.\n\t * @returns The canonized document.\n\t */\n\tpublic static async canonize<T extends IJsonLdNodeObject>(\n\t\tdocument: T,\n\t\toptions?: {\n\t\t\talgorithm?: \"URDNA2015\" | \"URGNA2012\" | undefined;\n\t\t}\n\t): Promise<string> {\n\t\ttry {\n\t\t\tconst normalized = await jsonLd.canonize(ObjectHelper.removeEmptyProperties(document), {\n\t\t\t\talgorithm: options?.algorithm ?? \"URDNA2015\",\n\t\t\t\tformat: \"application/n-quads\",\n\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t});\n\t\t\treturn normalized;\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"canonize\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Add a redirect to use during document resolution.\n\t * @param from The URL to redirect from.\n\t * @param to The URL to redirect to.\n\t */\n\tpublic static addRedirect(from: RegExp, to: string): void {\n\t\tconst redirects = JsonLdProcessor.getRedirects();\n\t\tif (!redirects.some(r => r.from.source === from.source)) {\n\t\t\tredirects.push({ from, to });\n\t\t}\n\t}\n\n\t/**\n\t * Combine contexts.\n\t * @param context1 The first JSON-LD context to combine.\n\t * @param context2 The second JSON-LD context to combine.\n\t * @returns The combined context.\n\t */\n\tpublic static combineContexts(\n\t\tcontext1: IJsonLdContextDefinitionRoot | undefined,\n\t\tcontext2: IJsonLdContextDefinitionRoot | undefined\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tconst combinedContext: IJsonLdContextDefinitionRoot = [];\n\n\t\tif (Is.string(context1)) {\n\t\t\tif (!combinedContext.includes(context1)) {\n\t\t\t\tcombinedContext.push(context1);\n\t\t\t}\n\t\t} else if (Is.array(context1)) {\n\t\t\tfor (const context of context1) {\n\t\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tcombinedContext.push(context);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context1)) {\n\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context1));\n\t\t\tif (!hasMatch) {\n\t\t\t\tcombinedContext.push(context1);\n\t\t\t}\n\t\t}\n\n\t\tif (Is.string(context2)) {\n\t\t\tif (!combinedContext.includes(context2)) {\n\t\t\t\tcombinedContext.push(context2);\n\t\t\t}\n\t\t} else if (Is.array(context2)) {\n\t\t\tfor (const context of context2) {\n\t\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tcombinedContext.push(context);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context2)) {\n\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context2));\n\t\t\tif (!hasMatch) {\n\t\t\t\tcombinedContext.push(context2);\n\t\t\t}\n\t\t}\n\n\t\tif (combinedContext.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (combinedContext.length === 1) {\n\t\t\treturn combinedContext[0];\n\t\t}\n\n\t\treturn combinedContext;\n\t}\n\n\t/**\n\t * Gather all the contexts from the element and it's children.\n\t * @param element The element to gather the contexts from.\n\t * @param initial The initial context.\n\t * @returns The combined contexts.\n\t */\n\tpublic static gatherContexts<T>(\n\t\telement: T,\n\t\tinitial?: IJsonLdContextDefinitionRoot\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tlet combinedContexts: IJsonLdContextDefinitionRoot | undefined = initial;\n\n\t\tif (Is.object<IJsonLdNodeObject>(element)) {\n\t\t\tif (!Is.empty(element[\"@context\"])) {\n\t\t\t\tcombinedContexts = JsonLdProcessor.combineContexts(\n\t\t\t\t\tinitial,\n\t\t\t\t\telement[\"@context\"] as IJsonLdContextDefinitionRoot\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfor (const prop of Object.keys(element)) {\n\t\t\t\tconst value = element[prop];\n\t\t\t\tif (Is.object(value)) {\n\t\t\t\t\tcombinedContexts = JsonLdProcessor.gatherContexts(\n\t\t\t\t\t\tvalue as IJsonLdNodeObject,\n\t\t\t\t\t\tcombinedContexts\n\t\t\t\t\t);\n\t\t\t\t} else if (Is.array(value)) {\n\t\t\t\t\tfor (const item of value) {\n\t\t\t\t\t\tif (Is.object(item)) {\n\t\t\t\t\t\t\tcombinedContexts = JsonLdProcessor.gatherContexts(\n\t\t\t\t\t\t\t\titem as IJsonLdNodeObject,\n\t\t\t\t\t\t\t\tcombinedContexts\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn combinedContexts;\n\t}\n\n\t/**\n\t * Remove all the contexts that match the pattern.\n\t * @param context The context to remove the entries from.\n\t * @param match The element to try and match.\n\t * @returns The updated contexts.\n\t */\n\tpublic static removeContexts(\n\t\tcontext: IJsonLdContextDefinitionRoot | undefined,\n\t\tmatch?: IJsonLdContextDefinitionElement[]\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tif (!Is.arrayValue(match)) {\n\t\t\treturn context;\n\t\t}\n\n\t\tlet finalContext: IJsonLdContextDefinitionRoot | undefined;\n\t\tif (Is.string(context)) {\n\t\t\tfor (const m of match) {\n\t\t\t\tif (context === m) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.array(context)) {\n\t\t\tfor (const item of context) {\n\t\t\t\tconst hasMatch = match.some(m => ObjectHelper.equal(m, item));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tfinalContext ??= [];\n\t\t\t\t\tif (Is.array(finalContext)) {\n\t\t\t\t\t\tfinalContext.push(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context)) {\n\t\t\tconst hasMatch = match.some(m => ObjectHelper.equal(m, context));\n\t\t\tif (!hasMatch) {\n\t\t\t\tfinalContext = context;\n\t\t\t}\n\t\t}\n\n\t\treturn Is.arrayValue(finalContext) && finalContext.length === 1\n\t\t\t? finalContext[0]\n\t\t\t: finalContext;\n\t}\n\n\t/**\n\t * Add a context directly to the document loader cache.\n\t * @param url The url the ld context is for.\n\t * @param ldContext The context to add.\n\t * @returns Nothing.\n\t */\n\tpublic static async documentCacheAdd(url: string, ldContext: unknown): Promise<void> {\n\t\tawait FetchHelper.setCacheEntry(url, ldContext);\n\t}\n\n\t/**\n\t * Remove a context from the document loader cache.\n\t * @param url The url the ld context is for.\n\t * @returns Nothing.\n\t */\n\tpublic static async documentCacheRemove(url: string): Promise<void> {\n\t\tFetchHelper.removeCacheEntry(url);\n\t}\n\n\t/**\n\t * Document loader which uses a caching mechanism.\n\t * @param url The document url to load.\n\t * @returns The document.\n\t * @internal\n\t */\n\tprivate static async documentLoader(url: Url): Promise<RemoteDocument> {\n\t\tconst redirects = JsonLdProcessor.getRedirects();\n\t\tfor (const redirect of redirects) {\n\t\t\tif (redirect.from.test(url)) {\n\t\t\t\turl = redirect.to;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await FetchHelper.fetchJson<never, JsonLd>(\n\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\turl,\n\t\t\t\tHttpMethod.GET,\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tcacheTtlMs: JsonLdProcessor.getCacheLimit(),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t[HeaderTypes.Accept]: MimeTypes.JsonLd\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tdocumentUrl: url,\n\t\t\t\tdocument: response\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tconst error = BaseError.fromError(err);\n\t\t\tif (error.message.includes(\"is not valid JSON\")) {\n\t\t\t\tconst response = await FetchHelper.fetchJson<never, JsonLd>(\n\t\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\t\turl,\n\t\t\t\t\tHttpMethod.GET,\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\tcacheTtlMs: JsonLdProcessor.getCacheLimit(),\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t[HeaderTypes.Accept]: MimeTypes.Json\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tdocumentUrl: url,\n\t\t\t\t\tdocument: response\n\t\t\t\t};\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Handle common errors.\n\t * @param err The error to handle.\n\t * @internal\n\t */\n\tprivate static handleCommonErrors(err: unknown): void {\n\t\tif (\n\t\t\tIs.object<{ name: string; details?: { url?: string } }>(err) &&\n\t\t\terr.name === \"jsonld.InvalidUrl\"\n\t\t) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\t\"invalidUrl\",\n\t\t\t\t{ url: err.details?.url },\n\t\t\t\terr\n\t\t\t);\n\t\t} else if (\n\t\t\tIs.object<{ name: string; details?: { code: string } & { [id: string]: unknown } }>(err) &&\n\t\t\terr.name.startsWith(\"jsonld.\")\n\t\t) {\n\t\t\tconst { code, ...other } = err.details ?? {};\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"jsonLdError\", { code, ...other }, err);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"jsonLdProcessor.js","sourceRoot":"","sources":["../../../src/utils/jsonLdProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseError, GeneralError, Is, ObjectHelper, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport {\n\tFetchHelper,\n\tHeaderHelper,\n\tHeaderTypes,\n\tHttpLinkRelType,\n\tHttpMethod,\n\tHttpStatusCode,\n\tMimeTypes\n} from \"@twin.org/web\";\nimport jsonLd from \"jsonld\";\nimport type { JsonLd, RemoteDocument, Url } from \"jsonld/jsonld-spec.js\";\nimport type { IJsonLdContextDefinition } from \"../models/IJsonLdContextDefinition.js\";\nimport type { IJsonLdContextDefinitionElement } from \"../models/IJsonLdContextDefinitionElement.js\";\nimport type { IJsonLdContextDefinitionRoot } from \"../models/IJsonLdContextDefinitionRoot.js\";\nimport type { IJsonLdNodeObject } from \"../models/IJsonLdNodeObject.js\";\n\n/**\n * JSON-LD Processor.\n */\nexport class JsonLdProcessor {\n\t/**\n\t * The class name.\n\t * @internal\n\t */\n\tpublic static readonly CLASS_NAME = nameof<JsonLdProcessor>();\n\n\t/**\n\t * Maximum number of HTTP Link-header discovery hops (namespace URL → context document).\n\t * @internal\n\t */\n\tprivate static readonly _MAX_LINK_DISCOVERY_DEPTH = 1;\n\n\t/**\n\t * The document loader to use.\n\t * @param documentLoader The document loader to use.\n\t */\n\tpublic static setDocumentLoader(documentLoader: (url: Url) => Promise<RemoteDocument>): void {\n\t\tSharedStore.set(\"jsonLdDocumentLoader\", documentLoader);\n\t}\n\n\t/**\n\t * The document loader to use for retrieving JSON-LD documents.\n\t * @returns The document loader.\n\t */\n\tpublic static getDocumentLoader(): (url: Url) => Promise<RemoteDocument> {\n\t\tlet documentLoader =\n\t\t\tSharedStore.get<(url: Url) => Promise<RemoteDocument>>(\"jsonLdDocumentLoader\");\n\t\tif (!Is.function(documentLoader)) {\n\t\t\tdocumentLoader = async (url: string) => JsonLdProcessor.documentLoader(url);\n\t\t}\n\t\treturn documentLoader;\n\t}\n\n\t/**\n\t * Set the cache time limit for documents.\n\t * @param cacheLimitMs The cache limit in milliseconds.\n\t */\n\tpublic static setCacheLimit(cacheLimitMs: number): void {\n\t\tSharedStore.set(\"jsonLdDocumentCacheLimit\", cacheLimitMs);\n\t}\n\n\t/**\n\t * Get the cache limit for documents.\n\t * @returns The document loader.\n\t */\n\tpublic static getCacheLimit(): number {\n\t\tlet cacheLimitMs = SharedStore.get<number>(\"jsonLdDocumentCacheLimit\");\n\t\tif (Is.empty(cacheLimitMs)) {\n\t\t\tcacheLimitMs = 3600000;\n\t\t\tSharedStore.set(\"jsonLdDocumentCacheLimit\", cacheLimitMs);\n\t\t}\n\t\treturn cacheLimitMs;\n\t}\n\n\t/**\n\t * Replace the global redirect list (use {@link JsonLdProcessor.addRedirect} to append without replacing).\n\t * Redirects run before any HTTP GET or `Link` discovery; use them for stable overrides, tests, or hosts that do not expose a suitable `Link` header.\n\t * @param redirects The redirects to use.\n\t */\n\tpublic static setRedirects(\n\t\tredirects: {\n\t\t\tfrom: RegExp;\n\t\t\tto: string;\n\t\t}[]\n\t): void {\n\t\tSharedStore.set(\"jsonLdRedirects\", redirects);\n\t}\n\n\t/**\n\t * Get the global redirects for JSON-LD.\n\t * @returns The registered redirects.\n\t */\n\tpublic static getRedirects(): {\n\t\tfrom: RegExp;\n\t\tto: string;\n\t}[] {\n\t\tlet redirects = SharedStore.get<\n\t\t\t{\n\t\t\t\tfrom: RegExp;\n\t\t\t\tto: string;\n\t\t\t}[]\n\t\t>(\"jsonLdRedirects\");\n\t\tif (Is.empty(redirects)) {\n\t\t\tredirects = [];\n\t\t\tSharedStore.set(\"jsonLdRedirects\", redirects);\n\t\t}\n\t\treturn redirects;\n\t}\n\n\t/**\n\t * Append a redirect rule (ignored if the same `RegExp.source` is already registered).\n\t * Optional when the vocabulary URL supports HTTP `Link` discovery (`rel` includes `alternate`, `type` is `application/ld+json`) via the default document loader.\n\t * Standards packages often expose `registerRedirects()` helpers that call this method; those are optional for the same reason.\n\t * @param from The URL to redirect from.\n\t * @param to The URL to redirect to.\n\t */\n\tpublic static addRedirect(from: RegExp, to: string): void {\n\t\tconst redirects = JsonLdProcessor.getRedirects();\n\t\tif (!redirects.some(r => r.from.source === from.source)) {\n\t\t\tredirects.push({ from, to });\n\t\t}\n\t}\n\n\t/**\n\t * Compact a document according to a particular context.\n\t * @param document The JSON-LD document to compact.\n\t * @param context The context to compact the document to, if not provided will use the one in the document.\n\t * @param options The options for compacting the document.\n\t * @param options.itemListOverride Whether to override the itemListElement context with a set, defaults to true.\n\t * @returns The compacted JSON-LD document.\n\t */\n\tpublic static async compact<T>(\n\t\tdocument: T,\n\t\tcontext?: IJsonLdContextDefinitionRoot,\n\t\toptions?: { itemListOverride: boolean }\n\t): Promise<T> {\n\t\ttry {\n\t\t\tif (Is.object<IJsonLdNodeObject>(document)) {\n\t\t\t\t// If the user didn't provide a context, use the one from the document\n\t\t\t\tif (Is.empty(context) && !Is.empty(document[\"@context\"])) {\n\t\t\t\t\tcontext = document[\"@context\"];\n\t\t\t\t}\n\n\t\t\t\tconst overrideListElementOption = options?.itemListOverride ?? true;\n\t\t\t\tlet overrideContext: IJsonLdContextDefinitionElement | undefined;\n\n\t\t\t\tif (overrideListElementOption) {\n\t\t\t\t\t// The compactArrays flag doesn't work with the current version of jsonld.js\n\t\t\t\t\t// For list results we standardise on ItemList and itemListElement\n\t\t\t\t\t// so we modify the schema.org type for itemListElement to be a set which bypasses the issue\n\t\t\t\t\t// https://github.com/digitalbazaar/jsonld.js/issues/247\n\t\t\t\t\toverrideContext = {\n\t\t\t\t\t\titemListElement: {\n\t\t\t\t\t\t\t\"@id\": \"http://schema.org/itemListElement\",\n\t\t\t\t\t\t\t\"@container\": \"@set\",\n\t\t\t\t\t\t\t\"@protected\": true\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif (Is.object(context) && \"@context\" in context) {\n\t\t\t\t\t\t// If the context is an object, we need to merge it with the override context\n\t\t\t\t\t\tcontext = JsonLdProcessor.combineContexts(\n\t\t\t\t\t\t\tcontext[\"@context\"] as IJsonLdContextDefinitionRoot,\n\t\t\t\t\t\t\toverrideContext\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the context is a string or an array, we need to merge it with the override context\n\t\t\t\t\t\tcontext = JsonLdProcessor.combineContexts(context, overrideContext);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst compacted = await jsonLd.compact(\n\t\t\t\t\tObjectHelper.removeEmptyProperties(document),\n\t\t\t\t\tcontext as IJsonLdContextDefinition,\n\t\t\t\t\t{\n\t\t\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tif (!Is.empty(overrideContext)) {\n\t\t\t\t\t// Remove the override context from the compacted document\n\t\t\t\t\tcompacted[\"@context\"] = JsonLdProcessor.removeContexts(\n\t\t\t\t\t\tcompacted[\"@context\"] as IJsonLdContextDefinitionRoot,\n\t\t\t\t\t\t[overrideContext]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn compacted as T;\n\t\t\t}\n\t\t\treturn document;\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"compact\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Expand a document, removing its context.\n\t * @param compacted The compacted JSON-LD document to expand.\n\t * @returns The expanded JSON-LD document.\n\t */\n\tpublic static async expand<T>(compacted: T): Promise<IJsonLdNodeObject[]> {\n\t\ttry {\n\t\t\tif (Is.object<IJsonLdNodeObject>(compacted)) {\n\t\t\t\tconst expanded = await jsonLd.expand(ObjectHelper.removeEmptyProperties(compacted), {\n\t\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t\t});\n\t\t\t\treturn expanded;\n\t\t\t}\n\t\t\treturn [];\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"expand\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Canonize a document.\n\t * @param document The document to canonize.\n\t * @param options The options for canonization.\n\t * @param options.algorithm The algorithm to use for canonization, defaults to URDNA2015.\n\t * @returns The canonized document.\n\t */\n\tpublic static async canonize<T extends IJsonLdNodeObject>(\n\t\tdocument: T,\n\t\toptions?: {\n\t\t\talgorithm?: \"URDNA2015\" | \"URGNA2012\" | undefined;\n\t\t}\n\t): Promise<string> {\n\t\ttry {\n\t\t\tconst normalized = await jsonLd.canonize(ObjectHelper.removeEmptyProperties(document), {\n\t\t\t\talgorithm: options?.algorithm ?? \"URDNA2015\",\n\t\t\t\tformat: \"application/n-quads\",\n\t\t\t\tdocumentLoader: JsonLdProcessor.getDocumentLoader()\n\t\t\t});\n\t\t\treturn normalized;\n\t\t} catch (err) {\n\t\t\tJsonLdProcessor.handleCommonErrors(err);\n\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"canonize\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Combine contexts.\n\t * @param context1 The first JSON-LD context to combine.\n\t * @param context2 The second JSON-LD context to combine.\n\t * @returns The combined context.\n\t */\n\tpublic static combineContexts(\n\t\tcontext1: IJsonLdContextDefinitionRoot | undefined,\n\t\tcontext2: IJsonLdContextDefinitionRoot | undefined\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tconst combinedContext: IJsonLdContextDefinitionRoot = [];\n\n\t\tif (Is.string(context1)) {\n\t\t\tif (!combinedContext.includes(context1)) {\n\t\t\t\tcombinedContext.push(context1);\n\t\t\t}\n\t\t} else if (Is.array(context1)) {\n\t\t\tfor (const context of context1) {\n\t\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tcombinedContext.push(context);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context1)) {\n\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context1));\n\t\t\tif (!hasMatch) {\n\t\t\t\tcombinedContext.push(context1);\n\t\t\t}\n\t\t}\n\n\t\tif (Is.string(context2)) {\n\t\t\tif (!combinedContext.includes(context2)) {\n\t\t\t\tcombinedContext.push(context2);\n\t\t\t}\n\t\t} else if (Is.array(context2)) {\n\t\t\tfor (const context of context2) {\n\t\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tcombinedContext.push(context);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context2)) {\n\t\t\tconst hasMatch = combinedContext.some(c => ObjectHelper.equal(c, context2));\n\t\t\tif (!hasMatch) {\n\t\t\t\tcombinedContext.push(context2);\n\t\t\t}\n\t\t}\n\n\t\tif (combinedContext.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (combinedContext.length === 1) {\n\t\t\treturn combinedContext[0];\n\t\t}\n\n\t\treturn combinedContext;\n\t}\n\n\t/**\n\t * Gather all the contexts from the element and it's children.\n\t * @param element The element to gather the contexts from.\n\t * @param initial The initial context.\n\t * @returns The combined contexts.\n\t */\n\tpublic static gatherContexts<T>(\n\t\telement: T,\n\t\tinitial?: IJsonLdContextDefinitionRoot\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tlet combinedContexts: IJsonLdContextDefinitionRoot | undefined = initial;\n\n\t\tif (Is.object<IJsonLdNodeObject>(element)) {\n\t\t\tif (!Is.empty(element[\"@context\"])) {\n\t\t\t\tcombinedContexts = JsonLdProcessor.combineContexts(\n\t\t\t\t\tinitial,\n\t\t\t\t\telement[\"@context\"] as IJsonLdContextDefinitionRoot\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfor (const prop of Object.keys(element)) {\n\t\t\t\tconst value = element[prop];\n\t\t\t\tif (Is.object(value)) {\n\t\t\t\t\tcombinedContexts = JsonLdProcessor.gatherContexts(\n\t\t\t\t\t\tvalue as IJsonLdNodeObject,\n\t\t\t\t\t\tcombinedContexts\n\t\t\t\t\t);\n\t\t\t\t} else if (Is.array(value)) {\n\t\t\t\t\tfor (const item of value) {\n\t\t\t\t\t\tif (Is.object(item)) {\n\t\t\t\t\t\t\tcombinedContexts = JsonLdProcessor.gatherContexts(\n\t\t\t\t\t\t\t\titem as IJsonLdNodeObject,\n\t\t\t\t\t\t\t\tcombinedContexts\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn combinedContexts;\n\t}\n\n\t/**\n\t * Remove all the contexts that match the pattern.\n\t * @param context The context to remove the entries from.\n\t * @param match The element to try and match.\n\t * @returns The updated contexts.\n\t */\n\tpublic static removeContexts(\n\t\tcontext: IJsonLdContextDefinitionRoot | undefined,\n\t\tmatch?: IJsonLdContextDefinitionElement[]\n\t): IJsonLdContextDefinitionRoot | undefined {\n\t\tif (!Is.arrayValue(match)) {\n\t\t\treturn context;\n\t\t}\n\n\t\tlet finalContext: IJsonLdContextDefinitionRoot | undefined;\n\t\tif (Is.string(context)) {\n\t\t\tfor (const m of match) {\n\t\t\t\tif (context === m) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.array(context)) {\n\t\t\tfor (const item of context) {\n\t\t\t\tconst hasMatch = match.some(m => ObjectHelper.equal(m, item));\n\t\t\t\tif (!hasMatch) {\n\t\t\t\t\tfinalContext ??= [];\n\t\t\t\t\tif (Is.array(finalContext)) {\n\t\t\t\t\t\tfinalContext.push(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (Is.object(context)) {\n\t\t\tconst hasMatch = match.some(m => ObjectHelper.equal(m, context));\n\t\t\tif (!hasMatch) {\n\t\t\t\tfinalContext = context;\n\t\t\t}\n\t\t}\n\n\t\treturn Is.arrayValue(finalContext) && finalContext.length === 1\n\t\t\t? finalContext[0]\n\t\t\t: finalContext;\n\t}\n\n\t/**\n\t * Add a context directly to the document loader cache.\n\t * @param url The url the ld context is for.\n\t * @param ldContext The context to add.\n\t * @returns Nothing.\n\t */\n\tpublic static async documentCacheAdd(url: string, ldContext: unknown): Promise<void> {\n\t\tawait FetchHelper.setCacheEntry(url, ldContext);\n\t}\n\n\t/**\n\t * Remove a context from the document loader cache.\n\t * @param url The url the ld context is for.\n\t * @returns Nothing.\n\t */\n\tpublic static async documentCacheRemove(url: string): Promise<void> {\n\t\tFetchHelper.removeCacheEntry(url);\n\t}\n\n\t/**\n\t * Document loader which uses a caching mechanism.\n\t * @param url The document url to load.\n\t * @returns The document.\n\t * @internal\n\t */\n\tprivate static async documentLoader(url: Url): Promise<RemoteDocument> {\n\t\tconst redirects = JsonLdProcessor.getRedirects();\n\t\tfor (const redirect of redirects) {\n\t\t\tif (redirect.from.test(url)) {\n\t\t\t\turl = redirect.to;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn JsonLdProcessor.fetchRemoteJsonLdDocument(url, 0);\n\t}\n\n\t/**\n\t * True when FetchHelper failed to decode JSON from the response (e.g. HTML or plain text).\n\t * @param err The error from fetchJson.\n\t * @internal\n\t */\n\tprivate static isFetchJsonDecodeFailure(err: unknown): boolean {\n\t\t// Raw JSON.parse / response.json() failures (FetchHelper may rethrow as FetchError with cause,\n\t\t// or propagate SyntaxError when error-response body is not JSON).\n\t\tconst error = BaseError.fromError(err);\n\t\tif (error.name === \"SyntaxError\" || error.cause?.name === \"SyntaxError\") {\n\t\t\treturn true;\n\t\t}\n\t\treturn error.message.includes(\"decodingJSON\") || error.message.includes(\"is not valid JSON\");\n\t}\n\n\t/**\n\t * Use HTTP Link (rel=alternate, type=application/ld+json) to discover a JSON-LD context URL.\n\t * @param sourceUrl URL that did not yield JSON (e.g. vocabulary namespace HTML page).\n\t * @returns Absolute context document URL, or undefined.\n\t * @internal\n\t */\n\tprivate static async tryDiscoverAlternateJsonLdContextUrl(\n\t\tsourceUrl: string\n\t): Promise<string | undefined> {\n\t\tconst fetchOpts = {\n\t\t\ttimeoutMs: 30_000,\n\t\t\theaders: {\n\t\t\t\t[HeaderTypes.Accept]: `${MimeTypes.JsonLd},${MimeTypes.Json};q=0.9,*/*;q=0.8`\n\t\t\t}\n\t\t};\n\n\t\tlet response = await FetchHelper.fetch(\n\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\tsourceUrl,\n\t\t\tHttpMethod.HEAD,\n\t\t\tundefined,\n\t\t\tfetchOpts\n\t\t);\n\n\t\tif (\n\t\t\tresponse.status === HttpStatusCode.methodNotAllowed ||\n\t\t\tresponse.status === HttpStatusCode.notImplemented\n\t\t) {\n\t\t\tresponse = await FetchHelper.fetch(\n\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\tsourceUrl,\n\t\t\t\tHttpMethod.GET,\n\t\t\t\tundefined,\n\t\t\t\tfetchOpts\n\t\t\t);\n\t\t\tawait response.arrayBuffer();\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst linkHeader = response.headers.get(HeaderTypes.Link);\n\t\tif (Is.empty(linkHeader)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// response.url is \"\" for many mocked/synthetic Responses; Is.empty(\"\") is false, but\n\t\t// new URL(absoluteHref, \"\") throws — use a non-empty resolved URL as base only.\n\t\tconst baseUrl = Is.stringValue(response.url) ? response.url : sourceUrl;\n\n\t\tconst alternateLinkHeaders = HeaderHelper.extractLinkHeaderRelations(\n\t\t\tlinkHeader,\n\t\t\tHttpLinkRelType.alternate\n\t\t);\n\n\t\tif (Is.arrayValue(alternateLinkHeaders)) {\n\t\t\tfor (const alternateLinkHeader of alternateLinkHeaders) {\n\t\t\t\tif (alternateLinkHeader.params?.type === MimeTypes.JsonLd) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn new URL(alternateLinkHeader.url, baseUrl).href;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Malformed URL for this segment; try the next Link segment.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Fetch a remote JSON-LD document, with Accept fallbacks and optional Link-header discovery.\n\t * @param url Resolved document URL.\n\t * @param linkDiscoveryDepth Current discovery recursion depth.\n\t * @internal\n\t */\n\tprivate static async fetchRemoteJsonLdDocument(\n\t\turl: string,\n\t\tlinkDiscoveryDepth: number\n\t): Promise<RemoteDocument> {\n\t\tconst cacheTtlMs = JsonLdProcessor.getCacheLimit();\n\t\tconst fetchJsonLdOptions = {\n\t\t\tcacheTtlMs,\n\t\t\theaders: {\n\t\t\t\t[HeaderTypes.Accept]: MimeTypes.JsonLd\n\t\t\t}\n\t\t};\n\t\tconst fetchJsonOptions = {\n\t\t\tcacheTtlMs,\n\t\t\theaders: {\n\t\t\t\t[HeaderTypes.Accept]: MimeTypes.Json\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tconst document = await FetchHelper.fetchJson<never, JsonLd>(\n\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\turl,\n\t\t\t\tHttpMethod.GET,\n\t\t\t\tundefined,\n\t\t\t\tfetchJsonLdOptions\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tdocumentUrl: url,\n\t\t\t\tdocument\n\t\t\t};\n\t\t} catch (errLd) {\n\t\t\tif (JsonLdProcessor.isFetchJsonDecodeFailure(errLd)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst document = await FetchHelper.fetchJson<never, JsonLd>(\n\t\t\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tHttpMethod.GET,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tfetchJsonOptions\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdocumentUrl: url,\n\t\t\t\t\t\tdocument\n\t\t\t\t\t};\n\t\t\t\t} catch (errJson) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tlinkDiscoveryDepth < JsonLdProcessor._MAX_LINK_DISCOVERY_DEPTH &&\n\t\t\t\t\t\tJsonLdProcessor.isFetchJsonDecodeFailure(errJson)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst discovered = await JsonLdProcessor.tryDiscoverAlternateJsonLdContextUrl(url);\n\t\t\t\t\t\tif (Is.stringValue(discovered) && discovered !== url) {\n\t\t\t\t\t\t\treturn JsonLdProcessor.fetchRemoteJsonLdDocument(discovered, linkDiscoveryDepth + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthrow errJson;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow errLd;\n\t\t}\n\t}\n\n\t/**\n\t * Handle common errors.\n\t * @param err The error to handle.\n\t * @internal\n\t */\n\tprivate static handleCommonErrors(err: unknown): void {\n\t\tif (\n\t\t\tIs.object<{ name: string; details?: { url?: string } }>(err) &&\n\t\t\terr.name === \"jsonld.InvalidUrl\"\n\t\t) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tJsonLdProcessor.CLASS_NAME,\n\t\t\t\t\"invalidUrl\",\n\t\t\t\t{ url: err.details?.url },\n\t\t\t\terr\n\t\t\t);\n\t\t} else if (\n\t\t\tIs.object<{ name: string; details?: { code: string } & { [id: string]: unknown } }>(err) &&\n\t\t\terr.name.startsWith(\"jsonld.\")\n\t\t) {\n\t\t\tconst { code, ...other } = err.details ?? {};\n\t\t\tthrow new GeneralError(JsonLdProcessor.CLASS_NAME, \"jsonLdError\", { code, ...other }, err);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { IJsonLdContextDefinitionRoot } from "../models/IJsonLdContextDefinitionRoot.js";
|
|
2
|
+
/**
|
|
3
|
+
* Extract the optional property names from a type.
|
|
4
|
+
*/
|
|
5
|
+
export type JsonLdOptionalKeys<T> = {
|
|
6
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? K : never;
|
|
7
|
+
}[keyof T];
|
|
8
|
+
/**
|
|
9
|
+
* Extract the required property names from a type.
|
|
10
|
+
*/
|
|
11
|
+
export type JsonLdRequiredKeys<T> = Exclude<keyof T, JsonLdOptionalKeys<T>>;
|
|
12
|
+
/**
|
|
13
|
+
* Keep JSON-LD keys as-is and prefix non-JSON-LD keys.
|
|
14
|
+
*/
|
|
15
|
+
export type JsonLdAliasKey<K extends string, Prefix extends string> = K extends `@${string}` ? K : `${Prefix}:${K}`;
|
|
16
|
+
/**
|
|
17
|
+
* Remap an object type so JSON-LD keys ("@...") are preserved and
|
|
18
|
+
* non-JSON-LD keys are exposed as `Prefix:key` aliases, while preserving
|
|
19
|
+
* each key's original required/optional status.
|
|
20
|
+
*/
|
|
21
|
+
export type JsonLdWithAliases<T extends object, Prefix extends string> = {
|
|
22
|
+
[K in Extract<JsonLdRequiredKeys<T>, string> as JsonLdAliasKey<K, Prefix>]: T[K];
|
|
23
|
+
} & {
|
|
24
|
+
[K in Extract<JsonLdOptionalKeys<T>, string> as JsonLdAliasKey<K, Prefix>]?: T[K];
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Keep only JSON-LD keys ("@...") from a type.
|
|
28
|
+
*/
|
|
29
|
+
export type JsonLdKeys<T extends object> = Pick<T, Extract<keyof T, `@${string}`>>;
|
|
30
|
+
/**
|
|
31
|
+
* Create a JSON-LD object shape containing only JSON-LD keys plus aliased
|
|
32
|
+
* non-JSON-LD keys.
|
|
33
|
+
*/
|
|
34
|
+
export type JsonLdObjectWithAliases<T extends object, Prefix extends string> = JsonLdKeys<T> & JsonLdWithAliases<T, Prefix>;
|
|
35
|
+
/**
|
|
36
|
+
* Add "@context" to a type.
|
|
37
|
+
*/
|
|
38
|
+
export type JsonLdObjectWithContext<T extends object, C = IJsonLdContextDefinitionRoot> = Omit<T, "@context"> & {
|
|
39
|
+
"@context": C;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Infer an existing property's type from a source type, or fall back to a default.
|
|
43
|
+
*/
|
|
44
|
+
export type JsonLdExistingProperty<T extends object, P extends PropertyKey, D> = T extends {
|
|
45
|
+
[K in P]?: infer PropertyType;
|
|
46
|
+
} ? Exclude<PropertyType, undefined> : D;
|
|
47
|
+
/**
|
|
48
|
+
* Infer an existing property's type from either of two source properties,
|
|
49
|
+
* or fall back to a default when neither exists.
|
|
50
|
+
*/
|
|
51
|
+
export type JsonLdExistingPropertyEither<T extends object, P1 extends PropertyKey, P2 extends PropertyKey, D> = [JsonLdExistingProperty<T, P1, never> | JsonLdExistingProperty<T, P2, never>] extends [never] ? D : JsonLdExistingProperty<T, P1, never> | JsonLdExistingProperty<T, P2, never>;
|
|
52
|
+
/**
|
|
53
|
+
* Add optional "@context" to a type, inferring an existing context type from
|
|
54
|
+
* the source type when available, otherwise using the provided default.
|
|
55
|
+
*/
|
|
56
|
+
export type JsonLdObjectWithOptionalContext<T extends object, C = JsonLdExistingProperty<T, "@context", IJsonLdContextDefinitionRoot>> = Omit<T, "@context"> & {
|
|
57
|
+
"@context"?: C;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Omit optional "@context" from a type, inferring an existing context type from
|
|
61
|
+
* the source type when available, otherwise using the provided default.
|
|
62
|
+
*/
|
|
63
|
+
export type JsonLdObjectWithNoContext<T extends object> = Omit<T, "@context">;
|
|
64
|
+
/**
|
|
65
|
+
* Add "type" to a type.
|
|
66
|
+
*/
|
|
67
|
+
export type JsonLdObjectWithType<T extends object, Ty = JsonLdExistingPropertyEither<T, "type", "@type", string | string[]>> = Omit<T, "type" | "@type"> & {
|
|
68
|
+
type: Ty;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Add optional "type" to a type.
|
|
72
|
+
*/
|
|
73
|
+
export type JsonLdObjectWithOptionalType<T extends object, Ty = JsonLdExistingPropertyEither<T, "type", "@type", string | string[]>> = Omit<T, "type" | "@type"> & {
|
|
74
|
+
type?: Ty;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Omit "type" from a type.
|
|
78
|
+
*/
|
|
79
|
+
export type JsonLdObjectWithNoType<T extends object> = Omit<T, "type">;
|
|
80
|
+
/**
|
|
81
|
+
* Add "@type" to a type.
|
|
82
|
+
*/
|
|
83
|
+
export type JsonLdObjectWithAtType<T extends object, Ty = JsonLdExistingPropertyEither<T, "@type", "type", string | string[]>> = Omit<T, "@type" | "type"> & {
|
|
84
|
+
"@type": Ty;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Add optional "@type" to a type.
|
|
88
|
+
*/
|
|
89
|
+
export type JsonLdObjectWithOptionalAtType<T extends object, Ty = JsonLdExistingPropertyEither<T, "@type", "type", string | string[]>> = Omit<T, "@type" | "type"> & {
|
|
90
|
+
"@type"?: Ty;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Omit "@type" from a type.
|
|
94
|
+
*/
|
|
95
|
+
export type JsonLdObjectWithNoAtType<T extends object> = Omit<T, "@type">;
|
|
96
|
+
/**
|
|
97
|
+
* Add "id" to a type.
|
|
98
|
+
*/
|
|
99
|
+
export type JsonLdObjectWithId<T extends object, Id = JsonLdExistingPropertyEither<T, "id", "@id", string>> = Omit<T, "id" | "@id"> & {
|
|
100
|
+
id: Id;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Add optional "id" to a type.
|
|
104
|
+
*/
|
|
105
|
+
export type JsonLdObjectWithOptionalId<T extends object, Id = JsonLdExistingPropertyEither<T, "id", "@id", string>> = Omit<T, "id" | "@id"> & {
|
|
106
|
+
id?: Id;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Omit "id" from a type.
|
|
110
|
+
*/
|
|
111
|
+
export type JsonLdObjectWithNoId<T extends object> = Omit<T, "id">;
|
|
112
|
+
/**
|
|
113
|
+
* Add "@id" to a type.
|
|
114
|
+
*/
|
|
115
|
+
export type JsonLdObjectWithAtId<T extends object, Id = JsonLdExistingPropertyEither<T, "@id", "id", string>> = Omit<T, "@id" | "id"> & {
|
|
116
|
+
"@id": Id;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Add optional "@id" to a type.
|
|
120
|
+
*/
|
|
121
|
+
export type JsonLdObjectWithOptionalAtId<T extends object, Id = JsonLdExistingPropertyEither<T, "@id", "id", string>> = Omit<T, "@id" | "id"> & {
|
|
122
|
+
"@id"?: Id;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Omit "@id" from a type.
|
|
126
|
+
*/
|
|
127
|
+
export type JsonLdObjectWithNoAtId<T extends object> = Omit<T, "@id">;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const JsonLdContexts: {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The canonical RDF namespace URI for JSON-LD.
|
|
7
7
|
*/
|
|
8
|
-
readonly
|
|
8
|
+
readonly Namespace: "https://schema.twindev.org/json-ld/";
|
|
9
|
+
/**
|
|
10
|
+
* The value to use in JSON-LD context for JSON-LD.
|
|
11
|
+
*/
|
|
12
|
+
readonly Context: "https://schema.twindev.org/json-ld/";
|
|
13
|
+
/**
|
|
14
|
+
* The JSON-LD Context URL for JSON-LD.
|
|
15
|
+
*/
|
|
16
|
+
readonly JsonLdContext: "https://schema.twindev.org/json-ld/types.jsonld";
|
|
9
17
|
};
|
|
10
18
|
/**
|
|
11
19
|
* The contexts of JSON-LD data.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type IValidationFailure } from "@twin.org/core";
|
|
2
2
|
import { type ValidationMode } from "@twin.org/data-core";
|
|
3
3
|
import type { IJsonLdDocument } from "../models/IJsonLdDocument.js";
|
|
4
|
+
import type { IJsonLdNodeObject } from "../models/IJsonLdNodeObject.js";
|
|
5
|
+
import type { IJsonLdNodePrimitive } from "../models/IJsonLdNodePrimitive.js";
|
|
4
6
|
/**
|
|
5
7
|
* Class to help with JSON LD.
|
|
6
8
|
*/
|
|
@@ -18,23 +20,78 @@ export declare class JsonLdHelper {
|
|
|
18
20
|
validationMode?: ValidationMode;
|
|
19
21
|
failOnMissingType?: boolean;
|
|
20
22
|
}): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Convert an object to a JSON-LD node object.
|
|
25
|
+
* @param object The object to convert.
|
|
26
|
+
* @returns The JSON-LD node object.
|
|
27
|
+
*/
|
|
28
|
+
static toNodeObject<T = unknown>(object: T): T & IJsonLdNodeObject;
|
|
29
|
+
/**
|
|
30
|
+
* Convert the JSON-LD node object to a structured object.
|
|
31
|
+
* @param nodeObject The JSON-LD node object to convert.
|
|
32
|
+
* @returns The structured object.
|
|
33
|
+
*/
|
|
34
|
+
static toStructuredObject<T = unknown>(nodeObject: IJsonLdNodeObject): T;
|
|
35
|
+
/**
|
|
36
|
+
* Expand the JSON-LD document.
|
|
37
|
+
* @param document The JSON-LD document to expand.
|
|
38
|
+
* @returns The expanded JSON-LD document.
|
|
39
|
+
*/
|
|
40
|
+
static expand(document: IJsonLdDocument): Promise<IJsonLdNodeObject[]>;
|
|
21
41
|
/**
|
|
22
42
|
* Expand the JSON-LD document and check if it is of a specific type.
|
|
23
|
-
* @param
|
|
43
|
+
* @param documentOrExpanded The JSON-LD document to check or already expanded document.
|
|
24
44
|
* @param type The type to check for.
|
|
25
45
|
* @returns True if the document is of the specified type.
|
|
26
46
|
*/
|
|
27
|
-
static isType(
|
|
47
|
+
static isType(documentOrExpanded: IJsonLdDocument | IJsonLdNodeObject[], type: string[]): Promise<boolean>;
|
|
28
48
|
/**
|
|
29
49
|
* Get the types from the document.
|
|
30
|
-
* @param
|
|
50
|
+
* @param documentOrExpanded The JSON-LD document to check or already expanded document.
|
|
31
51
|
* @returns The type(s) extracted from the document.
|
|
32
52
|
*/
|
|
33
|
-
static getType(
|
|
53
|
+
static getType(documentOrExpanded: IJsonLdDocument | IJsonLdNodeObject[]): Promise<string[]>;
|
|
34
54
|
/**
|
|
35
55
|
* Get the id from the document.
|
|
36
|
-
* @param
|
|
56
|
+
* @param documentOrExpanded The JSON-LD document to get the id from or already expanded document.
|
|
57
|
+
* @param additionalIdProperties Optional additional properties to check for the id, in addition to "@id" and "id".
|
|
37
58
|
* @returns The id extracted from the document.
|
|
38
59
|
*/
|
|
39
|
-
static getId(
|
|
60
|
+
static getId(documentOrExpanded: IJsonLdDocument | IJsonLdNodeObject[], additionalIdProperties?: string[]): Promise<string | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Get property values by a single full expanded property name.
|
|
63
|
+
* @param documentOrExpanded The JSON-LD document to get the property from or already expanded document.
|
|
64
|
+
* @param propertyFullName The full expanded property name.
|
|
65
|
+
* @param language Optional filter values by their language property.
|
|
66
|
+
* @returns Matching property values for the input property.
|
|
67
|
+
*/
|
|
68
|
+
static getPropertyValue(documentOrExpanded: IJsonLdDocument | IJsonLdNodeObject[], propertyFullName: string, language?: string): Promise<IJsonLdNodePrimitive[] | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Get property values by their full expanded property names.
|
|
71
|
+
* @param documentOrExpanded The JSON-LD document to get the property from or already expanded document.
|
|
72
|
+
* @param propertyFullNames The full expanded property names.
|
|
73
|
+
* @param language Optional filter values by their language property.
|
|
74
|
+
* @returns Matching property values for each input property, in the same index order.
|
|
75
|
+
*/
|
|
76
|
+
static getPropertyValues(documentOrExpanded: IJsonLdDocument | IJsonLdNodeObject[], propertyFullNames: string[], language?: string): Promise<(IJsonLdNodePrimitive[] | undefined)[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Prefix all properties in the document with the provided prefix, except for JSON-LD properties.
|
|
79
|
+
* This is useful for ensuring that all properties are fully qualified with a namespace.
|
|
80
|
+
* For example, if the prefix is "ex" and the document has a property "name", it will be transformed to "ex:name".
|
|
81
|
+
* @param nodeObject The JSON-LD node object to prefix properties on.
|
|
82
|
+
* @param prefix The prefix to add to the properties.
|
|
83
|
+
* @param properties Optional list of properties to prefix. If not provided, all properties except for JSON-LD properties.
|
|
84
|
+
* @returns A new JSON-LD node object with the properties prefixed.
|
|
85
|
+
*/
|
|
86
|
+
static prefixProperties<T extends IJsonLdNodeObject>(nodeObject: T, prefix: string, properties?: string[]): IJsonLdNodeObject;
|
|
87
|
+
/**
|
|
88
|
+
* Strip a prefix from properties in the document, except for JSON-LD properties.
|
|
89
|
+
* This is useful for converting fully qualified namespaced properties back to local names.
|
|
90
|
+
* For example, if the prefix is "ex" and the document has a property "ex:name", it will be transformed to "name".
|
|
91
|
+
* @param nodeObject The JSON-LD node object to strip prefixed properties from.
|
|
92
|
+
* @param prefix The prefix to remove from the properties.
|
|
93
|
+
* @param properties Optional list of unprefixed properties to strip. If not provided, all matching prefixed properties.
|
|
94
|
+
* @returns A new JSON-LD node object with the prefix stripped from matching properties.
|
|
95
|
+
*/
|
|
96
|
+
static stripPrefixProperties<T extends IJsonLdNodeObject>(nodeObject: T, prefix: string, properties?: string[]): IJsonLdNodeObject;
|
|
40
97
|
}
|
|
@@ -27,7 +27,8 @@ export declare class JsonLdProcessor {
|
|
|
27
27
|
*/
|
|
28
28
|
static getCacheLimit(): number;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Replace the global redirect list (use {@link JsonLdProcessor.addRedirect} to append without replacing).
|
|
31
|
+
* Redirects run before any HTTP GET or `Link` discovery; use them for stable overrides, tests, or hosts that do not expose a suitable `Link` header.
|
|
31
32
|
* @param redirects The redirects to use.
|
|
32
33
|
*/
|
|
33
34
|
static setRedirects(redirects: {
|
|
@@ -42,6 +43,14 @@ export declare class JsonLdProcessor {
|
|
|
42
43
|
from: RegExp;
|
|
43
44
|
to: string;
|
|
44
45
|
}[];
|
|
46
|
+
/**
|
|
47
|
+
* Append a redirect rule (ignored if the same `RegExp.source` is already registered).
|
|
48
|
+
* Optional when the vocabulary URL supports HTTP `Link` discovery (`rel` includes `alternate`, `type` is `application/ld+json`) via the default document loader.
|
|
49
|
+
* Standards packages often expose `registerRedirects()` helpers that call this method; those are optional for the same reason.
|
|
50
|
+
* @param from The URL to redirect from.
|
|
51
|
+
* @param to The URL to redirect to.
|
|
52
|
+
*/
|
|
53
|
+
static addRedirect(from: RegExp, to: string): void;
|
|
45
54
|
/**
|
|
46
55
|
* Compact a document according to a particular context.
|
|
47
56
|
* @param document The JSON-LD document to compact.
|
|
@@ -69,12 +78,6 @@ export declare class JsonLdProcessor {
|
|
|
69
78
|
static canonize<T extends IJsonLdNodeObject>(document: T, options?: {
|
|
70
79
|
algorithm?: "URDNA2015" | "URGNA2012" | undefined;
|
|
71
80
|
}): Promise<string>;
|
|
72
|
-
/**
|
|
73
|
-
* Add a redirect to use during document resolution.
|
|
74
|
-
* @param from The URL to redirect from.
|
|
75
|
-
* @param to The URL to redirect to.
|
|
76
|
-
*/
|
|
77
|
-
static addRedirect(from: RegExp, to: string): void;
|
|
78
81
|
/**
|
|
79
82
|
* Combine contexts.
|
|
80
83
|
* @param context1 The first JSON-LD context to combine.
|