@narrative.io/jsonforms-provider-protocols 2.11.0 → 3.0.0-beta.10
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 +101 -29
- package/dist/core/initFormData.d.ts +10 -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 +32 -0
- package/dist/core/projection.d.ts.map +1 -0
- package/dist/core/projection.js +74 -0
- package/dist/core/projection.js.map +1 -0
- package/dist/core/resolveScope.d.ts +11 -0
- package/dist/core/resolveScope.d.ts.map +1 -0
- package/dist/core/resolveScope.js +22 -0
- package/dist/core/resolveScope.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 +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/jsonforms-provider-protocols.css +2 -2
- package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderAutocomplete.vue.js +10 -5
- 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 +12 -7
- package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
- 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 +13 -6
- 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 +41 -0
- package/dist/vue/composables/useProjection.d.ts.map +1 -0
- package/dist/vue/composables/useProjection.js +84 -0
- package/dist/vue/composables/useProjection.js.map +1 -0
- package/dist/vue/index.d.ts +7 -0
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +35 -27
- 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 +35 -13
- 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 +31 -22
- 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 +33 -18
- 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 +31 -22
- 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 +40 -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 +32 -18
- 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/package.json +3 -1
- package/src/core/initFormData.ts +189 -0
- package/src/core/projection.ts +136 -0
- package/src/core/resolveScope.ts +39 -0
- package/src/core/transforms.ts +118 -26
- package/src/core/types.ts +9 -0
- package/src/index.ts +7 -1
- package/src/vue/components/ProviderAutocomplete.vue +10 -5
- package/src/vue/components/ProviderMultiSelect.vue +14 -7
- package/src/vue/components/ProviderSelect.vue +15 -6
- 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 +181 -0
- package/src/vue/index.ts +35 -41
- package/src/vue/primevue/JfBoolean.vue +25 -7
- package/src/vue/primevue/JfEnum.vue +29 -22
- package/src/vue/primevue/JfEnumArray.vue +31 -16
- package/src/vue/primevue/JfNumber.vue +29 -22
- package/src/vue/primevue/JfText.vue +34 -27
- package/src/vue/primevue/JfTextArea.vue +29 -17
- package/src/vue/primevue/index.ts +114 -8
- package/src/vue/styles.css +26 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDerive.js","sources":["../../../src/vue/composables/useDerive.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useDerive.js","sources":["../../../src/vue/composables/useDerive.ts"],"sourcesContent":["import {\n computed,\n ref,\n watch,\n unref,\n inject,\n type Ref,\n type ComputedRef,\n} from \"vue\";\nimport { type ControlElement } from \"@jsonforms/core\";\nimport { useDataLayer } from \"./useDataLayer\";\n\ninterface DeriveOptions {\n control: Ref<{\n uischema: ControlElement;\n path: string;\n data: unknown;\n }>;\n handleChange: (path: string, value: unknown) => void;\n /** When projection is active, pass projectedData so the comparison\n * matches the projected (unwrapped) value rather than raw scope data. */\n data?: Ref<unknown> | ComputedRef<unknown>;\n}\n\nexport function useDerive({\n control,\n handleChange,\n data: dataOverride,\n}: DeriveOptions) {\n // Get the root form data from JSONForms context\n const injectedFormData = inject<{ value: unknown }>(\"formData\", {\n value: {},\n });\n const rootData = computed(() => injectedFormData.value || {});\n\n // Get data from the dataLayer\n const dataLayerState = useDataLayer();\n const dataLayerData = computed(() => dataLayerState.value || {});\n\n // Extract derive configuration from uischema options\n const deriveConfig = computed(() => {\n const options = control.value.uischema?.options as\n | { derive?: string; mode?: string }\n | undefined;\n return {\n expression: options?.derive,\n mode: options?.mode || \"follow\", // 'follow' = auto-update, 'manual' = user controlled\n };\n });\n\n // Track the last resolved source value so we only update the field\n // when the source itself changes, not on every form data mutation.\n const lastDerivedValue = ref<unknown>(undefined);\n // First watch fire is special: a pre-populated field (edit flow seeded\n // from a saved connection) must not be clobbered by whatever the source\n // resolves to on mount. We record the source value but skip handleChange.\n let isFirstRun = true;\n\n // Watch for changes in form data and dataLayer and update derived field\n watch(\n [rootData, dataLayerData, deriveConfig],\n ([data, extData, config]) => {\n if (!config.expression || config.mode !== \"follow\") {\n return;\n }\n\n try {\n const derivedValue = resolveDeriveExpression(\n config.expression,\n data,\n extData,\n );\n const compareData = dataOverride\n ? unref(dataOverride)\n : control.value.data;\n\n if (isFirstRun) {\n isFirstRun = false;\n lastDerivedValue.value = derivedValue;\n // On mount, only populate the field if it's empty.\n // A non-empty seed represents user intent (edit flow) and must\n // be preserved. Subsequent source changes will still propagate.\n const isFieldEmpty =\n compareData === undefined ||\n compareData === null ||\n compareData === \"\";\n if (isFieldEmpty && derivedValue !== compareData) {\n handleChange(control.value.path, derivedValue);\n }\n return;\n }\n\n // Only update if the SOURCE value changed, not just the field value\n if (derivedValue === lastDerivedValue.value) return;\n lastDerivedValue.value = derivedValue;\n\n if (derivedValue !== compareData) {\n handleChange(control.value.path, derivedValue);\n }\n } catch (error) {\n console.warn(\n `Failed to derive value for ${control.value.path}:`,\n error,\n );\n }\n },\n { deep: true, immediate: true },\n );\n}\n\nfunction resolveDeriveExpression(\n expression: string,\n data: unknown,\n dataLayerData?: unknown,\n): unknown {\n // Handle dataLayer() syntax\n if (expression.startsWith(\"dataLayer(\") && expression.endsWith(\")\")) {\n const propertyPath = expression.slice(10, -1); // Remove \"dataLayer(\" and \")\"\n return resolvePropertyPath(propertyPath, dataLayerData);\n }\n\n // Handle simple property paths like \"country.name\"\n if (\n !expression.includes(\"(\") &&\n !expression.includes(\"+\") &&\n !expression.includes(\"?\")\n ) {\n return resolvePropertyPath(expression, data);\n }\n\n // For now, we'll only support simple property paths and dataLayer() calls\n // Complex expressions would require a safe expression evaluator\n return resolvePropertyPath(expression, data);\n}\n\nfunction resolvePropertyPath(path: string, data: unknown): unknown {\n if (!path || !data) return \"\";\n\n const keys = path.split(\".\");\n let value: unknown = data;\n\n for (const key of keys) {\n if (value && typeof value === \"object\" && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return null;\n }\n }\n\n return value;\n}\n"],"names":[],"mappings":";;;AAwBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,MAAM;AACR,GAAkB;AAEhB,QAAM,mBAAmB,OAA2B,YAAY;AAAA,IAC9D,OAAO,CAAA;AAAA,EAAC,CACT;AACD,QAAM,WAAW,SAAS,MAAM,iBAAiB,SAAS,CAAA,CAAE;AAG5D,QAAM,iBAAiB,aAAA;AACvB,QAAM,gBAAgB,SAAS,MAAM,eAAe,SAAS,CAAA,CAAE;AAG/D,QAAM,eAAe,SAAS,MAAM;AAClC,UAAM,UAAU,QAAQ,MAAM,UAAU;AAGxC,WAAO;AAAA,MACL,YAAY,SAAS;AAAA,MACrB,MAAM,SAAS,QAAQ;AAAA;AAAA,IAAA;AAAA,EAE3B,CAAC;AAID,QAAM,mBAAmB,IAAa,MAAS;AAI/C,MAAI,aAAa;AAGjB;AAAA,IACE,CAAC,UAAU,eAAe,YAAY;AAAA,IACtC,CAAC,CAAC,MAAM,SAAS,MAAM,MAAM;AAC3B,UAAI,CAAC,OAAO,cAAc,OAAO,SAAS,UAAU;AAClD;AAAA,MACF;AAEA,UAAI;AACF,cAAM,eAAe;AAAA,UACnB,OAAO;AAAA,UACP;AAAA,UACA;AAAA,QAAA;AAEF,cAAM,cAAc,eAChB,MAAM,YAAY,IAClB,QAAQ,MAAM;AAElB,YAAI,YAAY;AACd,uBAAa;AACb,2BAAiB,QAAQ;AAIzB,gBAAM,eACJ,gBAAgB,UAChB,gBAAgB,QAChB,gBAAgB;AAClB,cAAI,gBAAgB,iBAAiB,aAAa;AAChD,yBAAa,QAAQ,MAAM,MAAM,YAAY;AAAA,UAC/C;AACA;AAAA,QACF;AAGA,YAAI,iBAAiB,iBAAiB,MAAO;AAC7C,yBAAiB,QAAQ;AAEzB,YAAI,iBAAiB,aAAa;AAChC,uBAAa,QAAQ,MAAM,MAAM,YAAY;AAAA,QAC/C;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ;AAAA,UACN,8BAA8B,QAAQ,MAAM,IAAI;AAAA,UAChD;AAAA,QAAA;AAAA,MAEJ;AAAA,IACF;AAAA,IACA,EAAE,MAAM,MAAM,WAAW,KAAA;AAAA,EAAK;AAElC;AAEA,SAAS,wBACP,YACA,MACA,eACS;AAET,MAAI,WAAW,WAAW,YAAY,KAAK,WAAW,SAAS,GAAG,GAAG;AACnE,UAAM,eAAe,WAAW,MAAM,IAAI,EAAE;AAC5C,WAAO,oBAAoB,cAAc,aAAa;AAAA,EACxD;AAGA,MACE,CAAC,WAAW,SAAS,GAAG,KACxB,CAAC,WAAW,SAAS,GAAG,KACxB,CAAC,WAAW,SAAS,GAAG,GACxB;AACA,WAAO,oBAAoB,YAAY,IAAI;AAAA,EAC7C;AAIA,SAAO,oBAAoB,YAAY,IAAI;AAC7C;AAEA,SAAS,oBAAoB,MAAc,MAAwB;AACjE,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAE3B,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,MAAI,QAAiB;AAErB,aAAW,OAAO,MAAM;AACtB,QAAI,SAAS,OAAO,UAAU,YAAY,OAAO,OAAO;AACtD,cAAS,MAAkC,GAAG;AAAA,IAChD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Ref, type ComputedRef } from "vue";
|
|
2
|
+
import { type ControlElement } from "@jsonforms/core";
|
|
3
|
+
import { type TransformPipeline } from "../../core/transforms";
|
|
4
|
+
import type { AuthConfig } from "../../core/types";
|
|
5
|
+
export interface DeriveInitialValueCfg {
|
|
6
|
+
protocol: string;
|
|
7
|
+
config: {
|
|
8
|
+
url: string;
|
|
9
|
+
method?: "GET" | "POST";
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
query?: Record<string, unknown>;
|
|
12
|
+
body?: unknown;
|
|
13
|
+
auth?: AuthConfig;
|
|
14
|
+
items: string;
|
|
15
|
+
map: {
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
transforms?: TransformPipeline;
|
|
19
|
+
showError?: boolean;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface DeriveInitialValueOptions {
|
|
23
|
+
control: Ref<{
|
|
24
|
+
uischema: ControlElement;
|
|
25
|
+
path: string;
|
|
26
|
+
data: unknown;
|
|
27
|
+
}>;
|
|
28
|
+
handleChange: (path: string, value: unknown) => void;
|
|
29
|
+
data?: Ref<unknown> | ComputedRef<unknown>;
|
|
30
|
+
}
|
|
31
|
+
export declare function useDeriveInitialValue({ control, handleChange, }: DeriveInitialValueOptions): {
|
|
32
|
+
loading: Ref<boolean, boolean>;
|
|
33
|
+
error: Ref<string | undefined, string | undefined>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=useDeriveInitialValue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeriveInitialValue.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDeriveInitialValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAC/E,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,IAAI,CAAC,EAAE,UAAU,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACvB,UAAU,CAAC,EAAE,iBAAiB,CAAC;QAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAED,UAAU,yBAAyB;IACjC,OAAO,EAAE,GAAG,CAAC;QACX,QAAQ,EAAE,cAAc,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,OAAO,CAAC;KACf,CAAC,CAAC;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;CAC5C;AAsDD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,YAAY,GACb,EAAE,yBAAyB;;;EAuG3B"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { inject, computed, ref, watch } from "vue";
|
|
2
|
+
import "@jsonforms/core";
|
|
3
|
+
import { renderTpl, renderObj } from "../../core/templating.js";
|
|
4
|
+
import { jp } from "../../core/jsonpath.js";
|
|
5
|
+
import { applyTransformPipeline } from "../../core/transforms.js";
|
|
6
|
+
function buildAuthHeaders(auth, globalAuth) {
|
|
7
|
+
const headers = {};
|
|
8
|
+
if (!auth) return headers;
|
|
9
|
+
if (auth.use && globalAuth?.[auth.use]) {
|
|
10
|
+
const globalValue = globalAuth[auth.use];
|
|
11
|
+
const value = typeof globalValue === "function" ? globalValue() : globalValue;
|
|
12
|
+
if (auth.use === "apiKey") headers["X-API-Key"] = String(value);
|
|
13
|
+
else if (auth.use === "bearer")
|
|
14
|
+
headers["Authorization"] = `Bearer ${value}`;
|
|
15
|
+
else if (auth.use === "token") headers["Authorization"] = `Token ${value}`;
|
|
16
|
+
return headers;
|
|
17
|
+
}
|
|
18
|
+
if (auth.bearer) {
|
|
19
|
+
const v = typeof auth.bearer === "function" ? auth.bearer() : auth.bearer;
|
|
20
|
+
headers["Authorization"] = `Bearer ${v}`;
|
|
21
|
+
}
|
|
22
|
+
if (auth.apiKey) {
|
|
23
|
+
const v = typeof auth.apiKey === "function" ? auth.apiKey() : auth.apiKey;
|
|
24
|
+
headers["X-API-Key"] = String(v);
|
|
25
|
+
}
|
|
26
|
+
if (auth.token) {
|
|
27
|
+
const v = typeof auth.token === "function" ? auth.token() : auth.token;
|
|
28
|
+
headers["Authorization"] = `Token ${v}`;
|
|
29
|
+
}
|
|
30
|
+
return headers;
|
|
31
|
+
}
|
|
32
|
+
function hasUnresolvedTemplates(templateUrl, renderedUrl) {
|
|
33
|
+
if (!templateUrl.includes("{{")) return false;
|
|
34
|
+
const pathPart = renderedUrl.replace(/^https?:\/\/[^/]+/, "");
|
|
35
|
+
if (pathPart.includes("//")) return true;
|
|
36
|
+
if (renderedUrl.endsWith("/") && !templateUrl.endsWith("/")) return true;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function useDeriveInitialValue({
|
|
40
|
+
control,
|
|
41
|
+
handleChange
|
|
42
|
+
}) {
|
|
43
|
+
const injectedFormData = inject("formData", {
|
|
44
|
+
value: {}
|
|
45
|
+
});
|
|
46
|
+
const rootData = computed(() => injectedFormData.value || {});
|
|
47
|
+
const auth = inject("providerAuth", {});
|
|
48
|
+
const cfg = computed(() => {
|
|
49
|
+
return control.value.uischema?.options?.deriveInitialValue;
|
|
50
|
+
});
|
|
51
|
+
const resolvedUrl = computed(() => {
|
|
52
|
+
const c = cfg.value;
|
|
53
|
+
if (!c?.config?.url) return null;
|
|
54
|
+
const rendered = renderTpl(c.config.url, { data: rootData.value });
|
|
55
|
+
if (hasUnresolvedTemplates(c.config.url, rendered)) return null;
|
|
56
|
+
return rendered;
|
|
57
|
+
});
|
|
58
|
+
const lastFetchedUrl = ref(null);
|
|
59
|
+
const loading = ref(false);
|
|
60
|
+
const error = ref(void 0);
|
|
61
|
+
watch(
|
|
62
|
+
resolvedUrl,
|
|
63
|
+
async (url) => {
|
|
64
|
+
if (!url || !cfg.value) return;
|
|
65
|
+
if (url === lastFetchedUrl.value) return;
|
|
66
|
+
lastFetchedUrl.value = url;
|
|
67
|
+
loading.value = true;
|
|
68
|
+
error.value = void 0;
|
|
69
|
+
try {
|
|
70
|
+
const c = cfg.value.config;
|
|
71
|
+
const fullUrl = new URL(url);
|
|
72
|
+
const q = renderObj(c.query ?? {}, {
|
|
73
|
+
data: rootData.value
|
|
74
|
+
});
|
|
75
|
+
for (const [k, v] of Object.entries(q)) {
|
|
76
|
+
if (v !== void 0 && v !== "")
|
|
77
|
+
fullUrl.searchParams.set(k, String(v));
|
|
78
|
+
}
|
|
79
|
+
const baseHeaders = renderObj(c.headers ?? {}, {
|
|
80
|
+
data: rootData.value
|
|
81
|
+
});
|
|
82
|
+
const authHeaders = buildAuthHeaders(c.auth, auth);
|
|
83
|
+
const headers = { ...baseHeaders, ...authHeaders };
|
|
84
|
+
const method = c.method ?? "GET";
|
|
85
|
+
const requestInit = { method, headers };
|
|
86
|
+
if (method !== "GET" && c.body) {
|
|
87
|
+
requestInit.body = JSON.stringify(
|
|
88
|
+
renderObj(c.body, { data: rootData.value })
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const res = await fetch(fullUrl.toString(), requestInit);
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
if (c.showError !== false) {
|
|
94
|
+
throw new Error(`REST ${res.status}`);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const json = await res.json();
|
|
99
|
+
let items = jp(json, c.items);
|
|
100
|
+
if (c.transforms && c.transforms.length > 0) {
|
|
101
|
+
items = applyTransformPipeline(items, c.transforms);
|
|
102
|
+
}
|
|
103
|
+
if (items.length === 0) return;
|
|
104
|
+
const derivedValue = jp(items[0], c.map.value)[0];
|
|
105
|
+
if (derivedValue !== void 0) {
|
|
106
|
+
handleChange(control.value.path, derivedValue);
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
error.value = e?.message ?? String(e);
|
|
110
|
+
console.warn(
|
|
111
|
+
`deriveInitialValue fetch failed for ${control.value.path}:`,
|
|
112
|
+
e
|
|
113
|
+
);
|
|
114
|
+
} finally {
|
|
115
|
+
loading.value = false;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{ immediate: true }
|
|
119
|
+
);
|
|
120
|
+
return { loading, error };
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
useDeriveInitialValue
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=useDeriveInitialValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeriveInitialValue.js","sources":["../../../src/vue/composables/useDeriveInitialValue.ts"],"sourcesContent":["import { computed, inject, ref, watch, type Ref, type ComputedRef } from \"vue\";\nimport { type ControlElement } from \"@jsonforms/core\";\nimport { renderTpl, renderObj } from \"../../core/templating\";\nimport { jp } from \"../../core/jsonpath\";\nimport {\n applyTransformPipeline,\n type TransformPipeline,\n} from \"../../core/transforms\";\nimport type { AuthConfig } from \"../../core/types\";\n\nexport interface DeriveInitialValueCfg {\n protocol: string;\n config: {\n url: string;\n method?: \"GET\" | \"POST\";\n headers?: Record<string, string>;\n query?: Record<string, unknown>;\n body?: unknown;\n auth?: AuthConfig;\n items: string;\n map: { value: string };\n transforms?: TransformPipeline;\n showError?: boolean;\n };\n}\n\ninterface DeriveInitialValueOptions {\n control: Ref<{\n uischema: ControlElement;\n path: string;\n data: unknown;\n }>;\n handleChange: (path: string, value: unknown) => void;\n data?: Ref<unknown> | ComputedRef<unknown>;\n}\n\nfunction buildAuthHeaders(\n auth?: AuthConfig,\n globalAuth?: Record<string, unknown>,\n): Record<string, string> {\n const headers: Record<string, string> = {};\n if (!auth) return headers;\n\n if (auth.use && globalAuth?.[auth.use]) {\n const globalValue = globalAuth[auth.use];\n const value =\n typeof globalValue === \"function\" ? globalValue() : globalValue;\n if (auth.use === \"apiKey\") headers[\"X-API-Key\"] = String(value);\n else if (auth.use === \"bearer\")\n headers[\"Authorization\"] = `Bearer ${value}`;\n else if (auth.use === \"token\") headers[\"Authorization\"] = `Token ${value}`;\n return headers;\n }\n\n if (auth.bearer) {\n const v = typeof auth.bearer === \"function\" ? auth.bearer() : auth.bearer;\n headers[\"Authorization\"] = `Bearer ${v}`;\n }\n if (auth.apiKey) {\n const v = typeof auth.apiKey === \"function\" ? auth.apiKey() : auth.apiKey;\n headers[\"X-API-Key\"] = String(v);\n }\n if (auth.token) {\n const v = typeof auth.token === \"function\" ? auth.token() : auth.token;\n headers[\"Authorization\"] = `Token ${v}`;\n }\n\n return headers;\n}\n\n/**\n * Returns true when the template URL contains `{{…}}` placeholders but\n * one or more of those placeholders resolved to an empty string, which\n * means a required data dependency hasn't been set yet.\n */\nfunction hasUnresolvedTemplates(\n templateUrl: string,\n renderedUrl: string,\n): boolean {\n if (!templateUrl.includes(\"{{\")) return false;\n // After protocol, empty segments indicate unresolved vars\n const pathPart = renderedUrl.replace(/^https?:\\/\\/[^/]+/, \"\");\n if (pathPart.includes(\"//\")) return true;\n // Trailing slash when the template didn't have one\n if (renderedUrl.endsWith(\"/\") && !templateUrl.endsWith(\"/\")) return true;\n return false;\n}\n\nexport function useDeriveInitialValue({\n control,\n handleChange,\n}: DeriveInitialValueOptions) {\n const injectedFormData = inject<{ value: unknown }>(\"formData\", {\n value: {},\n });\n const rootData = computed(() => injectedFormData.value || {});\n const auth = inject(\"providerAuth\", {}) as Record<string, unknown>;\n\n const cfg = computed<DeriveInitialValueCfg | undefined>(() => {\n return control.value.uischema?.options?.deriveInitialValue as\n | DeriveInitialValueCfg\n | undefined;\n });\n\n // Compute the resolved URL reactively\n const resolvedUrl = computed<string | null>(() => {\n const c = cfg.value;\n if (!c?.config?.url) return null;\n const rendered = renderTpl(c.config.url, { data: rootData.value });\n if (hasUnresolvedTemplates(c.config.url, rendered)) return null;\n return rendered;\n });\n\n const lastFetchedUrl = ref<string | null>(null);\n const loading = ref(false);\n const error = ref<string | undefined>(undefined);\n\n watch(\n resolvedUrl,\n async (url) => {\n if (!url || !cfg.value) return;\n // Only fetch when the URL changes (new context).\n // Same URL = same context; don't override user selection.\n if (url === lastFetchedUrl.value) return;\n lastFetchedUrl.value = url;\n\n loading.value = true;\n error.value = undefined;\n\n try {\n const c = cfg.value.config;\n const fullUrl = new URL(url);\n\n // Query params\n const q = renderObj(c.query ?? {}, {\n data: rootData.value,\n }) as Record<string, unknown>;\n for (const [k, v] of Object.entries(q)) {\n if (v !== undefined && v !== \"\")\n fullUrl.searchParams.set(k, String(v));\n }\n\n // Headers\n const baseHeaders = renderObj(c.headers ?? {}, {\n data: rootData.value,\n }) as Record<string, string>;\n const authHeaders = buildAuthHeaders(c.auth, auth);\n const headers = { ...baseHeaders, ...authHeaders };\n\n const method = c.method ?? \"GET\";\n const requestInit: RequestInit = { method, headers };\n if (method !== \"GET\" && c.body) {\n requestInit.body = JSON.stringify(\n renderObj(c.body, { data: rootData.value }),\n );\n }\n\n const res = await fetch(fullUrl.toString(), requestInit);\n if (!res.ok) {\n if (c.showError !== false) {\n throw new Error(`REST ${res.status}`);\n }\n return;\n }\n\n const json = await res.json();\n let items = jp(json, c.items);\n\n // Apply transforms if provided\n if (c.transforms && c.transforms.length > 0) {\n items = applyTransformPipeline(items, c.transforms);\n }\n\n if (items.length === 0) return; // No items → leave field empty\n\n // Extract value from first item\n const derivedValue = jp(items[0], c.map.value)[0];\n if (derivedValue !== undefined) {\n handleChange(control.value.path, derivedValue);\n }\n } catch (e) {\n error.value = (e as Error)?.message ?? String(e);\n console.warn(\n `deriveInitialValue fetch failed for ${control.value.path}:`,\n e,\n );\n } finally {\n loading.value = false;\n }\n },\n { immediate: true },\n );\n\n return { loading, error };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Ref, type ComputedRef } from "vue";
|
|
2
|
+
export declare function useDirtyValidation(control: Ref<{
|
|
3
|
+
errors: string;
|
|
4
|
+
}>, errorsOverride?: Ref<string> | ComputedRef<string>): {
|
|
5
|
+
hasInteracted: Ref<boolean, boolean>;
|
|
6
|
+
showErrors: ComputedRef<boolean>;
|
|
7
|
+
markDirty: () => void;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=useDirtyValidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDirtyValidation.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useDirtyValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAEhE,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,EAChC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;;;;EAenD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ref, computed } from "vue";
|
|
2
|
+
function useDirtyValidation(control, errorsOverride) {
|
|
3
|
+
const hasInteracted = ref(false);
|
|
4
|
+
const showErrors = computed(
|
|
5
|
+
() => hasInteracted.value && !!(errorsOverride ? errorsOverride.value : control.value.errors)
|
|
6
|
+
);
|
|
7
|
+
const markDirty = () => {
|
|
8
|
+
hasInteracted.value = true;
|
|
9
|
+
};
|
|
10
|
+
return { hasInteracted, showErrors, markDirty };
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useDirtyValidation
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useDirtyValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDirtyValidation.js","sources":["../../../src/vue/composables/useDirtyValidation.ts"],"sourcesContent":["import { ref, computed, type Ref, type ComputedRef } from \"vue\";\n\nexport function useDirtyValidation(\n control: Ref<{ errors: string }>,\n errorsOverride?: Ref<string> | ComputedRef<string>,\n) {\n const hasInteracted = ref(false);\n\n const showErrors = computed(\n () =>\n hasInteracted.value &&\n !!(errorsOverride ? errorsOverride.value : control.value.errors),\n );\n\n const markDirty = () => {\n hasInteracted.value = true;\n };\n\n return { hasInteracted, showErrors, markDirty };\n}\n"],"names":[],"mappings":";AAEO,SAAS,mBACd,SACA,gBACA;AACA,QAAM,gBAAgB,IAAI,KAAK;AAE/B,QAAM,aAAa;AAAA,IACjB,MACE,cAAc,SACd,CAAC,EAAE,iBAAiB,eAAe,QAAQ,QAAQ,MAAM;AAAA,EAAA;AAG7D,QAAM,YAAY,MAAM;AACtB,kBAAc,QAAQ;AAAA,EACxB;AAEA,SAAO,EAAE,eAAe,YAAY,UAAA;AACtC;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ComputedRef, type Ref } from "vue";
|
|
2
|
+
interface ProjectionControl {
|
|
3
|
+
data: unknown;
|
|
4
|
+
path: string;
|
|
5
|
+
errors: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
schema: Record<string, any>;
|
|
8
|
+
uischema: {
|
|
9
|
+
options?: {
|
|
10
|
+
projection?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface ProjectionResult {
|
|
16
|
+
/** The value at the projected path (for rendering) */
|
|
17
|
+
projectedData: ComputedRef<unknown>;
|
|
18
|
+
/** The schema at the projected path (for renderer selection) */
|
|
19
|
+
projectedSchema: ComputedRef<Record<string, any>>;
|
|
20
|
+
/** Wrapped handleChange that writes through the projection */
|
|
21
|
+
handleProjectedChange: (path: string, value: unknown) => void;
|
|
22
|
+
/** Whether projection is active */
|
|
23
|
+
hasProjection: boolean;
|
|
24
|
+
/** Resolved display label (options.label → projected schema title → control.label) */
|
|
25
|
+
projectedLabel: ComputedRef<string>;
|
|
26
|
+
/** Error string combining base-path and projected sub-path errors */
|
|
27
|
+
projectedErrors: ComputedRef<string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Composable that wraps a JSON Forms control with projection support.
|
|
31
|
+
*
|
|
32
|
+
* When `options.projection` is set on the uischema, this composable:
|
|
33
|
+
* - Reads the projected sub-value from the control data
|
|
34
|
+
* - Resolves the projected sub-schema for renderer type resolution
|
|
35
|
+
* - Wraps handleChange to write back through the projection path (preserving siblings)
|
|
36
|
+
*
|
|
37
|
+
* When no projection is set, it passes through control data/schema/handleChange unchanged.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useProjection(control: Ref<ProjectionControl>, handleChange: (path: string, value: unknown) => void): ProjectionResult;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=useProjection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjection.d.ts","sourceRoot":"","sources":["../../../src/vue/composables/useProjection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,WAAW,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAOnE,UAAU,iBAAiB;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,QAAQ,EAAE;QAAE,OAAO,CAAC,EAAE;YAAE,UAAU,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;CACzE;AAyDD,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,aAAa,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,gEAAgE;IAEhE,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAClD,8DAA8D;IAC9D,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9D,mCAAmC;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,sFAAsF;IACtF,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,qEAAqE;IACrE,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,GAAG,CAAC,iBAAiB,CAAC,EAC/B,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GACnD,gBAAgB,CA+ElB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { computed, inject } from "vue";
|
|
2
|
+
import { getProjectedValue, getProjectedSchema, setProjectedValue } from "../../core/projection.js";
|
|
3
|
+
function resolveLabel(ctrl, schemaTitle) {
|
|
4
|
+
return ctrl.uischema?.options?.label ?? schemaTitle ?? ctrl.label ?? "";
|
|
5
|
+
}
|
|
6
|
+
function normalizeErrors(errors) {
|
|
7
|
+
if (!errors) return errors;
|
|
8
|
+
return errors.replace(/is a required property/g, "is required").replace(/must have required property '[^']*'/g, "is required");
|
|
9
|
+
}
|
|
10
|
+
function prefixErrors(label, errors) {
|
|
11
|
+
if (!label || !errors) return errors;
|
|
12
|
+
return errors.split("\n").map((line) => `${label} ${line}`).join("\n");
|
|
13
|
+
}
|
|
14
|
+
function getErrorPath(error) {
|
|
15
|
+
let p = (error.instancePath || "").replace(/\//g, ".").replace(/^\./, "");
|
|
16
|
+
if (error.keyword === "required" && error.params?.missingProperty) {
|
|
17
|
+
p = p ? p + "." + error.params.missingProperty : error.params.missingProperty;
|
|
18
|
+
}
|
|
19
|
+
return p;
|
|
20
|
+
}
|
|
21
|
+
function useProjection(control, handleChange) {
|
|
22
|
+
const projection = control.value.uischema?.options?.projection;
|
|
23
|
+
if (!projection) {
|
|
24
|
+
const label2 = computed(() => resolveLabel(control.value));
|
|
25
|
+
return {
|
|
26
|
+
projectedData: computed(() => control.value.data),
|
|
27
|
+
projectedSchema: computed(() => control.value.schema),
|
|
28
|
+
handleProjectedChange: handleChange,
|
|
29
|
+
hasProjection: false,
|
|
30
|
+
projectedLabel: label2,
|
|
31
|
+
projectedErrors: computed(
|
|
32
|
+
() => prefixErrors(
|
|
33
|
+
label2.value.replace(/\*$/, "").trim(),
|
|
34
|
+
normalizeErrors(control.value.errors)
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const jsonforms = inject(
|
|
40
|
+
"jsonforms",
|
|
41
|
+
null
|
|
42
|
+
);
|
|
43
|
+
const fullProjectedPath = control.value.path + "." + projection;
|
|
44
|
+
const projectedData = computed(
|
|
45
|
+
() => getProjectedValue(control.value.data, projection)
|
|
46
|
+
);
|
|
47
|
+
const projectedSchema = computed(
|
|
48
|
+
() => getProjectedSchema(control.value.schema, projection)
|
|
49
|
+
);
|
|
50
|
+
const label = computed(
|
|
51
|
+
() => resolveLabel(control.value, projectedSchema.value?.title)
|
|
52
|
+
);
|
|
53
|
+
const projectedErrors = computed(() => {
|
|
54
|
+
const baseErrors = normalizeErrors(control.value.errors || "");
|
|
55
|
+
const rawErrors = jsonforms?.core?.errors ?? [];
|
|
56
|
+
const matching = rawErrors.filter(
|
|
57
|
+
(err) => getErrorPath(err) === fullProjectedPath
|
|
58
|
+
);
|
|
59
|
+
let errStr;
|
|
60
|
+
if (matching.length === 0) {
|
|
61
|
+
errStr = baseErrors;
|
|
62
|
+
} else {
|
|
63
|
+
const projMsg = matching.map((e) => e.keyword === "required" ? "is required" : e.message).filter(Boolean).join("\n");
|
|
64
|
+
errStr = [baseErrors, projMsg].filter(Boolean).join("\n");
|
|
65
|
+
}
|
|
66
|
+
return prefixErrors(label.value.replace(/\*$/, "").trim(), errStr);
|
|
67
|
+
});
|
|
68
|
+
const handleProjectedChange = (path, value) => {
|
|
69
|
+
const fullValue = setProjectedValue(control.value.data, projection, value);
|
|
70
|
+
handleChange(path, fullValue);
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
projectedData,
|
|
74
|
+
projectedSchema,
|
|
75
|
+
handleProjectedChange,
|
|
76
|
+
hasProjection: true,
|
|
77
|
+
projectedLabel: label,
|
|
78
|
+
projectedErrors
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
useProjection
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=useProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjection.js","sources":["../../../src/vue/composables/useProjection.ts"],"sourcesContent":["import { computed, inject, type ComputedRef, type Ref } from \"vue\";\nimport {\n getProjectedValue,\n setProjectedValue,\n getProjectedSchema,\n} from \"../../core/projection\";\n\ninterface ProjectionControl {\n data: unknown;\n path: string;\n errors: string;\n label?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>;\n uischema: { options?: { projection?: string; [key: string]: unknown } };\n}\n\n// Minimal AJV ErrorObject shape for filtering\ninterface ErrorLike {\n instancePath?: string;\n keyword?: string;\n message?: string;\n params?: { missingProperty?: string };\n}\n\n/**\n * Resolve the display label for a control.\n * Priority: uischema options.label → schemaTitle (projected sub-schema) → control.label.\n */\nfunction resolveLabel(ctrl: ProjectionControl, schemaTitle?: string): string {\n return (\n (ctrl.uischema?.options?.label as string) ?? schemaTitle ?? ctrl.label ?? \"\"\n );\n}\n\n/**\n * Normalize AJV error message fragments into user-friendly text.\n * e.g. \"is a required property\" → \"is required\"\n */\nfunction normalizeErrors(errors: string): string {\n if (!errors) return errors;\n return errors\n .replace(/is a required property/g, \"is required\")\n .replace(/must have required property '[^']*'/g, \"is required\");\n}\n\n/**\n * Prefix each error message line with the field label so that AJV fragments\n * like \"is required\" become \"Name is required\".\n */\nfunction prefixErrors(label: string, errors: string): string {\n if (!label || !errors) return errors;\n return errors\n .split(\"\\n\")\n .map((line) => `${label} ${line}`)\n .join(\"\\n\");\n}\n\n/**\n * Convert an AJV ErrorObject's instancePath to a dot-separated control path.\n * Replicates the logic from @jsonforms/core getControlPath.\n */\nfunction getErrorPath(error: ErrorLike): string {\n let p = (error.instancePath || \"\").replace(/\\//g, \".\").replace(/^\\./, \"\");\n if (error.keyword === \"required\" && error.params?.missingProperty) {\n p = p\n ? p + \".\" + error.params.missingProperty\n : error.params.missingProperty;\n }\n return p;\n}\n\nexport interface ProjectionResult {\n /** The value at the projected path (for rendering) */\n projectedData: ComputedRef<unknown>;\n /** The schema at the projected path (for renderer selection) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n projectedSchema: ComputedRef<Record<string, any>>;\n /** Wrapped handleChange that writes through the projection */\n handleProjectedChange: (path: string, value: unknown) => void;\n /** Whether projection is active */\n hasProjection: boolean;\n /** Resolved display label (options.label → projected schema title → control.label) */\n projectedLabel: ComputedRef<string>;\n /** Error string combining base-path and projected sub-path errors */\n projectedErrors: ComputedRef<string>;\n}\n\n/**\n * Composable that wraps a JSON Forms control with projection support.\n *\n * When `options.projection` is set on the uischema, this composable:\n * - Reads the projected sub-value from the control data\n * - Resolves the projected sub-schema for renderer type resolution\n * - Wraps handleChange to write back through the projection path (preserving siblings)\n *\n * When no projection is set, it passes through control data/schema/handleChange unchanged.\n */\nexport function useProjection(\n control: Ref<ProjectionControl>,\n handleChange: (path: string, value: unknown) => void,\n): ProjectionResult {\n const projection = control.value.uischema?.options?.projection as\n | string\n | undefined;\n\n if (!projection) {\n const label = computed(() => resolveLabel(control.value));\n return {\n projectedData: computed(() => control.value.data),\n projectedSchema: computed(() => control.value.schema),\n handleProjectedChange: handleChange,\n hasProjection: false,\n projectedLabel: label,\n projectedErrors: computed(() =>\n prefixErrors(\n label.value.replace(/\\*$/, \"\").trim(),\n normalizeErrors(control.value.errors),\n ),\n ),\n };\n }\n\n // Inject JSONForms state to access raw AJV errors for projected sub-paths.\n // control.errors only contains errors at the exact control path (e.g. \"data_rates\"),\n // but projected fields need errors at the full path (e.g. \"data_rates.0.video_rate_usd\").\n const jsonforms = inject<{ core?: { errors?: ErrorLike[] } } | null>(\n \"jsonforms\",\n null,\n );\n\n const fullProjectedPath = control.value.path + \".\" + projection;\n\n const projectedData = computed(() =>\n getProjectedValue(control.value.data, projection),\n );\n\n const projectedSchema = computed(() =>\n getProjectedSchema(control.value.schema, projection),\n );\n\n const label = computed(() =>\n resolveLabel(control.value, projectedSchema.value?.title),\n );\n\n const projectedErrors = computed(() => {\n const baseErrors = normalizeErrors(control.value.errors || \"\");\n\n const rawErrors = jsonforms?.core?.errors ?? [];\n const matching = rawErrors.filter(\n (err) => getErrorPath(err) === fullProjectedPath,\n );\n\n let errStr: string;\n if (matching.length === 0) {\n errStr = baseErrors;\n } else {\n const projMsg = matching\n .map((e) => (e.keyword === \"required\" ? \"is required\" : e.message))\n .filter(Boolean)\n .join(\"\\n\");\n errStr = [baseErrors, projMsg].filter(Boolean).join(\"\\n\");\n }\n\n return prefixErrors(label.value.replace(/\\*$/, \"\").trim(), errStr);\n });\n\n const handleProjectedChange = (path: string, value: unknown) => {\n const fullValue = setProjectedValue(control.value.data, projection, value);\n handleChange(path, fullValue);\n };\n\n return {\n projectedData,\n projectedSchema,\n handleProjectedChange,\n hasProjection: true,\n projectedLabel: label,\n projectedErrors,\n };\n}\n"],"names":["label"],"mappings":";;AA6BA,SAAS,aAAa,MAAyB,aAA8B;AAC3E,SACG,KAAK,UAAU,SAAS,SAAoB,eAAe,KAAK,SAAS;AAE9E;AAMA,SAAS,gBAAgB,QAAwB;AAC/C,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OACJ,QAAQ,2BAA2B,aAAa,EAChD,QAAQ,wCAAwC,aAAa;AAClE;AAMA,SAAS,aAAa,OAAe,QAAwB;AAC3D,MAAI,CAAC,SAAS,CAAC,OAAQ,QAAO;AAC9B,SAAO,OACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,IAAI,EAAE,EAChC,KAAK,IAAI;AACd;AAMA,SAAS,aAAa,OAA0B;AAC9C,MAAI,KAAK,MAAM,gBAAgB,IAAI,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACxE,MAAI,MAAM,YAAY,cAAc,MAAM,QAAQ,iBAAiB;AACjE,QAAI,IACA,IAAI,MAAM,MAAM,OAAO,kBACvB,MAAM,OAAO;AAAA,EACnB;AACA,SAAO;AACT;AA4BO,SAAS,cACd,SACA,cACkB;AAClB,QAAM,aAAa,QAAQ,MAAM,UAAU,SAAS;AAIpD,MAAI,CAAC,YAAY;AACf,UAAMA,SAAQ,SAAS,MAAM,aAAa,QAAQ,KAAK,CAAC;AACxD,WAAO;AAAA,MACL,eAAe,SAAS,MAAM,QAAQ,MAAM,IAAI;AAAA,MAChD,iBAAiB,SAAS,MAAM,QAAQ,MAAM,MAAM;AAAA,MACpD,uBAAuB;AAAA,MACvB,eAAe;AAAA,MACf,gBAAgBA;AAAAA,MAChB,iBAAiB;AAAA,QAAS,MACxB;AAAA,UACEA,OAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,KAAA;AAAA,UAC/B,gBAAgB,QAAQ,MAAM,MAAM;AAAA,QAAA;AAAA,MACtC;AAAA,IACF;AAAA,EAEJ;AAKA,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,EAAA;AAGF,QAAM,oBAAoB,QAAQ,MAAM,OAAO,MAAM;AAErD,QAAM,gBAAgB;AAAA,IAAS,MAC7B,kBAAkB,QAAQ,MAAM,MAAM,UAAU;AAAA,EAAA;AAGlD,QAAM,kBAAkB;AAAA,IAAS,MAC/B,mBAAmB,QAAQ,MAAM,QAAQ,UAAU;AAAA,EAAA;AAGrD,QAAM,QAAQ;AAAA,IAAS,MACrB,aAAa,QAAQ,OAAO,gBAAgB,OAAO,KAAK;AAAA,EAAA;AAG1D,QAAM,kBAAkB,SAAS,MAAM;AACrC,UAAM,aAAa,gBAAgB,QAAQ,MAAM,UAAU,EAAE;AAE7D,UAAM,YAAY,WAAW,MAAM,UAAU,CAAA;AAC7C,UAAM,WAAW,UAAU;AAAA,MACzB,CAAC,QAAQ,aAAa,GAAG,MAAM;AAAA,IAAA;AAGjC,QAAI;AACJ,QAAI,SAAS,WAAW,GAAG;AACzB,eAAS;AAAA,IACX,OAAO;AACL,YAAM,UAAU,SACb,IAAI,CAAC,MAAO,EAAE,YAAY,aAAa,gBAAgB,EAAE,OAAQ,EACjE,OAAO,OAAO,EACd,KAAK,IAAI;AACZ,eAAS,CAAC,YAAY,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IAC1D;AAEA,WAAO,aAAa,MAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,KAAA,GAAQ,MAAM;AAAA,EACnE,CAAC;AAED,QAAM,wBAAwB,CAAC,MAAc,UAAmB;AAC9D,UAAM,YAAY,kBAAkB,QAAQ,MAAM,MAAM,YAAY,KAAK;AACzE,iBAAa,MAAM,SAAS;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB;AAAA,EAAA;AAEJ;"}
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -17,6 +17,13 @@ export declare const providerRenderers: {
|
|
|
17
17
|
export { primevueRenderers, registerPrimevueRenderers } from "./primevue";
|
|
18
18
|
export { ProviderAutocomplete, ProviderSelect, ProviderMultiSelect };
|
|
19
19
|
export { useProvider } from "./composables/useProvider";
|
|
20
|
+
export { useProjection } from "./composables/useProjection";
|
|
21
|
+
export type { ProjectionResult } from "./composables/useProjection";
|
|
22
|
+
export { createDataLayer, useDataLayer } from "./composables/useDataLayer";
|
|
23
|
+
export type { DataLayer } from "./composables/useDataLayer";
|
|
24
|
+
export { useDeriveInitialValue } from "./composables/useDeriveInitialValue";
|
|
25
|
+
export type { DeriveInitialValueCfg } from "./composables/useDeriveInitialValue";
|
|
26
|
+
export { useDirtyValidation } from "./composables/useDirtyValidation";
|
|
20
27
|
export * from "./testers";
|
|
21
28
|
export { JfText, JfTextArea, JfNumber, JfEnum, JfEnumArray, JfBoolean, } from "./primevue";
|
|
22
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/vue/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAWvD,OAAO,oBAAoB,MAAM,uCAAuC,CAAC;AACzE,OAAO,cAAc,MAAM,iCAAiC,CAAC;AAC7D,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AAqEvE,eAAO,MAAM,iBAAiB;;;;;;;;;;;GAI7B,CAAC;AAGF,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAG1E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,YAAY,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,cAAc,WAAW,CAAC;AAG1B,OAAO,EACL,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/vue/index.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { rankWith, and, or, isStringControl, isNumberControl, isControl } from "@jsonforms/core";
|
|
1
|
+
import { rankWith, and, or, isStringControl, isNumberControl, isIntegerControl, isControl } from "@jsonforms/core";
|
|
2
|
+
import { resolveScopeSchema } from "../core/resolveScope.js";
|
|
2
3
|
import _sfc_main from "./components/ProviderAutocomplete.vue.js";
|
|
3
4
|
import ProviderSelect from "./components/ProviderSelect.vue.js";
|
|
4
5
|
import ProviderMultiSelect from "./components/ProviderMultiSelect.vue.js";
|
|
5
6
|
import { primevueRenderers, registerPrimevueRenderers } from "./primevue/index.js";
|
|
6
7
|
import { useProvider } from "./composables/useProvider.js";
|
|
8
|
+
import { useProjection } from "./composables/useProjection.js";
|
|
9
|
+
import { createDataLayer, useDataLayer } from "./composables/useDataLayer.js";
|
|
10
|
+
import { useDeriveInitialValue } from "./composables/useDeriveInitialValue.js";
|
|
11
|
+
import { useDirtyValidation } from "./composables/useDirtyValidation.js";
|
|
7
12
|
import { providerTester } from "./testers.js";
|
|
8
13
|
import { default as default2 } from "./primevue/JfText.vue.js";
|
|
9
14
|
import { default as default3 } from "./primevue/JfTextArea.vue.js";
|
|
@@ -14,43 +19,39 @@ import { default as default7 } from "./primevue/JfBoolean.vue.js";
|
|
|
14
19
|
const hasProvider = (uischema) => {
|
|
15
20
|
return uischema?.options?.provider !== void 0;
|
|
16
21
|
};
|
|
22
|
+
const isIntegerScope = (uischema, schema) => {
|
|
23
|
+
const ui = uischema;
|
|
24
|
+
if (ui?.type !== "Control" || !ui?.scope) return false;
|
|
25
|
+
const propertySchema = resolveScopeSchema(
|
|
26
|
+
ui.scope,
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
schema
|
|
29
|
+
);
|
|
30
|
+
return propertySchema?.type === "integer";
|
|
31
|
+
};
|
|
17
32
|
const providerSelectTester = rankWith(
|
|
18
|
-
|
|
19
|
-
// Higher than PrimeVue
|
|
33
|
+
107,
|
|
34
|
+
// Higher than PrimeVue JfNumber integer renderer (106) so provider wins
|
|
20
35
|
and(
|
|
21
36
|
or(
|
|
22
37
|
isStringControl,
|
|
23
38
|
isNumberControl,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const rootSchema = schema;
|
|
27
|
-
if (ui?.type !== "Control" || !ui?.scope || !rootSchema?.properties)
|
|
28
|
-
return false;
|
|
29
|
-
const propertyName = ui.scope.replace("#/properties/", "");
|
|
30
|
-
const propertySchema = rootSchema.properties[propertyName];
|
|
31
|
-
return propertySchema?.type === "integer";
|
|
32
|
-
})
|
|
39
|
+
isIntegerControl,
|
|
40
|
+
and(isControl, isIntegerScope)
|
|
33
41
|
),
|
|
34
42
|
hasProvider,
|
|
35
43
|
(uischema) => !uischema?.options?.autocomplete
|
|
36
44
|
)
|
|
37
45
|
);
|
|
38
46
|
const providerAutocompleteTester = rankWith(
|
|
39
|
-
|
|
40
|
-
// Higher than
|
|
47
|
+
108,
|
|
48
|
+
// Higher than providerSelectTester so autocomplete variant wins when flagged
|
|
41
49
|
and(
|
|
42
50
|
or(
|
|
43
51
|
isStringControl,
|
|
44
52
|
isNumberControl,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const rootSchema = schema;
|
|
48
|
-
if (ui?.type !== "Control" || !ui?.scope || !rootSchema?.properties)
|
|
49
|
-
return false;
|
|
50
|
-
const propertyName = ui.scope.replace("#/properties/", "");
|
|
51
|
-
const propertySchema = rootSchema.properties[propertyName];
|
|
52
|
-
return propertySchema?.type === "integer";
|
|
53
|
-
})
|
|
53
|
+
isIntegerControl,
|
|
54
|
+
and(isControl, isIntegerScope)
|
|
54
55
|
),
|
|
55
56
|
hasProvider,
|
|
56
57
|
(uischema) => uischema?.options?.autocomplete === true
|
|
@@ -61,13 +62,15 @@ const isArrayControl = (uischema, schema) => {
|
|
|
61
62
|
if (controlSchema.type !== "Control" || !controlSchema.scope) {
|
|
62
63
|
return false;
|
|
63
64
|
}
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
const propertySchema = resolveScopeSchema(
|
|
66
|
+
controlSchema.scope,
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
schema
|
|
69
|
+
);
|
|
67
70
|
return propertySchema?.type === "array";
|
|
68
71
|
};
|
|
69
72
|
const providerMultiSelectTester = rankWith(
|
|
70
|
-
|
|
73
|
+
109,
|
|
71
74
|
// Highest priority for array controls with providers
|
|
72
75
|
and(isArrayControl, hasProvider)
|
|
73
76
|
);
|
|
@@ -86,10 +89,15 @@ export {
|
|
|
86
89
|
_sfc_main as ProviderAutocomplete,
|
|
87
90
|
ProviderMultiSelect,
|
|
88
91
|
ProviderSelect,
|
|
92
|
+
createDataLayer,
|
|
89
93
|
primevueRenderers,
|
|
90
94
|
providerRenderers,
|
|
91
95
|
providerTester,
|
|
92
96
|
registerPrimevueRenderers,
|
|
97
|
+
useDataLayer,
|
|
98
|
+
useDeriveInitialValue,
|
|
99
|
+
useDirtyValidation,
|
|
100
|
+
useProjection,
|
|
93
101
|
useProvider
|
|
94
102
|
};
|
|
95
103
|
//# sourceMappingURL=index.js.map
|
package/dist/vue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/vue/index.ts"],"sourcesContent":["import type { UISchemaElement } from \"@jsonforms/core\";\nimport {\n and,\n isNumberControl,\n isStringControl,\n or,\n rankWith,\n isControl,\n} from \"@jsonforms/core\";\nimport ProviderAutocomplete from \"./components/ProviderAutocomplete.vue\";\nimport ProviderSelect from \"./components/ProviderSelect.vue\";\nimport ProviderMultiSelect from \"./components/ProviderMultiSelect.vue\";\n\n// Custom tester that checks if provider option exists (as object or boolean)\nconst hasProvider = (uischema: UISchemaElement) => {\n return uischema?.options?.provider !== undefined;\n};\n\n//
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/vue/index.ts"],"sourcesContent":["import type { UISchemaElement } from \"@jsonforms/core\";\nimport {\n and,\n isIntegerControl,\n isNumberControl,\n isStringControl,\n or,\n rankWith,\n isControl,\n} from \"@jsonforms/core\";\nimport { resolveScopeSchema } from \"../core/resolveScope\";\nimport ProviderAutocomplete from \"./components/ProviderAutocomplete.vue\";\nimport ProviderSelect from \"./components/ProviderSelect.vue\";\nimport ProviderMultiSelect from \"./components/ProviderMultiSelect.vue\";\n\n// Custom tester that checks if provider option exists (as object or boolean)\nconst hasProvider = (uischema: UISchemaElement) => {\n return uischema?.options?.provider !== undefined;\n};\n\n// Integer fallback tester — handles nested scopes like #/properties/parent/properties/child\nconst isIntegerScope = (uischema: unknown, schema: unknown) => {\n const ui = uischema as { type?: string; scope?: string };\n if (ui?.type !== \"Control\" || !ui?.scope) return false;\n\n const propertySchema = resolveScopeSchema(\n ui.scope,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema as Record<string, any>,\n );\n return propertySchema?.type === \"integer\";\n};\n\n// Create specific testers for each component type\nconst providerSelectTester = rankWith(\n 107, // Higher than PrimeVue JfNumber integer renderer (106) so provider wins\n and(\n or(\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and(isControl, isIntegerScope),\n ),\n hasProvider,\n (uischema) => !uischema?.options?.autocomplete,\n ),\n);\n\nconst providerAutocompleteTester = rankWith(\n 108, // Higher than providerSelectTester so autocomplete variant wins when flagged\n and(\n or(\n isStringControl,\n isNumberControl,\n isIntegerControl,\n and(isControl, isIntegerScope),\n ),\n hasProvider,\n (uischema) => uischema?.options?.autocomplete === true,\n ),\n);\n\n// Custom array tester - supports nested scope paths\nconst isArrayControl = (uischema: UISchemaElement, schema: unknown) => {\n const controlSchema = uischema as { type: string; scope?: string };\n if (controlSchema.type !== \"Control\" || !controlSchema.scope) {\n return false;\n }\n\n const propertySchema = resolveScopeSchema(\n controlSchema.scope,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema as Record<string, any>,\n );\n return propertySchema?.type === \"array\";\n};\n\nconst providerMultiSelectTester = rankWith(\n 109, // Highest priority for array controls with providers\n and(isArrayControl, hasProvider),\n);\n\nexport const providerRenderers = [\n { tester: providerMultiSelectTester, renderer: ProviderMultiSelect },\n { tester: providerAutocompleteTester, renderer: ProviderAutocomplete },\n { tester: providerSelectTester, renderer: ProviderSelect },\n];\n\n// Export PrimeVue renderers (styles are auto-injected)\nexport { primevueRenderers, registerPrimevueRenderers } from \"./primevue\";\n\n// Export individual components\nexport { ProviderAutocomplete, ProviderSelect, ProviderMultiSelect };\nexport { useProvider } from \"./composables/useProvider\";\nexport { useProjection } from \"./composables/useProjection\";\nexport type { ProjectionResult } from \"./composables/useProjection\";\nexport { createDataLayer, useDataLayer } from \"./composables/useDataLayer\";\nexport type { DataLayer } from \"./composables/useDataLayer\";\nexport { useDeriveInitialValue } from \"./composables/useDeriveInitialValue\";\nexport type { DeriveInitialValueCfg } from \"./composables/useDeriveInitialValue\";\nexport { useDirtyValidation } from \"./composables/useDirtyValidation\";\nexport * from \"./testers\";\n\n// Export individual PrimeVue components using lazy evaluation to avoid circular deps\nexport {\n JfText,\n JfTextArea,\n JfNumber,\n JfEnum,\n JfEnumArray,\n JfBoolean,\n} from \"./primevue\";\n"],"names":["ProviderAutocomplete"],"mappings":";;;;;;;;;;;;;;;;;;AAgBA,MAAM,cAAc,CAAC,aAA8B;AACjD,SAAO,UAAU,SAAS,aAAa;AACzC;AAGA,MAAM,iBAAiB,CAAC,UAAmB,WAAoB;AAC7D,QAAM,KAAK;AACX,MAAI,IAAI,SAAS,aAAa,CAAC,IAAI,MAAO,QAAO;AAEjD,QAAM,iBAAiB;AAAA,IACrB,GAAG;AAAA;AAAA,IAEH;AAAA,EAAA;AAEF,SAAO,gBAAgB,SAAS;AAClC;AAGA,MAAM,uBAAuB;AAAA,EAC3B;AAAA;AAAA,EACA;AAAA,IACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,WAAW,cAAc;AAAA,IAAA;AAAA,IAE/B;AAAA,IACA,CAAC,aAAa,CAAC,UAAU,SAAS;AAAA,EAAA;AAEtC;AAEA,MAAM,6BAA6B;AAAA,EACjC;AAAA;AAAA,EACA;AAAA,IACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,WAAW,cAAc;AAAA,IAAA;AAAA,IAE/B;AAAA,IACA,CAAC,aAAa,UAAU,SAAS,iBAAiB;AAAA,EAAA;AAEtD;AAGA,MAAM,iBAAiB,CAAC,UAA2B,WAAoB;AACrE,QAAM,gBAAgB;AACtB,MAAI,cAAc,SAAS,aAAa,CAAC,cAAc,OAAO;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB;AAAA,IACrB,cAAc;AAAA;AAAA,IAEd;AAAA,EAAA;AAEF,SAAO,gBAAgB,SAAS;AAClC;AAEA,MAAM,4BAA4B;AAAA,EAChC;AAAA;AAAA,EACA,IAAI,gBAAgB,WAAW;AACjC;AAEO,MAAM,oBAAoB;AAAA,EAC/B,EAAE,QAAQ,2BAA2B,UAAU,oBAAA;AAAA,EAC/C,EAAE,QAAQ,4BAA4B,UAAUA,UAAA;AAAA,EAChD,EAAE,QAAQ,sBAAsB,UAAU,eAAA;AAC5C;"}
|
|
@@ -18,14 +18,17 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
18
18
|
renderers: {
|
|
19
19
|
type: ArrayConstructor;
|
|
20
20
|
required: false;
|
|
21
|
+
default: undefined;
|
|
21
22
|
};
|
|
22
23
|
cells: {
|
|
23
24
|
type: ArrayConstructor;
|
|
24
25
|
required: false;
|
|
26
|
+
default: undefined;
|
|
25
27
|
};
|
|
26
28
|
config: {
|
|
27
29
|
type: ObjectConstructor;
|
|
28
30
|
required: false;
|
|
31
|
+
default: undefined;
|
|
29
32
|
};
|
|
30
33
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
31
34
|
uischema: {
|
|
@@ -47,17 +50,23 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
47
50
|
renderers: {
|
|
48
51
|
type: ArrayConstructor;
|
|
49
52
|
required: false;
|
|
53
|
+
default: undefined;
|
|
50
54
|
};
|
|
51
55
|
cells: {
|
|
52
56
|
type: ArrayConstructor;
|
|
53
57
|
required: false;
|
|
58
|
+
default: undefined;
|
|
54
59
|
};
|
|
55
60
|
config: {
|
|
56
61
|
type: ObjectConstructor;
|
|
57
62
|
required: false;
|
|
63
|
+
default: undefined;
|
|
58
64
|
};
|
|
59
65
|
}>> & Readonly<{}>, {
|
|
66
|
+
config: Record<string, any>;
|
|
60
67
|
enabled: boolean;
|
|
68
|
+
renderers: unknown[];
|
|
69
|
+
cells: unknown[];
|
|
61
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
62
71
|
export default _default;
|
|
63
72
|
//# sourceMappingURL=JfBoolean.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JfBoolean.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfBoolean.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"JfBoolean.vue.d.ts","sourceRoot":"","sources":["../../../src/vue/primevue/JfBoolean.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,wBAoLK"}
|