@narrative.io/data-collaboration-sdk-ts 2.100.0 → 2.101.1-beta.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.
- package/build/apps/index.d.ts +7 -0
- package/build/apps/index.js +9 -0
- package/build/collaboration-policy/core/filter-builder.js +7 -1
- package/build/collaboration-policy/core/jsonschema/json-schema-types.d.ts +45 -0
- package/build/collaboration-policy/core/jsonschema/json-schema-types.js +1 -0
- package/build/collaboration-policy/core/jsonschema/policy-branches.d.ts +49 -0
- package/build/collaboration-policy/core/jsonschema/policy-branches.js +1 -0
- package/build/collaboration-policy/core/jsonschema/policy-evaluator.d.ts +22 -0
- package/build/collaboration-policy/core/jsonschema/policy-evaluator.js +250 -0
- package/build/collaboration-policy/core/jsonschema/sql-builder.d.ts +79 -0
- package/build/collaboration-policy/core/jsonschema/sql-builder.js +306 -0
- package/build/collaboration-policy/core/jsonschema/sql-poc.d.ts +79 -0
- package/build/collaboration-policy/core/jsonschema/sql-poc.js +305 -0
- package/build/collaboration-policy/core/types.d.ts +81 -10
- package/build/collaboration-policy/index.d.ts +5 -4
- package/build/collaboration-policy/index.js +4 -3
- package/build/collaboration-policy/types/collaboration-policy.d.ts +20 -20
- package/build/collaboration-policy/useCollaborationPolicy.d.ts +13 -4
- package/build/collaboration-policy/useCollaborationPolicy.js +23 -1
- package/build/collaboration-policy/utils/path-helpers.d.ts +7 -3
- package/build/collaboration-policy/utils/path-helpers.js +6 -22
- package/build/datasets/index.d.ts +11 -2
- package/build/datasets/index.js +12 -0
- package/build/datasets/types.d.ts +25 -0
- package/build/installations/index.d.ts +27 -8
- package/build/installations/index.js +34 -9
- package/build/installations/types.d.ts +14 -7
- package/build/nql/SubstraitParser.d.ts +771 -0
- package/build/nql/SubstraitParser.js +797 -0
- package/build/nql/types.d.ts +8 -8
- package/package.json +2 -1
package/build/apps/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseApi } from "../base-api";
|
|
2
|
+
import type { JsonSchemaConnectorPolicy } from "../collaboration-policy/core/jsonschema/json-schema-types";
|
|
2
3
|
import type { ApiRecords } from "../types";
|
|
3
4
|
import type { App, Installation } from "./types";
|
|
4
5
|
/**
|
|
@@ -14,5 +15,11 @@ declare class AppsApi extends BaseApi {
|
|
|
14
15
|
*/
|
|
15
16
|
getApps(appCategory?: string): Promise<ApiRecords<App>>;
|
|
16
17
|
getInstalledApps(appCategory?: string): Promise<ApiRecords<Installation>>;
|
|
18
|
+
/**
|
|
19
|
+
* Get all interfaces for the current user's installed connectors.
|
|
20
|
+
* @param {string[]} [tags] - Optional tags to filter interfaces (e.g. ["audience_delivery"]).
|
|
21
|
+
* @returns {Promise<ApiRecords<JsonSchemaConnectorPolicy>>} - Promise resolving with the list of interfaces.
|
|
22
|
+
*/
|
|
23
|
+
getInstalledInterfaces(tags?: string[]): Promise<ApiRecords<JsonSchemaConnectorPolicy>>;
|
|
17
24
|
}
|
|
18
25
|
export { type App, AppsApi, type Installation };
|
package/build/apps/index.js
CHANGED
|
@@ -21,5 +21,14 @@ class AppsApi extends BaseApi {
|
|
|
21
21
|
const url = `installations${appCategoryQuery}`;
|
|
22
22
|
return await this.get(url);
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Get all interfaces for the current user's installed connectors.
|
|
26
|
+
* @param {string[]} [tags] - Optional tags to filter interfaces (e.g. ["audience_delivery"]).
|
|
27
|
+
* @returns {Promise<ApiRecords<JsonSchemaConnectorPolicy>>} - Promise resolving with the list of interfaces.
|
|
28
|
+
*/
|
|
29
|
+
async getInstalledInterfaces(tags) {
|
|
30
|
+
const queryString = this.constructQueryString(tags != null ? { tags } : undefined);
|
|
31
|
+
return await this.get(`${resourceName}/installed/interfaces${queryString}`);
|
|
32
|
+
}
|
|
24
33
|
}
|
|
25
34
|
export { AppsApi };
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { normalizePathValue } from "../utils/path-helpers";
|
|
2
2
|
import { resolveAttributeExpression } from "../utils/sql-helpers";
|
|
3
|
-
|
|
3
|
+
function isAttributeReference(node) {
|
|
4
|
+
return (!!node &&
|
|
5
|
+
typeof node === "object" &&
|
|
6
|
+
"type" in node &&
|
|
7
|
+
node.type === "attribute" &&
|
|
8
|
+
"attribute_name" in node);
|
|
9
|
+
}
|
|
4
10
|
export function filterToSql(filter, attributeByName, datasetName) {
|
|
5
11
|
const op = filter.op.toLowerCase();
|
|
6
12
|
switch (op) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { JSONSchema7 } from "json-schema";
|
|
2
|
+
/**
|
|
3
|
+
* Base JSON Schema type used for connector policies.
|
|
4
|
+
*
|
|
5
|
+
* Uses JSONSchema7 as a structural base. The real API schemas declare
|
|
6
|
+
* `$schema: "https://json-schema.org/draft/2020-12/schema"` and are
|
|
7
|
+
* validated with AJV 2020-12.
|
|
8
|
+
*/
|
|
9
|
+
export type JsonSchema = JSONSchema7;
|
|
10
|
+
/**
|
|
11
|
+
* Shape of a JSON-Schema-based connector policy as returned by the backend API.
|
|
12
|
+
*
|
|
13
|
+
* The `policy` field is a JSON Schema document that must be satisfied
|
|
14
|
+
* by `dataset.schema`. Refresh schedule lives in `metadata.refresh_schedule.max`.
|
|
15
|
+
*
|
|
16
|
+
* Filters live on property definitions inside the schema (as `filters` arrays
|
|
17
|
+
* on individual attribute entries), not on anyOf branches.
|
|
18
|
+
*/
|
|
19
|
+
export interface JsonSchemaConnectorPolicy {
|
|
20
|
+
/** Stable identifier (e.g., "audience_first_party_new"). */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Policy ID, typically matches name. */
|
|
23
|
+
id: string;
|
|
24
|
+
/** The app this policy belongs to. */
|
|
25
|
+
app_id: number;
|
|
26
|
+
/** Metadata including tags and refresh schedule. */
|
|
27
|
+
metadata: {
|
|
28
|
+
tags?: string[];
|
|
29
|
+
refresh_schedule?: {
|
|
30
|
+
min: string | null;
|
|
31
|
+
max: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The JSON Schema that must be satisfied by dataset.schema.
|
|
36
|
+
* Contains `properties`, `required`, `anyOf`/`allOf` for branch structure.
|
|
37
|
+
* Filters are on property definitions (sibling `properties` next to `anyOf`).
|
|
38
|
+
* May declare `$schema: "https://json-schema.org/draft/2020-12/schema"`.
|
|
39
|
+
*/
|
|
40
|
+
policy: JsonSchema;
|
|
41
|
+
/** UI form schema — not used by the SDK. */
|
|
42
|
+
schema?: unknown;
|
|
43
|
+
/** UI schema — not used by the SDK. */
|
|
44
|
+
uischema?: unknown;
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PolicyFilter } from "../types";
|
|
2
|
+
import type { JsonSchemaConnectorPolicy } from "./json-schema-types";
|
|
3
|
+
/**
|
|
4
|
+
* A single logical branch within a JSON-Schema policy that matched the dataset.
|
|
5
|
+
* Typically corresponds to one entry in schema.properties.properties.anyOf[*],
|
|
6
|
+
* or an allOf group inside one of those entries.
|
|
7
|
+
*/
|
|
8
|
+
export interface PolicyBranchMatch {
|
|
9
|
+
/**
|
|
10
|
+
* Index into the top-level anyOf array under the policy's
|
|
11
|
+
* `policy.properties.properties.anyOf`.
|
|
12
|
+
*/
|
|
13
|
+
branchIndex: number;
|
|
14
|
+
/**
|
|
15
|
+
* Required attribute names for this branch. These correspond to Schema.properties keys
|
|
16
|
+
* like "sha256_hashed_email", "postal_code", etc.
|
|
17
|
+
*/
|
|
18
|
+
requiredAttributes: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Filters collected from the property definitions for this branch's required attributes.
|
|
21
|
+
* Filters live on the property definitions (sibling `properties` to `anyOf`), not on branches.
|
|
22
|
+
* These follow the existing PolicyFilter structure and can be fed directly into filterToSql.
|
|
23
|
+
*/
|
|
24
|
+
filters: PolicyFilter[];
|
|
25
|
+
/**
|
|
26
|
+
* Additional required subfield paths per attribute, used to generate IS NOT NULL WHERE clauses.
|
|
27
|
+
* Derived from `$ref` resolution against `$defs` in the JSON Schema.
|
|
28
|
+
*
|
|
29
|
+
* Example: for `sha256_hashed_phone_number` referencing an object-type `$def`,
|
|
30
|
+
* this produces `(company_data."ds"."_rosetta_stone"."sha256_hashed_phone_number"."type" IS NOT NULL)`.
|
|
31
|
+
*/
|
|
32
|
+
additionalRequiredProperties: Array<{
|
|
33
|
+
attributeName: string;
|
|
34
|
+
paths: string[];
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Evaluation result for a single JSON-Schema-based policy.
|
|
39
|
+
*/
|
|
40
|
+
export interface PolicyEvaluation {
|
|
41
|
+
/** The policy that was evaluated. */
|
|
42
|
+
policy: JsonSchemaConnectorPolicy;
|
|
43
|
+
/** Whether dataset.schema is compatible with the policy's JSON Schema. */
|
|
44
|
+
isValid: boolean;
|
|
45
|
+
/** Branches within the policy that are satisfied for this dataset. */
|
|
46
|
+
matches: PolicyBranchMatch[];
|
|
47
|
+
/** Human-readable validation issues if isValid === false. */
|
|
48
|
+
errors: string[];
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Attribute } from "../../../attributes/types";
|
|
2
|
+
import type { Dataset } from "../../../datasets/types";
|
|
3
|
+
import type { JsonSchemaConnectorPolicy } from "./json-schema-types";
|
|
4
|
+
import type { PolicyEvaluation } from "./policy-branches";
|
|
5
|
+
/**
|
|
6
|
+
* Evaluate an array of JSON-Schema-based connector policies against a dataset.
|
|
7
|
+
*
|
|
8
|
+
* Eligibility is determined by checking whether the dataset's Rosetta Stone
|
|
9
|
+
* attributes satisfy at least one anyOf branch in the policy schema. This uses
|
|
10
|
+
* the `attributes` array (resolved from dataset mappings) as the source of truth,
|
|
11
|
+
* NOT the raw dataset.schema — the raw schema contains storage-level column names
|
|
12
|
+
* and flat types that don't match the policy's Rosetta Stone attribute names.
|
|
13
|
+
*
|
|
14
|
+
* A policy is considered valid (compatible) if `findMatchingBranches` finds at
|
|
15
|
+
* least one satisfied branch.
|
|
16
|
+
*
|
|
17
|
+
* @param _dataset - The dataset (currently unused; attributes carry the relevant info).
|
|
18
|
+
* @param attributes - Rosetta Stone attributes associated with the dataset.
|
|
19
|
+
* @param policies - JSON-Schema-based connector policies to evaluate.
|
|
20
|
+
* @returns An array of PolicyEvaluation results, one per policy.
|
|
21
|
+
*/
|
|
22
|
+
export declare function evaluateJsonSchemaPolicies(_dataset: Dataset, attributes: Attribute[], policies: JsonSchemaConnectorPolicy[]): PolicyEvaluation[];
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collect filters for a list of required attribute names by looking them up
|
|
3
|
+
* in the property definitions object (sibling to anyOf).
|
|
4
|
+
*
|
|
5
|
+
* In the real API shape, filters live on individual property definitions:
|
|
6
|
+
*
|
|
7
|
+
* schema.properties.properties.properties = {
|
|
8
|
+
* "sha256_hashed_email": {
|
|
9
|
+
* "$ref": "#/$defs/object_value",
|
|
10
|
+
* "attribute": "https://api.narrative.io/attributes/sha256_hashed_email",
|
|
11
|
+
* "filters": [ ... ]
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* @param requiredAttrs - Attribute names whose filters should be collected.
|
|
16
|
+
* @param propertyDefs - The property definitions object from the schema.
|
|
17
|
+
* @returns Collected filters from all matching property definitions.
|
|
18
|
+
*/
|
|
19
|
+
function collectFiltersForAttributes(requiredAttrs, propertyDefs) {
|
|
20
|
+
if (!propertyDefs)
|
|
21
|
+
return [];
|
|
22
|
+
const filters = [];
|
|
23
|
+
for (const attrName of requiredAttrs) {
|
|
24
|
+
const propDef = propertyDefs[attrName];
|
|
25
|
+
if (propDef?.filters && Array.isArray(propDef.filters)) {
|
|
26
|
+
filters.push(...propDef.filters);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return filters;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a `$ref` on a property definition to its `$defs` entry and extract
|
|
33
|
+
* the required data subfields that should generate IS NOT NULL WHERE clauses.
|
|
34
|
+
*
|
|
35
|
+
* Only object-type `$defs` (where `properties.type.const === "object"`) have
|
|
36
|
+
* data subfields. The data subfields are listed in
|
|
37
|
+
* `properties.properties.required`.
|
|
38
|
+
*
|
|
39
|
+
* Note: the top-level `required` array on an object-type $def (typically
|
|
40
|
+
* `["type", "properties"]`) describes the schema's structural envelope —
|
|
41
|
+
* `"type"` there is the meta-schema discriminator (`{const: "object"}`),
|
|
42
|
+
* not a Rosetta Stone data column — so it must not be emitted as a subfield.
|
|
43
|
+
*
|
|
44
|
+
* Primitive types (like `string_value_type`) return no subfields.
|
|
45
|
+
*
|
|
46
|
+
* @param propDef - The property definition that may have a `$ref`.
|
|
47
|
+
* @param defs - The `$defs` object from the schema root.
|
|
48
|
+
* @returns Array of subfield names that require IS NOT NULL checks.
|
|
49
|
+
*/
|
|
50
|
+
function resolveRefRequiredSubfields(propDef, defs) {
|
|
51
|
+
if (!propDef.$ref || !defs)
|
|
52
|
+
return [];
|
|
53
|
+
const defName = propDef.$ref.replace(/^#\/\$defs\//, "");
|
|
54
|
+
const def = defs[defName];
|
|
55
|
+
if (!def)
|
|
56
|
+
return [];
|
|
57
|
+
const defProperties = def.properties;
|
|
58
|
+
if (!defProperties)
|
|
59
|
+
return [];
|
|
60
|
+
// Only object-type $defs have data subfields
|
|
61
|
+
const typeProperty = defProperties.type;
|
|
62
|
+
if (typeProperty?.const !== "object")
|
|
63
|
+
return [];
|
|
64
|
+
const innerProps = defProperties.properties;
|
|
65
|
+
const innerRequired = innerProps?.required;
|
|
66
|
+
if (!innerRequired)
|
|
67
|
+
return [];
|
|
68
|
+
return [...innerRequired];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Collect required data subfields for a list of attribute names by resolving
|
|
72
|
+
* their `$ref` entries against the schema's `$defs`.
|
|
73
|
+
*
|
|
74
|
+
* These generate IS NOT NULL WHERE clauses in the SQL builder.
|
|
75
|
+
*
|
|
76
|
+
* @param requiredAttrs - Attribute names whose required subfields should be collected.
|
|
77
|
+
* @param propertyDefs - The property definitions object from the schema.
|
|
78
|
+
* @param defs - The `$defs` object from the schema root.
|
|
79
|
+
* @returns Per-attribute list of subfield paths that require IS NOT NULL checks.
|
|
80
|
+
*/
|
|
81
|
+
function collectRequiredSubfieldsFromRefs(requiredAttrs, propertyDefs, defs) {
|
|
82
|
+
if (!propertyDefs)
|
|
83
|
+
return [];
|
|
84
|
+
const result = [];
|
|
85
|
+
for (const attrName of requiredAttrs) {
|
|
86
|
+
const propDef = propertyDefs[attrName];
|
|
87
|
+
if (!propDef)
|
|
88
|
+
continue;
|
|
89
|
+
const paths = resolveRefRequiredSubfields(propDef, defs);
|
|
90
|
+
if (paths.length > 0) {
|
|
91
|
+
result.push({ attributeName: attrName, paths });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Determine which branches in a JSON-Schema policy are satisfied for the given attributes.
|
|
98
|
+
*
|
|
99
|
+
* Expects the real API structure:
|
|
100
|
+
*
|
|
101
|
+
* schema.properties.properties = {
|
|
102
|
+
* anyOf: [
|
|
103
|
+
* { required: ["sha256_hashed_email"] },
|
|
104
|
+
* { allOf: [
|
|
105
|
+
* { required: ["person_name"] },
|
|
106
|
+
* { required: ["iso_3166_1_country"] },
|
|
107
|
+
* { required: ["postal_address"] }
|
|
108
|
+
* ]
|
|
109
|
+
* }
|
|
110
|
+
* ],
|
|
111
|
+
* properties: {
|
|
112
|
+
* "sha256_hashed_email": {
|
|
113
|
+
* "$ref": "#/$defs/attribute_value",
|
|
114
|
+
* "attribute": "https://api.narrative.io/attributes/sha256_hashed_email",
|
|
115
|
+
* "filters": [ ... ],
|
|
116
|
+
* "$ref": "#/$defs/object_value"
|
|
117
|
+
* },
|
|
118
|
+
* ...
|
|
119
|
+
* }
|
|
120
|
+
* }
|
|
121
|
+
*
|
|
122
|
+
* Branches only contain `required` arrays. Filters are defined on the property
|
|
123
|
+
* definitions (sibling `properties` object next to `anyOf`). Required subfields
|
|
124
|
+
* for IS NOT NULL clauses are derived by resolving `$ref` entries against `$defs`.
|
|
125
|
+
*
|
|
126
|
+
* A branch is considered satisfied if:
|
|
127
|
+
* - For a simple branch: all required property names exist as Attributes by name.
|
|
128
|
+
* - For an allOf group: all sub-branches' required property names exist as Attributes.
|
|
129
|
+
*
|
|
130
|
+
* @param policy - The JSON-Schema connector policy to inspect.
|
|
131
|
+
* @param attributes - Attributes available on the dataset.
|
|
132
|
+
* @returns A list of matching branches with their required attributes, filters, and additional requirements.
|
|
133
|
+
*/
|
|
134
|
+
function findMatchingBranches(policy, attributes) {
|
|
135
|
+
const attributeByName = new Map();
|
|
136
|
+
for (const attr of attributes) {
|
|
137
|
+
attributeByName.set(attr.name, attr);
|
|
138
|
+
}
|
|
139
|
+
const schema = policy.policy;
|
|
140
|
+
const schemaProps = schema.properties;
|
|
141
|
+
// Extract $defs from the schema root for $ref resolution
|
|
142
|
+
const defs = schema.$defs;
|
|
143
|
+
// Expect something like: schema.properties.properties.anyOf
|
|
144
|
+
const propertiesObj = schemaProps &&
|
|
145
|
+
schemaProps.properties;
|
|
146
|
+
const anyOfBranches = propertiesObj?.anyOf;
|
|
147
|
+
if (!Array.isArray(anyOfBranches)) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
// Property definitions live as a sibling to anyOf — this is where filters are.
|
|
151
|
+
const propertyDefs = propertiesObj?.properties;
|
|
152
|
+
const matches = [];
|
|
153
|
+
anyOfBranches.forEach((branch, index) => {
|
|
154
|
+
if (!branch || typeof branch !== "object")
|
|
155
|
+
return;
|
|
156
|
+
const branchObj = branch;
|
|
157
|
+
// Case 1: "allOf" group branch (bundle of multiple fields)
|
|
158
|
+
if (Array.isArray(branchObj.allOf)) {
|
|
159
|
+
const groupRequiredAttrs = [];
|
|
160
|
+
let allSubBranchesSatisfied = true;
|
|
161
|
+
for (const sub of branchObj.allOf) {
|
|
162
|
+
if (!sub || typeof sub !== "object") {
|
|
163
|
+
allSubBranchesSatisfied = false;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
const subObj = sub;
|
|
167
|
+
const subRequired = Array.isArray(subObj.required)
|
|
168
|
+
? subObj.required
|
|
169
|
+
: [];
|
|
170
|
+
// Sub-branch is satisfied if all required keys exist as attributes.
|
|
171
|
+
const missingSub = subRequired.filter((key) => !attributeByName.has(key));
|
|
172
|
+
if (missingSub.length > 0) {
|
|
173
|
+
allSubBranchesSatisfied = false;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
groupRequiredAttrs.push(...subRequired);
|
|
177
|
+
}
|
|
178
|
+
if (!allSubBranchesSatisfied) {
|
|
179
|
+
return; // this outer anyOf branch is not satisfied
|
|
180
|
+
}
|
|
181
|
+
const deduped = Array.from(new Set(groupRequiredAttrs));
|
|
182
|
+
matches.push({
|
|
183
|
+
branchIndex: index,
|
|
184
|
+
requiredAttributes: deduped,
|
|
185
|
+
filters: collectFiltersForAttributes(deduped, propertyDefs),
|
|
186
|
+
additionalRequiredProperties: collectRequiredSubfieldsFromRefs(deduped, propertyDefs, defs),
|
|
187
|
+
});
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Case 2: simple single-field branch
|
|
191
|
+
const branchRequired = Array.isArray(branchObj.required)
|
|
192
|
+
? branchObj.required
|
|
193
|
+
: [];
|
|
194
|
+
const missing = branchRequired.filter((key) => !attributeByName.has(key));
|
|
195
|
+
if (missing.length > 0) {
|
|
196
|
+
return; // this branch is not satisfied
|
|
197
|
+
}
|
|
198
|
+
matches.push({
|
|
199
|
+
branchIndex: index,
|
|
200
|
+
requiredAttributes: branchRequired,
|
|
201
|
+
filters: collectFiltersForAttributes(branchRequired, propertyDefs),
|
|
202
|
+
additionalRequiredProperties: collectRequiredSubfieldsFromRefs(branchRequired, propertyDefs, defs),
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
return matches;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Evaluate an array of JSON-Schema-based connector policies against a dataset.
|
|
209
|
+
*
|
|
210
|
+
* Eligibility is determined by checking whether the dataset's Rosetta Stone
|
|
211
|
+
* attributes satisfy at least one anyOf branch in the policy schema. This uses
|
|
212
|
+
* the `attributes` array (resolved from dataset mappings) as the source of truth,
|
|
213
|
+
* NOT the raw dataset.schema — the raw schema contains storage-level column names
|
|
214
|
+
* and flat types that don't match the policy's Rosetta Stone attribute names.
|
|
215
|
+
*
|
|
216
|
+
* A policy is considered valid (compatible) if `findMatchingBranches` finds at
|
|
217
|
+
* least one satisfied branch.
|
|
218
|
+
*
|
|
219
|
+
* @param _dataset - The dataset (currently unused; attributes carry the relevant info).
|
|
220
|
+
* @param attributes - Rosetta Stone attributes associated with the dataset.
|
|
221
|
+
* @param policies - JSON-Schema-based connector policies to evaluate.
|
|
222
|
+
* @returns An array of PolicyEvaluation results, one per policy.
|
|
223
|
+
*/
|
|
224
|
+
export function evaluateJsonSchemaPolicies(_dataset, attributes, policies) {
|
|
225
|
+
const evaluations = [];
|
|
226
|
+
for (const policy of policies) {
|
|
227
|
+
// Determine which branches within the policy are satisfied by the
|
|
228
|
+
// dataset's Rosetta Stone attributes.
|
|
229
|
+
const matches = findMatchingBranches(policy, attributes);
|
|
230
|
+
if (matches.length > 0) {
|
|
231
|
+
evaluations.push({
|
|
232
|
+
policy,
|
|
233
|
+
isValid: true,
|
|
234
|
+
matches,
|
|
235
|
+
errors: [],
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
evaluations.push({
|
|
240
|
+
policy,
|
|
241
|
+
isValid: false,
|
|
242
|
+
matches: [],
|
|
243
|
+
errors: [
|
|
244
|
+
`No anyOf branches are satisfied by the available attributes for policy "${policy.name}"`,
|
|
245
|
+
],
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return evaluations;
|
|
250
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Attribute } from "../../../attributes/types";
|
|
2
|
+
import type { Dataset } from "../../../datasets/types";
|
|
3
|
+
import type { PolicyMatchResult, PolicySqlFragments } from "../types";
|
|
4
|
+
import type { JsonSchemaConnectorPolicy } from "./json-schema-types";
|
|
5
|
+
import type { PolicyBranchMatch } from "./policy-branches";
|
|
6
|
+
/**
|
|
7
|
+
* JSON-Schema-based equivalent of PolicyMatchResult, but instead of fully-built SQL,
|
|
8
|
+
* it carries branch-level matches that your existing SQL builder can consume.
|
|
9
|
+
*/
|
|
10
|
+
export interface JsonSchemaPolicyMatchResult {
|
|
11
|
+
/** Names of policies whose JSON Schemas were compatible with the dataset. */
|
|
12
|
+
appliedPolicies: string[];
|
|
13
|
+
/** Policies that were skipped because validation failed. */
|
|
14
|
+
skippedPolicies: PolicyMatchResult["skippedPolicies"];
|
|
15
|
+
/** Non-fatal warnings (e.g. some policies were skipped). */
|
|
16
|
+
warnings: string[];
|
|
17
|
+
/**
|
|
18
|
+
* The minimum refresh schedule (most frequent) across all applied policies,
|
|
19
|
+
* expressed as an ISO 8601 duration string.
|
|
20
|
+
*/
|
|
21
|
+
refresh_schedule: string;
|
|
22
|
+
/**
|
|
23
|
+
* For each applied policy, which branches matched and what filters/attributes
|
|
24
|
+
* they require. This is what your SQL builder layer should consume.
|
|
25
|
+
*/
|
|
26
|
+
branchMatches: Array<{
|
|
27
|
+
policyName: string;
|
|
28
|
+
branches: PolicyBranchMatch[];
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Categorize JSON-Schema-based connector policies into matching and non-matching
|
|
33
|
+
* groups based on dataset compatibility.
|
|
34
|
+
*
|
|
35
|
+
* @param policies - JSON-Schema-based connector policies.
|
|
36
|
+
* @param dataset - Dataset whose schema is used for validation.
|
|
37
|
+
* @param attributes - Attributes associated with the dataset.
|
|
38
|
+
* @returns Object with matching policies, nonMatching policies, and skip details.
|
|
39
|
+
*/
|
|
40
|
+
export declare function categorizePolicies(policies: JsonSchemaConnectorPolicy[], dataset: Dataset, attributes: Attribute[]): {
|
|
41
|
+
matching: JsonSchemaConnectorPolicy[];
|
|
42
|
+
nonMatching: JsonSchemaConnectorPolicy[];
|
|
43
|
+
skippedDetails: PolicyMatchResult["skippedPolicies"];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Helper that evaluates JSON-Schema-based policies and returns branch-level
|
|
47
|
+
* matches plus scheduling information.
|
|
48
|
+
*
|
|
49
|
+
* This is intended to be consumed by a separate SQL builder layer or for
|
|
50
|
+
* inspection of branch-level match details.
|
|
51
|
+
*
|
|
52
|
+
* @param dataset - The dataset against which policies should be evaluated.
|
|
53
|
+
* @param policies - JSON-Schema-based connector policies.
|
|
54
|
+
* @param attributes - Attributes associated with the dataset.
|
|
55
|
+
* @returns JsonSchemaPolicyMatchResult with applied/skipped policies and branch matches.
|
|
56
|
+
* @throws If no policies are compatible with the dataset.
|
|
57
|
+
*/
|
|
58
|
+
export declare function buildPolicySqlWithJsonSchema(dataset: Dataset, policies: JsonSchemaConnectorPolicy[], attributes: Attribute[]): JsonSchemaPolicyMatchResult;
|
|
59
|
+
/**
|
|
60
|
+
* Uses JSON Schema branch matching to determine valid policies, then builds
|
|
61
|
+
* SELECT and WHERE SQL fragments.
|
|
62
|
+
*
|
|
63
|
+
* @param dataset - Dataset for which to evaluate policies and produce SQL.
|
|
64
|
+
* @param policies - JSON-Schema-based connector policies.
|
|
65
|
+
* @param attributes - Attributes associated with the dataset.
|
|
66
|
+
* @returns PolicyMatchResult with select, where, applied/skipped policies, warnings, and refresh schedule.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildPolicySqlWithValidation(dataset: Dataset, policies: JsonSchemaConnectorPolicy[], attributes: Attribute[]): PolicyMatchResult;
|
|
69
|
+
/**
|
|
70
|
+
* Build SQL fragments without validation. Assumes you already filtered the policies
|
|
71
|
+
* however you want (e.g. via categorizePolicies). Builds SELECT and WHERE SQL
|
|
72
|
+
* fragments from all provided policies.
|
|
73
|
+
*
|
|
74
|
+
* @param dataset - Dataset for which to build SQL fragments.
|
|
75
|
+
* @param policies - JSON-Schema-based connector policies.
|
|
76
|
+
* @param attributes - Attributes associated with the dataset.
|
|
77
|
+
* @returns PolicySqlFragments with select and where arrays.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildPolicySql(dataset: Dataset, policies: JsonSchemaConnectorPolicy[], attributes: Attribute[]): PolicySqlFragments;
|