@openframe-org/criteria-set-protocol 2.7.7 → 2.7.8-alpha.3

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,2 @@
1
+ export type HashableParameters = Record<string, string | string[]>;
2
+ export declare const hashParameters: (parameters: HashableParameters) => string;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashParameters = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const utils_1 = require("./utils");
6
+ const normalizeText = (text) => {
7
+ return text.normalize("NFC");
8
+ };
9
+ const isValidParametersValue = (value) => {
10
+ if (typeof value === "string") {
11
+ return true;
12
+ }
13
+ if (!Array.isArray(value)) {
14
+ return false;
15
+ }
16
+ for (const childValue of value) {
17
+ if (typeof childValue !== "string") {
18
+ return false;
19
+ }
20
+ }
21
+ return true;
22
+ };
23
+ const compareUtf8 = (stringA, stringB) => {
24
+ const bufferA = Buffer.from(stringA, "utf8");
25
+ const bufferB = Buffer.from(stringB, "utf8");
26
+ const minimum = Math.min(bufferA.length, bufferB.length);
27
+ for (let index = 0; index < minimum; index++) {
28
+ const difference = bufferA[index] - bufferB[index];
29
+ if (difference !== 0) {
30
+ return difference;
31
+ }
32
+ }
33
+ return bufferA.length - bufferB.length;
34
+ };
35
+ const canonicalizeStringParameters = (parameters) => {
36
+ if ((0, utils_1.isNil)(parameters) || typeof parameters !== "object" || Array.isArray(parameters)) {
37
+ throw new Error("Cannot canonicalize parameters objects that are not string maps of strings or arrays of strings");
38
+ }
39
+ const parts = [];
40
+ const normalizedParameters = {};
41
+ for (const [key, value] of Object.entries(parameters)) {
42
+ normalizedParameters[normalizeText(key)] = value;
43
+ }
44
+ for (const key of Object.keys(normalizedParameters).sort(compareUtf8)) {
45
+ const rawValue = normalizedParameters[key];
46
+ if (!isValidParametersValue(rawValue)) {
47
+ throw new Error(`Invalid parameters value for '${key}': ${rawValue}`);
48
+ }
49
+ const encodedKey = JSON.stringify(key);
50
+ let encodedValue;
51
+ if (typeof rawValue === "string") {
52
+ encodedValue = JSON.stringify(normalizeText(rawValue));
53
+ }
54
+ else {
55
+ const normalized = rawValue.map(normalizeText).sort(compareUtf8);
56
+ encodedValue = `[${normalized.map((entry) => JSON.stringify(entry)).join(",")}]`;
57
+ }
58
+ parts.push(`${encodedKey}:${encodedValue}`);
59
+ }
60
+ return `{${parts.join(",")}}`;
61
+ };
62
+ const hashParameters = (parameters) => {
63
+ const canonical = canonicalizeStringParameters(parameters);
64
+ return (0, node_crypto_1.createHash)("sha256").update(canonical, "utf8").digest("hex");
65
+ };
66
+ exports.hashParameters = hashParameters;
@@ -1,5 +1,6 @@
1
1
  export * from "./schemas";
2
2
  export * from "./services";
3
3
  export * from "./types";
4
+ export * from "./functions";
4
5
  export * from "./utils";
5
6
  export * from "./errors";
package/dist/v1/index.js CHANGED
@@ -17,5 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./schemas"), exports);
18
18
  __exportStar(require("./services"), exports);
19
19
  __exportStar(require("./types"), exports);
20
+ __exportStar(require("./functions"), exports);
20
21
  __exportStar(require("./utils"), exports);
21
22
  __exportStar(require("./errors"), exports);
