@stubber/form-fields 1.4.6 → 1.5.1

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 (98) hide show
  1. package/README.md +61 -295
  2. package/dist/fields2/FieldLabel.svelte +8 -0
  3. package/dist/fields2/FieldLabel.svelte.d.ts +20 -0
  4. package/dist/fields2/FieldMessage.svelte +16 -0
  5. package/dist/fields2/FieldMessage.svelte.d.ts +20 -0
  6. package/dist/fields2/Form.svelte +29 -0
  7. package/dist/fields2/Form.svelte.d.ts +23 -0
  8. package/dist/fields2/fileserver.d.ts +15 -0
  9. package/dist/fields2/fileserver.js +52 -0
  10. package/dist/fields2/form-field.svelte +10 -0
  11. package/dist/fields2/form-field.svelte.d.ts +20 -0
  12. package/dist/fields2/index.d.ts +3 -0
  13. package/dist/fields2/index.js +2 -0
  14. package/dist/fields2/interfaces.d.ts +207 -0
  15. package/dist/fields2/interfaces.js +82 -0
  16. package/dist/fields2/sub/array-builder-field.svelte +110 -0
  17. package/dist/fields2/sub/array-builder-field.svelte.d.ts +27 -0
  18. package/dist/fields2/sub/checkbox-autocomplete.svelte +56 -0
  19. package/dist/fields2/sub/checkbox-autocomplete.svelte.d.ts +27 -0
  20. package/dist/fields2/sub/checkbox-field.svelte +41 -0
  21. package/dist/fields2/sub/checkbox-field.svelte.d.ts +28 -0
  22. package/dist/fields2/sub/code-field.svelte +146 -0
  23. package/dist/fields2/sub/code-field.svelte.d.ts +27 -0
  24. package/dist/fields2/sub/contact-selector-field.svelte +84 -0
  25. package/dist/fields2/sub/contact-selector-field.svelte.d.ts +30 -0
  26. package/dist/fields2/sub/currency-field.svelte +197 -0
  27. package/dist/fields2/sub/currency-field.svelte.d.ts +29 -0
  28. package/dist/fields2/sub/data-indication-field.svelte +19 -0
  29. package/dist/fields2/sub/data-indication-field.svelte.d.ts +23 -0
  30. package/dist/fields2/sub/date-field.svelte +31 -0
  31. package/dist/fields2/sub/date-field.svelte.d.ts +23 -0
  32. package/dist/fields2/sub/date-time-field.svelte +31 -0
  33. package/dist/fields2/sub/date-time-field.svelte.d.ts +23 -0
  34. package/dist/fields2/sub/email-field.svelte +40 -0
  35. package/dist/fields2/sub/email-field.svelte.d.ts +23 -0
  36. package/dist/fields2/sub/field-builder-field.svelte +525 -0
  37. package/dist/fields2/sub/field-builder-field.svelte.d.ts +23 -0
  38. package/dist/fields2/sub/file-field.svelte +150 -0
  39. package/dist/fields2/sub/file-field.svelte.d.ts +27 -0
  40. package/dist/fields2/sub/grid-field.svelte +54 -0
  41. package/dist/fields2/sub/grid-field.svelte.d.ts +30 -0
  42. package/dist/fields2/sub/heading-field.svelte +28 -0
  43. package/dist/fields2/sub/heading-field.svelte.d.ts +28 -0
  44. package/dist/fields2/sub/hidden-field.svelte +142 -0
  45. package/dist/fields2/sub/hidden-field.svelte.d.ts +37 -0
  46. package/dist/fields2/sub/hidden-location-field.svelte +23 -0
  47. package/dist/fields2/sub/hidden-location-field.svelte.d.ts +23 -0
  48. package/dist/fields2/sub/html-field.svelte +22 -0
  49. package/dist/fields2/sub/html-field.svelte.d.ts +27 -0
  50. package/dist/fields2/sub/json-editor-bound.svelte +17 -0
  51. package/dist/fields2/sub/json-editor-bound.svelte.d.ts +65 -0
  52. package/dist/fields2/sub/jsoneditor-field.svelte +23 -0
  53. package/dist/fields2/sub/jsoneditor-field.svelte.d.ts +27 -0
  54. package/dist/fields2/sub/map-field.svelte +144 -0
  55. package/dist/fields2/sub/map-field.svelte.d.ts +28 -0
  56. package/dist/fields2/sub/multi-checkbox-field.svelte +83 -0
  57. package/dist/fields2/sub/multi-checkbox-field.svelte.d.ts +34 -0
  58. package/dist/fields2/sub/multistep-field.svelte +70 -0
  59. package/dist/fields2/sub/multistep-field.svelte.d.ts +24 -0
  60. package/dist/fields2/sub/note-field.svelte +18 -0
  61. package/dist/fields2/sub/note-field.svelte.d.ts +23 -0
  62. package/dist/fields2/sub/number-field.svelte +77 -0
  63. package/dist/fields2/sub/number-field.svelte.d.ts +29 -0
  64. package/dist/fields2/sub/object-builder-field.svelte +123 -0
  65. package/dist/fields2/sub/object-builder-field.svelte.d.ts +28 -0
  66. package/dist/fields2/sub/qr-code-scanner-field.svelte +86 -0
  67. package/dist/fields2/sub/qr-code-scanner-field.svelte.d.ts +23 -0
  68. package/dist/fields2/sub/radio-field.svelte +69 -0
  69. package/dist/fields2/sub/radio-field.svelte.d.ts +30 -0
  70. package/dist/fields2/sub/screenrecorder-field.svelte +182 -0
  71. package/dist/fields2/sub/screenrecorder-field.svelte.d.ts +27 -0
  72. package/dist/fields2/sub/screenshot-field.svelte +165 -0
  73. package/dist/fields2/sub/screenshot-field.svelte.d.ts +26 -0
  74. package/dist/fields2/sub/scroll-and-read-display-field.svelte +92 -0
  75. package/dist/fields2/sub/scroll-and-read-display-field.svelte.d.ts +29 -0
  76. package/dist/fields2/sub/section-field.svelte +27 -0
  77. package/dist/fields2/sub/section-field.svelte.d.ts +26 -0
  78. package/dist/fields2/sub/select-field.svelte +138 -0
  79. package/dist/fields2/sub/select-field.svelte.d.ts +34 -0
  80. package/dist/fields2/sub/selectresource-field.svelte +69 -0
  81. package/dist/fields2/sub/selectresource-field.svelte.d.ts +29 -0
  82. package/dist/fields2/sub/signature-field.svelte +84 -0
  83. package/dist/fields2/sub/signature-field.svelte.d.ts +23 -0
  84. package/dist/fields2/sub/slider-field.svelte +28 -0
  85. package/dist/fields2/sub/slider-field.svelte.d.ts +28 -0
  86. package/dist/fields2/sub/smart-text-field.svelte +245 -0
  87. package/dist/fields2/sub/smart-text-field.svelte.d.ts +36 -0
  88. package/dist/fields2/sub/telephone-field.svelte +68 -0
  89. package/dist/fields2/sub/telephone-field.svelte.d.ts +26 -0
  90. package/dist/fields2/sub/text-field.svelte +46 -0
  91. package/dist/fields2/sub/text-field.svelte.d.ts +27 -0
  92. package/dist/fields2/sub/voicenote-field.svelte +161 -0
  93. package/dist/fields2/sub/voicenote-field.svelte.d.ts +26 -0
  94. package/dist/fields2/utils.d.ts +9 -0
  95. package/dist/fields2/utils.js +116 -0
  96. package/dist/fields2/validations/validate_field.d.ts +11 -0
  97. package/dist/fields2/validations/validate_field.js +121 -0
  98. package/package.json +10 -9
