ldkit 2.2.0 → 2.3.0

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.
@@ -1,6 +1,6 @@
1
- import { fromRdf } from "./rdf.js";
2
1
  import { ldkit } from "../namespaces/ldkit.js";
3
2
  import { rdf } from "../namespaces/rdf.js";
3
+ import { translateFromRdf } from "./translator.js";
4
4
  export const decode = (graph, schema, options) => {
5
5
  return Decoder.decode(graph, schema, options);
6
6
  };
@@ -185,7 +185,7 @@ class Decoder {
185
185
  return term.value;
186
186
  }
187
187
  else if (term.termType === "Literal") {
188
- return fromRdf(term);
188
+ return translateFromRdf(term);
189
189
  }
190
190
  else {
191
191
  throw new Error(`Unsupported term type to resolve: ${term.termType}`);
@@ -1,7 +1,8 @@
1
- import { DataFactory, toRdf } from "./rdf.js";
1
+ import { DataFactory } from "./rdf.js";
2
2
  import { xsd } from "../namespaces/xsd.js";
3
3
  import { rdf } from "../namespaces/rdf.js";
4
4
  import { ldkit } from "../namespaces/ldkit.js";
5
+ import { translateToRdf } from "./translator.js";
5
6
  export const encode = (node, schema, options, includeType = true, variableInitCounter = 0) => {
6
7
  return Encoder.encode(node, schema, options, includeType, variableInitCounter);
7
8
  };
@@ -9,9 +10,7 @@ export const encodeValue = (value, datatype, df) => {
9
10
  if (datatype === ldkit.IRI) {
10
11
  return df.namedNode(value);
11
12
  }
12
- return toRdf(value, {
13
- datatype: df.namedNode(datatype),
14
- });
13
+ return translateToRdf(value, datatype);
15
14
  };
16
15
  class Encoder {
17
16
  constructor(options, includeType, variableInitCounter) {
@@ -0,0 +1,62 @@
1
+ import { DataFactory, fromRdf, toRdf } from "./rdf.js";
2
+ const df = new DataFactory();
3
+ const rdfToNativeHandlers = new Map();
4
+ const nativeToRdfHandlers = new Map();
5
+ /**
6
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
7
+ *
8
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
9
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
10
+ *
11
+ * Two handlers are required:
12
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
13
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { registerDataHandler } from "ldkit";
18
+ *
19
+ * const customNumberDataType = "http://example.org/number";
20
+ *
21
+ * declare module "ldkit" {
22
+ * interface CustomDataTypes {
23
+ * [customNumberDataType]: number;
24
+ * }
25
+ * }
26
+ *
27
+ * registerDataHandler(
28
+ * customNumberDataType,
29
+ * (literalValue: string) => parseInt(literalValue),
30
+ * (nativeValue: number) => nativeValue.toString(),
31
+ * );
32
+ * ```
33
+ *
34
+ * @param dataType - The data type to register.
35
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
36
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
37
+ */
38
+ export function registerDataHandler(dataType, translateFromRDF, translateToRDF) {
39
+ rdfToNativeHandlers.set(dataType, translateFromRDF);
40
+ nativeToRdfHandlers.set(dataType, translateToRDF);
41
+ }
42
+ export function translateFromRdf(literal) {
43
+ const dataType = literal.datatype.value;
44
+ const customHandler = rdfToNativeHandlers.get(dataType);
45
+ if (customHandler) {
46
+ return customHandler(literal.value);
47
+ }
48
+ else {
49
+ return fromRdf(literal);
50
+ }
51
+ }
52
+ export function translateToRdf(value, dataType) {
53
+ const customHandler = nativeToRdfHandlers.get(dataType);
54
+ if (customHandler) {
55
+ return df.literal(customHandler(value), df.namedNode(dataType));
56
+ }
57
+ else {
58
+ return toRdf(value, {
59
+ datatype: df.namedNode(dataType),
60
+ });
61
+ }
62
+ }
package/esm/mod.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { setGlobalOptions } from "./library/options.js";
2
+ export { registerDataHandler } from "./library/translator.js";
2
3
  export * from "./library/lens/mod.js";
3
4
  export * from "./library/namespace.js";
4
5
  export * from "./library/engine/mod.js";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "main": "./script/mod.js",
4
4
  "types": "./types/mod.d.ts",
5
5
  "name": "ldkit",
6
- "version": "2.2.0",
6
+ "version": "2.3.0",
7
7
  "description": "LDkit, a Linked Data query toolkit for TypeScript developers",
8
8
  "homepage": "https://ldkit.io",
9
9
  "author": "Karel Klima <karelklima@gmail.com> (https://karelklima.com)",
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.decode = void 0;
4
- const rdf_js_1 = require("./rdf.js");
5
4
  const ldkit_js_1 = require("../namespaces/ldkit.js");
6
- const rdf_js_2 = require("../namespaces/rdf.js");
5
+ const rdf_js_1 = require("../namespaces/rdf.js");
6
+ const translator_js_1 = require("./translator.js");
7
7
  const decode = (graph, schema, options) => {
8
8
  return Decoder.decode(graph, schema, options);
9
9
  };
@@ -56,8 +56,8 @@ class Decoder {
56
56
  decode() {
57
57
  const output = [];
58
58
  for (const [iri, properties] of this.graph) {
59
- if (properties.has(rdf_js_2.rdf.type)) {
60
- const types = properties.get(rdf_js_2.rdf.type);
59
+ if (properties.has(rdf_js_1.rdf.type)) {
60
+ const types = properties.get(rdf_js_1.rdf.type);
61
61
  for (const type of types) {
62
62
  if (type.termType === "NamedNode" && type.value === ldkit_js_1.ldkit.Resource) {
63
63
  output.push(this.decodeNode(iri, this.schema));
@@ -96,7 +96,7 @@ class Decoder {
96
96
  }
97
97
  decodeNodeProperty(nodeIri, node, propertyKey, property) {
98
98
  const allTerms = node.get(property["@id"]);
99
- const terms = property["@id"] !== rdf_js_2.rdf.type
99
+ const terms = property["@id"] !== rdf_js_1.rdf.type
100
100
  ? allTerms
101
101
  : allTerms?.filter((term) => term.value !== ldkit_js_1.ldkit.Resource);
102
102
  if (!terms) {
@@ -189,7 +189,7 @@ class Decoder {
189
189
  return term.value;
190
190
  }
191
191
  else if (term.termType === "Literal") {
192
- return (0, rdf_js_1.fromRdf)(term);
192
+ return (0, translator_js_1.translateFromRdf)(term);
193
193
  }
194
194
  else {
195
195
  throw new Error(`Unsupported term type to resolve: ${term.termType}`);
@@ -5,6 +5,7 @@ const rdf_js_1 = require("./rdf.js");
5
5
  const xsd_js_1 = require("../namespaces/xsd.js");
6
6
  const rdf_js_2 = require("../namespaces/rdf.js");
7
7
  const ldkit_js_1 = require("../namespaces/ldkit.js");
8
+ const translator_js_1 = require("./translator.js");
8
9
  const encode = (node, schema, options, includeType = true, variableInitCounter = 0) => {
9
10
  return Encoder.encode(node, schema, options, includeType, variableInitCounter);
10
11
  };
@@ -13,9 +14,7 @@ const encodeValue = (value, datatype, df) => {
13
14
  if (datatype === ldkit_js_1.ldkit.IRI) {
14
15
  return df.namedNode(value);
15
16
  }
16
- return (0, rdf_js_1.toRdf)(value, {
17
- datatype: df.namedNode(datatype),
18
- });
17
+ return (0, translator_js_1.translateToRdf)(value, datatype);
19
18
  };
20
19
  exports.encodeValue = encodeValue;
21
20
  class Encoder {
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateToRdf = exports.translateFromRdf = exports.registerDataHandler = void 0;
4
+ const rdf_js_1 = require("./rdf.js");
5
+ const df = new rdf_js_1.DataFactory();
6
+ const rdfToNativeHandlers = new Map();
7
+ const nativeToRdfHandlers = new Map();
8
+ /**
9
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
10
+ *
11
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
12
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
13
+ *
14
+ * Two handlers are required:
15
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
16
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { registerDataHandler } from "ldkit";
21
+ *
22
+ * const customNumberDataType = "http://example.org/number";
23
+ *
24
+ * declare module "ldkit" {
25
+ * interface CustomDataTypes {
26
+ * [customNumberDataType]: number;
27
+ * }
28
+ * }
29
+ *
30
+ * registerDataHandler(
31
+ * customNumberDataType,
32
+ * (literalValue: string) => parseInt(literalValue),
33
+ * (nativeValue: number) => nativeValue.toString(),
34
+ * );
35
+ * ```
36
+ *
37
+ * @param dataType - The data type to register.
38
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
39
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
40
+ */
41
+ function registerDataHandler(dataType, translateFromRDF, translateToRDF) {
42
+ rdfToNativeHandlers.set(dataType, translateFromRDF);
43
+ nativeToRdfHandlers.set(dataType, translateToRDF);
44
+ }
45
+ exports.registerDataHandler = registerDataHandler;
46
+ function translateFromRdf(literal) {
47
+ const dataType = literal.datatype.value;
48
+ const customHandler = rdfToNativeHandlers.get(dataType);
49
+ if (customHandler) {
50
+ return customHandler(literal.value);
51
+ }
52
+ else {
53
+ return (0, rdf_js_1.fromRdf)(literal);
54
+ }
55
+ }
56
+ exports.translateFromRdf = translateFromRdf;
57
+ function translateToRdf(value, dataType) {
58
+ const customHandler = nativeToRdfHandlers.get(dataType);
59
+ if (customHandler) {
60
+ return df.literal(customHandler(value), df.namedNode(dataType));
61
+ }
62
+ else {
63
+ return (0, rdf_js_1.toRdf)(value, {
64
+ datatype: df.namedNode(dataType),
65
+ });
66
+ }
67
+ }
68
+ exports.translateToRdf = translateToRdf;
package/script/mod.js CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.setGlobalOptions = void 0;
17
+ exports.registerDataHandler = exports.setGlobalOptions = void 0;
18
18
  var options_js_1 = require("./library/options.js");
19
19
  Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return options_js_1.setGlobalOptions; } });
20
+ var translator_js_1 = require("./library/translator.js");
21
+ Object.defineProperty(exports, "registerDataHandler", { enumerable: true, get: function () { return translator_js_1.registerDataHandler; } });
20
22
  __exportStar(require("./library/lens/mod.js"), exports);
21
23
  __exportStar(require("./library/namespace.js"), exports);
22
24
  __exportStar(require("./library/engine/mod.js"), exports);
@@ -3,5 +3,5 @@ import { DataFactory, type RDF } from "./rdf.js";
3
3
  import type { ExpandedSchema } from "./schema/mod.js";
4
4
  type DecodedNode = Record<string, unknown>;
5
5
  export declare const encode: (node: DecodedNode, schema: ExpandedSchema, options: Options, includeType?: boolean, variableInitCounter?: number) => RDF.Quad[];
6
- export declare const encodeValue: (value: unknown, datatype: string, df: DataFactory) => RDF.Literal | import("rdf-data-factory").NamedNode<string>;
6
+ export declare const encodeValue: (value: unknown, datatype: string, df: DataFactory) => RDF.Literal | import("rdf-data-factory").Literal | import("rdf-data-factory").NamedNode<string>;
7
7
  export {};
@@ -2,8 +2,8 @@ import { xsd } from "../../namespaces/xsd.js";
2
2
  import { rdf } from "../../namespaces/rdf.js";
3
3
  import { ldkit } from "../../namespaces/ldkit.js";
4
4
  import { type IRI } from "../rdf.js";
5
- /** Map of supported RDF data types and their JavaScript native counterparts */
6
- export type SupportedDataTypes = {
5
+ /** Map of default RDF data types and their JavaScript native counterparts */
6
+ type DefaultDataTypes = {
7
7
  [xsd.dateTime]: Date;
8
8
  [xsd.date]: Date;
9
9
  [xsd.gDay]: Date;
@@ -42,5 +42,15 @@ export type SupportedDataTypes = {
42
42
  [xsd.duration]: string;
43
43
  [ldkit.IRI]: IRI;
44
44
  };
45
+ /** Custom data types definition. Keys are type IRIs, values are JavaScript native types */
46
+ export interface CustomDataTypes {
47
+ }
48
+ /**
49
+ * Map of supported RDF data types and their JavaScript native counterparts,
50
+ * combines default data types with custom data types.
51
+ * The keys are the IRIs of the data types, and the values are the corresponding JavaScript types.
52
+ */
53
+ export type SupportedDataTypes = Omit<DefaultDataTypes, keyof CustomDataTypes> & CustomDataTypes;
45
54
  /** List of supported native JavaScript types */
46
55
  export type SupportedNativeTypes = SupportedDataTypes[keyof SupportedDataTypes];
56
+ export {};
@@ -1,4 +1,4 @@
1
- export type { SupportedDataTypes, SupportedNativeTypes } from "./data_types.js";
1
+ export type { CustomDataTypes, SupportedDataTypes, SupportedNativeTypes, } from "./data_types.js";
2
2
  export type { Identity, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, } from "./interface.js";
3
3
  export type { ExpandedProperty, ExpandedSchema, Property, Schema, } from "./schema.js";
4
4
  export type { SearchFilters, SearchSchema } from "./search.js";
@@ -0,0 +1,38 @@
1
+ import { RDF } from "./rdf.js";
2
+ import { SupportedDataTypes } from "./schema/mod.js";
3
+ /**
4
+ * Registers a data type handler for translating between RDF literals and JavaScript values.
5
+ *
6
+ * In order to register a custom data type handler, the custom data type TypeScript mapping needs
7
+ * to be added to the {@link CustomDataTypes} interface using module augmentation.
8
+ *
9
+ * Two handlers are required:
10
+ * 1) A function to translate from RDF literal value (string) to JavaScript value.
11
+ * 2) A function to translate from JavaScript value to RDF literal value (string).
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { registerDataHandler } from "ldkit";
16
+ *
17
+ * const customNumberDataType = "http://example.org/number";
18
+ *
19
+ * declare module "ldkit" {
20
+ * interface CustomDataTypes {
21
+ * [customNumberDataType]: number;
22
+ * }
23
+ * }
24
+ *
25
+ * registerDataHandler(
26
+ * customNumberDataType,
27
+ * (literalValue: string) => parseInt(literalValue),
28
+ * (nativeValue: number) => nativeValue.toString(),
29
+ * );
30
+ * ```
31
+ *
32
+ * @param dataType - The data type to register.
33
+ * @param translateFromRDF - Function to translate from RDF literal to JavaScript value.
34
+ * @param translateToRDF - Function to translate from JavaScript value to RDF literal.
35
+ */
36
+ export declare function registerDataHandler<T extends keyof SupportedDataTypes>(dataType: T, translateFromRDF: (literalValue: string) => SupportedDataTypes[T], translateToRDF: (nativeValue: SupportedDataTypes[T]) => string): void;
37
+ export declare function translateFromRdf(literal: RDF.Literal): any;
38
+ export declare function translateToRdf(value: unknown, dataType: keyof SupportedDataTypes | string): RDF.Literal | import("rdf-data-factory").Literal;
package/types/mod.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { type Options, setGlobalOptions } from "./library/options.js";
2
- export type { Identity, Property, Schema, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, SupportedDataTypes, } from "./library/schema/mod.js";
2
+ export type { CustomDataTypes, Identity, Property, Schema, SchemaInterface, SchemaSearchInterface, SchemaUpdateInterface, SupportedDataTypes, } from "./library/schema/mod.js";
3
+ export { registerDataHandler } from "./library/translator.js";
3
4
  export * from "./library/lens/mod.js";
4
5
  export * from "./library/namespace.js";
5
6
  export * from "./library/engine/mod.js";