@narrative.io/jsonforms-provider-protocols 2.11.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 +12 -6
- 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 +21 -11
- 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 +22 -10
- 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 +44 -17
- 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 +38 -24
- 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 +40 -20
- 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 +33 -23
- 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 +51 -35
- 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 +34 -19
- 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 +100 -8
- package/dist/vue/primevue/index.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 +11 -7
- 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 +35 -26
- package/src/vue/primevue/JfEnumArray.vue +37 -20
- package/src/vue/primevue/JfNumber.vue +32 -24
- package/src/vue/primevue/JfText.vue +48 -33
- package/src/vue/primevue/JfTextArea.vue +32 -21
- package/src/vue/primevue/index.ts +114 -8
- package/src/vue/styles.css +26 -1
- package/src/vue/utils/objectMultiSelect.ts +171 -0
- package/src/vue/utils/placeholder.ts +42 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getProjectedValue,
|
|
3
|
+
parseProjectionPath,
|
|
4
|
+
setProjectedValue,
|
|
5
|
+
} from "./projection";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Materialize array indices targeted by `options.projection` controls in a
|
|
9
|
+
* UI schema, so that JSON Schema validators (AJV / cfworker) emit
|
|
10
|
+
* `items.required` errors on otherwise-empty arrays.
|
|
11
|
+
*
|
|
12
|
+
* Why this exists:
|
|
13
|
+
* `initFormDataFromSchema` omits optional fields, so an optional array
|
|
14
|
+
* like `data_rates: { type: 'array', items: { $ref: '#/$defs/DataRate' } }`
|
|
15
|
+
* produces `undefined` (or, historically, `[]`). Both shapes pass schema
|
|
16
|
+
* validation: `undefined` doesn't trigger `type: array`, and `[]` has no
|
|
17
|
+
* items to apply `items.required` to. As a result, a projection-targeted
|
|
18
|
+
* field rendered with `Video CPM rate *` lies — the asterisk says
|
|
19
|
+
* "required" but the validator never enforces it on an untouched form.
|
|
20
|
+
*
|
|
21
|
+
* This utility opts the consumer into per-item enforcement by walking the
|
|
22
|
+
* UI schema, finding every `Control` with `options.projection` that
|
|
23
|
+
* addresses an array index, and ensuring the corresponding data path has
|
|
24
|
+
* that index materialized as at least `{}`. With the empty object in
|
|
25
|
+
* place, the schema's `items.required` fires and the projected control's
|
|
26
|
+
* error string surfaces at form-validity time.
|
|
27
|
+
*
|
|
28
|
+
* Tradeoff:
|
|
29
|
+
* This re-introduces "noise" on untouched forms — required-field errors
|
|
30
|
+
* for fields the user hasn't seen yet. Use it when validation enforcement
|
|
31
|
+
* on projection targets matters more than a clean initial form state.
|
|
32
|
+
* The alternative is to declare these arrays as `required` + `minItems: 1`
|
|
33
|
+
* + `default: [{}]` at the schema level, which avoids needing this helper.
|
|
34
|
+
*
|
|
35
|
+
* Properties:
|
|
36
|
+
* - Idempotent: running twice yields the same result as running once.
|
|
37
|
+
* - Non-destructive: existing values at target paths are preserved.
|
|
38
|
+
* - Pure: returns a new object; does not mutate `data`.
|
|
39
|
+
*
|
|
40
|
+
* Example:
|
|
41
|
+
* ```ts
|
|
42
|
+
* const data = initFormDataFromSchema(schema);
|
|
43
|
+
* const seeded = seedProjectionTargets(data, uischema);
|
|
44
|
+
* // For uischema controls like
|
|
45
|
+
* // { type: 'Control', scope: '#/properties/data_rates',
|
|
46
|
+
* // options: { projection: '0.video_rate_usd' } }
|
|
47
|
+
* // seeded.data_rates is now `[{}]` (was `undefined` or `[]`).
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function seedProjectionTargets(
|
|
51
|
+
data: unknown,
|
|
52
|
+
uischema: UISchemaLike | UISchemaLike[] | undefined,
|
|
53
|
+
): unknown {
|
|
54
|
+
if (!uischema) return data;
|
|
55
|
+
|
|
56
|
+
const controls: { scope: string; projection: string }[] = [];
|
|
57
|
+
collectProjectionControls(uischema, controls);
|
|
58
|
+
|
|
59
|
+
let result = data;
|
|
60
|
+
for (const { scope, projection } of controls) {
|
|
61
|
+
const dataPath = scopeToDataPath(scope);
|
|
62
|
+
const segments = parseProjectionPath(projection);
|
|
63
|
+
|
|
64
|
+
// Seed only when a numeric segment is followed by a *string* segment —
|
|
65
|
+
// i.e., the consumer is reading a property of the array item, so the
|
|
66
|
+
// item must be an object. Numeric-at-end (`'0'`) addresses the array
|
|
67
|
+
// element itself, which can be any type (primitive, nested array,
|
|
68
|
+
// object) — we can't infer it from the uischema alone, so leave it
|
|
69
|
+
// alone. Numeric-followed-by-numeric (`'0.0'`) is a nested array; we'd
|
|
70
|
+
// need to seed `[]`, but again the inner item type is unknown.
|
|
71
|
+
for (let i = 0; i < segments.length; i++) {
|
|
72
|
+
if (typeof segments[i] !== "number") continue;
|
|
73
|
+
if (i + 1 >= segments.length) continue;
|
|
74
|
+
if (typeof segments[i + 1] !== "string") continue;
|
|
75
|
+
|
|
76
|
+
const partial = segments
|
|
77
|
+
.slice(0, i + 1)
|
|
78
|
+
.map((s) => String(s))
|
|
79
|
+
.join(".");
|
|
80
|
+
const fullPath = dataPath ? `${dataPath}.${partial}` : partial;
|
|
81
|
+
|
|
82
|
+
if (getProjectedValue(result, fullPath) === undefined) {
|
|
83
|
+
result = setProjectedValue(result, fullPath, {});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Minimal UI schema shape this utility traverses. Compatible with
|
|
93
|
+
* `@jsonforms/core`'s `UISchemaElement` but kept local to avoid a runtime
|
|
94
|
+
* dep on `@jsonforms/core` (it's a peer dep — types only).
|
|
95
|
+
*/
|
|
96
|
+
export interface UISchemaLike {
|
|
97
|
+
type?: string;
|
|
98
|
+
scope?: string;
|
|
99
|
+
options?: { projection?: string; [key: string]: unknown };
|
|
100
|
+
elements?: UISchemaLike[];
|
|
101
|
+
[key: string]: unknown;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function collectProjectionControls(
|
|
105
|
+
ui: UISchemaLike | UISchemaLike[] | undefined,
|
|
106
|
+
out: { scope: string; projection: string }[],
|
|
107
|
+
): void {
|
|
108
|
+
if (!ui) return;
|
|
109
|
+
if (Array.isArray(ui)) {
|
|
110
|
+
for (const el of ui) collectProjectionControls(el, out);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (typeof ui !== "object") return;
|
|
114
|
+
|
|
115
|
+
const projection = ui.options?.projection;
|
|
116
|
+
if (
|
|
117
|
+
ui.type === "Control" &&
|
|
118
|
+
typeof ui.scope === "string" &&
|
|
119
|
+
typeof projection === "string"
|
|
120
|
+
) {
|
|
121
|
+
out.push({ scope: ui.scope, projection });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (Array.isArray(ui.elements)) {
|
|
125
|
+
for (const el of ui.elements) collectProjectionControls(el, out);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Convert a JsonForms scope pointer (`#/properties/foo/properties/bar`) to
|
|
131
|
+
* a dot-separated data path (`foo.bar`). Drops `items` segments — array
|
|
132
|
+
* indices are added at runtime via the projection path, not the scope.
|
|
133
|
+
*/
|
|
134
|
+
function scopeToDataPath(scope: string): string {
|
|
135
|
+
if (!scope.startsWith("#/")) return "";
|
|
136
|
+
const parts = scope.slice(2).split("/");
|
|
137
|
+
const out: string[] = [];
|
|
138
|
+
for (let i = 0; i < parts.length; i++) {
|
|
139
|
+
if (parts[i] === "properties" && i + 1 < parts.length) {
|
|
140
|
+
out.push(parts[++i]!);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return out.join(".");
|
|
144
|
+
}
|
package/src/core/transforms.ts
CHANGED
|
@@ -14,30 +14,38 @@ export interface FlattenTransform extends Transform {
|
|
|
14
14
|
labelFormat?: string; // Optional format string like "{parent.name} → {name}"
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export type FilterOperator =
|
|
18
|
+
| "eq"
|
|
19
|
+
| "neq"
|
|
20
|
+
| "empty"
|
|
21
|
+
| "notEmpty"
|
|
22
|
+
| "gt"
|
|
23
|
+
| "gte"
|
|
24
|
+
| "lt"
|
|
25
|
+
| "lte"
|
|
26
|
+
| "contains";
|
|
27
|
+
|
|
28
|
+
export interface FilterCondition {
|
|
29
|
+
key: string;
|
|
30
|
+
operator?: FilterOperator; // Defaults to "eq" when values is provided, "exists" behavior when neither
|
|
31
|
+
values?: unknown[];
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
export interface FilterTransform extends Transform {
|
|
18
35
|
name: "filter";
|
|
19
|
-
key
|
|
20
|
-
values?: unknown[]; //
|
|
36
|
+
key?: string; // Legacy: single key to check
|
|
37
|
+
values?: unknown[]; // Legacy: single values array
|
|
38
|
+
conditions?: FilterCondition[]; // Multi-condition filter (AND logic)
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
export type TransformStep = FlattenTransform | FilterTransform;
|
|
24
42
|
|
|
25
43
|
export type TransformPipeline = TransformStep[];
|
|
26
44
|
|
|
27
|
-
/**
|
|
28
|
-
* Registry of transform functions
|
|
29
|
-
*/
|
|
30
45
|
type TransformFunction = (items: unknown[], config: Transform) => unknown[];
|
|
31
46
|
|
|
32
47
|
const transformRegistry: Record<string, TransformFunction> = {};
|
|
33
48
|
|
|
34
|
-
/**
|
|
35
|
-
* Register a transform function
|
|
36
|
-
*/
|
|
37
|
-
export function registerTransform(name: string, fn: TransformFunction): void {
|
|
38
|
-
transformRegistry[name] = fn;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
49
|
/**
|
|
42
50
|
* Apply a pipeline of transforms to data
|
|
43
51
|
*/
|
|
@@ -124,29 +132,113 @@ function flattenTransform(items: unknown[], config: Transform): unknown[] {
|
|
|
124
132
|
return flattened;
|
|
125
133
|
}
|
|
126
134
|
|
|
135
|
+
function isEmpty(value: unknown): boolean {
|
|
136
|
+
if (value === null || value === undefined) return true;
|
|
137
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
138
|
+
if (typeof value === "string") return value.length === 0;
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function evaluateCondition(
|
|
143
|
+
itemObj: Record<string, unknown>,
|
|
144
|
+
condition: FilterCondition,
|
|
145
|
+
): boolean {
|
|
146
|
+
const value = itemObj[condition.key];
|
|
147
|
+
const operator = condition.operator ?? (condition.values ? "eq" : "eq");
|
|
148
|
+
|
|
149
|
+
switch (operator) {
|
|
150
|
+
case "eq":
|
|
151
|
+
if (!condition.values || condition.values.length === 0) {
|
|
152
|
+
return condition.key in itemObj;
|
|
153
|
+
}
|
|
154
|
+
return condition.values.includes(value);
|
|
155
|
+
case "neq":
|
|
156
|
+
if (!condition.values || condition.values.length === 0) {
|
|
157
|
+
return !(condition.key in itemObj);
|
|
158
|
+
}
|
|
159
|
+
return !condition.values.includes(value);
|
|
160
|
+
case "empty":
|
|
161
|
+
return isEmpty(value);
|
|
162
|
+
case "notEmpty":
|
|
163
|
+
return !isEmpty(value);
|
|
164
|
+
case "gt":
|
|
165
|
+
return (
|
|
166
|
+
typeof value === "number" &&
|
|
167
|
+
condition.values !== undefined &&
|
|
168
|
+
value > (condition.values[0] as number)
|
|
169
|
+
);
|
|
170
|
+
case "gte":
|
|
171
|
+
return (
|
|
172
|
+
typeof value === "number" &&
|
|
173
|
+
condition.values !== undefined &&
|
|
174
|
+
value >= (condition.values[0] as number)
|
|
175
|
+
);
|
|
176
|
+
case "lt":
|
|
177
|
+
return (
|
|
178
|
+
typeof value === "number" &&
|
|
179
|
+
condition.values !== undefined &&
|
|
180
|
+
value < (condition.values[0] as number)
|
|
181
|
+
);
|
|
182
|
+
case "lte":
|
|
183
|
+
return (
|
|
184
|
+
typeof value === "number" &&
|
|
185
|
+
condition.values !== undefined &&
|
|
186
|
+
value <= (condition.values[0] as number)
|
|
187
|
+
);
|
|
188
|
+
case "contains":
|
|
189
|
+
if (typeof value === "string" && condition.values) {
|
|
190
|
+
return condition.values.some((v) => value.includes(String(v)));
|
|
191
|
+
}
|
|
192
|
+
if (Array.isArray(value) && condition.values) {
|
|
193
|
+
return condition.values.some((v) => value.includes(v));
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
default:
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
127
201
|
/**
|
|
128
|
-
* Filter transform - filters items based on
|
|
202
|
+
* Filter transform - filters items based on conditions
|
|
203
|
+
*
|
|
204
|
+
* Supports legacy single key/values syntax and new multi-condition syntax.
|
|
205
|
+
* When using conditions, all conditions must match (AND logic).
|
|
206
|
+
*
|
|
207
|
+
* Operators:
|
|
208
|
+
* eq - item[key] matches one of values (default)
|
|
209
|
+
* neq - item[key] does NOT match any of values
|
|
210
|
+
* empty - item[key] is null, undefined, empty array, or empty string
|
|
211
|
+
* notEmpty - inverse of empty
|
|
212
|
+
* gt - item[key] > values[0]
|
|
213
|
+
* gte - item[key] >= values[0]
|
|
214
|
+
* lt - item[key] < values[0]
|
|
215
|
+
* lte - item[key] <= values[0]
|
|
216
|
+
* contains - string includes substring, or array includes value
|
|
129
217
|
*/
|
|
130
218
|
function filterTransform(items: unknown[], config: Transform): unknown[] {
|
|
131
219
|
const filterConfig = config as FilterTransform;
|
|
132
|
-
|
|
220
|
+
|
|
221
|
+
// Build conditions array from either new or legacy syntax
|
|
222
|
+
let conditions: FilterCondition[];
|
|
223
|
+
|
|
224
|
+
if (filterConfig.conditions) {
|
|
225
|
+
conditions = filterConfig.conditions;
|
|
226
|
+
} else if (filterConfig.key) {
|
|
227
|
+
// Legacy single key/values syntax
|
|
228
|
+
conditions = [{ key: filterConfig.key, values: filterConfig.values }];
|
|
229
|
+
} else {
|
|
230
|
+
return items;
|
|
231
|
+
}
|
|
133
232
|
|
|
134
233
|
return items.filter((item) => {
|
|
135
234
|
if (typeof item !== "object" || item === null) return false;
|
|
136
|
-
|
|
137
235
|
const itemObj = item as Record<string, unknown>;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return key in itemObj;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// If values array provided, check if item[key] matches any of the values
|
|
145
|
-
const itemValue = itemObj[key];
|
|
146
|
-
return values.includes(itemValue);
|
|
236
|
+
return conditions.every((condition) =>
|
|
237
|
+
evaluateCondition(itemObj, condition),
|
|
238
|
+
);
|
|
147
239
|
});
|
|
148
240
|
}
|
|
149
241
|
|
|
150
242
|
// Register built-in transforms
|
|
151
|
-
|
|
152
|
-
|
|
243
|
+
transformRegistry["flatten"] = flattenTransform;
|
|
244
|
+
transformRegistry["filter"] = filterTransform;
|
package/src/core/types.ts
CHANGED
|
@@ -44,3 +44,12 @@ export interface AuthConfig {
|
|
|
44
44
|
token?: string | (() => string); // Generic token auth
|
|
45
45
|
[key: string]: unknown; // Custom auth fields
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
export interface ConnectorDataLayer {
|
|
49
|
+
dataset_name?: string;
|
|
50
|
+
dataset_description?: string;
|
|
51
|
+
dataset_id?: number;
|
|
52
|
+
profile_id?: string;
|
|
53
|
+
profile_name?: string;
|
|
54
|
+
datasetWriteMode?: "append" | "overwrite";
|
|
55
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,19 +3,35 @@ import { cache as globalCache } from "./core/cache";
|
|
|
3
3
|
import { registry as globalRegistry } from "./core/registry";
|
|
4
4
|
import type { Protocol, AuthConfig } from "./core/types";
|
|
5
5
|
|
|
6
|
-
console.log("[jsonforms-provider-protocols] loaded v2.10.0");
|
|
7
|
-
|
|
8
6
|
export { cache } from "./core/cache";
|
|
9
7
|
export * from "./core/jsonpath";
|
|
10
8
|
export { registry } from "./core/registry";
|
|
11
9
|
export * from "./core/templating";
|
|
12
10
|
export * from "./core/transforms";
|
|
11
|
+
export * from "./core/projection";
|
|
12
|
+
export * from "./core/resolveScope";
|
|
13
13
|
// Core exports
|
|
14
14
|
export * from "./core/types";
|
|
15
|
+
export { initFormDataFromSchema } from "./core/initFormData";
|
|
16
|
+
export { seedProjectionTargets } from "./core/seedProjectionTargets";
|
|
17
|
+
export type { UISchemaLike } from "./core/seedProjectionTargets";
|
|
15
18
|
|
|
16
19
|
// Protocol exports
|
|
17
20
|
export { RestApiProtocol } from "./protocols/rest_api";
|
|
18
21
|
|
|
22
|
+
// CSP-safe validator
|
|
23
|
+
export {
|
|
24
|
+
createNoEvalAjv,
|
|
25
|
+
transformUnit,
|
|
26
|
+
transformErrors,
|
|
27
|
+
} from "./no-eval-ajv";
|
|
28
|
+
export type {
|
|
29
|
+
NoEvalAjv,
|
|
30
|
+
NoEvalErrorObject,
|
|
31
|
+
NoEvalValidateFunction,
|
|
32
|
+
CreateNoEvalAjvOptions,
|
|
33
|
+
} from "./no-eval-ajv";
|
|
34
|
+
|
|
19
35
|
// Vue exports - using named imports to avoid potential bundling issues
|
|
20
36
|
export {
|
|
21
37
|
providerRenderers,
|
|
@@ -23,7 +39,10 @@ export {
|
|
|
23
39
|
ProviderAutocomplete,
|
|
24
40
|
ProviderSelect,
|
|
25
41
|
ProviderMultiSelect,
|
|
42
|
+
ProviderObjectMultiSelect,
|
|
26
43
|
useProvider,
|
|
44
|
+
createDataLayer,
|
|
45
|
+
useDataLayer,
|
|
27
46
|
JfText,
|
|
28
47
|
JfTextArea,
|
|
29
48
|
JfNumber,
|
|
@@ -31,6 +50,7 @@ export {
|
|
|
31
50
|
JfEnumArray,
|
|
32
51
|
JfBoolean,
|
|
33
52
|
} from "./vue";
|
|
53
|
+
export type { DataLayer } from "./vue";
|
|
34
54
|
|
|
35
55
|
export interface ProviderConfig {
|
|
36
56
|
protocols?: Protocol[];
|