@@ -0,0 +1,161 @@
1
+ <script context="module">import {} from "../interfaces";
2
+ </script>
3
+
4
+ <script>import { Textarea } from "@stubber/ui/textarea";
5
+ import { Button } from "@stubber/ui/button";
6
+ import FieldLabel from "../FieldLabel.svelte";
7
+ import FieldMessage from "../FieldMessage.svelte";
8
+ import { snakeCase } from "lodash-es";
9
+ import {
10
+ append_attachment,
11
+ remove_attachment,
12
+ uploadFiles
13
+ } from "../fileserver";
14
+ export let fieldStore;
15
+ const file_name_prefix = snakeCase($fieldStore.label || "voicenote");
16
+ let mediaRecorder = null;
17
+ let media = [];
18
+ let fileList = [];
19
+ $: isRecording = mediaRecorder?.state === "recording";
20
+ $: buttonLabel = isRecording ? "Stop Recording" : "Start Recording";
21
+ let max_files_param = $fieldStore.params?.max_files;
22
+ $: max_files = isNaN(parseInt(max_files_param)) ? Infinity : parseInt(max_files_param);
23
+ $: limit_remaining = max_files - fileList.length;
24
+ const toggleRecording = () => {
25
+ if (mediaRecorder?.state === "recording") {
26
+ stopRecording();
27
+ } else {
28
+ startRecording();
29
+ }
30
+ };
31
+ async function startRecording() {
32
+ if (limit_remaining <= 0) {
33
+ alert("You have reached the maximum number of files allowed");
34
+ return;
35
+ }
36
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
37
+ mediaRecorder = new MediaRecorder(stream);
38
+ mediaRecorder.ondataavailable = (e) => media.push(e.data);
39
+ mediaRecorder.onstop = function() {
40
+ let id = Math.random().toString(36).substring(7);
41
+ let filename = `${file_name_prefix}_${id}.ogg`;
42
+ let blob = new Blob(media, { type: "audio/ogg; codecs=opus" });
43
+ let file = new File([blob], filename, { type: "audio/ogg; codecs=opus" });
44
+ uploadFile(file, blob, filename);
45
+ media = [];
46
+ mediaRecorder = null;
47
+ };
48
+ mediaRecorder.start();
49
+ }
50
+ async function uploadFile(file, blob, filename) {
51
+ fileList = [
52
+ ...fileList,
53
+ {
54
+ file,
55
+ blob,
56
+ filename,
57
+ is_uploaded: false,
58
+ is_failed: false
59
+ }
60
+ ];
61
+ const upload_res = await uploadFiles([file], $fieldStore.formDependencies);
62
+ const { uploaded_files = [], failed_files = [] } = upload_res || {};
63
+ const newly_uploaded = uploaded_files.find((f) => f.filename === filename) || {};
64
+ const is_uploaded = uploaded_files.length > 0;
65
+ const is_failed = failed_files.length > 0;
66
+ fileList = fileList.map((item) => {
67
+ if (item.filename === filename) {
68
+ return {
69
+ ...item,
70
+ ...newly_uploaded,
71
+ is_uploaded,
72
+ is_failed
73
+ };
74
+ }
75
+ return item;
76
+ });
77
+ if (newly_uploaded.fileuuid) {
78
+ append_attachment(newly_uploaded, $fieldStore.attachmentsStore);
79
+ }
80
+ }
81
+ const update_file_list = (field_value) => {
82
+ if (Array.isArray(field_value)) {
83
+ fileList = field_value.map((f) => ({
84
+ file: f.file,
85
+ blob: f.blob,
86
+ fileuuid: f.fileuuid,
87
+ contentType: f.contentType,
88
+ originalname: f.originalname,
89
+ filename: f.filename,
90
+ is_uploaded: f.is_uploaded || f.fileuuid ? true : false,
91
+ is_failed: f.is_failed || false
92
+ }));
93
+ }
94
+ };
95
+ update_file_list($fieldStore.value);
96
+ $: update_field_value(fileList);
97
+ const update_field_value = (files) => {
98
+ const uploaded_files = files.filter((f) => f.is_uploaded && f.fileuuid);
99
+ $fieldStore.value = uploaded_files.map((f) => ({
100
+ filename: f.filename,
101
+ fileuuid: f.fileuuid,
102
+ contentType: f.contentType,
103
+ originalname: f.originalname
104
+ }));
105
+ };
106
+ function stopRecording() {
107
+ mediaRecorder?.stop();
108
+ }
109
+ function removeFile(item) {
110
+ fileList = fileList.filter((f) => f !== item);
111
+ remove_attachment(item.fileuuid, $fieldStore.attachmentsStore);
112
+ }
113
+ </script>
114
+
115
+ <FieldLabel {fieldStore} />
116
+ <div class="flex flex-col gap-2 items-start">
117
+ <Button variant={isRecording ? "destructive" : "default"} on:click={toggleRecording}>
118
+ {#if isRecording}
119
+ <i class="fa-solid fa-microphone-slash" />
120
+ {:else}
121
+ <i class="fa-solid fa-microphone" />
122
+ {/if}
123
+ {buttonLabel}
124
+ </Button>
125
+ <div class="flex flex-col gap-1 w-full">
126
+ {#each fileList as item}
127
+ <div class="w-full flex flex-row items-center gap-1">
128
+ <div class="flex items-center justify-center w-6 h-6 shrink-0">
129
+ {#if item.is_uploaded}
130
+ <i class="fa fa-check text-success-500" />
131
+ {:else if item.is_failed}
132
+ <i class="fa-regular fa-triangle-exclamation text-danger-400" />
133
+ {:else}
134
+ <i class="fa fa-pulse fa-spinner text-surface-500" />
135
+ {/if}
136
+ </div>
137
+ {#if item?.blob}
138
+ <div class="shrink p-2 w-full">
139
+ <div class="overflow-hidden">
140
+ <audio class="w-full" controls src={window.URL.createObjectURL(item.blob)} />
141
+ </div>
142
+ </div>
143
+ {:else}
144
+ <div class="w-full shrink py-1 pl-2 truncate border border-surface-200 rounded-sm">
145
+ <p class="text-surface-800 text-fluid-md">
146
+ {item?.filename}
147
+ </p>
148
+ </div>
149
+ {/if}
150
+ <Button
151
+ variant="destructive"
152
+ class="h-6 w-6 p-0 shrink-0"
153
+ on:click={() => removeFile(item)}
154
+ >
155
+ <i class="fa-solid fa-2xs fa-x" />
156
+ </Button>
157
+ </div>
158
+ {/each}
159
+ </div>
160
+ </div>
161
+ <FieldMessage {fieldStore} />
@@ -0,0 +1,26 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Writable } from "svelte/store";
3
+ import { type IBaseField, type IBuiltField } from "../interfaces";
4
+ interface IVoicenoteFieldParams {
5
+ max_files?: number | string;
6
+ }
7
+ export interface IVoicenoteField extends IBaseField<IVoicenoteFieldParams> {
8
+ fieldtype: "voicenote";
9
+ }
10
+ declare const __propDef: {
11
+ props: {
12
+ fieldStore: Writable<IBuiltField<IVoicenoteFieldParams>>;
13
+ };
14
+ events: {
15
+ [evt: string]: CustomEvent<any>;
16
+ };
17
+ slots: {};
18
+ exports?: {} | undefined;
19
+ bindings?: string | undefined;
20
+ };
21
+ export type VoicenoteFieldProps = typeof __propDef.props;
22
+ export type VoicenoteFieldEvents = typeof __propDef.events;
23
+ export type VoicenoteFieldSlots = typeof __propDef.slots;
24
+ export default class VoicenoteField extends SvelteComponent<VoicenoteFieldProps, VoicenoteFieldEvents, VoicenoteFieldSlots> {
25
+ }
26
+ export {};
@@ -0,0 +1,9 @@
1
+ import { type Writable } from "svelte/store";
2
+ import type { UploadedFile } from "./fileserver";
3
+ import type { IBuiltField, IField, IFormDependencies, IValidationResult } from "./interfaces";
4
+ export declare const build_fields: (formStore: Writable<any>, attachmentsStore: Writable<UploadedFile[]>, formDependencies: IFormDependencies | undefined, input_fields: Record<string, IField>, base_path?: string | null) => Writable<IBuiltField>[];
5
+ export declare const build_field: (formStore: Writable<any>, attachmentsStore: Writable<UploadedFile[]>, formDependencies: IFormDependencies | undefined, field_key: string, field: IField, base_path?: string | null) => Writable<IBuiltField>;
6
+ export declare const generate_field_data_path: (key: string, field: IField, base_path?: string | null) => string;
7
+ export declare const get_field_label: (key: string, field: IField) => string;
8
+ export declare const get_field_help_message: (field: IBuiltField) => IValidationResult | undefined;
9
+ export declare const set_value_details: (field: IBuiltField, key: "label" | "details", details: any) => void;
@@ -0,0 +1,116 @@
1
+ import { get, isEqual, set, startCase } from "lodash-es";
2
+ import { get as getStoreValue, writable } from "svelte/store";
3
+ export const build_fields = (formStore, attachmentsStore, formDependencies, input_fields, base_path = null) => {
4
+ return Object.entries(input_fields).map(([key, field]) => {
5
+ return build_field(formStore, attachmentsStore, formDependencies, key, field, base_path);
6
+ });
7
+ };
8
+ export const build_field = (formStore, attachmentsStore, formDependencies, field_key, field, base_path = null) => {
9
+ // console.log("dependencies", formDependencies);
10
+ let final_path = generate_field_data_path(field_key, field, base_path);
11
+ const built_field = {
12
+ id: `${field_key}-${final_path}`,
13
+ formStore,
14
+ attachmentsStore,
15
+ formDependencies,
16
+ data_path: final_path,
17
+ fieldtype: field.fieldtype,
18
+ label: get_field_label(field_key, field),
19
+ hide_label: field.hide_label ?? false,
20
+ hidden: false,
21
+ help: field.help,
22
+ validations: field.validations,
23
+ conditions: field.conditions,
24
+ without_value_details: field.without_value_details ?? false,
25
+ get value() {
26
+ const form_data = getStoreValue(formStore);
27
+ return get(form_data, final_path);
28
+ },
29
+ set value(val) {
30
+ formStore.update((f) => set(f, final_path, val));
31
+ },
32
+ get validation_result() {
33
+ return get_field_help_message(this);
34
+ },
35
+ params: field.params,
36
+ };
37
+ if (field.fieldtype === "number" || field.fieldtype === "slider") {
38
+ built_field.min = field.params?.min;
39
+ built_field.max = field.params?.max;
40
+ built_field.step = field.params?.step;
41
+ }
42
+ else if (field.fieldtype === "section" || field.fieldtype === "multistep") {
43
+ // we can build out all the fields in the section upfront
44
+ built_field.sub_fields = build_fields(formStore, attachmentsStore, formDependencies, field?.fields || {}, final_path);
45
+ }
46
+ else if (field.fieldtype === "arraybuilder") {
47
+ // we cant build fields yet, but this is the type of field we will need to build dynamically
48
+ if (!built_field.params) {
49
+ built_field.params = {};
50
+ }
51
+ built_field.params.new_entry_field =
52
+ field.params?.new_entry_field;
53
+ }
54
+ if (field.initvalue) {
55
+ const current_value = built_field.value;
56
+ if (current_value && field.initvalue.has_override) {
57
+ built_field.value = field.initvalue.override;
58
+ }
59
+ else if (!current_value && field.initvalue.has_default) {
60
+ built_field.value = field.initvalue.default;
61
+ }
62
+ }
63
+ return writable(built_field);
64
+ };
65
+ export const generate_field_data_path = (key, field, base_path = null) => {
66
+ let final_key = key;
67
+ if (field.__key) {
68
+ final_key = field.__key;
69
+ }
70
+ if (field.details?.keyname) {
71
+ final_key = field.details.keyname;
72
+ }
73
+ if (field.details?.datapath) {
74
+ final_key = field.details.datapath + "." + final_key;
75
+ }
76
+ if (base_path) {
77
+ final_key = base_path + "." + final_key;
78
+ }
79
+ return final_key;
80
+ };
81
+ export const get_field_label = (key, field) => {
82
+ return field.title || startCase(field.__key || key) || "Untitled Field";
83
+ };
84
+ export const get_field_help_message = (field) => {
85
+ const field_messages = field.errors;
86
+ if (!field_messages) {
87
+ if (field.help) {
88
+ return {
89
+ type: "info",
90
+ message: field.help,
91
+ };
92
+ }
93
+ }
94
+ if (Array.isArray(field_messages)) {
95
+ // return the first error message, else the first success message
96
+ const error = field_messages.find((m) => m.type === "error");
97
+ if (error) {
98
+ return error;
99
+ }
100
+ }
101
+ };
102
+ export const set_value_details = (field, key, details) => {
103
+ if (field.without_value_details) {
104
+ return;
105
+ }
106
+ const value = field.value;
107
+ const formStore = field.formStore;
108
+ const value_details_path = field.data_path + `_${key}`;
109
+ const current_value_details = getStoreValue(formStore)[value_details_path];
110
+ if (!isEqual(current_value_details, details)) {
111
+ formStore.update((f) => {
112
+ set(f, value_details_path, details);
113
+ return f;
114
+ });
115
+ }
116
+ };
@@ -0,0 +1,11 @@
1
+ import type { IJsonataValidation, IRequiredValidation, IRexegValidation, IValidationResult, IBuiltField } from "../interfaces";
2
+ import type { Writable } from "svelte/store";
3
+ export declare const validate_field: (formStore: Writable<any>, fieldStore: Writable<IBuiltField>) => Promise<void>;
4
+ export declare const required_validation: (results: IValidationResult[], value: any, validation: IRequiredValidation) => void;
5
+ export declare const regex_validation: (results: IValidationResult[], value: any, validation: IRexegValidation) => void;
6
+ export declare const jsonata_validation: (results: IValidationResult[], _value: any, validation: IJsonataValidation, context?: any) => Promise<void>;
7
+ export interface JsonataContext {
8
+ field: any;
9
+ form: any;
10
+ }
11
+ export declare const evaluate_field_conditions: (conditions: string[], context: JsonataContext) => Promise<boolean>;
@@ -0,0 +1,121 @@
1
+ import jsonata from "jsonata";
2
+ import { get, set, unset } from "lodash-es";
3
+ import { get as getStoreValue } from "svelte/store";
4
+ export const validate_field = async (formStore, fieldStore) => {
5
+ const results = [];
6
+ const form = getStoreValue(formStore);
7
+ const field = getStoreValue(fieldStore);
8
+ const jsonata_context = {
9
+ field: {
10
+ data: field.value,
11
+ },
12
+ form: {
13
+ data: form,
14
+ },
15
+ };
16
+ if (field.conditions && field.conditions.length > 0) {
17
+ const conditions_passed = await evaluate_field_conditions(field.conditions, jsonata_context);
18
+ if (!conditions_passed) {
19
+ fieldStore.update((f) => {
20
+ f.hidden = true;
21
+ return f;
22
+ });
23
+ return; // Skip validation if conditions are not met
24
+ }
25
+ else {
26
+ fieldStore.update((f) => {
27
+ f.hidden = false;
28
+ return f;
29
+ });
30
+ }
31
+ }
32
+ // validate sub_fields if they exist (arraybuilder and section fields)
33
+ if (field.sub_fields && field.sub_fields.length > 0) {
34
+ // console.log("sub_fields", field.sub_fields);
35
+ for (const sub_field of field.sub_fields || []) {
36
+ // console.log(`Validating sub_field: ${sub_field.__key}`);
37
+ await validate_field(formStore, sub_field);
38
+ }
39
+ }
40
+ const validations = field.validations || [];
41
+ const value = field.value;
42
+ // console.log(`Validating field: ${field.__key}`, value, validations);
43
+ for (const validation of validations) {
44
+ if (validation.validationtype === "required") {
45
+ required_validation(results, value, validation);
46
+ }
47
+ else if (validation.validationtype === "regex") {
48
+ regex_validation(results, value, validation);
49
+ }
50
+ else if (validation.validationtype === "jsonata") {
51
+ await jsonata_validation(results, value, validation, jsonata_context);
52
+ }
53
+ }
54
+ if (results.length === 0) {
55
+ fieldStore.update((f) => {
56
+ unset(f, "errors");
57
+ return f;
58
+ });
59
+ return;
60
+ }
61
+ // console.log(`setting errors for field: ${field.data_path}`, results);
62
+ // fieldStore.errors = results;
63
+ fieldStore.update((f) => {
64
+ f.errors = results;
65
+ return f;
66
+ });
67
+ };
68
+ export const required_validation = (results, value, validation) => {
69
+ if (!value || value.length === 0 || (typeof value === "string" && value.trim() === "")) {
70
+ results.push({
71
+ message: validation.invalid_message || "This field is required.",
72
+ type: "error",
73
+ });
74
+ }
75
+ };
76
+ export const regex_validation = (results, value, validation) => {
77
+ const regex = new RegExp(validation.params.regex);
78
+ if (!regex.test(value ?? "")) {
79
+ results.push({
80
+ message: validation.invalid_message || "This field is invalid.",
81
+ type: "error",
82
+ });
83
+ }
84
+ };
85
+ export const jsonata_validation = async (results, _value, validation, context = {}) => {
86
+ try {
87
+ let result = await jsonata(validation.params.jsonata).evaluate(context);
88
+ console.log(`jsonata context:`, context);
89
+ console.log(`jsonata ${validation.params.jsonata} result:`, result);
90
+ if (!result) {
91
+ results.push({
92
+ message: validation.invalid_message || "This field is invalid.",
93
+ type: "error",
94
+ });
95
+ }
96
+ }
97
+ catch (error) {
98
+ console.error("JSONata validation error:", error);
99
+ results.push({
100
+ message: validation.invalid_message || "Invalid JSONata expression.",
101
+ type: "error",
102
+ });
103
+ }
104
+ };
105
+ export const evaluate_field_conditions = async (conditions, context) => {
106
+ try {
107
+ for (const condition of conditions) {
108
+ // console.log(`Evaluating condition: ${condition}`);
109
+ // console.log("Context:", context);
110
+ const result = await jsonata(condition).evaluate(context);
111
+ if (!result) {
112
+ return false; // If any condition fails, return false
113
+ }
114
+ }
115
+ return true; // All conditions passed
116
+ }
117
+ catch (error) {
118
+ console.error("Error evaluating conditions:", error);
119
+ return false;
120
+ }
121
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stubber/form-fields",
3
- "version": "1.4.6",
3
+ "version": "1.5.1",
4
4
  "description": "An automatic form builder based on field specifications",
5
5
  "keywords": [
6
6
  "components",
@@ -19,6 +19,10 @@
19
19
  ".": {
20
20
  "types": "./dist/index.d.ts",
21
21
  "svelte": "./dist/index.js"
22
+ },
23
+ "./fields2": {
24
+ "types": "./dist/fields2/index.d.ts",
25
+ "svelte": "./dist/fields2/index.js"
22
26
  }
23
27
  },
24
28
  "scripts": {
@@ -32,6 +36,7 @@
32
36
  "format": "prettier --plugin-search-dir . --write ."
33
37
  },
34
38
  "devDependencies": {
39
+ "@beyonk/svelte-mapbox": "^11.0.0",
35
40
  "@sveltejs/adapter-node": "^2.0.0",
36
41
  "@sveltejs/kit": "^2.0.0",
37
42
  "@sveltejs/package": "^2.2.2",
@@ -55,13 +60,12 @@
55
60
  },
56
61
  "type": "module",
57
62
  "dependencies": {
58
- "@beyonk/svelte-mapbox": "^11.0.0",
59
63
  "@codemirror/autocomplete": "^6.19.0",
60
64
  "@codemirror/commands": "^6.8.1",
61
65
  "@codemirror/lang-javascript": "^6.2.4",
62
66
  "@codemirror/state": "^6.5.2",
63
67
  "@codemirror/view": "^6.38.4",
64
- "@stubber/ui": "^1.13.1",
68
+ "@stubber/ui": "^1.13.5",
65
69
  "ag-grid-community": "^31.0.2",
66
70
  "ag-grid-enterprise": "^31.0.2",
67
71
  "codemirror": "^6.0.2",
@@ -83,12 +87,9 @@
83
87
  "svelte-writable-derived": "^3.1.0"
84
88
  },
85
89
  "pnpm": {
86
- "onlyBuiltDependencies": [
87
- "@sveltejs/kit",
88
- "esbuild",
89
- "svelte-preprocess",
90
- "@parcel/watcher"
91
- ]
90
+ "patchedDependencies": {
91
+ "@beyonk/svelte-mapbox@11.0.0": "patches/@beyonk__svelte-mapbox@11.0.0.patch"
92
+ }
92
93
  },
93
94
  "release": {
94
95
  "branches": [