@narrative.io/jsonforms-provider-protocols 2.11.0-beta.0 → 2.12.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/README.md +193 -33
- package/dist/core/initFormData.d.ts +17 -0
- package/dist/core/initFormData.d.ts.map +1 -0
- package/dist/core/initFormData.js +99 -0
- package/dist/core/initFormData.js.map +1 -0
- package/dist/core/projection.d.ts +36 -0
- package/dist/core/projection.d.ts.map +1 -0
- package/dist/core/projection.js +77 -0
- package/dist/core/projection.js.map +1 -0
- package/dist/core/refs.d.ts +58 -0
- package/dist/core/refs.d.ts.map +1 -0
- package/dist/core/refs.js +70 -0
- package/dist/core/refs.js.map +1 -0
- package/dist/core/resolveScope.d.ts +17 -0
- package/dist/core/resolveScope.d.ts.map +1 -0
- package/dist/core/resolveScope.js +28 -0
- package/dist/core/resolveScope.js.map +1 -0
- package/dist/core/seedProjectionTargets.d.ts +60 -0
- package/dist/core/seedProjectionTargets.d.ts.map +1 -0
- package/dist/core/seedProjectionTargets.js +52 -0
- package/dist/core/seedProjectionTargets.js.map +1 -0
- package/dist/core/transforms.d.ts +8 -10
- package/dist/core/transforms.d.ts.map +1 -1
- package/dist/core/transforms.js +58 -13
- package/dist/core/transforms.js.map +1 -1
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/jsonforms-provider-protocols.css +6 -2
- package/dist/no-eval-ajv.d.ts +70 -0
- package/dist/no-eval-ajv.d.ts.map +1 -0
- package/dist/no-eval-ajv.js +247 -0
- package/dist/no-eval-ajv.js.map +1 -0
- package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderAutocomplete.vue.js +10 -4
- package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue2.js +19 -9
- package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
- package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts +9 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts.map +1 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.js +8 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue.js.map +1 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue2.js +142 -0
- package/dist/vue/components/ProviderObjectMultiSelect.vue2.js.map +1 -0
- package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.js +1 -1
- package/dist/vue/components/ProviderSelect.vue2.js +20 -8
- package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
- package/dist/vue/composables/useDataLayer.d.ts +10 -0
- package/dist/vue/composables/useDataLayer.d.ts.map +1 -0
- package/dist/vue/composables/useDataLayer.js +26 -0
- package/dist/vue/composables/useDataLayer.js.map +1 -0
- package/dist/vue/composables/useDerive.d.ts +5 -2
- package/dist/vue/composables/useDerive.d.ts.map +1 -1
- package/dist/vue/composables/useDerive.js +29 -12
- package/dist/vue/composables/useDerive.js.map +1 -1
- package/dist/vue/composables/useDeriveInitialValue.d.ts +36 -0
- package/dist/vue/composables/useDeriveInitialValue.d.ts.map +1 -0
- package/dist/vue/composables/useDeriveInitialValue.js +125 -0
- package/dist/vue/composables/useDeriveInitialValue.js.map +1 -0
- package/dist/vue/composables/useDirtyValidation.d.ts +9 -0
- package/dist/vue/composables/useDirtyValidation.d.ts.map +1 -0
- package/dist/vue/composables/useDirtyValidation.js +15 -0
- package/dist/vue/composables/useDirtyValidation.js.map +1 -0
- package/dist/vue/composables/useProjection.d.ts +42 -0
- package/dist/vue/composables/useProjection.d.ts.map +1 -0
- package/dist/vue/composables/useProjection.js +116 -0
- package/dist/vue/composables/useProjection.js.map +1 -0
- package/dist/vue/composables/useProvider.d.ts +2 -2
- package/dist/vue/composables/useProvider.d.ts.map +1 -1
- package/dist/vue/composables/useProvider.js +14 -10
- package/dist/vue/composables/useProvider.js.map +1 -1
- package/dist/vue/index.d.ts +9 -1
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +72 -34
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.d.ts +9 -0
- package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.js +42 -21
- package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.d.ts +9 -0
- package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.js +35 -21
- package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.d.ts +9 -0
- package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.js +37 -17
- package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.d.ts +9 -0
- package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.js +30 -20
- package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
- package/dist/vue/primevue/JfText.vue.d.ts +9 -0
- package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfText.vue.js +48 -32
- package/dist/vue/primevue/JfText.vue.js.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.d.ts +9 -0
- package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.js +31 -16
- package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
- package/dist/vue/primevue/index.d.ts.map +1 -1
- package/dist/vue/primevue/index.js +74 -7
- package/dist/vue/primevue/index.js.map +1 -1
- package/dist/vue/utils/autoSelect.js.map +1 -1
- package/dist/vue/utils/objectMultiSelect.d.ts +68 -0
- package/dist/vue/utils/objectMultiSelect.d.ts.map +1 -0
- package/dist/vue/utils/objectMultiSelect.js +72 -0
- package/dist/vue/utils/objectMultiSelect.js.map +1 -0
- package/dist/vue/utils/placeholder.d.ts +17 -0
- package/dist/vue/utils/placeholder.d.ts.map +1 -0
- package/dist/vue/utils/placeholder.js +17 -0
- package/dist/vue/utils/placeholder.js.map +1 -0
- package/package.json +10 -2
- package/src/core/initFormData.ts +208 -0
- package/src/core/projection.ts +147 -0
- package/src/core/refs.ts +166 -0
- package/src/core/resolveScope.ts +54 -0
- package/src/core/seedProjectionTargets.ts +144 -0
- package/src/core/transforms.ts +118 -26
- package/src/core/types.ts +9 -0
- package/src/index.ts +22 -2
- package/src/no-eval-ajv.ts +381 -0
- package/src/vue/components/ProviderAutocomplete.vue +10 -6
- package/src/vue/components/ProviderMultiSelect.vue +22 -15
- package/src/vue/components/ProviderObjectMultiSelect.vue +169 -0
- package/src/vue/components/ProviderSelect.vue +23 -14
- package/src/vue/composables/useDataLayer.ts +43 -0
- package/src/vue/composables/useDerive.ts +62 -16
- package/src/vue/composables/useDeriveInitialValue.ts +195 -0
- package/src/vue/composables/useDirtyValidation.ts +20 -0
- package/src/vue/composables/useProjection.ts +245 -0
- package/src/vue/composables/useProvider.ts +28 -11
- package/src/vue/index.ts +83 -47
- package/src/vue/primevue/JfBoolean.vue +35 -12
- package/src/vue/primevue/JfEnum.vue +34 -25
- package/src/vue/primevue/JfEnumArray.vue +36 -19
- package/src/vue/primevue/JfNumber.vue +30 -22
- package/src/vue/primevue/JfText.vue +46 -31
- package/src/vue/primevue/JfTextArea.vue +30 -19
- package/src/vue/primevue/index.ts +88 -7
- package/src/vue/utils/autoSelect.ts +2 -2
- package/src/vue/utils/objectMultiSelect.ts +171 -0
- package/src/vue/utils/placeholder.ts +42 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function resolvePointer(obj, pointer) {
|
|
2
|
+
if (!pointer.startsWith("#/")) return void 0;
|
|
3
|
+
const parts = pointer.slice(2).split("/");
|
|
4
|
+
let current = obj;
|
|
5
|
+
for (const part of parts) {
|
|
6
|
+
if (current && typeof current === "object" && part in current) {
|
|
7
|
+
current = current[part];
|
|
8
|
+
} else {
|
|
9
|
+
return void 0;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return current;
|
|
13
|
+
}
|
|
14
|
+
function resolveRef(property, root, seen) {
|
|
15
|
+
if (!property || typeof property !== "object") return property;
|
|
16
|
+
const ref = property.$ref;
|
|
17
|
+
if (!ref) return property;
|
|
18
|
+
const visited = seen ?? /* @__PURE__ */ new Set();
|
|
19
|
+
if (visited.has(ref)) return property;
|
|
20
|
+
visited.add(ref);
|
|
21
|
+
const resolved = resolvePointer(root, ref);
|
|
22
|
+
if (!resolved) return property;
|
|
23
|
+
return resolveRef(resolved, root, visited);
|
|
24
|
+
}
|
|
25
|
+
function deref(node, root) {
|
|
26
|
+
if (!node || typeof node !== "object") return node;
|
|
27
|
+
return resolveRef(node, root);
|
|
28
|
+
}
|
|
29
|
+
const COMBINATOR_DEPTH_LIMIT = 8;
|
|
30
|
+
function tryCombinatorBranches(node, root, tryFn, depth = 0) {
|
|
31
|
+
if (depth > COMBINATOR_DEPTH_LIMIT) return void 0;
|
|
32
|
+
if (!node || typeof node !== "object") return void 0;
|
|
33
|
+
const branches = node.oneOf || node.anyOf || node.allOf;
|
|
34
|
+
if (!Array.isArray(branches)) return void 0;
|
|
35
|
+
for (const raw of branches) {
|
|
36
|
+
const branch = deref(raw, root);
|
|
37
|
+
if (!branch || typeof branch !== "object") continue;
|
|
38
|
+
const direct = tryFn(branch);
|
|
39
|
+
if (direct !== void 0) return direct;
|
|
40
|
+
const nested = tryCombinatorBranches(branch, root, tryFn, depth + 1);
|
|
41
|
+
if (nested !== void 0) return nested;
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function deepDeref(node, root, seen = /* @__PURE__ */ new Set()) {
|
|
46
|
+
if (!node || typeof node !== "object") return node;
|
|
47
|
+
if (Array.isArray(node)) return node.map((n) => deepDeref(n, root, seen));
|
|
48
|
+
const ref = node.$ref;
|
|
49
|
+
if (typeof ref === "string") {
|
|
50
|
+
if (seen.has(ref)) return node;
|
|
51
|
+
const resolved = resolvePointer(root, ref);
|
|
52
|
+
if (!resolved || typeof resolved !== "object") return node;
|
|
53
|
+
const nextSeen = new Set(seen);
|
|
54
|
+
nextSeen.add(ref);
|
|
55
|
+
return deepDeref(resolved, root, nextSeen);
|
|
56
|
+
}
|
|
57
|
+
const result = {};
|
|
58
|
+
for (const [key, value] of Object.entries(node)) {
|
|
59
|
+
result[key] = deepDeref(value, root, seen);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
deepDeref,
|
|
65
|
+
deref,
|
|
66
|
+
resolvePointer,
|
|
67
|
+
resolveRef,
|
|
68
|
+
tryCombinatorBranches
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sources":["../../src/core/refs.ts"],"sourcesContent":["/**\n * JSON Schema $ref resolution helpers.\n *\n * Supports the pointer grammar used across consumer schemas:\n * - \"#/$defs/Name\"\n * - \"#/properties/foo/items\"\n *\n * External refs (URIs, file refs) are intentionally out of scope. A ref that\n * doesn't resolve leaves the node untouched — callers can still inspect the\n * unresolved `$ref` for debugging.\n */\n\n/**\n * Resolve a JSON pointer (`#/a/b/c`) against an object. Returns the node at\n * that path, or `undefined` if any segment is missing or the pointer doesn't\n * start with `#/`.\n */\nexport function resolvePointer(\n obj: Record<string, unknown>,\n pointer: string,\n): unknown {\n if (!pointer.startsWith(\"#/\")) return undefined;\n const parts = pointer.slice(2).split(\"/\");\n let current: unknown = obj;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\n/**\n * Dereference a schema node along a chain of `$ref`s. Follows `A → B → C`\n * transitively. A cycle (same `$ref` seen twice in one chain) returns the\n * last unresolved node rather than hanging. An unresolvable pointer returns\n * the current node unchanged.\n */\nexport function resolveRef(\n property: Record<string, unknown>,\n root: Record<string, unknown>,\n seen?: Set<string>,\n): Record<string, unknown> {\n if (!property || typeof property !== \"object\") return property;\n\n const ref = property.$ref as string | undefined;\n if (!ref) return property;\n\n const visited = seen ?? new Set<string>();\n if (visited.has(ref)) return property;\n visited.add(ref);\n\n const resolved = resolvePointer(root, ref);\n if (!resolved) return property;\n\n return resolveRef(resolved as Record<string, unknown>, root, visited);\n}\n\n/**\n * Convenience wrapper around `resolveRef` that starts a fresh cycle-detection\n * set. Intended for schema walkers that need to dereference at every step;\n * each call is an independent resolution.\n */\nexport function deref(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: Record<string, any> | undefined,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n root: Record<string, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> | undefined {\n if (!node || typeof node !== \"object\") return node;\n return resolveRef(node, root) as Record<string, unknown> | undefined;\n}\n\n/**\n * Depth limit for combinator (oneOf/anyOf/allOf) branch descent. Schemas\n * rarely nest combinators beyond one or two levels; this guard protects\n * against pathological nesting and cycles (e.g. `oneOf: [$ref back to self]`).\n */\nconst COMBINATOR_DEPTH_LIMIT = 8;\n\n/**\n * Try to navigate a segment through a schema node's combinator branches\n * (`oneOf` / `anyOf` / `allOf`) when direct navigation has failed.\n *\n * Semantics: for walker purposes (renderer-tester matching), we only need\n * ONE concrete schema that satisfies the next navigation step. First-match\n * by structural shape wins, same convention as `initOneOf` uses for seeding.\n *\n * @param node the schema node to search (already dereffed by caller)\n * @param root the root schema, for dereferencing branch `$ref`s\n * @param tryFn predicate that attempts navigation on a candidate branch\n * and returns the navigated value, or `undefined` if the\n * branch doesn't have what the caller's looking for\n * @param depth recursion depth (capped at `COMBINATOR_DEPTH_LIMIT`)\n */\nexport function tryCombinatorBranches<T>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: Record<string, any> | undefined,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n root: Record<string, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tryFn: (candidate: Record<string, any>) => T | undefined,\n depth = 0,\n): T | undefined {\n if (depth > COMBINATOR_DEPTH_LIMIT) return undefined;\n if (!node || typeof node !== \"object\") return undefined;\n\n const branches = (node.oneOf || node.anyOf || node.allOf) as\n | Record<string, unknown>[]\n | undefined;\n if (!Array.isArray(branches)) return undefined;\n\n for (const raw of branches) {\n const branch = deref(raw as Record<string, unknown>, root);\n if (!branch || typeof branch !== \"object\") continue;\n\n const direct = tryFn(branch);\n if (direct !== undefined) return direct;\n\n const nested = tryCombinatorBranches(branch, root, tryFn, depth + 1);\n if (nested !== undefined) return nested;\n }\n return undefined;\n}\n\n/**\n * Recursively dereference every `$ref` in a schema subtree, producing a\n * concrete schema with no remaining refs. Cycles along any single chain are\n * handled by leaving the first recursion back into a seen ref as the\n * unresolved node — matching `resolveRef`'s semantics.\n *\n * Intended for use at API boundaries (e.g. `resolveScopeSchema`'s return)\n * so downstream walkers can operate on self-contained schemas without\n * needing the original root.\n */\nexport function deepDeref(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n node: any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n root: Record<string, any>,\n seen: Set<string> = new Set(),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n if (!node || typeof node !== \"object\") return node;\n if (Array.isArray(node)) return node.map((n) => deepDeref(n, root, seen));\n\n const ref = (node as Record<string, unknown>).$ref as string | undefined;\n if (typeof ref === \"string\") {\n if (seen.has(ref)) return node;\n const resolved = resolvePointer(root, ref);\n if (!resolved || typeof resolved !== \"object\") return node;\n const nextSeen = new Set(seen);\n nextSeen.add(ref);\n return deepDeref(resolved, root, nextSeen);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(node)) {\n result[key] = deepDeref(value, root, seen);\n }\n return result;\n}\n"],"names":[],"mappings":"AAiBO,SAAS,eACd,KACA,SACS;AACT,MAAI,CAAC,QAAQ,WAAW,IAAI,EAAG,QAAO;AACtC,QAAM,QAAQ,QAAQ,MAAM,CAAC,EAAE,MAAM,GAAG;AACxC,MAAI,UAAmB;AACvB,aAAW,QAAQ,OAAO;AACxB,QAAI,WAAW,OAAO,YAAY,YAAY,QAAQ,SAAS;AAC7D,gBAAW,QAAoC,IAAI;AAAA,IACrD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,WACd,UACA,MACA,MACyB;AACzB,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAEtD,QAAM,MAAM,SAAS;AACrB,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,UAAU,QAAQ,oBAAI,IAAA;AAC5B,MAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AAC7B,UAAQ,IAAI,GAAG;AAEf,QAAM,WAAW,eAAe,MAAM,GAAG;AACzC,MAAI,CAAC,SAAU,QAAO;AAEtB,SAAO,WAAW,UAAqC,MAAM,OAAO;AACtE;AAOO,SAAS,MAEd,MAEA,MAEiC;AACjC,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,SAAO,WAAW,MAAM,IAAI;AAC9B;AAOA,MAAM,yBAAyB;AAiBxB,SAAS,sBAEd,MAEA,MAEA,OACA,QAAQ,GACO;AACf,MAAI,QAAQ,uBAAwB,QAAO;AAC3C,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAE9C,QAAM,WAAY,KAAK,SAAS,KAAK,SAAS,KAAK;AAGnD,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AAErC,aAAW,OAAO,UAAU;AAC1B,UAAM,SAAS,MAAM,KAAgC,IAAI;AACzD,QAAI,CAAC,UAAU,OAAO,WAAW,SAAU;AAE3C,UAAM,SAAS,MAAM,MAAM;AAC3B,QAAI,WAAW,OAAW,QAAO;AAEjC,UAAM,SAAS,sBAAsB,QAAQ,MAAM,OAAO,QAAQ,CAAC;AACnE,QAAI,WAAW,OAAW,QAAO;AAAA,EACnC;AACA,SAAO;AACT;AAYO,SAAS,UAEd,MAEA,MACA,OAAoB,oBAAI,OAEnB;AACL,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,CAAC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAExE,QAAM,MAAO,KAAiC;AAC9C,MAAI,OAAO,QAAQ,UAAU;AAC3B,QAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,UAAM,WAAW,eAAe,MAAM,GAAG;AACzC,QAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AACtD,UAAM,WAAW,IAAI,IAAI,IAAI;AAC7B,aAAS,IAAI,GAAG;AAChB,WAAO,UAAU,UAAU,MAAM,QAAQ;AAAA,EAC3C;AAGA,QAAM,SAA8B,CAAA;AACpC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,WAAO,GAAG,IAAI,UAAU,OAAO,MAAM,IAAI;AAAA,EAC3C;AACA,SAAO;AACT;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a JSON Forms scope path to its schema within a root schema.
|
|
3
|
+
* Handles nested paths like "#/properties/parent/properties/child".
|
|
4
|
+
*
|
|
5
|
+
* Follows JSON Schema structure:
|
|
6
|
+
* - "properties" segments navigate into object `.properties`
|
|
7
|
+
* - "items" segments navigate into array `.items`
|
|
8
|
+
* - all other segments index directly into the current object
|
|
9
|
+
*
|
|
10
|
+
* Dereferences `$ref` nodes transparently at every step, and falls through
|
|
11
|
+
* to `oneOf` / `anyOf` / `allOf` branches when a segment can't resolve
|
|
12
|
+
* directly — picks the first branch that satisfies the navigation. The
|
|
13
|
+
* returned schema is deep-dereferenced so downstream walkers can operate on
|
|
14
|
+
* a self-contained sub-schema without needing the original root.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveScopeSchema(scope: string, rootSchema: Record<string, any>): Record<string, any> | undefined;
|
|
17
|
+
//# sourceMappingURL=resolveScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveScope.d.ts","sourceRoot":"","sources":["../../src/core/resolveScope.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAEb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAE9B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA+BjC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { deepDeref, deref, tryCombinatorBranches } from "./refs.js";
|
|
2
|
+
function resolveScopeSchema(scope, rootSchema) {
|
|
3
|
+
if (!scope || !rootSchema) return void 0;
|
|
4
|
+
const path = scope.replace(/^#\/?/, "");
|
|
5
|
+
if (!path) return deepDeref(rootSchema, rootSchema);
|
|
6
|
+
const segments = path.split("/");
|
|
7
|
+
let current = rootSchema;
|
|
8
|
+
for (const segment of segments) {
|
|
9
|
+
current = deref(current, rootSchema);
|
|
10
|
+
if (!current || typeof current !== "object") return void 0;
|
|
11
|
+
const navigate = (node) => {
|
|
12
|
+
if (segment === "properties") return node.properties;
|
|
13
|
+
if (segment === "items") return node.items;
|
|
14
|
+
return node[segment];
|
|
15
|
+
};
|
|
16
|
+
let next = navigate(current);
|
|
17
|
+
if (next === void 0) {
|
|
18
|
+
next = tryCombinatorBranches(current, rootSchema, navigate);
|
|
19
|
+
}
|
|
20
|
+
if (next === void 0) return void 0;
|
|
21
|
+
current = next;
|
|
22
|
+
}
|
|
23
|
+
return deepDeref(current, rootSchema);
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
resolveScopeSchema
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=resolveScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveScope.js","sources":["../../src/core/resolveScope.ts"],"sourcesContent":["import { deepDeref, deref, tryCombinatorBranches } from \"./refs\";\n\n/**\n * Resolve a JSON Forms scope path to its schema within a root schema.\n * Handles nested paths like \"#/properties/parent/properties/child\".\n *\n * Follows JSON Schema structure:\n * - \"properties\" segments navigate into object `.properties`\n * - \"items\" segments navigate into array `.items`\n * - all other segments index directly into the current object\n *\n * Dereferences `$ref` nodes transparently at every step, and falls through\n * to `oneOf` / `anyOf` / `allOf` branches when a segment can't resolve\n * directly — picks the first branch that satisfies the navigation. The\n * returned schema is deep-dereferenced so downstream walkers can operate on\n * a self-contained sub-schema without needing the original root.\n */\nexport function resolveScopeSchema(\n scope: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n rootSchema: Record<string, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> | undefined {\n if (!scope || !rootSchema) return undefined;\n\n // Remove the leading \"#/\" and split into segments\n const path = scope.replace(/^#\\/?/, \"\");\n if (!path) return deepDeref(rootSchema, rootSchema);\n\n const segments = path.split(\"/\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = rootSchema;\n\n for (const segment of segments) {\n current = deref(current, rootSchema);\n if (!current || typeof current !== \"object\") return undefined;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const navigate = (node: Record<string, any>): unknown => {\n if (segment === \"properties\") return node.properties;\n if (segment === \"items\") return node.items;\n return node[segment];\n };\n\n let next = navigate(current);\n if (next === undefined) {\n next = tryCombinatorBranches(current, rootSchema, navigate);\n }\n if (next === undefined) return undefined;\n current = next;\n }\n\n return deepDeref(current, rootSchema);\n}\n"],"names":[],"mappings":";AAiBO,SAAS,mBACd,OAEA,YAEiC;AACjC,MAAI,CAAC,SAAS,CAAC,WAAY,QAAO;AAGlC,QAAM,OAAO,MAAM,QAAQ,SAAS,EAAE;AACtC,MAAI,CAAC,KAAM,QAAO,UAAU,YAAY,UAAU;AAElD,QAAM,WAAW,KAAK,MAAM,GAAG;AAE/B,MAAI,UAAe;AAEnB,aAAW,WAAW,UAAU;AAC9B,cAAU,MAAM,SAAS,UAAU;AACnC,QAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AAGpD,UAAM,WAAW,CAAC,SAAuC;AACvD,UAAI,YAAY,aAAc,QAAO,KAAK;AAC1C,UAAI,YAAY,QAAS,QAAO,KAAK;AACrC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,QAAI,OAAO,SAAS,OAAO;AAC3B,QAAI,SAAS,QAAW;AACtB,aAAO,sBAAsB,SAAS,YAAY,QAAQ;AAAA,IAC5D;AACA,QAAI,SAAS,OAAW,QAAO;AAC/B,cAAU;AAAA,EACZ;AAEA,SAAO,UAAU,SAAS,UAAU;AACtC;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Materialize array indices targeted by `options.projection` controls in a
|
|
3
|
+
* UI schema, so that JSON Schema validators (AJV / cfworker) emit
|
|
4
|
+
* `items.required` errors on otherwise-empty arrays.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists:
|
|
7
|
+
* `initFormDataFromSchema` omits optional fields, so an optional array
|
|
8
|
+
* like `data_rates: { type: 'array', items: { $ref: '#/$defs/DataRate' } }`
|
|
9
|
+
* produces `undefined` (or, historically, `[]`). Both shapes pass schema
|
|
10
|
+
* validation: `undefined` doesn't trigger `type: array`, and `[]` has no
|
|
11
|
+
* items to apply `items.required` to. As a result, a projection-targeted
|
|
12
|
+
* field rendered with `Video CPM rate *` lies — the asterisk says
|
|
13
|
+
* "required" but the validator never enforces it on an untouched form.
|
|
14
|
+
*
|
|
15
|
+
* This utility opts the consumer into per-item enforcement by walking the
|
|
16
|
+
* UI schema, finding every `Control` with `options.projection` that
|
|
17
|
+
* addresses an array index, and ensuring the corresponding data path has
|
|
18
|
+
* that index materialized as at least `{}`. With the empty object in
|
|
19
|
+
* place, the schema's `items.required` fires and the projected control's
|
|
20
|
+
* error string surfaces at form-validity time.
|
|
21
|
+
*
|
|
22
|
+
* Tradeoff:
|
|
23
|
+
* This re-introduces "noise" on untouched forms — required-field errors
|
|
24
|
+
* for fields the user hasn't seen yet. Use it when validation enforcement
|
|
25
|
+
* on projection targets matters more than a clean initial form state.
|
|
26
|
+
* The alternative is to declare these arrays as `required` + `minItems: 1`
|
|
27
|
+
* + `default: [{}]` at the schema level, which avoids needing this helper.
|
|
28
|
+
*
|
|
29
|
+
* Properties:
|
|
30
|
+
* - Idempotent: running twice yields the same result as running once.
|
|
31
|
+
* - Non-destructive: existing values at target paths are preserved.
|
|
32
|
+
* - Pure: returns a new object; does not mutate `data`.
|
|
33
|
+
*
|
|
34
|
+
* Example:
|
|
35
|
+
* ```ts
|
|
36
|
+
* const data = initFormDataFromSchema(schema);
|
|
37
|
+
* const seeded = seedProjectionTargets(data, uischema);
|
|
38
|
+
* // For uischema controls like
|
|
39
|
+
* // { type: 'Control', scope: '#/properties/data_rates',
|
|
40
|
+
* // options: { projection: '0.video_rate_usd' } }
|
|
41
|
+
* // seeded.data_rates is now `[{}]` (was `undefined` or `[]`).
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function seedProjectionTargets(data: unknown, uischema: UISchemaLike | UISchemaLike[] | undefined): unknown;
|
|
45
|
+
/**
|
|
46
|
+
* Minimal UI schema shape this utility traverses. Compatible with
|
|
47
|
+
* `@jsonforms/core`'s `UISchemaElement` but kept local to avoid a runtime
|
|
48
|
+
* dep on `@jsonforms/core` (it's a peer dep — types only).
|
|
49
|
+
*/
|
|
50
|
+
export interface UISchemaLike {
|
|
51
|
+
type?: string;
|
|
52
|
+
scope?: string;
|
|
53
|
+
options?: {
|
|
54
|
+
projection?: string;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
};
|
|
57
|
+
elements?: UISchemaLike[];
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=seedProjectionTargets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seedProjectionTargets.d.ts","sourceRoot":"","sources":["../../src/core/seedProjectionTargets.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,SAAS,GAClD,OAAO,CAoCT;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1D,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { parseProjectionPath, getProjectedValue, setProjectedValue } from "./projection.js";
|
|
2
|
+
function seedProjectionTargets(data, uischema) {
|
|
3
|
+
if (!uischema) return data;
|
|
4
|
+
const controls = [];
|
|
5
|
+
collectProjectionControls(uischema, controls);
|
|
6
|
+
let result = data;
|
|
7
|
+
for (const { scope, projection } of controls) {
|
|
8
|
+
const dataPath = scopeToDataPath(scope);
|
|
9
|
+
const segments = parseProjectionPath(projection);
|
|
10
|
+
for (let i = 0; i < segments.length; i++) {
|
|
11
|
+
if (typeof segments[i] !== "number") continue;
|
|
12
|
+
if (i + 1 >= segments.length) continue;
|
|
13
|
+
if (typeof segments[i + 1] !== "string") continue;
|
|
14
|
+
const partial = segments.slice(0, i + 1).map((s) => String(s)).join(".");
|
|
15
|
+
const fullPath = dataPath ? `${dataPath}.${partial}` : partial;
|
|
16
|
+
if (getProjectedValue(result, fullPath) === void 0) {
|
|
17
|
+
result = setProjectedValue(result, fullPath, {});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function collectProjectionControls(ui, out) {
|
|
24
|
+
if (!ui) return;
|
|
25
|
+
if (Array.isArray(ui)) {
|
|
26
|
+
for (const el of ui) collectProjectionControls(el, out);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (typeof ui !== "object") return;
|
|
30
|
+
const projection = ui.options?.projection;
|
|
31
|
+
if (ui.type === "Control" && typeof ui.scope === "string" && typeof projection === "string") {
|
|
32
|
+
out.push({ scope: ui.scope, projection });
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(ui.elements)) {
|
|
35
|
+
for (const el of ui.elements) collectProjectionControls(el, out);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function scopeToDataPath(scope) {
|
|
39
|
+
if (!scope.startsWith("#/")) return "";
|
|
40
|
+
const parts = scope.slice(2).split("/");
|
|
41
|
+
const out = [];
|
|
42
|
+
for (let i = 0; i < parts.length; i++) {
|
|
43
|
+
if (parts[i] === "properties" && i + 1 < parts.length) {
|
|
44
|
+
out.push(parts[++i]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out.join(".");
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
seedProjectionTargets
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=seedProjectionTargets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seedProjectionTargets.js","sources":["../../src/core/seedProjectionTargets.ts"],"sourcesContent":["import {\n getProjectedValue,\n parseProjectionPath,\n setProjectedValue,\n} from \"./projection\";\n\n/**\n * Materialize array indices targeted by `options.projection` controls in a\n * UI schema, so that JSON Schema validators (AJV / cfworker) emit\n * `items.required` errors on otherwise-empty arrays.\n *\n * Why this exists:\n * `initFormDataFromSchema` omits optional fields, so an optional array\n * like `data_rates: { type: 'array', items: { $ref: '#/$defs/DataRate' } }`\n * produces `undefined` (or, historically, `[]`). Both shapes pass schema\n * validation: `undefined` doesn't trigger `type: array`, and `[]` has no\n * items to apply `items.required` to. As a result, a projection-targeted\n * field rendered with `Video CPM rate *` lies — the asterisk says\n * \"required\" but the validator never enforces it on an untouched form.\n *\n * This utility opts the consumer into per-item enforcement by walking the\n * UI schema, finding every `Control` with `options.projection` that\n * addresses an array index, and ensuring the corresponding data path has\n * that index materialized as at least `{}`. With the empty object in\n * place, the schema's `items.required` fires and the projected control's\n * error string surfaces at form-validity time.\n *\n * Tradeoff:\n * This re-introduces \"noise\" on untouched forms — required-field errors\n * for fields the user hasn't seen yet. Use it when validation enforcement\n * on projection targets matters more than a clean initial form state.\n * The alternative is to declare these arrays as `required` + `minItems: 1`\n * + `default: [{}]` at the schema level, which avoids needing this helper.\n *\n * Properties:\n * - Idempotent: running twice yields the same result as running once.\n * - Non-destructive: existing values at target paths are preserved.\n * - Pure: returns a new object; does not mutate `data`.\n *\n * Example:\n * ```ts\n * const data = initFormDataFromSchema(schema);\n * const seeded = seedProjectionTargets(data, uischema);\n * // For uischema controls like\n * // { type: 'Control', scope: '#/properties/data_rates',\n * // options: { projection: '0.video_rate_usd' } }\n * // seeded.data_rates is now `[{}]` (was `undefined` or `[]`).\n * ```\n */\nexport function seedProjectionTargets(\n data: unknown,\n uischema: UISchemaLike | UISchemaLike[] | undefined,\n): unknown {\n if (!uischema) return data;\n\n const controls: { scope: string; projection: string }[] = [];\n collectProjectionControls(uischema, controls);\n\n let result = data;\n for (const { scope, projection } of controls) {\n const dataPath = scopeToDataPath(scope);\n const segments = parseProjectionPath(projection);\n\n // Seed only when a numeric segment is followed by a *string* segment —\n // i.e., the consumer is reading a property of the array item, so the\n // item must be an object. Numeric-at-end (`'0'`) addresses the array\n // element itself, which can be any type (primitive, nested array,\n // object) — we can't infer it from the uischema alone, so leave it\n // alone. Numeric-followed-by-numeric (`'0.0'`) is a nested array; we'd\n // need to seed `[]`, but again the inner item type is unknown.\n for (let i = 0; i < segments.length; i++) {\n if (typeof segments[i] !== \"number\") continue;\n if (i + 1 >= segments.length) continue;\n if (typeof segments[i + 1] !== \"string\") continue;\n\n const partial = segments\n .slice(0, i + 1)\n .map((s) => String(s))\n .join(\".\");\n const fullPath = dataPath ? `${dataPath}.${partial}` : partial;\n\n if (getProjectedValue(result, fullPath) === undefined) {\n result = setProjectedValue(result, fullPath, {});\n }\n }\n }\n\n return result;\n}\n\n/**\n * Minimal UI schema shape this utility traverses. Compatible with\n * `@jsonforms/core`'s `UISchemaElement` but kept local to avoid a runtime\n * dep on `@jsonforms/core` (it's a peer dep — types only).\n */\nexport interface UISchemaLike {\n type?: string;\n scope?: string;\n options?: { projection?: string; [key: string]: unknown };\n elements?: UISchemaLike[];\n [key: string]: unknown;\n}\n\nfunction collectProjectionControls(\n ui: UISchemaLike | UISchemaLike[] | undefined,\n out: { scope: string; projection: string }[],\n): void {\n if (!ui) return;\n if (Array.isArray(ui)) {\n for (const el of ui) collectProjectionControls(el, out);\n return;\n }\n if (typeof ui !== \"object\") return;\n\n const projection = ui.options?.projection;\n if (\n ui.type === \"Control\" &&\n typeof ui.scope === \"string\" &&\n typeof projection === \"string\"\n ) {\n out.push({ scope: ui.scope, projection });\n }\n\n if (Array.isArray(ui.elements)) {\n for (const el of ui.elements) collectProjectionControls(el, out);\n }\n}\n\n/**\n * Convert a JsonForms scope pointer (`#/properties/foo/properties/bar`) to\n * a dot-separated data path (`foo.bar`). Drops `items` segments — array\n * indices are added at runtime via the projection path, not the scope.\n */\nfunction scopeToDataPath(scope: string): string {\n if (!scope.startsWith(\"#/\")) return \"\";\n const parts = scope.slice(2).split(\"/\");\n const out: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n if (parts[i] === \"properties\" && i + 1 < parts.length) {\n out.push(parts[++i]!);\n }\n }\n return out.join(\".\");\n}\n"],"names":[],"mappings":";AAiDO,SAAS,sBACd,MACA,UACS;AACT,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,WAAoD,CAAA;AAC1D,4BAA0B,UAAU,QAAQ;AAE5C,MAAI,SAAS;AACb,aAAW,EAAE,OAAO,WAAA,KAAgB,UAAU;AAC5C,UAAM,WAAW,gBAAgB,KAAK;AACtC,UAAM,WAAW,oBAAoB,UAAU;AAS/C,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAI,OAAO,SAAS,CAAC,MAAM,SAAU;AACrC,UAAI,IAAI,KAAK,SAAS,OAAQ;AAC9B,UAAI,OAAO,SAAS,IAAI,CAAC,MAAM,SAAU;AAEzC,YAAM,UAAU,SACb,MAAM,GAAG,IAAI,CAAC,EACd,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,EACpB,KAAK,GAAG;AACX,YAAM,WAAW,WAAW,GAAG,QAAQ,IAAI,OAAO,KAAK;AAEvD,UAAI,kBAAkB,QAAQ,QAAQ,MAAM,QAAW;AACrD,iBAAS,kBAAkB,QAAQ,UAAU,CAAA,CAAE;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAeA,SAAS,0BACP,IACA,KACM;AACN,MAAI,CAAC,GAAI;AACT,MAAI,MAAM,QAAQ,EAAE,GAAG;AACrB,eAAW,MAAM,GAAI,2BAA0B,IAAI,GAAG;AACtD;AAAA,EACF;AACA,MAAI,OAAO,OAAO,SAAU;AAE5B,QAAM,aAAa,GAAG,SAAS;AAC/B,MACE,GAAG,SAAS,aACZ,OAAO,GAAG,UAAU,YACpB,OAAO,eAAe,UACtB;AACA,QAAI,KAAK,EAAE,OAAO,GAAG,OAAO,YAAY;AAAA,EAC1C;AAEA,MAAI,MAAM,QAAQ,GAAG,QAAQ,GAAG;AAC9B,eAAW,MAAM,GAAG,SAAU,2BAA0B,IAAI,GAAG;AAAA,EACjE;AACF;AAOA,SAAS,gBAAgB,OAAuB;AAC9C,MAAI,CAAC,MAAM,WAAW,IAAI,EAAG,QAAO;AACpC,QAAM,QAAQ,MAAM,MAAM,CAAC,EAAE,MAAM,GAAG;AACtC,QAAM,MAAgB,CAAA;AACtB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI,MAAM,CAAC,MAAM,gBAAgB,IAAI,IAAI,MAAM,QAAQ;AACrD,UAAI,KAAK,MAAM,EAAE,CAAC,CAAE;AAAA,IACtB;AAAA,EACF;AACA,SAAO,IAAI,KAAK,GAAG;AACrB;"}
|
|
@@ -11,24 +11,22 @@ export interface FlattenTransform extends Transform {
|
|
|
11
11
|
key: string;
|
|
12
12
|
labelFormat?: string;
|
|
13
13
|
}
|
|
14
|
+
export type FilterOperator = "eq" | "neq" | "empty" | "notEmpty" | "gt" | "gte" | "lt" | "lte" | "contains";
|
|
15
|
+
export interface FilterCondition {
|
|
16
|
+
key: string;
|
|
17
|
+
operator?: FilterOperator;
|
|
18
|
+
values?: unknown[];
|
|
19
|
+
}
|
|
14
20
|
export interface FilterTransform extends Transform {
|
|
15
21
|
name: "filter";
|
|
16
|
-
key
|
|
22
|
+
key?: string;
|
|
17
23
|
values?: unknown[];
|
|
24
|
+
conditions?: FilterCondition[];
|
|
18
25
|
}
|
|
19
26
|
export type TransformStep = FlattenTransform | FilterTransform;
|
|
20
27
|
export type TransformPipeline = TransformStep[];
|
|
21
|
-
/**
|
|
22
|
-
* Registry of transform functions
|
|
23
|
-
*/
|
|
24
|
-
type TransformFunction = (items: unknown[], config: Transform) => unknown[];
|
|
25
|
-
/**
|
|
26
|
-
* Register a transform function
|
|
27
|
-
*/
|
|
28
|
-
export declare function registerTransform(name: string, fn: TransformFunction): void;
|
|
29
28
|
/**
|
|
30
29
|
* Apply a pipeline of transforms to data
|
|
31
30
|
*/
|
|
32
31
|
export declare function applyTransformPipeline(items: unknown[], pipeline: TransformPipeline): unknown[];
|
|
33
|
-
export {};
|
|
34
32
|
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../src/core/transforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../src/core/transforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,KAAK,GACL,OAAO,GACP,UAAU,GACV,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,UAAU,CAAC;AAEf,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAE/D,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAMhD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EAAE,EAChB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,EAAE,CAYX"}
|
package/dist/core/transforms.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
const transformRegistry = {};
|
|
2
|
-
function registerTransform(name, fn) {
|
|
3
|
-
transformRegistry[name] = fn;
|
|
4
|
-
}
|
|
5
2
|
function applyTransformPipeline(items, pipeline) {
|
|
6
3
|
let result = items;
|
|
7
4
|
for (const transform of pipeline) {
|
|
@@ -59,23 +56,71 @@ function flattenTransform(items, config) {
|
|
|
59
56
|
}
|
|
60
57
|
return flattened;
|
|
61
58
|
}
|
|
59
|
+
function isEmpty(value) {
|
|
60
|
+
if (value === null || value === void 0) return true;
|
|
61
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
62
|
+
if (typeof value === "string") return value.length === 0;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function evaluateCondition(itemObj, condition) {
|
|
66
|
+
const value = itemObj[condition.key];
|
|
67
|
+
const operator = condition.operator ?? (condition.values ? "eq" : "eq");
|
|
68
|
+
switch (operator) {
|
|
69
|
+
case "eq":
|
|
70
|
+
if (!condition.values || condition.values.length === 0) {
|
|
71
|
+
return condition.key in itemObj;
|
|
72
|
+
}
|
|
73
|
+
return condition.values.includes(value);
|
|
74
|
+
case "neq":
|
|
75
|
+
if (!condition.values || condition.values.length === 0) {
|
|
76
|
+
return !(condition.key in itemObj);
|
|
77
|
+
}
|
|
78
|
+
return !condition.values.includes(value);
|
|
79
|
+
case "empty":
|
|
80
|
+
return isEmpty(value);
|
|
81
|
+
case "notEmpty":
|
|
82
|
+
return !isEmpty(value);
|
|
83
|
+
case "gt":
|
|
84
|
+
return typeof value === "number" && condition.values !== void 0 && value > condition.values[0];
|
|
85
|
+
case "gte":
|
|
86
|
+
return typeof value === "number" && condition.values !== void 0 && value >= condition.values[0];
|
|
87
|
+
case "lt":
|
|
88
|
+
return typeof value === "number" && condition.values !== void 0 && value < condition.values[0];
|
|
89
|
+
case "lte":
|
|
90
|
+
return typeof value === "number" && condition.values !== void 0 && value <= condition.values[0];
|
|
91
|
+
case "contains":
|
|
92
|
+
if (typeof value === "string" && condition.values) {
|
|
93
|
+
return condition.values.some((v) => value.includes(String(v)));
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(value) && condition.values) {
|
|
96
|
+
return condition.values.some((v) => value.includes(v));
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
default:
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
62
103
|
function filterTransform(items, config) {
|
|
63
104
|
const filterConfig = config;
|
|
64
|
-
|
|
105
|
+
let conditions;
|
|
106
|
+
if (filterConfig.conditions) {
|
|
107
|
+
conditions = filterConfig.conditions;
|
|
108
|
+
} else if (filterConfig.key) {
|
|
109
|
+
conditions = [{ key: filterConfig.key, values: filterConfig.values }];
|
|
110
|
+
} else {
|
|
111
|
+
return items;
|
|
112
|
+
}
|
|
65
113
|
return items.filter((item) => {
|
|
66
114
|
if (typeof item !== "object" || item === null) return false;
|
|
67
115
|
const itemObj = item;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const itemValue = itemObj[key];
|
|
72
|
-
return values.includes(itemValue);
|
|
116
|
+
return conditions.every(
|
|
117
|
+
(condition) => evaluateCondition(itemObj, condition)
|
|
118
|
+
);
|
|
73
119
|
});
|
|
74
120
|
}
|
|
75
|
-
|
|
76
|
-
|
|
121
|
+
transformRegistry["flatten"] = flattenTransform;
|
|
122
|
+
transformRegistry["filter"] = filterTransform;
|
|
77
123
|
export {
|
|
78
|
-
applyTransformPipeline
|
|
79
|
-
registerTransform
|
|
124
|
+
applyTransformPipeline
|
|
80
125
|
};
|
|
81
126
|
//# sourceMappingURL=transforms.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.js","sources":["../../src/core/transforms.ts"],"sourcesContent":["/**\n * Transform pipeline system for manipulating API response data\n * Transforms are applied sequentially in the order they appear in the pipeline\n */\n\nexport interface Transform {\n name: string;\n [key: string]: unknown;\n}\n\nexport interface FlattenTransform extends Transform {\n name: \"flatten\";\n key: string; // The key containing the nested array to flatten\n labelFormat?: string; // Optional format string like \"{parent.name} → {name}\"\n}\n\nexport interface FilterTransform extends Transform {\n name: \"filter\";\n key: string; // The key to check\n values?: unknown[]; // Optional array of values to match against\n}\n\nexport type TransformStep = FlattenTransform | FilterTransform;\n\nexport type TransformPipeline = TransformStep[];\n\n/**\n * Registry of transform functions\n */\ntype TransformFunction = (items: unknown[], config: Transform) => unknown[];\n\nconst transformRegistry: Record<string, TransformFunction> = {};\n\n/**\n * Register a transform function\n */\nexport function registerTransform(name: string, fn: TransformFunction): void {\n transformRegistry[name] = fn;\n}\n\n/**\n * Apply a pipeline of transforms to data\n */\nexport function applyTransformPipeline(\n items: unknown[],\n pipeline: TransformPipeline,\n): unknown[] {\n let result = items;\n\n for (const transform of pipeline) {\n const fn = transformRegistry[transform.name];\n if (!fn) {\n throw new Error(`Unknown transform: ${transform.name}`);\n }\n result = fn(result, transform);\n }\n\n return result;\n}\n\n/**\n * Flatten transform - recursively flattens nested arrays into a single level\n */\nfunction flattenTransform(items: unknown[], config: Transform): unknown[] {\n const flattenConfig = config as FlattenTransform;\n const { key, labelFormat } = flattenConfig;\n const flattened: unknown[] = [];\n\n function flattenRecursive(\n item: unknown,\n parent: Record<string, unknown> | null = null,\n depth: number = 0,\n ): void {\n if (typeof item !== \"object\" || item === null) return;\n\n const itemObj = item as Record<string, unknown>;\n\n // Add the current item\n if (labelFormat && parent) {\n const formattedItem = { ...itemObj };\n\n // Replace placeholders like {parent.name} and {name}\n let formattedLabel = labelFormat;\n formattedLabel = formattedLabel.replace(/\\{parent\\.(\\w+)\\}/g, (_, prop) =>\n String(parent[prop] ?? \"\"),\n );\n formattedLabel = formattedLabel.replace(/\\{(\\w+)\\}/g, (_, prop) =>\n String(itemObj[prop] ?? \"\"),\n );\n\n formattedItem._formattedLabel = formattedLabel;\n formattedItem._parent = parent;\n formattedItem._depth = depth;\n flattened.push(formattedItem);\n } else if (parent) {\n // Child node with parent reference\n flattened.push({\n ...itemObj,\n _parent: parent,\n _depth: depth,\n });\n } else {\n // Root node\n flattened.push({\n ...itemObj,\n _depth: depth,\n });\n }\n\n // Recursively flatten children\n const children = itemObj[key];\n if (Array.isArray(children)) {\n for (const child of children) {\n flattenRecursive(child, itemObj, depth + 1);\n }\n }\n }\n\n // Start flattening from root items\n for (const item of items) {\n flattenRecursive(item, null, 0);\n }\n\n return flattened;\n}\n\n/**\n * Filter transform - filters items based on a key and optional values\n */\nfunction filterTransform(items: unknown[], config: Transform): unknown[] {\n const filterConfig = config as FilterTransform;\n const { key, values } = filterConfig;\n\n return items.filter((item) => {\n if (typeof item !== \"object\" || item === null) return false;\n\n const itemObj = item as Record<string, unknown>;\n\n // If no values array provided, just check if the key exists\n if (!values || values.length === 0) {\n return key in itemObj;\n }\n\n // If values array provided, check if item[key] matches any of the values\n const itemValue = itemObj[key];\n return values.includes(itemValue);\n });\n}\n\n// Register built-in transforms\nregisterTransform(\"flatten\", flattenTransform);\nregisterTransform(\"filter\", filterTransform);\n"],"names":[],"mappings":"AA+BA,MAAM,oBAAuD,CAAA;AAKtD,SAAS,kBAAkB,MAAc,IAA6B;AAC3E,oBAAkB,IAAI,IAAI;AAC5B;AAKO,SAAS,uBACd,OACA,UACW;AACX,MAAI,SAAS;AAEb,aAAW,aAAa,UAAU;AAChC,UAAM,KAAK,kBAAkB,UAAU,IAAI;AAC3C,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,sBAAsB,UAAU,IAAI,EAAE;AAAA,IACxD;AACA,aAAS,GAAG,QAAQ,SAAS;AAAA,EAC/B;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,OAAkB,QAA8B;AACxE,QAAM,gBAAgB;AACtB,QAAM,EAAE,KAAK,YAAA,IAAgB;AAC7B,QAAM,YAAuB,CAAA;AAE7B,WAAS,iBACP,MACA,SAAyC,MACzC,QAAgB,GACV;AACN,QAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAE/C,UAAM,UAAU;AAGhB,QAAI,eAAe,QAAQ;AACzB,YAAM,gBAAgB,EAAE,GAAG,QAAA;AAG3B,UAAI,iBAAiB;AACrB,uBAAiB,eAAe;AAAA,QAAQ;AAAA,QAAsB,CAAC,GAAG,SAChE,OAAO,OAAO,IAAI,KAAK,EAAE;AAAA,MAAA;AAE3B,uBAAiB,eAAe;AAAA,QAAQ;AAAA,QAAc,CAAC,GAAG,SACxD,OAAO,QAAQ,IAAI,KAAK,EAAE;AAAA,MAAA;AAG5B,oBAAc,kBAAkB;AAChC,oBAAc,UAAU;AACxB,oBAAc,SAAS;AACvB,gBAAU,KAAK,aAAa;AAAA,IAC9B,WAAW,QAAQ;AAEjB,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,SAAS;AAAA,QACT,QAAQ;AAAA,MAAA,CACT;AAAA,IACH,OAAO;AAEL,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,QAAQ;AAAA,MAAA,CACT;AAAA,IACH;AAGA,UAAM,WAAW,QAAQ,GAAG;AAC5B,QAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,iBAAW,SAAS,UAAU;AAC5B,yBAAiB,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAGA,aAAW,QAAQ,OAAO;AACxB,qBAAiB,MAAM,MAAM,CAAC;AAAA,EAChC;AAEA,SAAO;AACT;AAKA,SAAS,gBAAgB,OAAkB,QAA8B;AACvE,QAAM,eAAe;AACrB,QAAM,EAAE,KAAK,OAAA,IAAW;AAExB,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,QAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AAEtD,UAAM,UAAU;AAGhB,QAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,aAAO,OAAO;AAAA,IAChB;AAGA,UAAM,YAAY,QAAQ,GAAG;AAC7B,WAAO,OAAO,SAAS,SAAS;AAAA,EAClC,CAAC;AACH;AAGA,kBAAkB,WAAW,gBAAgB;AAC7C,kBAAkB,UAAU,eAAe;"}
|
|
1
|
+
{"version":3,"file":"transforms.js","sources":["../../src/core/transforms.ts"],"sourcesContent":["/**\n * Transform pipeline system for manipulating API response data\n * Transforms are applied sequentially in the order they appear in the pipeline\n */\n\nexport interface Transform {\n name: string;\n [key: string]: unknown;\n}\n\nexport interface FlattenTransform extends Transform {\n name: \"flatten\";\n key: string; // The key containing the nested array to flatten\n labelFormat?: string; // Optional format string like \"{parent.name} → {name}\"\n}\n\nexport type FilterOperator =\n | \"eq\"\n | \"neq\"\n | \"empty\"\n | \"notEmpty\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"contains\";\n\nexport interface FilterCondition {\n key: string;\n operator?: FilterOperator; // Defaults to \"eq\" when values is provided, \"exists\" behavior when neither\n values?: unknown[];\n}\n\nexport interface FilterTransform extends Transform {\n name: \"filter\";\n key?: string; // Legacy: single key to check\n values?: unknown[]; // Legacy: single values array\n conditions?: FilterCondition[]; // Multi-condition filter (AND logic)\n}\n\nexport type TransformStep = FlattenTransform | FilterTransform;\n\nexport type TransformPipeline = TransformStep[];\n\ntype TransformFunction = (items: unknown[], config: Transform) => unknown[];\n\nconst transformRegistry: Record<string, TransformFunction> = {};\n\n/**\n * Apply a pipeline of transforms to data\n */\nexport function applyTransformPipeline(\n items: unknown[],\n pipeline: TransformPipeline,\n): unknown[] {\n let result = items;\n\n for (const transform of pipeline) {\n const fn = transformRegistry[transform.name];\n if (!fn) {\n throw new Error(`Unknown transform: ${transform.name}`);\n }\n result = fn(result, transform);\n }\n\n return result;\n}\n\n/**\n * Flatten transform - recursively flattens nested arrays into a single level\n */\nfunction flattenTransform(items: unknown[], config: Transform): unknown[] {\n const flattenConfig = config as FlattenTransform;\n const { key, labelFormat } = flattenConfig;\n const flattened: unknown[] = [];\n\n function flattenRecursive(\n item: unknown,\n parent: Record<string, unknown> | null = null,\n depth: number = 0,\n ): void {\n if (typeof item !== \"object\" || item === null) return;\n\n const itemObj = item as Record<string, unknown>;\n\n // Add the current item\n if (labelFormat && parent) {\n const formattedItem = { ...itemObj };\n\n // Replace placeholders like {parent.name} and {name}\n let formattedLabel = labelFormat;\n formattedLabel = formattedLabel.replace(/\\{parent\\.(\\w+)\\}/g, (_, prop) =>\n String(parent[prop] ?? \"\"),\n );\n formattedLabel = formattedLabel.replace(/\\{(\\w+)\\}/g, (_, prop) =>\n String(itemObj[prop] ?? \"\"),\n );\n\n formattedItem._formattedLabel = formattedLabel;\n formattedItem._parent = parent;\n formattedItem._depth = depth;\n flattened.push(formattedItem);\n } else if (parent) {\n // Child node with parent reference\n flattened.push({\n ...itemObj,\n _parent: parent,\n _depth: depth,\n });\n } else {\n // Root node\n flattened.push({\n ...itemObj,\n _depth: depth,\n });\n }\n\n // Recursively flatten children\n const children = itemObj[key];\n if (Array.isArray(children)) {\n for (const child of children) {\n flattenRecursive(child, itemObj, depth + 1);\n }\n }\n }\n\n // Start flattening from root items\n for (const item of items) {\n flattenRecursive(item, null, 0);\n }\n\n return flattened;\n}\n\nfunction isEmpty(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"string\") return value.length === 0;\n return false;\n}\n\nfunction evaluateCondition(\n itemObj: Record<string, unknown>,\n condition: FilterCondition,\n): boolean {\n const value = itemObj[condition.key];\n const operator = condition.operator ?? (condition.values ? \"eq\" : \"eq\");\n\n switch (operator) {\n case \"eq\":\n if (!condition.values || condition.values.length === 0) {\n return condition.key in itemObj;\n }\n return condition.values.includes(value);\n case \"neq\":\n if (!condition.values || condition.values.length === 0) {\n return !(condition.key in itemObj);\n }\n return !condition.values.includes(value);\n case \"empty\":\n return isEmpty(value);\n case \"notEmpty\":\n return !isEmpty(value);\n case \"gt\":\n return (\n typeof value === \"number\" &&\n condition.values !== undefined &&\n value > (condition.values[0] as number)\n );\n case \"gte\":\n return (\n typeof value === \"number\" &&\n condition.values !== undefined &&\n value >= (condition.values[0] as number)\n );\n case \"lt\":\n return (\n typeof value === \"number\" &&\n condition.values !== undefined &&\n value < (condition.values[0] as number)\n );\n case \"lte\":\n return (\n typeof value === \"number\" &&\n condition.values !== undefined &&\n value <= (condition.values[0] as number)\n );\n case \"contains\":\n if (typeof value === \"string\" && condition.values) {\n return condition.values.some((v) => value.includes(String(v)));\n }\n if (Array.isArray(value) && condition.values) {\n return condition.values.some((v) => value.includes(v));\n }\n return false;\n default:\n return false;\n }\n}\n\n/**\n * Filter transform - filters items based on conditions\n *\n * Supports legacy single key/values syntax and new multi-condition syntax.\n * When using conditions, all conditions must match (AND logic).\n *\n * Operators:\n * eq - item[key] matches one of values (default)\n * neq - item[key] does NOT match any of values\n * empty - item[key] is null, undefined, empty array, or empty string\n * notEmpty - inverse of empty\n * gt - item[key] > values[0]\n * gte - item[key] >= values[0]\n * lt - item[key] < values[0]\n * lte - item[key] <= values[0]\n * contains - string includes substring, or array includes value\n */\nfunction filterTransform(items: unknown[], config: Transform): unknown[] {\n const filterConfig = config as FilterTransform;\n\n // Build conditions array from either new or legacy syntax\n let conditions: FilterCondition[];\n\n if (filterConfig.conditions) {\n conditions = filterConfig.conditions;\n } else if (filterConfig.key) {\n // Legacy single key/values syntax\n conditions = [{ key: filterConfig.key, values: filterConfig.values }];\n } else {\n return items;\n }\n\n return items.filter((item) => {\n if (typeof item !== \"object\" || item === null) return false;\n const itemObj = item as Record<string, unknown>;\n return conditions.every((condition) =>\n evaluateCondition(itemObj, condition),\n );\n });\n}\n\n// Register built-in transforms\ntransformRegistry[\"flatten\"] = flattenTransform;\ntransformRegistry[\"filter\"] = filterTransform;\n"],"names":[],"mappings":"AA8CA,MAAM,oBAAuD,CAAA;AAKtD,SAAS,uBACd,OACA,UACW;AACX,MAAI,SAAS;AAEb,aAAW,aAAa,UAAU;AAChC,UAAM,KAAK,kBAAkB,UAAU,IAAI;AAC3C,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,sBAAsB,UAAU,IAAI,EAAE;AAAA,IACxD;AACA,aAAS,GAAG,QAAQ,SAAS;AAAA,EAC/B;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,OAAkB,QAA8B;AACxE,QAAM,gBAAgB;AACtB,QAAM,EAAE,KAAK,YAAA,IAAgB;AAC7B,QAAM,YAAuB,CAAA;AAE7B,WAAS,iBACP,MACA,SAAyC,MACzC,QAAgB,GACV;AACN,QAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAE/C,UAAM,UAAU;AAGhB,QAAI,eAAe,QAAQ;AACzB,YAAM,gBAAgB,EAAE,GAAG,QAAA;AAG3B,UAAI,iBAAiB;AACrB,uBAAiB,eAAe;AAAA,QAAQ;AAAA,QAAsB,CAAC,GAAG,SAChE,OAAO,OAAO,IAAI,KAAK,EAAE;AAAA,MAAA;AAE3B,uBAAiB,eAAe;AAAA,QAAQ;AAAA,QAAc,CAAC,GAAG,SACxD,OAAO,QAAQ,IAAI,KAAK,EAAE;AAAA,MAAA;AAG5B,oBAAc,kBAAkB;AAChC,oBAAc,UAAU;AACxB,oBAAc,SAAS;AACvB,gBAAU,KAAK,aAAa;AAAA,IAC9B,WAAW,QAAQ;AAEjB,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,SAAS;AAAA,QACT,QAAQ;AAAA,MAAA,CACT;AAAA,IACH,OAAO;AAEL,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,QAAQ;AAAA,MAAA,CACT;AAAA,IACH;AAGA,UAAM,WAAW,QAAQ,GAAG;AAC5B,QAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,iBAAW,SAAS,UAAU;AAC5B,yBAAiB,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAGA,aAAW,QAAQ,OAAO;AACxB,qBAAiB,MAAM,MAAM,CAAC;AAAA,EAChC;AAEA,SAAO;AACT;AAEA,SAAS,QAAQ,OAAyB;AACxC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,WAAW;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,WAAW;AACvD,SAAO;AACT;AAEA,SAAS,kBACP,SACA,WACS;AACT,QAAM,QAAQ,QAAQ,UAAU,GAAG;AACnC,QAAM,WAAW,UAAU,aAAa,UAAU,SAAS,OAAO;AAElE,UAAQ,UAAA;AAAA,IACN,KAAK;AACH,UAAI,CAAC,UAAU,UAAU,UAAU,OAAO,WAAW,GAAG;AACtD,eAAO,UAAU,OAAO;AAAA,MAC1B;AACA,aAAO,UAAU,OAAO,SAAS,KAAK;AAAA,IACxC,KAAK;AACH,UAAI,CAAC,UAAU,UAAU,UAAU,OAAO,WAAW,GAAG;AACtD,eAAO,EAAE,UAAU,OAAO;AAAA,MAC5B;AACA,aAAO,CAAC,UAAU,OAAO,SAAS,KAAK;AAAA,IACzC,KAAK;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,KAAK;AACH,aAAO,CAAC,QAAQ,KAAK;AAAA,IACvB,KAAK;AACH,aACE,OAAO,UAAU,YACjB,UAAU,WAAW,UACrB,QAAS,UAAU,OAAO,CAAC;AAAA,IAE/B,KAAK;AACH,aACE,OAAO,UAAU,YACjB,UAAU,WAAW,UACrB,SAAU,UAAU,OAAO,CAAC;AAAA,IAEhC,KAAK;AACH,aACE,OAAO,UAAU,YACjB,UAAU,WAAW,UACrB,QAAS,UAAU,OAAO,CAAC;AAAA,IAE/B,KAAK;AACH,aACE,OAAO,UAAU,YACjB,UAAU,WAAW,UACrB,SAAU,UAAU,OAAO,CAAC;AAAA,IAEhC,KAAK;AACH,UAAI,OAAO,UAAU,YAAY,UAAU,QAAQ;AACjD,eAAO,UAAU,OAAO,KAAK,CAAC,MAAM,MAAM,SAAS,OAAO,CAAC,CAAC,CAAC;AAAA,MAC/D;AACA,UAAI,MAAM,QAAQ,KAAK,KAAK,UAAU,QAAQ;AAC5C,eAAO,UAAU,OAAO,KAAK,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AAAA,MACvD;AACA,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAmBA,SAAS,gBAAgB,OAAkB,QAA8B;AACvE,QAAM,eAAe;AAGrB,MAAI;AAEJ,MAAI,aAAa,YAAY;AAC3B,iBAAa,aAAa;AAAA,EAC5B,WAAW,aAAa,KAAK;AAE3B,iBAAa,CAAC,EAAE,KAAK,aAAa,KAAK,QAAQ,aAAa,QAAQ;AAAA,EACtE,OAAO;AACL,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,OAAO,CAAC,SAAS;AAC5B,QAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,UAAM,UAAU;AAChB,WAAO,WAAW;AAAA,MAAM,CAAC,cACvB,kBAAkB,SAAS,SAAS;AAAA,IAAA;AAAA,EAExC,CAAC;AACH;AAGA,kBAAkB,SAAS,IAAI;AAC/B,kBAAkB,QAAQ,IAAI;"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -41,4 +41,12 @@ export interface AuthConfig {
|
|
|
41
41
|
token?: string | (() => string);
|
|
42
42
|
[key: string]: unknown;
|
|
43
43
|
}
|
|
44
|
+
export interface ConnectorDataLayer {
|
|
45
|
+
dataset_name?: string;
|
|
46
|
+
dataset_description?: string;
|
|
47
|
+
dataset_id?: number;
|
|
48
|
+
profile_id?: string;
|
|
49
|
+
profile_name?: string;
|
|
50
|
+
datasetWriteMode?: "append" | "overwrite";
|
|
51
|
+
}
|
|
44
52
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,EAAE,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,QAAQ,CAAC,GAAG,GAAG,OAAO;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,EAAE,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,QAAQ,CAAC,GAAG,GAAG,OAAO;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;CAC3C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,17 @@ export * from "./core/jsonpath";
|
|
|
5
5
|
export { registry } from "./core/registry";
|
|
6
6
|
export * from "./core/templating";
|
|
7
7
|
export * from "./core/transforms";
|
|
8
|
+
export * from "./core/projection";
|
|
9
|
+
export * from "./core/resolveScope";
|
|
8
10
|
export * from "./core/types";
|
|
11
|
+
export { initFormDataFromSchema } from "./core/initFormData";
|
|
12
|
+
export { seedProjectionTargets } from "./core/seedProjectionTargets";
|
|
13
|
+
export type { UISchemaLike } from "./core/seedProjectionTargets";
|
|
9
14
|
export { RestApiProtocol } from "./protocols/rest_api";
|
|
10
|
-
export {
|
|
15
|
+
export { createNoEvalAjv, transformUnit, transformErrors, } from "./no-eval-ajv";
|
|
16
|
+
export type { NoEvalAjv, NoEvalErrorObject, NoEvalValidateFunction, CreateNoEvalAjvOptions, } from "./no-eval-ajv";
|
|
17
|
+
export { providerRenderers, primevueRenderers, ProviderAutocomplete, ProviderSelect, ProviderMultiSelect, ProviderObjectMultiSelect, useProvider, createDataLayer, useDataLayer, JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean, } from "./vue";
|
|
18
|
+
export type { DataLayer } from "./vue";
|
|
11
19
|
export interface ProviderConfig {
|
|
12
20
|
protocols?: Protocol[];
|
|
13
21
|
auth?: AuthConfig;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EACL,eAAe,EACf,aAAa,EACb,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,YAAY,EACZ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,SAAS,GACV,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;;iBAGc,GAAG,SAAS,cAAc;;AADzC,wBAYE"}
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,13 @@ import { cache } from "./core/cache.js";
|
|
|
2
2
|
import { registry } from "./core/registry.js";
|
|
3
3
|
import { jp } from "./core/jsonpath.js";
|
|
4
4
|
import { renderObj, renderTpl } from "./core/templating.js";
|
|
5
|
-
import { applyTransformPipeline
|
|
5
|
+
import { applyTransformPipeline } from "./core/transforms.js";
|
|
6
|
+
import { getProjectedSchema, getProjectedValue, parseProjectionPath, setProjectedValue } from "./core/projection.js";
|
|
7
|
+
import { resolveScopeSchema } from "./core/resolveScope.js";
|
|
8
|
+
import { initFormDataFromSchema } from "./core/initFormData.js";
|
|
9
|
+
import { seedProjectionTargets } from "./core/seedProjectionTargets.js";
|
|
6
10
|
import { RestApiProtocol } from "./protocols/rest_api.js";
|
|
11
|
+
import { createNoEvalAjv, transformErrors, transformUnit } from "./no-eval-ajv.js";
|
|
7
12
|
import { providerRenderers } from "./vue/index.js";
|
|
8
13
|
import { default as default2 } from "./vue/components/ProviderAutocomplete.vue.js";
|
|
9
14
|
import { default as default3 } from "./vue/primevue/JfText.vue.js";
|
|
@@ -15,8 +20,9 @@ import { default as default8 } from "./vue/primevue/JfBoolean.vue.js";
|
|
|
15
20
|
import { primevueRenderers } from "./vue/primevue/index.js";
|
|
16
21
|
import { default as default9 } from "./vue/components/ProviderSelect.vue.js";
|
|
17
22
|
import { default as default10 } from "./vue/components/ProviderMultiSelect.vue.js";
|
|
23
|
+
import { default as default11 } from "./vue/components/ProviderObjectMultiSelect.vue.js";
|
|
18
24
|
import { useProvider } from "./vue/composables/useProvider.js";
|
|
19
|
-
|
|
25
|
+
import { createDataLayer, useDataLayer } from "./vue/composables/useDataLayer.js";
|
|
20
26
|
const index = {
|
|
21
27
|
install(app, opts) {
|
|
22
28
|
const reg = registry;
|
|
@@ -39,18 +45,30 @@ export {
|
|
|
39
45
|
default4 as JfTextArea,
|
|
40
46
|
default2 as ProviderAutocomplete,
|
|
41
47
|
default10 as ProviderMultiSelect,
|
|
48
|
+
default11 as ProviderObjectMultiSelect,
|
|
42
49
|
default9 as ProviderSelect,
|
|
43
50
|
RestApiProtocol,
|
|
44
51
|
applyTransformPipeline,
|
|
45
52
|
cache,
|
|
53
|
+
createDataLayer,
|
|
54
|
+
createNoEvalAjv,
|
|
46
55
|
index as default,
|
|
56
|
+
getProjectedSchema,
|
|
57
|
+
getProjectedValue,
|
|
58
|
+
initFormDataFromSchema,
|
|
47
59
|
jp,
|
|
60
|
+
parseProjectionPath,
|
|
48
61
|
primevueRenderers,
|
|
49
62
|
providerRenderers,
|
|
50
|
-
registerTransform,
|
|
51
63
|
registry,
|
|
52
64
|
renderObj,
|
|
53
65
|
renderTpl,
|
|
66
|
+
resolveScopeSchema,
|
|
67
|
+
seedProjectionTargets,
|
|
68
|
+
setProjectedValue,
|
|
69
|
+
transformErrors,
|
|
70
|
+
transformUnit,
|
|
71
|
+
useDataLayer,
|
|
54
72
|
useProvider
|
|
55
73
|
};
|
|
56
74
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { App } from \"vue\";\nimport { cache as globalCache } from \"./core/cache\";\nimport { registry as globalRegistry } from \"./core/registry\";\nimport type { Protocol, AuthConfig } from \"./core/types\";\n\
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { App } from \"vue\";\nimport { cache as globalCache } from \"./core/cache\";\nimport { registry as globalRegistry } from \"./core/registry\";\nimport type { Protocol, AuthConfig } from \"./core/types\";\n\nexport { cache } from \"./core/cache\";\nexport * from \"./core/jsonpath\";\nexport { registry } from \"./core/registry\";\nexport * from \"./core/templating\";\nexport * from \"./core/transforms\";\nexport * from \"./core/projection\";\nexport * from \"./core/resolveScope\";\n// Core exports\nexport * from \"./core/types\";\nexport { initFormDataFromSchema } from \"./core/initFormData\";\nexport { seedProjectionTargets } from \"./core/seedProjectionTargets\";\nexport type { UISchemaLike } from \"./core/seedProjectionTargets\";\n\n// Protocol exports\nexport { RestApiProtocol } from \"./protocols/rest_api\";\n\n// CSP-safe validator\nexport {\n createNoEvalAjv,\n transformUnit,\n transformErrors,\n} from \"./no-eval-ajv\";\nexport type {\n NoEvalAjv,\n NoEvalErrorObject,\n NoEvalValidateFunction,\n CreateNoEvalAjvOptions,\n} from \"./no-eval-ajv\";\n\n// Vue exports - using named imports to avoid potential bundling issues\nexport {\n providerRenderers,\n primevueRenderers,\n ProviderAutocomplete,\n ProviderSelect,\n ProviderMultiSelect,\n ProviderObjectMultiSelect,\n useProvider,\n createDataLayer,\n useDataLayer,\n JfText,\n JfTextArea,\n JfNumber,\n JfEnum,\n JfEnumArray,\n JfBoolean,\n} from \"./vue\";\nexport type { DataLayer } from \"./vue\";\n\nexport interface ProviderConfig {\n protocols?: Protocol[];\n auth?: AuthConfig;\n}\n\nexport default {\n install(app: App, opts?: ProviderConfig) {\n const reg = globalRegistry;\n if (opts?.protocols) {\n for (const p of opts.protocols) {\n reg.register(p);\n }\n }\n app.provide(\"providerRegistry\", reg);\n app.provide(\"providerCache\", globalCache);\n app.provide(\"providerAuth\", opts?.auth ?? {});\n },\n};\n"],"names":["globalRegistry","globalCache"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,MAAA,QAAe;AAAA,EACb,QAAQ,KAAU,MAAuB;AACvC,UAAM,MAAMA;AACZ,QAAI,MAAM,WAAW;AACnB,iBAAW,KAAK,KAAK,WAAW;AAC9B,YAAI,SAAS,CAAC;AAAA,MAChB;AAAA,IACF;AACA,QAAI,QAAQ,oBAAoB,GAAG;AACnC,QAAI,QAAQ,iBAAiBC,KAAW;AACxC,QAAI,QAAQ,gBAAgB,MAAM,QAAQ,CAAA,CAAE;AAAA,EAC9C;AACF;"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
[data-v-
|
|
2
|
+
[data-v-cbb98bc4] .p-dropdown-label {
|
|
3
3
|
text-align: left;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
[data-v-
|
|
6
|
+
[data-v-0d0d0f03] .p-multiselect-label {
|
|
7
|
+
text-align: left;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[data-v-2ee6c7be] .p-multiselect-label {
|
|
7
11
|
text-align: left;
|
|
8
12
|
}
|