@twin.org/data-processing-extractors 0.0.2-next.3 → 0.0.3-next.1

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.
@@ -0,0 +1,92 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ import { BaseError, Coerce, GeneralError, Guards, Is, ObjectHelper } from "@twin.org/core";
4
+ import { JsonPathHelper } from "@twin.org/data-json-path";
5
+ /**
6
+ * Class for extracting data from a JSON source.
7
+ */
8
+ export class JsonPathExtractorConnector {
9
+ /**
10
+ * The namespace supported by the data extractor connector.
11
+ */
12
+ static NAMESPACE = "json-path";
13
+ /**
14
+ * Runtime name for the class.
15
+ */
16
+ static CLASS_NAME = "JsonPathExtractorConnector";
17
+ /**
18
+ * Returns the class name of the component.
19
+ * @returns The class name of the component.
20
+ */
21
+ className() {
22
+ return JsonPathExtractorConnector.CLASS_NAME;
23
+ }
24
+ /**
25
+ * Extracts data from the provided input.
26
+ * @param data The object to extract from.
27
+ * @param rules The rules to use to extract the data.
28
+ * @returns The extracted data.
29
+ */
30
+ async extract(data, rules) {
31
+ Guards.object(JsonPathExtractorConnector.CLASS_NAME, "data", data);
32
+ Guards.array(JsonPathExtractorConnector.CLASS_NAME, "rules", rules);
33
+ const outputObject = {};
34
+ for (const extractRule of rules) {
35
+ this.extractValue(data, extractRule, outputObject);
36
+ }
37
+ return outputObject;
38
+ }
39
+ /**
40
+ * Extracts the value from the JSON object.
41
+ * @param jsonObject The JSON object to extract from.
42
+ * @param rule The rule to use to extract the data.
43
+ * @param outputObject The object to output the extracted data to.
44
+ * @internal
45
+ */
46
+ extractValue(jsonObject, rule, outputObject) {
47
+ try {
48
+ const jsonNodes = JsonPathHelper.query(rule.source, jsonObject);
49
+ const ruleParts = rule.source.split(".");
50
+ // Group values by their target path to handle multiple results correctly
51
+ const pathToValues = {};
52
+ for (const jsonNode of jsonNodes) {
53
+ const retainPathDepth = rule.retainPathDepth ?? 0;
54
+ const fullTargetPath = `${rule.target}${retainPathDepth > 0 ? `.${jsonNode.location.slice(-retainPathDepth).join(".")}` : ""}`;
55
+ const coercedValue = Coerce.byType(jsonNode.value, rule.coerce);
56
+ const nodeLocation = jsonNode.location;
57
+ // If the last part of the location before the target property is an integer
58
+ // and the corresponding rule part ends with [*], we are dealing with an array
59
+ const isArray = nodeLocation.length > 1 &&
60
+ ruleParts.length > 1 &&
61
+ Is.integer(nodeLocation[nodeLocation.length - 2]) &&
62
+ ruleParts[nodeLocation.length - 2].endsWith("[*]");
63
+ if (isArray) {
64
+ // If the value is set and not currently an array, convert it to one
65
+ if (!Is.empty(pathToValues[fullTargetPath]) && !Is.array(pathToValues[fullTargetPath])) {
66
+ pathToValues[fullTargetPath] = [pathToValues[fullTargetPath]];
67
+ }
68
+ // Make sure the array exists
69
+ pathToValues[fullTargetPath] ??= [];
70
+ // And add the new value
71
+ if (Is.array(pathToValues[fullTargetPath])) {
72
+ pathToValues[fullTargetPath].push(coercedValue);
73
+ }
74
+ }
75
+ else {
76
+ // For single values, just set the value directly
77
+ pathToValues[fullTargetPath] = coercedValue;
78
+ }
79
+ }
80
+ // Set the values in the output object
81
+ for (const [path, values] of Object.entries(pathToValues)) {
82
+ ObjectHelper.propertySet(outputObject, path, values);
83
+ }
84
+ }
85
+ catch (err) {
86
+ throw new GeneralError(JsonPathExtractorConnector.CLASS_NAME, "invalidRule", {
87
+ rule: rule.source
88
+ }, BaseError.fromError(err));
89
+ }
90
+ }
91
+ }
92
+ //# sourceMappingURL=jsonPathExtractorConnector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonPathExtractorConnector.js","sourceRoot":"","sources":["../../../src/extractors/jsonPathExtractorConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseError, Coerce, GeneralError, Guards, Is, ObjectHelper } from \"@twin.org/core\";\nimport { JsonPathHelper } from \"@twin.org/data-json-path\";\nimport type { IDataExtractorConnector, IRule } from \"@twin.org/data-processing-models\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Class for extracting data from a JSON source.\n */\nexport class JsonPathExtractorConnector implements IDataExtractorConnector {\n\t/**\n\t * The namespace supported by the data extractor connector.\n\t */\n\tpublic static readonly NAMESPACE: string = \"json-path\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<JsonPathExtractorConnector>();\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn JsonPathExtractorConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Extracts data from the provided input.\n\t * @param data The object to extract from.\n\t * @param rules The rules to use to extract the data.\n\t * @returns The extracted data.\n\t */\n\tpublic async extract(data: unknown, rules: IRule[]): Promise<unknown> {\n\t\tGuards.object(JsonPathExtractorConnector.CLASS_NAME, nameof(data), data);\n\t\tGuards.array(JsonPathExtractorConnector.CLASS_NAME, nameof(rules), rules);\n\n\t\tconst outputObject: unknown = {};\n\n\t\tfor (const extractRule of rules) {\n\t\t\tthis.extractValue(data, extractRule, outputObject);\n\t\t}\n\n\t\treturn outputObject;\n\t}\n\n\t/**\n\t * Extracts the value from the JSON object.\n\t * @param jsonObject The JSON object to extract from.\n\t * @param rule The rule to use to extract the data.\n\t * @param outputObject The object to output the extracted data to.\n\t * @internal\n\t */\n\tprivate extractValue(jsonObject: unknown, rule: IRule, outputObject: unknown): void {\n\t\ttry {\n\t\t\tconst jsonNodes = JsonPathHelper.query(rule.source, jsonObject);\n\n\t\t\tconst ruleParts = rule.source.split(\".\");\n\n\t\t\t// Group values by their target path to handle multiple results correctly\n\t\t\tconst pathToValues: { [id: string]: unknown } = {};\n\n\t\t\tfor (const jsonNode of jsonNodes) {\n\t\t\t\tconst retainPathDepth = rule.retainPathDepth ?? 0;\n\t\t\t\tconst fullTargetPath = `${rule.target}${retainPathDepth > 0 ? `.${jsonNode.location.slice(-retainPathDepth).join(\".\")}` : \"\"}`;\n\t\t\t\tconst coercedValue = Coerce.byType(jsonNode.value, rule.coerce);\n\n\t\t\t\tconst nodeLocation = jsonNode.location;\n\n\t\t\t\t// If the last part of the location before the target property is an integer\n\t\t\t\t// and the corresponding rule part ends with [*], we are dealing with an array\n\t\t\t\tconst isArray =\n\t\t\t\t\tnodeLocation.length > 1 &&\n\t\t\t\t\truleParts.length > 1 &&\n\t\t\t\t\tIs.integer(nodeLocation[nodeLocation.length - 2]) &&\n\t\t\t\t\truleParts[nodeLocation.length - 2].endsWith(\"[*]\");\n\n\t\t\t\tif (isArray) {\n\t\t\t\t\t// If the value is set and not currently an array, convert it to one\n\t\t\t\t\tif (!Is.empty(pathToValues[fullTargetPath]) && !Is.array(pathToValues[fullTargetPath])) {\n\t\t\t\t\t\tpathToValues[fullTargetPath] = [pathToValues[fullTargetPath]];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Make sure the array exists\n\t\t\t\t\tpathToValues[fullTargetPath] ??= [];\n\t\t\t\t\t// And add the new value\n\t\t\t\t\tif (Is.array(pathToValues[fullTargetPath])) {\n\t\t\t\t\t\tpathToValues[fullTargetPath].push(coercedValue);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// For single values, just set the value directly\n\t\t\t\t\tpathToValues[fullTargetPath] = coercedValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the values in the output object\n\t\t\tfor (const [path, values] of Object.entries(pathToValues)) {\n\t\t\t\tObjectHelper.propertySet(outputObject, path, values);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tJsonPathExtractorConnector.CLASS_NAME,\n\t\t\t\t\"invalidRule\",\n\t\t\t\t{\n\t\t\t\t\trule: rule.source\n\t\t\t\t},\n\t\t\t\tBaseError.fromError(err)\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,4 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export * from "./extractors/jsonPathExtractorConnector.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,4CAA4C,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./extractors/jsonPathExtractorConnector.js\";\n"]}
@@ -11,6 +11,11 @@ export declare class JsonPathExtractorConnector implements IDataExtractorConnect
11
11
  * Runtime name for the class.
