@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.
Files changed (147) hide show
  1. package/README.md +193 -33
  2. package/dist/core/initFormData.d.ts +17 -0
  3. package/dist/core/initFormData.d.ts.map +1 -0
  4. package/dist/core/initFormData.js +99 -0
  5. package/dist/core/initFormData.js.map +1 -0
  6. package/dist/core/projection.d.ts +36 -0
  7. package/dist/core/projection.d.ts.map +1 -0
  8. package/dist/core/projection.js +77 -0
  9. package/dist/core/projection.js.map +1 -0
  10. package/dist/core/refs.d.ts +58 -0
  11. package/dist/core/refs.d.ts.map +1 -0
  12. package/dist/core/refs.js +70 -0
  13. package/dist/core/refs.js.map +1 -0
  14. package/dist/core/resolveScope.d.ts +17 -0
  15. package/dist/core/resolveScope.d.ts.map +1 -0
  16. package/dist/core/resolveScope.js +28 -0
  17. package/dist/core/resolveScope.js.map +1 -0
  18. package/dist/core/seedProjectionTargets.d.ts +60 -0
  19. package/dist/core/seedProjectionTargets.d.ts.map +1 -0
  20. package/dist/core/seedProjectionTargets.js +52 -0
  21. package/dist/core/seedProjectionTargets.js.map +1 -0
  22. package/dist/core/transforms.d.ts +8 -10
  23. package/dist/core/transforms.d.ts.map +1 -1
  24. package/dist/core/transforms.js +58 -13
  25. package/dist/core/transforms.js.map +1 -1
  26. package/dist/core/types.d.ts +8 -0
  27. package/dist/core/types.d.ts.map +1 -1
  28. package/dist/index.d.ts +9 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +21 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/jsonforms-provider-protocols.css +6 -2
  33. package/dist/no-eval-ajv.d.ts +70 -0
  34. package/dist/no-eval-ajv.d.ts.map +1 -0
  35. package/dist/no-eval-ajv.js +247 -0
  36. package/dist/no-eval-ajv.js.map +1 -0
  37. package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
  38. package/dist/vue/components/ProviderAutocomplete.vue.js +12 -6
  39. package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
  40. package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
  41. package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
  42. package/dist/vue/components/ProviderMultiSelect.vue2.js +21 -11
  43. package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
  44. package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts +9 -0
  45. package/dist/vue/components/ProviderObjectMultiSelect.vue.d.ts.map +1 -0
  46. package/dist/vue/components/ProviderObjectMultiSelect.vue.js +8 -0
  47. package/dist/vue/components/ProviderObjectMultiSelect.vue.js.map +1 -0
  48. package/dist/vue/components/ProviderObjectMultiSelect.vue2.js +142 -0
  49. package/dist/vue/components/ProviderObjectMultiSelect.vue2.js.map +1 -0
  50. package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
  51. package/dist/vue/components/ProviderSelect.vue.js +1 -1
  52. package/dist/vue/components/ProviderSelect.vue2.js +22 -10
  53. package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
  54. package/dist/vue/composables/useDataLayer.d.ts +10 -0
  55. package/dist/vue/composables/useDataLayer.d.ts.map +1 -0
  56. package/dist/vue/composables/useDataLayer.js +26 -0
  57. package/dist/vue/composables/useDataLayer.js.map +1 -0
  58. package/dist/vue/composables/useDerive.d.ts +5 -2
  59. package/dist/vue/composables/useDerive.d.ts.map +1 -1
  60. package/dist/vue/composables/useDerive.js +29 -12
  61. package/dist/vue/composables/useDerive.js.map +1 -1
  62. package/dist/vue/composables/useDeriveInitialValue.d.ts +36 -0
  63. package/dist/vue/composables/useDeriveInitialValue.d.ts.map +1 -0
  64. package/dist/vue/composables/useDeriveInitialValue.js +125 -0
  65. package/dist/vue/composables/useDeriveInitialValue.js.map +1 -0
  66. package/dist/vue/composables/useDirtyValidation.d.ts +9 -0
  67. package/dist/vue/composables/useDirtyValidation.d.ts.map +1 -0
  68. package/dist/vue/composables/useDirtyValidation.js +15 -0
  69. package/dist/vue/composables/useDirtyValidation.js.map +1 -0
  70. package/dist/vue/composables/useProjection.d.ts +42 -0
  71. package/dist/vue/composables/useProjection.d.ts.map +1 -0
  72. package/dist/vue/composables/useProjection.js +116 -0
  73. package/dist/vue/composables/useProjection.js.map +1 -0
  74. package/dist/vue/composables/useProvider.d.ts +2 -2
  75. package/dist/vue/composables/useProvider.d.ts.map +1 -1
  76. package/dist/vue/composables/useProvider.js +14 -10
  77. package/dist/vue/composables/useProvider.js.map +1 -1
  78. package/dist/vue/index.d.ts +9 -1
  79. package/dist/vue/index.d.ts.map +1 -1
  80. package/dist/vue/index.js +72 -34
  81. package/dist/vue/index.js.map +1 -1
  82. package/dist/vue/primevue/JfBoolean.vue.d.ts +9 -0
  83. package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
  84. package/dist/vue/primevue/JfBoolean.vue.js +44 -17
  85. package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
  86. package/dist/vue/primevue/JfEnum.vue.d.ts +9 -0
  87. package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
  88. package/dist/vue/primevue/JfEnum.vue.js +38 -24
  89. package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
  90. package/dist/vue/primevue/JfEnumArray.vue.d.ts +9 -0
  91. package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
  92. package/dist/vue/primevue/JfEnumArray.vue.js +40 -20
  93. package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
  94. package/dist/vue/primevue/JfNumber.vue.d.ts +9 -0
  95. package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
  96. package/dist/vue/primevue/JfNumber.vue.js +33 -23
  97. package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
  98. package/dist/vue/primevue/JfText.vue.d.ts +9 -0
  99. package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
  100. package/dist/vue/primevue/JfText.vue.js +51 -35
  101. package/dist/vue/primevue/JfText.vue.js.map +1 -1
  102. package/dist/vue/primevue/JfTextArea.vue.d.ts +9 -0
  103. package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
  104. package/dist/vue/primevue/JfTextArea.vue.js +34 -19
  105. package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
  106. package/dist/vue/primevue/index.d.ts.map +1 -1
  107. package/dist/vue/primevue/index.js +100 -8
  108. package/dist/vue/primevue/index.js.map +1 -1
  109. package/dist/vue/utils/objectMultiSelect.d.ts +68 -0
  110. package/dist/vue/utils/objectMultiSelect.d.ts.map +1 -0
  111. package/dist/vue/utils/objectMultiSelect.js +72 -0
  112. package/dist/vue/utils/objectMultiSelect.js.map +1 -0
  113. package/dist/vue/utils/placeholder.d.ts +17 -0
  114. package/dist/vue/utils/placeholder.d.ts.map +1 -0
  115. package/dist/vue/utils/placeholder.js +17 -0
  116. package/dist/vue/utils/placeholder.js.map +1 -0
  117. package/package.json +10 -2
  118. package/src/core/initFormData.ts +208 -0
  119. package/src/core/projection.ts +147 -0
  120. package/src/core/refs.ts +166 -0
  121. package/src/core/resolveScope.ts +54 -0
  122. package/src/core/seedProjectionTargets.ts +144 -0
  123. package/src/core/transforms.ts +118 -26
  124. package/src/core/types.ts +9 -0
  125. package/src/index.ts +22 -2
  126. package/src/no-eval-ajv.ts +381 -0
  127. package/src/vue/components/ProviderAutocomplete.vue +11 -7
  128. package/src/vue/components/ProviderMultiSelect.vue +22 -15
  129. package/src/vue/components/ProviderObjectMultiSelect.vue +169 -0
  130. package/src/vue/components/ProviderSelect.vue +23 -14
  131. package/src/vue/composables/useDataLayer.ts +43 -0
  132. package/src/vue/composables/useDerive.ts +62 -16
  133. package/src/vue/composables/useDeriveInitialValue.ts +195 -0
  134. package/src/vue/composables/useDirtyValidation.ts +20 -0
  135. package/src/vue/composables/useProjection.ts +245 -0
  136. package/src/vue/composables/useProvider.ts +28 -11
  137. package/src/vue/index.ts +83 -47
  138. package/src/vue/primevue/JfBoolean.vue +35 -12
  139. package/src/vue/primevue/JfEnum.vue +35 -26
  140. package/src/vue/primevue/JfEnumArray.vue +37 -20
  141. package/src/vue/primevue/JfNumber.vue +32 -24
  142. package/src/vue/primevue/JfText.vue +48 -33
  143. package/src/vue/primevue/JfTextArea.vue +32 -21
  144. package/src/vue/primevue/index.ts +114 -8
  145. package/src/vue/styles.css +26 -1
  146. package/src/vue/utils/objectMultiSelect.ts +171 -0
  147. package/src/vue/utils/placeholder.ts +42 -0
