@narrative.io/data-collaboration-sdk-ts 2.89.0 → 2.90.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.
|
@@ -35,7 +35,7 @@ export function validatePolicyAgainstDataset(policy, _dataset, attributes) {
|
|
|
35
35
|
for (const filter of filters) {
|
|
36
36
|
collectMissingAttributesFromFilter(filter, attributeByName, missingFilterAttributes);
|
|
37
37
|
}
|
|
38
|
-
visitStructureFilters(policy.policy.definition.structure, (filter) => collectMissingAttributesFromFilter(filter, attributeByName, missingFilterAttributes));
|
|
38
|
+
visitStructureFilters(policy.policy.definition.structure, (filter) => collectMissingAttributesFromFilter(filter, attributeByName, missingFilterAttributes), attributeByName);
|
|
39
39
|
if (missingFilterAttributes.size > 0) {
|
|
40
40
|
result.isValid = false;
|
|
41
41
|
const missingList = Array.from(missingFilterAttributes).sort();
|
|
@@ -115,27 +115,64 @@ function validatePolicyStructure(structure, attributeByName) {
|
|
|
115
115
|
}
|
|
116
116
|
return { isValid: true, errors: [] };
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Checks if a branch is satisfied (all required attributes exist).
|
|
120
|
+
* For anyOf: at least one child must be satisfied.
|
|
121
|
+
* For allOf: all children must be satisfied.
|
|
122
|
+
* For field nodes: the attribute must exist.
|
|
123
|
+
*/
|
|
124
|
+
function isBranchSatisfied(node, attributeByName) {
|
|
125
|
+
if (!node || typeof node !== "object") {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
if ("field" in node) {
|
|
129
|
+
const field = node.field;
|
|
130
|
+
if (field.type === "attribute" && field.attribute_name) {
|
|
131
|
+
return attributeByName.has(field.attribute_name);
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
if ("anyOf" in node && Array.isArray(node.anyOf)) {
|
|
136
|
+
return node.anyOf.some((child) => isBranchSatisfied(child, attributeByName));
|
|
137
|
+
}
|
|
138
|
+
if ("allOf" in node && Array.isArray(node.allOf)) {
|
|
139
|
+
return node.allOf.every((child) => isBranchSatisfied(child, attributeByName));
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Visits filters only in satisfied branches of the policy structure.
|
|
145
|
+
* For anyOf nodes, only visits filters in branches where the required attributes exist.
|
|
146
|
+
* For allOf nodes, visits filters in all branches (since all must be satisfied).
|
|
147
|
+
*/
|
|
148
|
+
function visitStructureFilters(node, visitor, attributeByName) {
|
|
119
149
|
if (!node || typeof node !== "object") {
|
|
120
150
|
return;
|
|
121
151
|
}
|
|
122
152
|
if ("field" in node) {
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
153
|
+
// Only visit filters if this branch is satisfied
|
|
154
|
+
if (isBranchSatisfied(node, attributeByName)) {
|
|
155
|
+
const filters = node.filters;
|
|
156
|
+
if (filters) {
|
|
157
|
+
for (const filter of filters) {
|
|
158
|
+
visitor(filter);
|
|
159
|
+
}
|
|
127
160
|
}
|
|
128
161
|
}
|
|
129
162
|
return;
|
|
130
163
|
}
|
|
131
164
|
if ("anyOf" in node && Array.isArray(node.anyOf)) {
|
|
165
|
+
// Only visit filters in satisfied branches
|
|
132
166
|
for (const child of node.anyOf) {
|
|
133
|
-
|
|
167
|
+
if (isBranchSatisfied(child, attributeByName)) {
|
|
168
|
+
visitStructureFilters(child, visitor, attributeByName);
|
|
169
|
+
}
|
|
134
170
|
}
|
|
135
171
|
}
|
|
136
172
|
if ("allOf" in node && Array.isArray(node.allOf)) {
|
|
173
|
+
// For allOf, visit all branches (they all must be satisfied)
|
|
137
174
|
for (const child of node.allOf) {
|
|
138
|
-
visitStructureFilters(child, visitor);
|
|
175
|
+
visitStructureFilters(child, visitor, attributeByName);
|
|
139
176
|
}
|
|
140
177
|
}
|
|
141
178
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ApiRecords, Config } from "src/types";
|
|
2
2
|
import { BaseApi } from "../base-api";
|
|
3
3
|
import { CompanyInfoApi } from "../company-info";
|
|
4
|
-
import type { CreateMapping, Mapping, MappingTestResult, MappingTestResults } from "./types";
|
|
4
|
+
import type { CreateMapping, Mapping, MappingExpressionDependencies, MappingTestResult, MappingTestResults, ObjectMapping, PropertyMapping, RawMappingDefinition, RawObjectMapping, RawPropertyMapping, RawValueMapping, ValueMapping } from "./types";
|
|
5
5
|
/**
|
|
6
6
|
* Class representing the Mappings API.
|
|
7
7
|
* Extends the BaseApi to provide functionalities specific to mappings.
|
|
@@ -111,4 +111,4 @@ declare class MappingsApi extends BaseApi {
|
|
|
111
111
|
*/
|
|
112
112
|
getMapping(mappingId: string): Promise<Mapping>;
|
|
113
113
|
}
|
|
114
|
-
export { type Mapping, MappingsApi, type CreateMapping, type MappingTestResult, type MappingTestResults, };
|
|
114
|
+
export { type Mapping, MappingsApi, type CreateMapping, type MappingExpressionDependencies, type MappingTestResult, type MappingTestResults, type ObjectMapping, type PropertyMapping, type RawMappingDefinition, type RawObjectMapping, type RawPropertyMapping, type RawValueMapping, type ValueMapping, };
|
|
@@ -17,9 +17,25 @@ export interface Mapping {
|
|
|
17
17
|
type MappingStatus = "active" | "archived" | "pending" | "rejected";
|
|
18
18
|
type MappingScope = "global" | "private";
|
|
19
19
|
type MappingSource = "system" | "admin" | "company";
|
|
20
|
+
export interface MappingExpressionDependencies {
|
|
21
|
+
properties: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface RawPropertyMapping {
|
|
24
|
+
path: string;
|
|
25
|
+
expression: string;
|
|
26
|
+
}
|
|
27
|
+
export interface RawObjectMapping {
|
|
28
|
+
type: "object_mapping";
|
|
29
|
+
property_mappings: RawPropertyMapping[];
|
|
30
|
+
}
|
|
31
|
+
export interface RawValueMapping {
|
|
32
|
+
type: "value_mapping";
|
|
33
|
+
expression: string;
|
|
34
|
+
}
|
|
20
35
|
export interface PropertyMapping {
|
|
21
36
|
path: string;
|
|
22
37
|
expression: string;
|
|
38
|
+
dependencies: MappingExpressionDependencies;
|
|
23
39
|
}
|
|
24
40
|
export interface ObjectMapping {
|
|
25
41
|
type: "object_mapping";
|
|
@@ -28,9 +44,16 @@ export interface ObjectMapping {
|
|
|
28
44
|
export interface ValueMapping {
|
|
29
45
|
type: "value_mapping";
|
|
30
46
|
expression: string;
|
|
47
|
+
dependencies: MappingExpressionDependencies;
|
|
48
|
+
}
|
|
49
|
+
export type RawMappingDefinition = RawObjectMapping | RawValueMapping;
|
|
50
|
+
export interface CreateMapping {
|
|
51
|
+
attribute_id: number;
|
|
52
|
+
dataset_id: number;
|
|
53
|
+
mapping: RawMappingDefinition;
|
|
54
|
+
tags?: string[];
|
|
55
|
+
status?: MappingStatus;
|
|
31
56
|
}
|
|
32
|
-
type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
33
|
-
export type CreateMapping = WithOptional<Pick<Mapping, "attribute_id" | "dataset_id" | "mapping" | "tags" | "status">, "status">;
|
|
34
57
|
export interface MappingTestResult {
|
|
35
58
|
input: Record<string, unknown>;
|
|
36
59
|
output: Record<string, unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narrative.io/data-collaboration-sdk-ts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.90.1",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"repository": "github:narrative-io/data-collaboration-sdk-ts",
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"@babel/preset-env": "7.28.5",
|
|
30
30
|
"@babel/preset-typescript": "7.28.5",
|
|
31
31
|
"@biomejs/biome": "2.3.8",
|
|
32
|
-
"@commitlint/cli": "20.
|
|
33
|
-
"@commitlint/config-conventional": "20.
|
|
32
|
+
"@commitlint/cli": "20.2.0",
|
|
33
|
+
"@commitlint/config-conventional": "20.2.0",
|
|
34
34
|
"@types/jest": "30.0.0",
|
|
35
35
|
"babel-jest": "30.2.0",
|
|
36
36
|
"jest": "30.2.0",
|
|
37
|
-
"lefthook": "2.0.
|
|
37
|
+
"lefthook": "2.0.9",
|
|
38
38
|
"ts-jest": "29.4.6"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|