@@ -2,6 +2,110 @@ import { z } from "zod";
2
2
  export declare const criteriaTreeSchema: z.ZodObject<{
3
3
  version: z.ZodString;
4
4
  revision: z.ZodString;
5
+ dataMap: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodType<{
6
+ text: string;
7
+ } & ({
8
+ [x: string]: any;
9
+ value: number;
10
+ total: number;
11
+ maximumValue?: number | undefined;
12
+ minimumValue?: number | undefined;
13
+ exclusiveMaximum?: number | undefined;
14
+ exclusiveMinimum?: number | undefined;
15
+ weight?: number | undefined;
16
+ type?: "number" | undefined;
17
+ } | {
18
+ [x: string]: any;
19
+ type: "percentage";
20
+ value: number;
21
+ maximumValue?: number | undefined;
22
+ minimumValue?: number | undefined;
23
+ exclusiveMaximum?: number | undefined;
24
+ exclusiveMinimum?: number | undefined;
25
+ weight?: number | undefined;
26
+ } | {
27
+ [x: string]: any;
28
+ type: "boolean";
29
+ value: boolean;
30
+ }), unknown, z.core.$ZodTypeInternals<{
31
+ text: string;
32
+ } & ({
33
+ [x: string]: any;
34
+ value: number;
35
+ total: number;
36
+ maximumValue?: number | undefined;
37
+ minimumValue?: number | undefined;
38
+ exclusiveMaximum?: number | undefined;
39
+ exclusiveMinimum?: number | undefined;
40
+ weight?: number | undefined;
41
+ type?: "number" | undefined;
42
+ } | {
43
+ [x: string]: any;
44
+ type: "percentage";
45
+ value: number;
46
+ maximumValue?: number | undefined;
47
+ minimumValue?: number | undefined;
48
+ exclusiveMaximum?: number | undefined;
49
+ exclusiveMinimum?: number | undefined;
50
+ weight?: number | undefined;
51
+ } | {
52
+ [x: string]: any;
53
+ type: "boolean";
54
+ value: boolean;
55
+ }), unknown>>, z.ZodIntersection<z.ZodType<{
56
+ text: string;
57
+ } & ({
58
+ [x: string]: any;
59
+ value: number;
60
+ total: number;
61
+ maximumValue?: number | undefined;
62
+ minimumValue?: number | undefined;
63
+ exclusiveMaximum?: number | undefined;
64
+ exclusiveMinimum?: number | undefined;
65
+ weight?: number | undefined;
66
+ type?: "number" | undefined;
67
+ } | {
68
+ [x: string]: any;
69
+ type: "percentage";
70
+ value: number;
71
+ maximumValue?: number | undefined;
72
+ minimumValue?: number | undefined;
73
+ exclusiveMaximum?: number | undefined;
74
+ exclusiveMinimum?: number | undefined;
75
+ weight?: number | undefined;
76
+ } | {
77
+ [x: string]: any;
78
+ type: "boolean";
79
+ value: boolean;
80
+ }), unknown, z.core.$ZodTypeInternals<{
81
+ text: string;
82
+ } & ({
83
+ [x: string]: any;
84
+ value: number;
85
+ total: number;
86
+ maximumValue?: number | undefined;
87
+ minimumValue?: number | undefined;
88
+ exclusiveMaximum?: number | undefined;
89
+ exclusiveMinimum?: number | undefined;
90
+ weight?: number | undefined;
91
+ type?: "number" | undefined;
92
+ } | {
93
+ [x: string]: any;
94
+ type: "percentage";
95
+ value: number;
96
+ maximumValue?: number | undefined;
97
+ minimumValue?: number | undefined;
98
+ exclusiveMaximum?: number | undefined;
99
+ exclusiveMinimum?: number | undefined;
100
+ weight?: number | undefined;
101
+ } | {
102
+ [x: string]: any;
103
+ type: "boolean";
104
+ value: boolean;
105
+ }), unknown>>, z.ZodObject<{
106
+ readOnly: z.ZodBoolean;
107
+ valueReference: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodArray<z.ZodString>]>>;
108
+ }, z.core.$strip>>]>>;
5
109
  result: z.ZodType<{
6
110
  text: string;
7
111
  } & ({
@@ -54,6 +158,7 @@ export declare const criteriaTreeSchema: z.ZodObject<{
54
158
  value: boolean;
55
159
  }), unknown>>;
56
160
  certifications: z.ZodOptional<z.ZodArray<z.ZodString>>;
161
+ parameterHash: z.ZodOptional<z.ZodString>;
57
162
  themes: z.ZodArray<z.ZodObject<{
58
163
  code: z.ZodString;
59
164
  title: z.ZodString;
@@ -14,8 +14,10 @@ exports.criteriaTreeSchema = data_map_1.dataMapSchema
14
14
  .pick({
15
15
  version: true,
16
16
  revision: true,
17
+ dataMap: true,
17
18
  result: true,
18
19
  certifications: true,
20
+ parameterHash: true,
19
21
  })
20
22
  .extend({
21
23
  themes: zod_1.z
@@ -106,7 +106,7 @@ export declare const elementDataMapSchema: z.ZodRecord<z.ZodString, z.ZodUnion<[
106
106
  export declare const dataMapSchema: z.ZodObject<{
107
107
  version: z.ZodString;
108
108
  revision: z.ZodString;
109
- elements: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodType<{
109
+ dataMap: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodType<{
110
110
  text: string;
111
111
  } & ({
112
112
  [x: string]: any;
@@ -262,4 +262,5 @@ export declare const dataMapSchema: z.ZodObject<{
262
262
  value: boolean;
263
263
  }), unknown>>;
264
264
  certifications: z.ZodOptional<z.ZodArray<z.ZodString>>;
265
+ parameterHash: z.ZodOptional<z.ZodString>;
265
266
  }, z.core.$strip>;
@@ -12,12 +12,16 @@ exports.dataMapSchema = zod_1.z
12
12
  .string()
13
13
  .describe("The version of the criteria set used to generate the data map"),
14
14
  revision: zod_1.z.string().describe("The internal version of this criteria set"),
15
- elements: exports.elementDataMapSchema
15
+ dataMap: exports.elementDataMapSchema
16
16
  .describe("The data map consisting of a map of element codes to their data"),
17
17
  result: common_1.treeResultSchema.describe("The overall result of the evaluation of the criteria set"),
18
18
  certifications: zod_1.z
19
19
  .array(zod_1.z.string())
20
20
  .optional()
21
21
  .describe("The attained certifications"),
22
+ parameterHash: zod_1.z
23
+ .string()
24
+ .optional()
25
+ .describe("The hash of the configuration. It is used to be able to compare two trees in the client side based on their configuration, as the criteria set defines which configuration options change the tree structure.")
22
26
  })
23
27
  .describe("DataMap");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openframe-org/criteria-set-protocol",
3
- "version": "2.7.7",
3
+ "version": "2.7.8-alpha.3",
4
4
  "description": "A protocol and tools for defining and working with criteria sets",
5
5
  "private": false,
6
6
  "author": "Andrés Angulo <aa@openframe.org>",