@@ -0,0 +1,70 @@
1
+ import { type OutputUnit, type SchemaDraft } from "@cfworker/json-schema";
2
+ /**
3
+ * CSP-safe JSON Schema validation backed by `@cfworker/json-schema`.
4
+ *
5
+ * Cloudflare Pages and similar strict-CSP environments forbid `new Function`,
6
+ * which is how AJV compiles validators. This factory returns an
7
+ * AJV-shaped facade whose `compile()` produces a synchronous validator
8
+ * function `(data) => boolean` with a mutable `errors` property — enough
9
+ * for `<JsonForms :ajv="..." />` to drop in without any other changes.
10
+ *
11
+ * Only `compile()` is functional; the rest of the surface (`addSchema`,
12
+ * `getSchema`, `removeSchema`, `addFormat`, `addKeyword`, `opts`) exists
13
+ * as no-ops for forward compatibility with plugins that probe the AJV
14
+ * interface but never reach those methods at runtime.
15
+ */
16
+ export interface NoEvalErrorObject {
17
+ instancePath: string;
18
+ schemaPath: string;
19
+ keyword: string;
20
+ params: Record<string, unknown>;
21
+ message?: string;
22
+ }
23
+ export interface NoEvalValidateFunction {
24
+ (data: unknown): boolean;
25
+ errors: NoEvalErrorObject[] | null;
26
+ }
27
+ export interface NoEvalAjv {
28
+ compile: (schema: unknown) => NoEvalValidateFunction;
29
+ addSchema: (schema: unknown, key?: string) => NoEvalAjv;
30
+ getSchema: (key: string) => NoEvalValidateFunction | undefined;
31
+ removeSchema: (schemaKeyRef?: unknown) => NoEvalAjv;
32
+ addFormat: (name: string, format: unknown) => NoEvalAjv;
33
+ addKeyword: (definition: unknown) => NoEvalAjv;
34
+ opts: Readonly<Record<string, unknown>>;
35
+ }
36
+ export interface CreateNoEvalAjvOptions {
37
+ /**
38
+ * JSON Schema draft to validate against. Defaults to `'2020-12'` to match
39
+ * the spec; schemas authored against draft-07 should pass `'7'`.
40
+ */
41
+ draft?: SchemaDraft;
42
+ }
43
+ /**
44
+ * Transform a single cfworker `OutputUnit` into an AJV-compatible
45
+ * `ErrorObject`, or `null` if the unit is a structural wrapper that should
46
+ * be filtered out (`properties` / `items` / `prefixItems` / `$ref`).
47
+ *
48
+ * Exported for unit testing.
49
+ */
50
+ export declare function transformUnit(unit: OutputUnit): NoEvalErrorObject | null;
51
+ /**
52
+ * Transform a cfworker `OutputUnit[]` into an AJV-compatible
53
+ * `ErrorObject[]`, with structural wrappers filtered out.
54
+ *
55
+ * Exported for unit testing.
56
+ */
57
+ export declare function transformErrors(units: OutputUnit[]): NoEvalErrorObject[];
58
+ /**
59
+ * Build a CSP-safe AJV-shaped validator backed by `@cfworker/json-schema`.
60
+ *
61
+ * Each `compile(schema)` call constructs a `Validator` and returns a
62
+ * synchronous validator function. The validator function's `errors`
63
+ * property is reassigned on every call, matching AJV's contract.
64
+ *
65
+ * Validators are memoized per-schema via a `WeakMap`, so JsonForms's
66
+ * repeated `compile()` calls on prop changes don't re-parse the schema
67
+ * graph each time.
68
+ */
69
+ export declare function createNoEvalAjv(options?: CreateNoEvalAjvOptions): NoEvalAjv;
70
+ //# sourceMappingURL=no-eval-ajv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-eval-ajv.d.ts","sourceRoot":"","sources":["../src/no-eval-ajv.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EAEf,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;CACpC;AAKD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,sBAAsB,CAAC;IACrD,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC;IACxD,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,sBAAsB,GAAG,SAAS,CAAC;IAC/D,YAAY,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC;IACpD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACxD,UAAU,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,SAAS,CAAC;IAC/C,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAsOD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,GAAG,IAAI,CAYxE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE,CAOxE;AASD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,SAAS,CAqCX"}
@@ -0,0 +1,247 @@
1
+ import { Validator } from "@cfworker/json-schema";
2
+ const KEYWORD_WRAPPERS = /* @__PURE__ */ new Set([
3
+ "properties",
4
+ "items",
5
+ "prefixItems",
6
+ "$ref"
7
+ ]);
8
+ const QUOTED_RE = /(['"])((?:\\.|(?!\1).)*?)\1/g;
9
+ function findQuoted(s) {
10
+ const out = [];
11
+ let m;
12
+ QUOTED_RE.lastIndex = 0;
13
+ while ((m = QUOTED_RE.exec(s)) !== null) {
14
+ out.push(m[2]);
15
+ }
16
+ return out;
17
+ }
18
+ function firstQuoted(s) {
19
+ const all = findQuoted(s);
20
+ return all[0];
21
+ }
22
+ function allQuoted(s) {
23
+ return findQuoted(s);
24
+ }
25
+ const NUMBER_RE = /-?\d+(?:\.\d+)?/g;
26
+ function extractNumbers(s) {
27
+ const out = [];
28
+ let m;
29
+ NUMBER_RE.lastIndex = 0;
30
+ while ((m = NUMBER_RE.exec(s)) !== null) {
31
+ out.push(Number(m[0]));
32
+ }
33
+ return out;
34
+ }
35
+ function firstNumber(s) {
36
+ const nums = extractNumbers(s);
37
+ return nums[0];
38
+ }
39
+ function stripPointerPrefix(p) {
40
+ return p.startsWith("#") ? p.slice(1) : p;
41
+ }
42
+ function transformByKeyword(unit) {
43
+ const { keyword, error } = unit;
44
+ switch (keyword) {
45
+ case "required": {
46
+ const prop = firstQuoted(error);
47
+ return {
48
+ params: { missingProperty: prop ?? "" },
49
+ message: prop ? `must have required property '${prop}'` : "must have required property"
50
+ };
51
+ }
52
+ case "type": {
53
+ const quoted = allQuoted(error);
54
+ const expected = quoted.slice(1).join(",") || quoted[0];
55
+ const message = expected ? `must be ${expected}` : "must be of expected type";
56
+ return {
57
+ params: expected ? { type: expected } : {},
58
+ message
59
+ };
60
+ }
61
+ case "enum": {
62
+ const match = error.match(/\[.*\]/);
63
+ let allowedValues = [];
64
+ if (match) {
65
+ try {
66
+ allowedValues = JSON.parse(match[0]);
67
+ } catch {
68
+ allowedValues = [];
69
+ }
70
+ }
71
+ return {
72
+ params: { allowedValues },
73
+ message: "must be equal to one of the allowed values"
74
+ };
75
+ }
76
+ case "const":
77
+ return {
78
+ params: {},
79
+ message: "must be equal to constant"
80
+ };
81
+ case "minimum": {
82
+ const limit = extractNumbers(error)[1];
83
+ return {
84
+ params: { comparison: ">=", limit: limit ?? 0 },
85
+ message: `must be >= ${limit ?? 0}`
86
+ };
87
+ }
88
+ case "exclusiveMinimum": {
89
+ const limit = extractNumbers(error)[1];
90
+ return {
91
+ params: { comparison: ">", limit: limit ?? 0 },
92
+ message: `must be > ${limit ?? 0}`
93
+ };
94
+ }
95
+ case "maximum": {
96
+ const limit = extractNumbers(error)[1];
97
+ return {
98
+ params: { comparison: "<=", limit: limit ?? 0 },
99
+ message: `must be <= ${limit ?? 0}`
100
+ };
101
+ }
102
+ case "exclusiveMaximum": {
103
+ const limit = extractNumbers(error)[1];
104
+ return {
105
+ params: { comparison: "<", limit: limit ?? 0 },
106
+ message: `must be < ${limit ?? 0}`
107
+ };
108
+ }
109
+ case "minLength": {
110
+ const limit = firstNumber(error) ?? 0;
111
+ return {
112
+ params: { limit },
113
+ message: `must NOT have fewer than ${limit} characters`
114
+ };
115
+ }
116
+ case "maxLength": {
117
+ const limit = firstNumber(error) ?? 0;
118
+ return {
119
+ params: { limit },
120
+ message: `must NOT have more than ${limit} characters`
121
+ };
122
+ }
123
+ case "minItems": {
124
+ const limit = firstNumber(error) ?? 0;
125
+ return {
126
+ params: { limit },
127
+ message: `must NOT have fewer than ${limit} items`
128
+ };
129
+ }
130
+ case "maxItems": {
131
+ const limit = firstNumber(error) ?? 0;
132
+ return {
133
+ params: { limit },
134
+ message: `must NOT have more than ${limit} items`
135
+ };
136
+ }
137
+ case "pattern": {
138
+ const pattern = firstQuoted(error) ?? "";
139
+ return {
140
+ params: { pattern },
141
+ message: `must match pattern "${pattern}"`
142
+ };
143
+ }
144
+ case "format": {
145
+ const format = firstQuoted(error) ?? "";
146
+ return {
147
+ params: { format },
148
+ message: `must match format "${format}"`
149
+ };
150
+ }
151
+ case "multipleOf": {
152
+ const nums = extractNumbers(error);
153
+ const multipleOf = nums[1] ?? nums[0] ?? 1;
154
+ return {
155
+ params: { multipleOf },
156
+ message: `must be multiple of ${multipleOf}`
157
+ };
158
+ }
159
+ case "uniqueItems":
160
+ return {
161
+ params: {},
162
+ message: "must NOT have duplicate items"
163
+ };
164
+ case "additionalProperties": {
165
+ const additionalProperty = firstQuoted(error) ?? "";
166
+ return {
167
+ params: { additionalProperty },
168
+ message: `must NOT have additional property '${additionalProperty}'`
169
+ };
170
+ }
171
+ case "anyOf":
172
+ return { params: {}, message: "must match a schema in anyOf" };
173
+ case "oneOf":
174
+ return {
175
+ params: { passingSchemas: null },
176
+ message: "must match exactly one schema in oneOf"
177
+ };
178
+ case "allOf":
179
+ return { params: {}, message: "must match all schemas in allOf" };
180
+ case "not":
181
+ return { params: {}, message: "must NOT be valid against schema" };
182
+ default:
183
+ return { params: {}, message: void 0 };
184
+ }
185
+ }
186
+ function transformUnit(unit) {
187
+ if (KEYWORD_WRAPPERS.has(unit.keyword)) return null;
188
+ const { params, message } = transformByKeyword(unit);
189
+ return {
190
+ instancePath: stripPointerPrefix(unit.instanceLocation),
191
+ schemaPath: unit.keywordLocation,
192
+ keyword: unit.keyword,
193
+ params,
194
+ message: message ?? unit.error
195
+ };
196
+ }
197
+ function transformErrors(units) {
198
+ const out = [];
199
+ for (const unit of units) {
200
+ const transformed = transformUnit(unit);
201
+ if (transformed !== null) out.push(transformed);
202
+ }
203
+ return out;
204
+ }
205
+ const FROZEN_OPTS = Object.freeze({
206
+ allErrors: true,
207
+ verbose: true,
208
+ errorDataPath: "",
209
+ strict: false
210
+ });
211
+ function createNoEvalAjv(options = {}) {
212
+ const draft = options.draft ?? "2020-12";
213
+ const cache = /* @__PURE__ */ new WeakMap();
214
+ const compile = (schema) => {
215
+ if (schema && typeof schema === "object") {
216
+ const cached = cache.get(schema);
217
+ if (cached) return cached;
218
+ }
219
+ const validator = new Validator(schema, draft, false);
220
+ const fn = ((data) => {
221
+ const result = validator.validate(data);
222
+ fn.errors = result.valid ? null : transformErrors(result.errors);
223
+ return result.valid;
224
+ });
225
+ fn.errors = null;
226
+ if (schema && typeof schema === "object") {
227
+ cache.set(schema, fn);
228
+ }
229
+ return fn;
230
+ };
231
+ const facade = {
232
+ compile,
233
+ addSchema: () => facade,
234
+ getSchema: () => void 0,
235
+ removeSchema: () => facade,
236
+ addFormat: () => facade,
237
+ addKeyword: () => facade,
238
+ opts: FROZEN_OPTS
239
+ };
240
+ return facade;
241
+ }
242
+ export {
243
+ createNoEvalAjv,
244
+ transformErrors,
245
+ transformUnit
246
+ };
247
+ //# sourceMappingURL=no-eval-ajv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-eval-ajv.js","sources":["../src/no-eval-ajv.ts"],"sourcesContent":["import {\n Validator,\n type OutputUnit,\n type Schema,\n type SchemaDraft,\n} from \"@cfworker/json-schema\";\n\n/**\n * CSP-safe JSON Schema validation backed by `@cfworker/json-schema`.\n *\n * Cloudflare Pages and similar strict-CSP environments forbid `new Function`,\n * which is how AJV compiles validators. This factory returns an\n * AJV-shaped facade whose `compile()` produces a synchronous validator\n * function `(data) => boolean` with a mutable `errors` property — enough\n * for `<JsonForms :ajv=\"...\" />` to drop in without any other changes.\n *\n * Only `compile()` is functional; the rest of the surface (`addSchema`,\n * `getSchema`, `removeSchema`, `addFormat`, `addKeyword`, `opts`) exists\n * as no-ops for forward compatibility with plugins that probe the AJV\n * interface but never reach those methods at runtime.\n */\n\n// AJV's ErrorObject shape. We don't import `ajv` here to keep the lib's\n// zero-runtime-deps philosophy intact; the consumer's transitive AJV types\n// are structurally compatible.\nexport interface NoEvalErrorObject {\n instancePath: string;\n schemaPath: string;\n keyword: string;\n params: Record<string, unknown>;\n message?: string;\n}\n\nexport interface NoEvalValidateFunction {\n (data: unknown): boolean;\n errors: NoEvalErrorObject[] | null;\n}\n\n// Minimal subset of AJV's surface that JsonForms touches. The factory\n// returns this as `unknown as Ajv` at the call site; consumers cast on\n// import or pass directly to `<JsonForms :ajv=\"...\" />`.\nexport interface NoEvalAjv {\n compile: (schema: unknown) => NoEvalValidateFunction;\n addSchema: (schema: unknown, key?: string) => NoEvalAjv;\n getSchema: (key: string) => NoEvalValidateFunction | undefined;\n removeSchema: (schemaKeyRef?: unknown) => NoEvalAjv;\n addFormat: (name: string, format: unknown) => NoEvalAjv;\n addKeyword: (definition: unknown) => NoEvalAjv;\n opts: Readonly<Record<string, unknown>>;\n}\n\nexport interface CreateNoEvalAjvOptions {\n /**\n * JSON Schema draft to validate against. Defaults to `'2020-12'` to match\n * the spec; schemas authored against draft-07 should pass `'7'`.\n */\n draft?: SchemaDraft;\n}\n\nconst KEYWORD_WRAPPERS = new Set([\n \"properties\",\n \"items\",\n \"prefixItems\",\n \"$ref\",\n]);\n\nconst QUOTED_RE = /(['\"])((?:\\\\.|(?!\\1).)*?)\\1/g;\n\nfunction findQuoted(s: string): string[] {\n const out: string[] = [];\n let m: RegExpExecArray | null;\n QUOTED_RE.lastIndex = 0;\n while ((m = QUOTED_RE.exec(s)) !== null) {\n out.push(m[2]!);\n }\n return out;\n}\n\nfunction firstQuoted(s: string): string | undefined {\n const all = findQuoted(s);\n return all[0];\n}\n\nfunction allQuoted(s: string): string[] {\n return findQuoted(s);\n}\n\nconst NUMBER_RE = /-?\\d+(?:\\.\\d+)?/g;\n\nfunction extractNumbers(s: string): number[] {\n const out: number[] = [];\n let m: RegExpExecArray | null;\n NUMBER_RE.lastIndex = 0;\n while ((m = NUMBER_RE.exec(s)) !== null) {\n out.push(Number(m[0]));\n }\n return out;\n}\n\nfunction firstNumber(s: string): number | undefined {\n const nums = extractNumbers(s);\n return nums[0];\n}\n\nfunction stripPointerPrefix(p: string): string {\n return p.startsWith(\"#\") ? p.slice(1) : p;\n}\n\ninterface KeywordTransform {\n params: Record<string, unknown>;\n message: string | undefined;\n}\n\nfunction transformByKeyword(unit: OutputUnit): KeywordTransform {\n const { keyword, error } = unit;\n\n switch (keyword) {\n case \"required\": {\n const prop = firstQuoted(error);\n return {\n params: { missingProperty: prop ?? \"\" },\n message: prop\n ? `must have required property '${prop}'`\n : \"must have required property\",\n };\n }\n\n case \"type\": {\n const quoted = allQuoted(error);\n // cfworker emits `Instance type \"X\" is invalid. Expected \"Y\".` (single)\n // or `... Expected \"Y\" or \"Z\".` (union). Per AJV: `params.type` is the\n // expected type as a string; for unions it's comma-separated.\n const expected = quoted.slice(1).join(\",\") || quoted[0];\n const message = expected ? `must be ${expected}` : \"must be of expected type\";\n return {\n params: expected ? { type: expected } : {},\n message,\n };\n }\n\n case \"enum\": {\n // cfworker error: `Instance does not match any of [...].`\n const match = error.match(/\\[.*\\]/);\n let allowedValues: unknown[] = [];\n if (match) {\n try {\n allowedValues = JSON.parse(match[0]);\n } catch {\n allowedValues = [];\n }\n }\n return {\n params: { allowedValues },\n message: \"must be equal to one of the allowed values\",\n };\n }\n\n case \"const\":\n return {\n params: {},\n message: \"must be equal to constant\",\n };\n\n case \"minimum\": {\n const limit = extractNumbers(error)[1];\n return {\n params: { comparison: \">=\", limit: limit ?? 0 },\n message: `must be >= ${limit ?? 0}`,\n };\n }\n\n case \"exclusiveMinimum\": {\n const limit = extractNumbers(error)[1];\n return {\n params: { comparison: \">\", limit: limit ?? 0 },\n message: `must be > ${limit ?? 0}`,\n };\n }\n\n case \"maximum\": {\n const limit = extractNumbers(error)[1];\n return {\n params: { comparison: \"<=\", limit: limit ?? 0 },\n message: `must be <= ${limit ?? 0}`,\n };\n }\n\n case \"exclusiveMaximum\": {\n const limit = extractNumbers(error)[1];\n return {\n params: { comparison: \"<\", limit: limit ?? 0 },\n message: `must be < ${limit ?? 0}`,\n };\n }\n\n case \"minLength\": {\n const limit = firstNumber(error) ?? 0;\n return {\n params: { limit },\n message: `must NOT have fewer than ${limit} characters`,\n };\n }\n\n case \"maxLength\": {\n const limit = firstNumber(error) ?? 0;\n return {\n params: { limit },\n message: `must NOT have more than ${limit} characters`,\n };\n }\n\n case \"minItems\": {\n const limit = firstNumber(error) ?? 0;\n return {\n params: { limit },\n message: `must NOT have fewer than ${limit} items`,\n };\n }\n\n case \"maxItems\": {\n const limit = firstNumber(error) ?? 0;\n return {\n params: { limit },\n message: `must NOT have more than ${limit} items`,\n };\n }\n\n case \"pattern\": {\n const pattern = firstQuoted(error) ?? \"\";\n return {\n params: { pattern },\n message: `must match pattern \"${pattern}\"`,\n };\n }\n\n case \"format\": {\n const format = firstQuoted(error) ?? \"\";\n return {\n params: { format },\n message: `must match format \"${format}\"`,\n };\n }\n\n case \"multipleOf\": {\n // cfworker emits two numbers: the value and the divisor.\n const nums = extractNumbers(error);\n const multipleOf = nums[1] ?? nums[0] ?? 1;\n return {\n params: { multipleOf },\n message: `must be multiple of ${multipleOf}`,\n };\n }\n\n case \"uniqueItems\":\n return {\n params: {},\n message: \"must NOT have duplicate items\",\n };\n\n case \"additionalProperties\": {\n const additionalProperty = firstQuoted(error) ?? \"\";\n return {\n params: { additionalProperty },\n message: `must NOT have additional property '${additionalProperty}'`,\n };\n }\n\n case \"anyOf\":\n return { params: {}, message: \"must match a schema in anyOf\" };\n\n case \"oneOf\":\n return {\n params: { passingSchemas: null },\n message: \"must match exactly one schema in oneOf\",\n };\n\n case \"allOf\":\n return { params: {}, message: \"must match all schemas in allOf\" };\n\n case \"not\":\n return { params: {}, message: \"must NOT be valid against schema\" };\n\n default:\n return { params: {}, message: undefined };\n }\n}\n\n/**\n * Transform a single cfworker `OutputUnit` into an AJV-compatible\n * `ErrorObject`, or `null` if the unit is a structural wrapper that should\n * be filtered out (`properties` / `items` / `prefixItems` / `$ref`).\n *\n * Exported for unit testing.\n */\nexport function transformUnit(unit: OutputUnit): NoEvalErrorObject | null {\n if (KEYWORD_WRAPPERS.has(unit.keyword)) return null;\n\n const { params, message } = transformByKeyword(unit);\n\n return {\n instancePath: stripPointerPrefix(unit.instanceLocation),\n schemaPath: unit.keywordLocation,\n keyword: unit.keyword,\n params,\n message: message ?? unit.error,\n };\n}\n\n/**\n * Transform a cfworker `OutputUnit[]` into an AJV-compatible\n * `ErrorObject[]`, with structural wrappers filtered out.\n *\n * Exported for unit testing.\n */\nexport function transformErrors(units: OutputUnit[]): NoEvalErrorObject[] {\n const out: NoEvalErrorObject[] = [];\n for (const unit of units) {\n const transformed = transformUnit(unit);\n if (transformed !== null) out.push(transformed);\n }\n return out;\n}\n\nconst FROZEN_OPTS: Readonly<Record<string, unknown>> = Object.freeze({\n allErrors: true,\n verbose: true,\n errorDataPath: \"\",\n strict: false,\n});\n\n/**\n * Build a CSP-safe AJV-shaped validator backed by `@cfworker/json-schema`.\n *\n * Each `compile(schema)` call constructs a `Validator` and returns a\n * synchronous validator function. The validator function's `errors`\n * property is reassigned on every call, matching AJV's contract.\n *\n * Validators are memoized per-schema via a `WeakMap`, so JsonForms's\n * repeated `compile()` calls on prop changes don't re-parse the schema\n * graph each time.\n */\nexport function createNoEvalAjv(\n options: CreateNoEvalAjvOptions = {},\n): NoEvalAjv {\n const draft: SchemaDraft = options.draft ?? \"2020-12\";\n const cache = new WeakMap<object, NoEvalValidateFunction>();\n\n const compile = (schema: unknown): NoEvalValidateFunction => {\n if (schema && typeof schema === \"object\") {\n const cached = cache.get(schema as object);\n if (cached) return cached;\n }\n\n const validator = new Validator(schema as Schema | boolean, draft, false);\n\n const fn: NoEvalValidateFunction = ((data: unknown) => {\n const result = validator.validate(data);\n fn.errors = result.valid ? null : transformErrors(result.errors);\n return result.valid;\n }) as NoEvalValidateFunction;\n\n fn.errors = null;\n\n if (schema && typeof schema === \"object\") {\n cache.set(schema as object, fn);\n }\n return fn;\n };\n\n const facade: NoEvalAjv = {\n compile,\n addSchema: () => facade,\n getSchema: () => undefined,\n removeSchema: () => facade,\n addFormat: () => facade,\n addKeyword: () => facade,\n opts: FROZEN_OPTS,\n };\n\n return facade;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"names":[],"mappings":"AA2EA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AA2JF,wBAEG"}
1
+ {"version":3,"file":"ProviderAutocomplete.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"names":[],"mappings":"AA+EA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AA2JF,wBAEG"}
@@ -1,15 +1,16 @@
1
1
  import { defineComponent, computed, ref, watch, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
2
2
  import { useJsonFormsControl } from "@jsonforms/vue";
3
3
  import { useProvider } from "../composables/useProvider.js";
4
+ import { useProjection } from "../composables/useProjection.js";
4
5
  import AutoComplete from "primevue/autocomplete";
5
- const _hoisted_1 = { class: "flex flex-col gap-1" };
6
+ const _hoisted_1 = { class: "jf-control" };
6
7
  const _hoisted_2 = {
7
8
  key: 0,
8
- class: "text-color text-left"
9
+ class: "jf-label"
9
10
  };
10
11
  const _hoisted_3 = {
11
12
  key: 1,
12
- class: "text-color-secondary text-left"
13
+ class: "jf-description"
13
14
  };
14
15
  const _hoisted_4 = {
15
16
  key: 2,
@@ -25,7 +26,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
25
26
  },
26
27
  setup(__props) {
27
28
  const props = __props;
28
- const { control, handleChange } = useJsonFormsControl(props);
29
+ const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
30
+ const {
31
+ projectedData,
32
+ projectedLabel,
33
+ handleProjectedChange: handleChange
34
+ } = useProjection(control, rawHandleChange);
29
35
  const binding = computed(() => {
30
36
  const provider = control.value.uischema?.options?.provider;
31
37
  if (provider && typeof provider === "object" && !provider.load) {
@@ -43,7 +49,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
43
49
  if (binding.value?.load === "query") reload();
44
50
  });
45
51
  const value = computed({
46
- get: () => control.value.data,
52
+ get: () => projectedData.value,
47
53
  set: (v) => handleChange(control.value.path, v)
48
54
  });
49
55
  const placeholder = computed(
@@ -57,7 +63,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
57
63
  };
58
64
  return (_ctx, _cache) => {
59
65
  return openBlock(), createElementBlock("div", _hoisted_1, [
60
- unref(control).schema.title ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).schema.title), 1)) : createCommentVNode("", true),
66
+ unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
61
67
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
62
68
  createVNode(unref(AutoComplete), {
63
69
  modelValue: value.value,
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderAutocomplete.vue.js","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport AutoComplete from \"primevue/autocomplete\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'query' by default for autocomplete\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"query\" };\n }\n return provider;\n});\n\nconst query = ref(\"\");\nconst { items, loading, error, reload } = useProvider(binding, {\n data: control.value.data,\n path: control.value.path,\n uiQuery: query.value,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst value = computed({\n get: () => control.value.data,\n set: (v) => handleChange(control.value.path, v),\n});\n\nconst placeholder = computed(() =>\n loading.value ? \"Loading…\" : \"Type to search…\",\n);\n\nconst onComplete = (event: { query: string }) => {\n query.value = event.query;\n};\n\nconst onSelect = (event: { value?: { value?: unknown } | unknown }) => {\n value.value = (event.value as { value?: unknown })?.value ?? event.value;\n};\n</script>\n\n<template>\n <div class=\"flex flex-col gap-1\">\n <label v-if=\"control.schema.title\" class=\"text-color text-left\">{{\n control.schema.title\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <AutoComplete\n v-model=\"value\"\n class=\"w-full!\"\n :suggestions=\"items\"\n option-label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n @complete=\"onComplete\"\n @item-select=\"onSelect\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\">Failed: {{ error }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,UAAM,QAAQ;AAKd,UAAM,EAAE,SAAS,iBAAiB,oBAAoB,KAAK;AAE3D,UAAM,UAAU,SAAS,MAAM;AAC7B,YAAM,WAAW,QAAQ,MAAM,UAAU,SAAS;AAElD,UAAI,YAAY,OAAO,aAAa,YAAY,CAAC,SAAS,MAAM;AAC9D,eAAO,EAAE,GAAG,UAAU,MAAM,QAAA;AAAA,MAC9B;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,QAAQ,IAAI,EAAE;AACpB,UAAM,EAAE,OAAO,SAAS,OAAO,OAAA,IAAW,YAAY,SAAS;AAAA,MAC7D,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,QAAQ,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,IAAA,CAChB;AAED,UAAM,OAAO,MAAM;AACjB,UAAI,QAAQ,OAAO,SAAS,QAAS,QAAA;AAAA,IACvC,CAAC;AAED,UAAM,QAAQ,SAAS;AAAA,MACrB,KAAK,MAAM,QAAQ,MAAM;AAAA,MACzB,KAAK,CAAC,MAAM,aAAa,QAAQ,MAAM,MAAM,CAAC;AAAA,IAAA,CAC/C;AAED,UAAM,cAAc;AAAA,MAAS,MAC3B,QAAQ,QAAQ,aAAa;AAAA,IAAA;AAG/B,UAAM,aAAa,CAAC,UAA6B;AAC/C,YAAM,QAAQ,MAAM;AAAA,IACtB;AAEA,UAAM,WAAW,CAAC,UAAqD;AACrE,YAAM,QAAS,MAAM,OAA+B,SAAS,MAAM;AAAA,IACrE;;AAIE,aAAAA,UAAA,GAAAC,mBAkBM,OAlBN,YAkBM;AAAA,QAjBSC,MAAA,OAAA,EAAQ,OAAO,SAA5BF,aAAAC,mBAEU,SAFV,YAEUE,gBADRD,eAAQ,OAAO,KAAK,GAAA,CAAA;QAEXA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YASEF,MAAA,YAAA,GAAA;AAAA,sBARS,MAAA;AAAA,uEAAA,MAAK,QAAA;AAAA,UACd,OAAM;AAAA,UACL,aAAaA,MAAA,KAAA;AAAA,UACd,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB;AAAA,UACA,cAAa;AAAA,QAAA;QAEHA,MAAA,KAAA,KAAbF,aAAAC,mBAA4E,SAA5E,YAAiD,6BAAWC,MAAA,KAAA,CAAK,GAAA,CAAA;;;;;"}
1
+ {"version":3,"file":"ProviderAutocomplete.vue.js","sources":["../../../src/vue/components/ProviderAutocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, ref, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport AutoComplete from \"primevue/autocomplete\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'query' by default for autocomplete\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"query\" };\n }\n return provider;\n});\n\nconst query = ref(\"\");\nconst { items, loading, error, reload } = useProvider(binding, {\n data: control.value.data,\n path: control.value.path,\n uiQuery: query.value,\n});\n\nwatch(query, () => {\n if (binding.value?.load === \"query\") reload();\n});\n\nconst value = computed({\n get: () => projectedData.value,\n set: (v) => handleChange(control.value.path, v),\n});\n\nconst placeholder = computed(() =>\n loading.value ? \"Loading…\" : \"Type to search…\",\n);\n\nconst onComplete = (event: { query: string }) => {\n query.value = event.query;\n};\n\nconst onSelect = (event: { value?: { value?: unknown } | unknown }) => {\n value.value = (event.value as { value?: unknown })?.value ?? event.value;\n};\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <AutoComplete\n v-model=\"value\"\n class=\"w-full!\"\n :suggestions=\"items\"\n option-label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled\"\n @complete=\"onComplete\"\n @item-select=\"onSelect\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\">Failed: {{ error }}</small>\n </div>\n</template>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AAKd,UAAM,EAAE,SAAS,cAAc,gBAAA,IAAoB,oBAAoB,KAAK;AAC5E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,uBAAuB;AAAA,IAAA,IACrB,cAAc,SAAS,eAAe;AAE1C,UAAM,UAAU,SAAS,MAAM;AAC7B,YAAM,WAAW,QAAQ,MAAM,UAAU,SAAS;AAElD,UAAI,YAAY,OAAO,aAAa,YAAY,CAAC,SAAS,MAAM;AAC9D,eAAO,EAAE,GAAG,UAAU,MAAM,QAAA;AAAA,MAC9B;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,QAAQ,IAAI,EAAE;AACpB,UAAM,EAAE,OAAO,SAAS,OAAO,OAAA,IAAW,YAAY,SAAS;AAAA,MAC7D,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,QAAQ,MAAM;AAAA,MACpB,SAAS,MAAM;AAAA,IAAA,CAChB;AAED,UAAM,OAAO,MAAM;AACjB,UAAI,QAAQ,OAAO,SAAS,QAAS,QAAA;AAAA,IACvC,CAAC;AAED,UAAM,QAAQ,SAAS;AAAA,MACrB,KAAK,MAAM,cAAc;AAAA,MACzB,KAAK,CAAC,MAAM,aAAa,QAAQ,MAAM,MAAM,CAAC;AAAA,IAAA,CAC/C;AAED,UAAM,cAAc;AAAA,MAAS,MAC3B,QAAQ,QAAQ,aAAa;AAAA,IAAA;AAG/B,UAAM,aAAa,CAAC,UAA6B;AAC/C,YAAM,QAAQ,MAAM;AAAA,IACtB;AAEA,UAAM,WAAW,CAAC,UAAqD;AACrE,YAAM,QAAS,MAAM,OAA+B,SAAS,MAAM;AAAA,IACrE;;AAIE,aAAAA,UAAA,GAAAC,mBAgBM,OAhBN,YAgBM;AAAA,QAfSC,MAAA,cAAA,kBAAbD,mBAA0E,SAA1E,YAA0EE,gBAAzBD,MAAA,cAAA,CAAc,GAAA,CAAA;QACpDA,MAAA,OAAA,EAAQ,eAAnBF,UAAA,GAAAC,mBAEM,OAFN,YAEME,gBADDD,MAAA,OAAA,EAAQ,WAAW,GAAA,CAAA;QAExBE,YASEF,MAAA,YAAA,GAAA;AAAA,sBARS,MAAA;AAAA,uEAAA,MAAK,QAAA;AAAA,UACd,OAAM;AAAA,UACL,aAAaA,MAAA,KAAA;AAAA,UACd,gBAAa;AAAA,UACZ,aAAa,YAAA;AAAA,UACb,UAAQ,CAAGA,MAAA,OAAA,EAAQ;AAAA,UACnB;AAAA,UACA,cAAa;AAAA,QAAA;QAEHA,MAAA,KAAA,KAAbF,aAAAC,mBAA4E,SAA5E,YAAiD,6BAAWC,MAAA,KAAA,CAAK,GAAA,CAAA;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderMultiSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"names":[],"mappings":"AAkIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAqMF,wBAEG"}
1
+ {"version":3,"file":"ProviderMultiSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AASlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAuMF,wBAEG"}
@@ -1,7 +1,7 @@
1
1
  import _sfc_main from "./ProviderMultiSelect.vue2.js";
2
2
  /* empty css */
3
3
  import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
4
- const ProviderMultiSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a32037c6"]]);
4
+ const ProviderMultiSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-0d0d0f03"]]);
5
5
  export {
6
6
  ProviderMultiSelect as default
7
7
  };
@@ -1,16 +1,18 @@
1
1
  import { defineComponent, computed, inject, watch, createElementBlock, openBlock, createCommentVNode, createVNode, unref, toDisplayString } from "vue";
2
2
  import { useJsonFormsControl } from "@jsonforms/vue";
3
3
  import { useProvider } from "../composables/useProvider.js";
4
+ import { useProjection } from "../composables/useProjection.js";
4
5
  import { shouldAutoSelectMulti } from "../utils/autoSelect.js";
6
+ import { resolvePlaceholder } from "../utils/placeholder.js";
5
7
  import MultiSelect from "primevue/multiselect";
6
- const _hoisted_1 = { class: "flex flex-col gap-2" };
8
+ const _hoisted_1 = { class: "jf-control" };
7
9
  const _hoisted_2 = {
8
10
  key: 0,
9
- class: "text-color text-left"
11
+ class: "jf-label"
10
12
  };
11
13
  const _hoisted_3 = {
12
14
  key: 1,
13
- class: "text-color-secondary text-left"
15
+ class: "jf-description"
14
16
  };
15
17
  const _hoisted_4 = {
16
18
  key: 2,
@@ -26,7 +28,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
26
28
  },
27
29
  setup(__props) {
28
30
  const props = __props;
29
- const { control, handleChange } = useJsonFormsControl(props);
31
+ const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
32
+ const {
33
+ projectedData,
34
+ projectedLabel,
35
+ handleProjectedChange: handleChange
36
+ } = useProjection(control, rawHandleChange);
30
37
  const binding = computed(() => {
31
38
  const provider = control.value.uischema?.options?.provider;
32
39
  if (provider && typeof provider === "object" && !provider.load) {
@@ -44,7 +51,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
44
51
  data: rootData,
45
52
  // Pass the reactive reference
46
53
  path: control.value.path,
47
- dependsOnValues: depValues.value
54
+ dependsOnValues: depValues
48
55
  });
49
56
  watch(
50
57
  [items, loading],
@@ -53,7 +60,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
53
60
  autoSelectSingle: control.value.uischema?.options?.autoSelectSingle === true,
54
61
  isLoading,
55
62
  items: newItems,
56
- currentValue: Array.isArray(control.value.data) ? control.value.data : []
63
+ currentValue: Array.isArray(projectedData.value) ? projectedData.value : []
57
64
  });
58
65
  if (valueToSelect !== null) {
59
66
  handleChange(control.value.path, valueToSelect);
@@ -69,23 +76,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
69
76
  };
70
77
  const value = computed({
71
78
  get() {
72
- const curr = Array.isArray(control.value.data) ? control.value.data : [];
79
+ const curr = Array.isArray(projectedData.value) ? projectedData.value : [];
73
80
  return [...curr];
74
81
  },
75
82
  set(val) {
76
83
  const next = Array.isArray(val) ? [...val] : [];
77
- const curr = Array.isArray(control.value.data) ? control.value.data : [];
84
+ const curr = Array.isArray(projectedData.value) ? projectedData.value : [];
78
85
  if (!sameSet(curr, next)) handleChange(control.value.path, next);
79
86
  }
80
87
  });
81
88
  const placeholder = computed(() => {
82
89
  if (loading.value) return "Loading…";
83
- const uischemaPlaceholder = control.value.uischema?.options?.placeholder;
84
- return uischemaPlaceholder || "Select…";
90
+ return resolvePlaceholder(
91
+ control.value.uischema,
92
+ projectedLabel.value,
93
+ "select"
94
+ );
85
95
  });
86
96
  return (_ctx, _cache) => {
87
97
  return openBlock(), createElementBlock("div", _hoisted_1, [
88
- unref(control).schema.title ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(control).schema.title), 1)) : createCommentVNode("", true),
98
+ unref(projectedLabel) ? (openBlock(), createElementBlock("label", _hoisted_2, toDisplayString(unref(projectedLabel)), 1)) : createCommentVNode("", true),
89
99
  unref(control).description ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(unref(control).description), 1)) : createCommentVNode("", true),
90
100
  createVNode(unref(MultiSelect), {
91
101
  modelValue: value.value,
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderMultiSelect.vue2.js","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport MultiSelect from \"primevue/multiselect\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange } = useJsonFormsControl(props);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues.value,\n});\n\n// Provider will automatically reload when rootData changes due to reactive cache key\n\n// Auto-select when provider returns only one item (opt-in for multiselect)\nwatch(\n [items, loading],\n ([newItems, isLoading]) => {\n const valueToSelect = shouldAutoSelectMulti({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle === true,\n isLoading,\n items: newItems,\n currentValue: Array.isArray(control.value.data) ? control.value.data : [],\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\n// order-insensitive shallow equality for primitive arrays\nconst sameSet = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n const s = new Set(b);\n return a.every((v) => s.has(v));\n};\n\n// v-model with guard to avoid recursive updates\nconst value = computed({\n get() {\n const curr = Array.isArray(control.value.data) ? control.value.data : [];\n // return a fresh copy so MultiSelect can't mutate JSONForms' array in place\n return [...curr];\n },\n set(val) {\n const next = Array.isArray(val) ? [...val] : [];\n const curr = Array.isArray(control.value.data) ? control.value.data : [];\n if (!sameSet(curr, next)) handleChange(control.value.path, next);\n },\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n // Check for placeholder in uischema options\n const uischemaPlaceholder = (\n control.value.uischema as { options?: { placeholder?: string } }\n )?.options?.placeholder;\n return uischemaPlaceholder || \"Select…\";\n});\n</script>\n\n<template>\n <div class=\"flex flex-col gap-2\">\n <label v-if=\"control.schema.title\" class=\"text-color text-left\">{{\n control.schema.title\n }}</label>\n <div v-if=\"control.description\" class=\"text-color-secondary text-left\">\n {{ control.description }}\n </div>\n <MultiSelect\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n option-value=\"value\"\n data-key=\"value\"\n display=\"chip\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-multiselect-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
1
+ {"version":3,"file":"ProviderMultiSelect.vue2.js","sources":["../../../src/vue/components/ProviderMultiSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ControlElement, JsonSchema } from \"@jsonforms/core\";\nimport { useJsonFormsControl } from \"@jsonforms/vue\";\nimport { computed, inject, watch } from \"vue\";\nimport { useProvider } from \"../composables/useProvider\";\nimport { useProjection } from \"../composables/useProjection\";\nimport { shouldAutoSelectMulti } from \"../utils/autoSelect\";\nimport { resolvePlaceholder } from \"../utils/placeholder\";\nimport MultiSelect from \"primevue/multiselect\";\n\nconst props = defineProps<{\n uischema: ControlElement;\n schema: JsonSchema;\n path: string;\n}>();\nconst { control, handleChange: rawHandleChange } = useJsonFormsControl(props);\nconst {\n projectedData,\n projectedLabel,\n handleProjectedChange: handleChange,\n} = useProjection(control, rawHandleChange);\n\nconst binding = computed(() => {\n const provider = control.value.uischema?.options?.provider;\n // Ensure load property is set to 'mount' by default\n if (provider && typeof provider === \"object\" && !provider.load) {\n return { ...provider, load: \"mount\" };\n }\n return provider;\n});\n\nconst deps = computed(\n () =>\n ((\n (control.value.schema as Record<string, unknown>)?.[\n \"x-provider\"\n ] as Record<string, unknown>\n )?.dependsOn as string[]) ?? [],\n);\nconst depValues = computed(() => deps.value.map(() => null)); // you can resolve actual values via control.value.data & pointers\n\n// Get the root form data from JSONForms context for template URL resolution\nconst injectedFormData = inject<{ value: unknown }>(\"formData\", { value: {} });\nconst rootData = computed(() => injectedFormData.value || {});\n\nconst { items, loading, error } = useProvider(binding, {\n data: rootData, // Pass the reactive reference\n path: control.value.path,\n dependsOnValues: depValues,\n});\n\n// Provider will automatically reload when rootData changes due to reactive cache key\n\n// Auto-select when provider returns only one item (opt-in for multiselect)\nwatch(\n [items, loading],\n ([newItems, isLoading]) => {\n const valueToSelect = shouldAutoSelectMulti({\n autoSelectSingle:\n control.value.uischema?.options?.autoSelectSingle === true,\n isLoading,\n items: newItems,\n currentValue: Array.isArray(projectedData.value)\n ? projectedData.value\n : [],\n });\n\n if (valueToSelect !== null) {\n handleChange(control.value.path, valueToSelect);\n }\n },\n { immediate: true },\n);\n\n// order-insensitive shallow equality for primitive arrays\nconst sameSet = (a: unknown[], b: unknown[]) => {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n const s = new Set(b);\n return a.every((v) => s.has(v));\n};\n\n// v-model with guard to avoid recursive updates\nconst value = computed({\n get() {\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n // return a fresh copy so MultiSelect can't mutate JSONForms' array in place\n return [...curr];\n },\n set(val) {\n const next = Array.isArray(val) ? [...val] : [];\n const curr = Array.isArray(projectedData.value) ? projectedData.value : [];\n if (!sameSet(curr, next)) handleChange(control.value.path, next);\n },\n});\n\nconst placeholder = computed(() => {\n if (loading.value) return \"Loading…\";\n return resolvePlaceholder(\n control.value.uischema,\n projectedLabel.value,\n \"select\",\n );\n});\n</script>\n\n<template>\n <div class=\"jf-control\">\n <label v-if=\"projectedLabel\" class=\"jf-label\">{{ projectedLabel }}</label>\n <div v-if=\"control.description\" class=\"jf-description\">\n {{ control.description }}\n </div>\n <MultiSelect\n v-model=\"value\"\n class=\"w-full!\"\n :options=\"items\"\n option-label=\"label\"\n option-value=\"value\"\n data-key=\"value\"\n display=\"chip\"\n :placeholder=\"placeholder\"\n :disabled=\"!control.enabled || loading\"\n :show-clear=\"true\"\n />\n <small v-if=\"error\" class=\"p-error\" role=\"alert\"\n >Failed to load: {{ error }}</small\n >\n </div>\n</template>\n\n<style scoped>\n:deep(.p-multiselect-label) {\n text-align: left;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_unref","_toDisplayString","_createVNode"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ControlElement, JsonSchema } from "@jsonforms/core";
2
+ type __VLS_Props = {
3
+ uischema: ControlElement;
4
+ schema: JsonSchema;
5
+ path: string;
6
+ };
7
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ export default _default;
9
+ //# sourceMappingURL=ProviderObjectMultiSelect.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderObjectMultiSelect.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/components/ProviderObjectMultiSelect.vue"],"names":[],"mappings":"AA2KA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAiBlE,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;;AAgOF,wBAEG"}
@@ -0,0 +1,8 @@
1
+ import _sfc_main from "./ProviderObjectMultiSelect.vue2.js";
2
+ /* empty css */
3
+ import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
4
+ const ProviderObjectMultiSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-2ee6c7be"]]);
5
+ export {
6
+ ProviderObjectMultiSelect as default
7
+ };
8
+ //# sourceMappingURL=ProviderObjectMultiSelect.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderObjectMultiSelect.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}