12
12
  */
13
13
  static readonly CLASS_NAME: string;
14
+ /**
15
+ * Returns the class name of the component.
16
+ * @returns The class name of the component.
17
+ */
18
+ className(): string;
14
19
  /**
15
20
  * Extracts data from the provided input.
16
21
  * @param data The object to extract from.
@@ -1 +1 @@
1
- export * from "./extractors/jsonPathExtractorConnector";
1
+ export * from "./extractors/jsonPathExtractorConnector.js";
package/docs/changelog.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @twin.org/data-processing-extractors - Changelog
2
2
 
3
+ ## [0.0.3-next.1](https://github.com/twinfoundation/data-processing/compare/data-processing-extractors-v0.0.3-next.0...data-processing-extractors-v0.0.3-next.1) (2025-11-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * add context id features ([#25](https://github.com/twinfoundation/data-processing/issues/25)) ([2a2a955](https://github.com/twinfoundation/data-processing/commit/2a2a9559d54e8c703e97e2c05996e678416ef560))
9
+ * Add rule group query functionality ([#2](https://github.com/twinfoundation/data-processing/issues/2)) ([0fbbfb0](https://github.com/twinfoundation/data-processing/commit/0fbbfb065b6ecc293920b25f97ba011743105486))
10
+ * add validate-locales ([9af0874](https://github.com/twinfoundation/data-processing/commit/9af0874cd3f44a4cfca514dde8380f002e62337e))
11
+ * eslint migration to flat config ([a8138b0](https://github.com/twinfoundation/data-processing/commit/a8138b020ed58baeff162a822d4df207a6aeadc4))
12
+ * update dependencies ([21b8e80](https://github.com/twinfoundation/data-processing/commit/21b8e8007c87136a09f0a8e35ffde13a07ff4711))
13
+ * update framework core ([96f6e80](https://github.com/twinfoundation/data-processing/commit/96f6e8016a4ef0fb873f6775e750b4ab42e9f491))
14
+ * use shared store mechanism ([#6](https://github.com/twinfoundation/data-processing/issues/6)) ([6009228](https://github.com/twinfoundation/data-processing/commit/600922880acef07cc2f818dee7645c342929108b))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * supporting array usage ([#20](https://github.com/twinfoundation/data-processing/issues/20)) ([d2c68cd](https://github.com/twinfoundation/data-processing/commit/d2c68cd3983622586cc073377545d6416b87a827))
20
+
21
+
22
+ ### Dependencies
23
+
24
+ * The following workspace dependencies were updated
25
+ * dependencies
26
+ * @twin.org/data-processing-models bumped from 0.0.3-next.0 to 0.0.3-next.1
27
+
28
+ ## [0.0.2-next.4](https://github.com/twinfoundation/data-processing/compare/data-processing-extractors-v0.0.2-next.3...data-processing-extractors-v0.0.2-next.4) (2025-10-22)
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * supporting array usage ([#20](https://github.com/twinfoundation/data-processing/issues/20)) ([d2c68cd](https://github.com/twinfoundation/data-processing/commit/d2c68cd3983622586cc073377545d6416b87a827))
34
+
35
+
36
+ ### Dependencies
37
+
38
+ * The following workspace dependencies were updated
39
+ * dependencies
40
+ * @twin.org/data-processing-models bumped from 0.0.2-next.3 to 0.0.2-next.4
41
+
3
42
  ## [0.0.2-next.3](https://github.com/twinfoundation/data-processing/compare/data-processing-extractors-v0.0.2-next.2...data-processing-extractors-v0.0.2-next.3) (2025-10-09)
4
43
 
5
44
 
@@ -34,6 +34,24 @@ Runtime name for the class.
34
34
 
35
35
  ## Methods
36
36
 
37
+ ### className()
38
+
39
+ > **className**(): `string`
40
+
41
+ Returns the class name of the component.
42
+
43
+ #### Returns
44
+
45
+ `string`
46
+
47
+ The class name of the component.
48
+
49
+ #### Implementation of
50
+
51
+ `IDataExtractorConnector.className`
52
+
53
+ ***
54
+
37
55
  ### extract()
38
56
 
39
57
  > **extract**(`data`, `rules`): `Promise`\<`unknown`\>
package/locales/en.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "error": {
3
3
  "jsonPathExtractorConnector": {
4
- "invalidRule": "The JSONPath rule \"{rule}\" failed with reason: \"{reason}\""
4
+ "invalidRule": "The JSONPath rule \"{rule}\" failed"
5
5
  }
6
6
  }
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/data-processing-extractors",
3
- "version": "0.0.2-next.3",
3
+ "version": "0.0.3-next.1",
4
4
  "description": "Data extractor connector implementations",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,25 +15,23 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@twin.org/core": "next",
18
- "@twin.org/data-processing-models": "0.0.2-next.3",
18
+ "@twin.org/data-json-path": "next",
19
+ "@twin.org/data-processing-models": "0.0.3-next.1",
19
20
  "@twin.org/nameof": "next",
20
- "@twin.org/web": "next",
21
- "json-p3": "2.2.2"
21
+ "@twin.org/web": "next"
22
22
  },
23
- "main": "./dist/cjs/index.cjs",
24
- "module": "./dist/esm/index.mjs",
23
+ "main": "./dist/es/index.js",
25
24
  "types": "./dist/types/index.d.ts",
26
25
  "exports": {
27
26
  ".": {
28
27
  "types": "./dist/types/index.d.ts",
29
- "require": "./dist/cjs/index.cjs",
30
- "import": "./dist/esm/index.mjs"
28
+ "import": "./dist/es/index.js",
29
+ "default": "./dist/es/index.js"
31
30
  },
32
31
  "./locales/*.json": "./locales/*.json"
33
32
  },
34
33
  "files": [
35
- "dist/cjs",
36
- "dist/esm",
34
+ "dist/es",
37
35
  "dist/types",
38
36
  "locales",
39
37
  "docs"
@@ -1,60 +0,0 @@
1
- 'use strict';
2
-
3
- var core = require('@twin.org/core');
4
- var jsonP3 = require('json-p3');
5
-
6
- // Copyright 2024 IOTA Stiftung.
7
- // SPDX-License-Identifier: Apache-2.0.
8
- /**
9
- * Class for extracting data from a JSON source.
10
- */
11
- class JsonPathExtractorConnector {
12
- /**
13
- * The namespace supported by the data extractor connector.
14
- */
15
- static NAMESPACE = "json-path";
16
- /**
17
- * Runtime name for the class.
18
- */
19
- static CLASS_NAME = "JsonPathExtractorConnector";
20
- /**
21
- * Extracts data from the provided input.
22
- * @param data The object to extract from.
23
- * @param rules The rules to use to extract the data.
24
- * @returns The extracted data.
25
- */
26
- async extract(data, rules) {
27
- core.Guards.object(JsonPathExtractorConnector.CLASS_NAME, "data", data);
28
- core.Guards.array(JsonPathExtractorConnector.CLASS_NAME, "rules", rules);
29
- const outputObject = {};
30
- for (const extractRule of rules) {
31
- this.extractValue(data, extractRule, outputObject);
32
- }
33
- return outputObject;
34
- }
35
- /**
36
- * Extracts the value from the JSON object.
37
- * @param jsonObject The JSON object to extract from.
38
- * @param rule The rule to use to extract the data.
39
- * @param outputObject The object to output the extracted data to.
40
- * @internal
41
- */
42
- extractValue(jsonObject, rule, outputObject) {
43
- try {
44
- const jsonNodes = jsonP3.query(rule.source, jsonObject);
45
- for (const jsonNode of jsonNodes) {
46
- const retainPathDepth = rule.retainPathDepth ?? 0;
47
- const fullTargetPath = `${rule.target}${retainPathDepth > 0 ? `.${jsonNode.location.slice(-retainPathDepth).join(".")}` : ""}`;
48
- core.ObjectHelper.propertySet(outputObject, fullTargetPath, core.Coerce.byType(jsonNode.value, rule.coerce));
49
- }
50
- }
51
- catch (err) {
52
- throw new core.GeneralError(JsonPathExtractorConnector.CLASS_NAME, "invalidRule", {
53
- rule: rule.source,
54
- reason: core.BaseError.fromError(err).message
55
- });
56
- }
57
- }
58
- }
59
-
60
- exports.JsonPathExtractorConnector = JsonPathExtractorConnector;
@@ -1,58 +0,0 @@
1
- import { Guards, ObjectHelper, Coerce, GeneralError, BaseError } from '@twin.org/core';
2
- import { query } from 'json-p3';
3
-
4
- // Copyright 2024 IOTA Stiftung.
5
- // SPDX-License-Identifier: Apache-2.0.
6
- /**
7
- * Class for extracting data from a JSON source.
8
- */
9
- class JsonPathExtractorConnector {
10
- /**
11
- * The namespace supported by the data extractor connector.
12
- */
13
- static NAMESPACE = "json-path";
14
- /**
15
- * Runtime name for the class.
16
- */
17
- static CLASS_NAME = "JsonPathExtractorConnector";
18
- /**
19
- * Extracts data from the provided input.
20
- * @param data The object to extract from.
21
- * @param rules The rules to use to extract the data.
22
- * @returns The extracted data.
23
- */
24
- async extract(data, rules) {
25
- Guards.object(JsonPathExtractorConnector.CLASS_NAME, "data", data);
26
- Guards.array(JsonPathExtractorConnector.CLASS_NAME, "rules", rules);
27
- const outputObject = {};
28
- for (const extractRule of rules) {
29
- this.extractValue(data, extractRule, outputObject);
30
- }
31
- return outputObject;
32
- }
33
- /**
34
- * Extracts the value from the JSON object.
35
- * @param jsonObject The JSON object to extract from.
36
- * @param rule The rule to use to extract the data.
37
- * @param outputObject The object to output the extracted data to.
38
- * @internal
39
- */
40
- extractValue(jsonObject, rule, outputObject) {
41
- try {
42
- const jsonNodes = query(rule.source, jsonObject);
43
- for (const jsonNode of jsonNodes) {
44
- const retainPathDepth = rule.retainPathDepth ?? 0;
45
- const fullTargetPath = `${rule.target}${retainPathDepth > 0 ? `.${jsonNode.location.slice(-retainPathDepth).join(".")}` : ""}`;
46
- ObjectHelper.propertySet(outputObject, fullTargetPath, Coerce.byType(jsonNode.value, rule.coerce));
47
- }
48
- }
49
- catch (err) {
50
- throw new GeneralError(JsonPathExtractorConnector.CLASS_NAME, "invalidRule", {
51
- rule: rule.source,
52
- reason: BaseError.fromError(err).message
53
- });
54
- }
55
- }
56
- }
57
-
58
- export { JsonPathExtractorConnector };