@evanschleret/formforgeclient 1.0.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 (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/dist/module.cjs +112 -0
  4. package/dist/module.d.cts +20 -0
  5. package/dist/module.d.mts +20 -0
  6. package/dist/module.d.ts +20 -0
  7. package/dist/module.json +12 -0
  8. package/dist/module.mjs +109 -0
  9. package/dist/runtime/api/categories.d.ts +9 -0
  10. package/dist/runtime/api/categories.js +83 -0
  11. package/dist/runtime/api/client.d.ts +45 -0
  12. package/dist/runtime/api/client.js +148 -0
  13. package/dist/runtime/api/drafts.d.ts +6 -0
  14. package/dist/runtime/api/drafts.js +77 -0
  15. package/dist/runtime/api/http.d.ts +3 -0
  16. package/dist/runtime/api/http.js +138 -0
  17. package/dist/runtime/api/index.d.ts +9 -0
  18. package/dist/runtime/api/index.js +11 -0
  19. package/dist/runtime/api/management.d.ts +19 -0
  20. package/dist/runtime/api/management.js +180 -0
  21. package/dist/runtime/api/request.d.ts +8 -0
  22. package/dist/runtime/api/request.js +52 -0
  23. package/dist/runtime/api/responses.d.ts +6 -0
  24. package/dist/runtime/api/responses.js +61 -0
  25. package/dist/runtime/api/schema.d.ts +7 -0
  26. package/dist/runtime/api/schema.js +56 -0
  27. package/dist/runtime/api/submission.d.ts +11 -0
  28. package/dist/runtime/api/submission.js +47 -0
  29. package/dist/runtime/api/upload.d.ts +8 -0
  30. package/dist/runtime/api/upload.js +37 -0
  31. package/dist/runtime/composables/index.d.ts +31 -0
  32. package/dist/runtime/composables/index.js +16 -0
  33. package/dist/runtime/composables/useFormForgeApi.d.ts +3 -0
  34. package/dist/runtime/composables/useFormForgeApi.js +4 -0
  35. package/dist/runtime/composables/useFormForgeBuilder.d.ts +57 -0
  36. package/dist/runtime/composables/useFormForgeBuilder.js +515 -0
  37. package/dist/runtime/composables/useFormForgeCategory.d.ts +61 -0
  38. package/dist/runtime/composables/useFormForgeCategory.js +248 -0
  39. package/dist/runtime/composables/useFormForgeClient.d.ts +3 -0
  40. package/dist/runtime/composables/useFormForgeClient.js +200 -0
  41. package/dist/runtime/composables/useFormForgeDrafts.d.ts +20 -0
  42. package/dist/runtime/composables/useFormForgeDrafts.js +78 -0
  43. package/dist/runtime/composables/useFormForgeForm.d.ts +26 -0
  44. package/dist/runtime/composables/useFormForgeForm.js +114 -0
  45. package/dist/runtime/composables/useFormForgeGetForm.d.ts +22 -0
  46. package/dist/runtime/composables/useFormForgeGetForm.js +36 -0
  47. package/dist/runtime/composables/useFormForgeI18n.d.ts +250 -0
  48. package/dist/runtime/composables/useFormForgeI18n.js +324 -0
  49. package/dist/runtime/composables/useFormForgeManagement.d.ts +40 -0
  50. package/dist/runtime/composables/useFormForgeManagement.js +153 -0
  51. package/dist/runtime/composables/useFormForgeResolver.d.ts +28 -0
  52. package/dist/runtime/composables/useFormForgeResolver.js +88 -0
  53. package/dist/runtime/composables/useFormForgeResponses.d.ts +45 -0
  54. package/dist/runtime/composables/useFormForgeResponses.js +206 -0
  55. package/dist/runtime/composables/useFormForgeSchema.d.ts +24 -0
  56. package/dist/runtime/composables/useFormForgeSchema.js +69 -0
  57. package/dist/runtime/composables/useFormForgeSubmission.d.ts +12 -0
  58. package/dist/runtime/composables/useFormForgeSubmission.js +4 -0
  59. package/dist/runtime/composables/useFormForgeSubmit.d.ts +29 -0
  60. package/dist/runtime/composables/useFormForgeSubmit.js +291 -0
  61. package/dist/runtime/composables/useFormForgeUploads.d.ts +21 -0
  62. package/dist/runtime/composables/useFormForgeUploads.js +37 -0
  63. package/dist/runtime/composables/useFormForgeWizard.d.ts +20 -0
  64. package/dist/runtime/composables/useFormForgeWizard.js +83 -0
  65. package/dist/runtime/index.d.ts +11 -0
  66. package/dist/runtime/index.js +14 -0
  67. package/dist/runtime/plugin.d.ts +3 -0
  68. package/dist/runtime/plugin.js +175 -0
  69. package/dist/runtime/renderers/default/FormForgeBuilder.d.vue.ts +40 -0
  70. package/dist/runtime/renderers/default/FormForgeBuilder.vue +1159 -0
  71. package/dist/runtime/renderers/default/FormForgeBuilder.vue.d.ts +40 -0
  72. package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.d.vue.ts +16 -0
  73. package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.vue +129 -0
  74. package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.vue.d.ts +16 -0
  75. package/dist/runtime/renderers/default/FormForgeRenderer.d.vue.ts +72 -0
  76. package/dist/runtime/renderers/default/FormForgeRenderer.vue +1188 -0
  77. package/dist/runtime/renderers/default/FormForgeRenderer.vue.d.ts +72 -0
  78. package/dist/runtime/renderers/default/FormForgeResponse.d.vue.ts +18 -0
  79. package/dist/runtime/renderers/default/FormForgeResponse.vue +744 -0
  80. package/dist/runtime/renderers/default/FormForgeResponse.vue.d.ts +18 -0
  81. package/dist/runtime/renderers/default/index.d.ts +5 -0
  82. package/dist/runtime/renderers/default/index.js +4 -0
  83. package/dist/runtime/renderers/index.d.ts +2 -0
  84. package/dist/runtime/renderers/index.js +1 -0
  85. package/dist/runtime/types/api.d.ts +129 -0
  86. package/dist/runtime/types/api.js +0 -0
  87. package/dist/runtime/types/category.d.ts +42 -0
  88. package/dist/runtime/types/category.js +0 -0
  89. package/dist/runtime/types/errors.d.ts +16 -0
  90. package/dist/runtime/types/errors.js +0 -0
  91. package/dist/runtime/types/index.d.ts +8 -0
  92. package/dist/runtime/types/index.js +0 -0
  93. package/dist/runtime/types/json.d.ts +6 -0
  94. package/dist/runtime/types/json.js +0 -0
  95. package/dist/runtime/types/management.d.ts +46 -0
  96. package/dist/runtime/types/management.js +0 -0
  97. package/dist/runtime/types/nuxt.d.ts +13 -0
  98. package/dist/runtime/types/nuxt.js +1 -0
  99. package/dist/runtime/types/schema.d.ts +93 -0
  100. package/dist/runtime/types/schema.js +0 -0
  101. package/dist/runtime/utils/category.d.ts +5 -0
  102. package/dist/runtime/utils/category.js +101 -0
  103. package/dist/runtime/utils/form-data.d.ts +8 -0
  104. package/dist/runtime/utils/form-data.js +64 -0
  105. package/dist/runtime/utils/object.d.ts +8 -0
  106. package/dist/runtime/utils/object.js +43 -0
  107. package/dist/runtime/utils/schema.d.ts +3 -0
  108. package/dist/runtime/utils/schema.js +309 -0
  109. package/dist/runtime/utils/submission.d.ts +4 -0
  110. package/dist/runtime/utils/submission.js +45 -0
  111. package/dist/runtime/validation/errors.d.ts +5 -0
  112. package/dist/runtime/validation/errors.js +130 -0
  113. package/dist/runtime/validation/zod.d.ts +6 -0
  114. package/dist/runtime/validation/zod.js +203 -0
  115. package/dist/runtime.cjs +16 -0
  116. package/dist/runtime.d.cts +1 -0
  117. package/dist/runtime.d.mts +1 -0
  118. package/dist/runtime.d.ts +1 -0
  119. package/dist/runtime.mjs +1 -0
  120. package/dist/types.d.mts +3 -0
  121. package/package.json +60 -0
@@ -0,0 +1,29 @@
1
+ import type { FormForgeRequestOptions } from '../api/request.js';
2
+ import type { FormForgeClient, FormForgeClientConfig, FormForgeFormSchema, FormForgeJsonObject, FormForgeScope, FormForgeSubmissionPayload, FormForgeSubmissionResponse, FormForgeUploadMode } from '../types/index.js';
3
+ export interface UseFormForgeSubmitOptions {
4
+ key: string;
5
+ schema: () => FormForgeFormSchema | null;
6
+ state: () => FormForgeSubmissionPayload;
7
+ version?: string;
8
+ endpoint?: string;
9
+ scope?: FormForgeScope;
10
+ client?: FormForgeClient;
11
+ clientConfig?: FormForgeClientConfig;
12
+ validateLocal?: boolean;
13
+ }
14
+ export interface FormForgeSubmitOptions extends FormForgeRequestOptions {
15
+ mode?: FormForgeUploadMode;
16
+ version?: string;
17
+ meta?: FormForgeJsonObject;
18
+ test?: boolean;
19
+ validateLocal?: boolean;
20
+ }
21
+ export declare function useFormForgeSubmit(options: UseFormForgeSubmitOptions): {
22
+ client: FormForgeClient;
23
+ submitting: any;
24
+ fieldErrors: any;
25
+ error: any;
26
+ response: any;
27
+ submit: (submitOptions?: FormForgeSubmitOptions) => Promise<FormForgeSubmissionResponse>;
28
+ };
29
+ //# sourceMappingURL=useFormForgeSubmit.d.ts.map
@@ -0,0 +1,291 @@
1
+ import { ref } from "#imports";
2
+ import { buildManagedFormData } from "../utils/form-data.js";
3
+ import { toFormForgeJsonSubmissionPayload } from "../utils/submission.js";
4
+ import { createFormForgeZodSchema, validateFormForgePayload } from "../validation/zod.js";
5
+ import { useFormForgeClient } from "./useFormForgeClient.js";
6
+ const RESERVED_SUBMISSION_FIELD_NAMES = [
7
+ "submitted_by_id",
8
+ "submitted_by_type",
9
+ "type",
10
+ "updated_at",
11
+ "ip_address"
12
+ ];
13
+ function isReservedSubmissionFieldName(fieldName) {
14
+ return RESERVED_SUBMISSION_FIELD_NAMES.includes(fieldName);
15
+ }
16
+ function isFileValue(value) {
17
+ if (typeof File === "undefined") {
18
+ return false;
19
+ }
20
+ return value instanceof File;
21
+ }
22
+ function isStagedUploadToken(value) {
23
+ if (value === null || Array.isArray(value) || typeof value !== "object") {
24
+ return false;
25
+ }
26
+ const uploadToken = value.upload_token;
27
+ return typeof uploadToken === "string";
28
+ }
29
+ function isPlainObject(value) {
30
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
31
+ return false;
32
+ }
33
+ if (typeof File !== "undefined" && value instanceof File) {
34
+ return false;
35
+ }
36
+ return true;
37
+ }
38
+ function hasUploadTokenOrPath(value) {
39
+ const uploadToken = value.upload_token;
40
+ if (typeof uploadToken === "string" && uploadToken.trim() !== "") {
41
+ return true;
42
+ }
43
+ const path = value.path;
44
+ if (typeof path === "string" && path.trim() !== "") {
45
+ return true;
46
+ }
47
+ return false;
48
+ }
49
+ function isEmptyFileSubmissionValue(value) {
50
+ if (value === void 0 || value === null) {
51
+ return true;
52
+ }
53
+ if (isFileValue(value) || isStagedUploadToken(value)) {
54
+ return false;
55
+ }
56
+ if (Array.isArray(value)) {
57
+ if (value.length === 0) {
58
+ return true;
59
+ }
60
+ return value.every((item) => {
61
+ if (item === void 0 || item === null) {
62
+ return true;
63
+ }
64
+ if (isFileValue(item)) {
65
+ return false;
66
+ }
67
+ if (isStagedUploadToken(item)) {
68
+ return false;
69
+ }
70
+ if (isPlainObject(item)) {
71
+ return !hasUploadTokenOrPath(item);
72
+ }
73
+ return false;
74
+ });
75
+ }
76
+ if (isPlainObject(value)) {
77
+ return !hasUploadTokenOrPath(value);
78
+ }
79
+ return false;
80
+ }
81
+ function isOptionalFieldValueAbsent(field, value) {
82
+ if (value === void 0 || value === null) {
83
+ return true;
84
+ }
85
+ if (typeof value === "string" && value.trim() === "") {
86
+ return true;
87
+ }
88
+ if (field.type === "file") {
89
+ return isEmptyFileSubmissionValue(value);
90
+ }
91
+ if (field.type === "checkbox_group" && Array.isArray(value) && value.length === 0) {
92
+ return true;
93
+ }
94
+ if ((field.type === "date_range" || field.type === "datetime_range") && isPlainObject(value)) {
95
+ const start = value.start;
96
+ const end = value.end;
97
+ const startEmpty = start === void 0 || start === null || start === "";
98
+ const endEmpty = end === void 0 || end === null || end === "";
99
+ return startEmpty && endEmpty;
100
+ }
101
+ if (Array.isArray(value) && value.length === 0) {
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+ function isFormForgeClientError(error) {
107
+ const maybeError = error;
108
+ return typeof maybeError.status === "number" && typeof maybeError.code === "string" && typeof maybeError.message === "string";
109
+ }
110
+ async function stageSingleFile(client, formKey, field, file, version, endpoint, scope) {
111
+ const staged = await client.stageUpload(
112
+ formKey,
113
+ {
114
+ field: field.name,
115
+ field_key: field.field_key,
116
+ file
117
+ },
118
+ {
119
+ version,
120
+ endpoint,
121
+ scope
122
+ }
123
+ );
124
+ return {
125
+ upload_token: staged.data.staged.upload_token
126
+ };
127
+ }
128
+ async function stageFieldFiles(client, formKey, field, value, version, endpoint, scope) {
129
+ if (value === null || value === void 0 || isStagedUploadToken(value)) {
130
+ return value;
131
+ }
132
+ if (isFileValue(value)) {
133
+ return stageSingleFile(client, formKey, field, value, version, endpoint, scope);
134
+ }
135
+ if (Array.isArray(value)) {
136
+ const stagedValues = [];
137
+ for (const item of value) {
138
+ if (isFileValue(item)) {
139
+ const stagedItem = await stageSingleFile(client, formKey, field, item, version, endpoint, scope);
140
+ stagedValues.push(stagedItem);
141
+ }
142
+ if (isStagedUploadToken(item)) {
143
+ stagedValues.push(item);
144
+ }
145
+ }
146
+ return stagedValues;
147
+ }
148
+ if (isPlainObject(value)) {
149
+ return hasUploadTokenOrPath(value) ? value : null;
150
+ }
151
+ return value;
152
+ }
153
+ function filterSubmittableFields(schema) {
154
+ return schema.fields.filter((field) => !isReservedSubmissionFieldName(field.name));
155
+ }
156
+ function buildSubmissionPayload(fields, state) {
157
+ const payload = {};
158
+ for (const field of fields) {
159
+ const fieldValue = state[field.name];
160
+ if (fieldValue === void 0) {
161
+ continue;
162
+ }
163
+ if (field.required === false && isOptionalFieldValueAbsent(field, fieldValue)) {
164
+ continue;
165
+ }
166
+ payload[field.name] = fieldValue;
167
+ }
168
+ return payload;
169
+ }
170
+ function pruneOptionalEmptyFields(payload, fields) {
171
+ for (const field of fields) {
172
+ if (field.required !== false) {
173
+ continue;
174
+ }
175
+ if (isOptionalFieldValueAbsent(field, payload[field.name])) {
176
+ delete payload[field.name];
177
+ }
178
+ }
179
+ }
180
+ export function useFormForgeSubmit(options) {
181
+ const client = options.client ?? useFormForgeClient(options.clientConfig);
182
+ const submitting = ref(false);
183
+ const fieldErrors = ref({});
184
+ const error = ref(null);
185
+ const response = ref(null);
186
+ async function submit(submitOptions = {}) {
187
+ const schema = options.schema();
188
+ if (schema === null) {
189
+ throw new Error("Schema is not loaded");
190
+ }
191
+ const submittableFields = filterSubmittableFields(schema);
192
+ const submittableSchema = {
193
+ ...schema,
194
+ fields: submittableFields
195
+ };
196
+ const mode = submitOptions.mode ?? options.clientConfig?.uploadMode ?? "staged";
197
+ const version = submitOptions.version ?? options.version;
198
+ const endpoint = submitOptions.endpoint ?? options.endpoint;
199
+ const scope = submitOptions.scope ?? options.scope;
200
+ const payload = buildSubmissionPayload(submittableFields, options.state());
201
+ pruneOptionalEmptyFields(payload, submittableFields);
202
+ fieldErrors.value = {};
203
+ error.value = null;
204
+ submitting.value = true;
205
+ try {
206
+ const shouldValidateLocal = submitOptions.validateLocal ?? options.validateLocal ?? true;
207
+ if (shouldValidateLocal) {
208
+ const localSchema = createFormForgeZodSchema(submittableSchema);
209
+ const localErrors = validateFormForgePayload(localSchema, payload);
210
+ if (Object.keys(localErrors).length > 0) {
211
+ fieldErrors.value = localErrors;
212
+ throw {
213
+ status: 422,
214
+ code: "validation",
215
+ message: "Validation failed",
216
+ fieldErrors: localErrors
217
+ };
218
+ }
219
+ }
220
+ if (mode === "managed") {
221
+ const formData = buildManagedFormData(payload, submitOptions.meta);
222
+ const managedResponse = await client.submitFormMultipart(options.key, formData, {
223
+ version,
224
+ test: submitOptions.test,
225
+ endpoint,
226
+ scope
227
+ });
228
+ response.value = managedResponse;
229
+ return managedResponse;
230
+ }
231
+ const jsonPayload = {
232
+ ...payload
233
+ };
234
+ if (mode === "staged") {
235
+ for (const field of submittableFields) {
236
+ if (field.type !== "file") {
237
+ continue;
238
+ }
239
+ const currentValue = jsonPayload[field.name];
240
+ if (currentValue === void 0) {
241
+ continue;
242
+ }
243
+ const stagedValue = await stageFieldFiles(client, options.key, field, currentValue, version, endpoint, scope);
244
+ if (stagedValue === void 0) {
245
+ delete jsonPayload[field.name];
246
+ continue;
247
+ }
248
+ jsonPayload[field.name] = stagedValue;
249
+ }
250
+ }
251
+ pruneOptionalEmptyFields(jsonPayload, submittableFields);
252
+ const submitResponse = await client.submitForm(
253
+ options.key,
254
+ {
255
+ payload: toFormForgeJsonSubmissionPayload(jsonPayload),
256
+ meta: submitOptions.meta,
257
+ test: submitOptions.test
258
+ },
259
+ {
260
+ version,
261
+ endpoint,
262
+ scope
263
+ }
264
+ );
265
+ response.value = submitResponse;
266
+ return submitResponse;
267
+ } catch (caughtError) {
268
+ if (typeof caughtError === "object" && caughtError !== null && isFormForgeClientError(caughtError)) {
269
+ error.value = caughtError;
270
+ fieldErrors.value = caughtError.fieldErrors ?? {};
271
+ } else {
272
+ error.value = {
273
+ status: 0,
274
+ code: "network_error",
275
+ message: caughtError instanceof Error ? caughtError.message : "Submission failed"
276
+ };
277
+ }
278
+ throw error.value;
279
+ } finally {
280
+ submitting.value = false;
281
+ }
282
+ }
283
+ return {
284
+ client,
285
+ submitting,
286
+ fieldErrors,
287
+ error,
288
+ response,
289
+ submit
290
+ };
291
+ }
@@ -0,0 +1,21 @@
1
+ import type { FormForgeRequestOptions } from '../api/request.js';
2
+ import type { FormForgeClient, FormForgeClientConfig, FormForgeScope, FormForgeStageUploadInput, FormForgeStagedUploadResponse } from '../types/index.js';
3
+ export interface UseFormForgeUploadsOptions {
4
+ key: string;
5
+ version?: string;
6
+ endpoint?: string;
7
+ scope?: FormForgeScope;
8
+ client?: FormForgeClient;
9
+ clientConfig?: FormForgeClientConfig;
10
+ }
11
+ export interface FormForgeUploadOptions extends FormForgeRequestOptions {
12
+ version?: string;
13
+ }
14
+ export declare function useFormForgeUploads(options: UseFormForgeUploadsOptions): {
15
+ client: FormForgeClient;
16
+ uploading: any;
17
+ error: any;
18
+ lastUpload: any;
19
+ stageUpload: (input: FormForgeStageUploadInput, stageOptions?: FormForgeUploadOptions) => Promise<FormForgeStagedUploadResponse>;
20
+ };
21
+ //# sourceMappingURL=useFormForgeUploads.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { ref } from "#imports";
2
+ import { useFormForgeClient } from "./useFormForgeClient.js";
3
+ export function useFormForgeUploads(options) {
4
+ const client = options.client ?? useFormForgeClient(options.clientConfig);
5
+ const uploading = ref(false);
6
+ const error = ref(null);
7
+ const lastUpload = ref(null);
8
+ async function stageUpload(input, stageOptions = {}) {
9
+ uploading.value = true;
10
+ error.value = null;
11
+ try {
12
+ const response = await client.stageUpload(
13
+ options.key,
14
+ input,
15
+ {
16
+ version: stageOptions.version ?? options.version,
17
+ endpoint: stageOptions.endpoint ?? options.endpoint,
18
+ scope: stageOptions.scope ?? options.scope
19
+ }
20
+ );
21
+ lastUpload.value = response;
22
+ return response;
23
+ } catch (caughtError) {
24
+ error.value = caughtError instanceof Error ? caughtError.message : "Failed to stage upload";
25
+ throw caughtError;
26
+ } finally {
27
+ uploading.value = false;
28
+ }
29
+ }
30
+ return {
31
+ client,
32
+ uploading,
33
+ error,
34
+ lastUpload,
35
+ stageUpload
36
+ };
37
+ }
@@ -0,0 +1,20 @@
1
+ import type { FormForgeFormSchema, FormForgePageSchema } from '../types/index.js';
2
+ export interface UseFormForgeWizardOptions {
3
+ schema: () => FormForgeFormSchema | null;
4
+ isPageVisible?: (page: FormForgePageSchema, index: number) => boolean;
5
+ }
6
+ export declare function useFormForgeWizard(options: UseFormForgeWizardOptions): {
7
+ pages: any;
8
+ visiblePages: any;
9
+ pageCount: any;
10
+ pageIndex: any;
11
+ currentPage: any;
12
+ canGoPrevious: any;
13
+ canGoNext: any;
14
+ setPageIndex: (index: number) => void;
15
+ nextPage: () => boolean;
16
+ previousPage: () => boolean;
17
+ goToPage: (pageKey: string) => boolean;
18
+ resetWizard: () => void;
19
+ };
20
+ //# sourceMappingURL=useFormForgeWizard.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { computed, ref, watch } from "#imports";
2
+ export function useFormForgeWizard(options) {
3
+ const pageIndex = ref(0);
4
+ const pages = computed(() => {
5
+ const schema = options.schema();
6
+ if (schema === null) {
7
+ return [];
8
+ }
9
+ return schema.pages;
10
+ });
11
+ const visiblePages = computed(() => {
12
+ if (options.isPageVisible === void 0) {
13
+ return pages.value;
14
+ }
15
+ return pages.value.filter((page, index) => options.isPageVisible?.(page, index) === true);
16
+ });
17
+ const pageCount = computed(() => visiblePages.value.length);
18
+ const currentPage = computed(() => {
19
+ const nextPage2 = visiblePages.value[pageIndex.value];
20
+ return nextPage2 ?? null;
21
+ });
22
+ const canGoPrevious = computed(() => pageIndex.value > 0);
23
+ const canGoNext = computed(() => pageIndex.value < pageCount.value - 1);
24
+ function setPageIndex(index) {
25
+ if (pageCount.value === 0) {
26
+ pageIndex.value = 0;
27
+ return;
28
+ }
29
+ if (index < 0) {
30
+ pageIndex.value = 0;
31
+ return;
32
+ }
33
+ if (index >= pageCount.value) {
34
+ pageIndex.value = pageCount.value - 1;
35
+ return;
36
+ }
37
+ pageIndex.value = index;
38
+ }
39
+ function nextPage() {
40
+ if (!canGoNext.value) {
41
+ return false;
42
+ }
43
+ setPageIndex(pageIndex.value + 1);
44
+ return true;
45
+ }
46
+ function previousPage() {
47
+ if (!canGoPrevious.value) {
48
+ return false;
49
+ }
50
+ setPageIndex(pageIndex.value - 1);
51
+ return true;
52
+ }
53
+ function goToPage(pageKey) {
54
+ const index = visiblePages.value.findIndex((page) => page.page_key === pageKey);
55
+ if (index < 0) {
56
+ return false;
57
+ }
58
+ setPageIndex(index);
59
+ return true;
60
+ }
61
+ function resetWizard() {
62
+ setPageIndex(0);
63
+ }
64
+ watch(visiblePages, () => {
65
+ setPageIndex(pageIndex.value);
66
+ }, {
67
+ immediate: true
68
+ });
69
+ return {
70
+ pages,
71
+ visiblePages,
72
+ pageCount,
73
+ pageIndex,
74
+ currentPage,
75
+ canGoPrevious,
76
+ canGoNext,
77
+ setPageIndex,
78
+ nextPage,
79
+ previousPage,
80
+ goToPage,
81
+ resetWizard
82
+ };
83
+ }
@@ -0,0 +1,11 @@
1
+ export * from './types/index.js';
2
+ export * from './api/index.js';
3
+ export * from './composables/index.js';
4
+ export * from './renderers/index.js';
5
+ export { createFormForgeZodSchema, mapFormForgeZodIssues, validateFormForgePayload } from './validation/zod.js';
6
+ export { normalizeFormForgeClientError, normalizeNetworkFormForgeError, parseFormForgeValidationPayload } from './validation/errors.js';
7
+ export { buildManagedFormData, buildJsonSubmitBody } from './utils/form-data.js';
8
+ export { toFormForgeJsonSubmissionPayload, toFormForgeJsonSubmissionValue } from './utils/submission.js';
9
+ export { normalizeFormForgeSchema } from './utils/schema.js';
10
+ export { normalizeFormForgeCategory, normalizeFormForgeCategoryListResponse, normalizeFormForgeCategoryOptions } from './utils/category.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ export * from "./types/index.js";
2
+ export * from "./api/index.js";
3
+ export * from "./composables/index.js";
4
+ export * from "./renderers/index.js";
5
+ export { createFormForgeZodSchema, mapFormForgeZodIssues, validateFormForgePayload } from "./validation/zod.js";
6
+ export { normalizeFormForgeClientError, normalizeNetworkFormForgeError, parseFormForgeValidationPayload } from "./validation/errors.js";
7
+ export { buildManagedFormData, buildJsonSubmitBody } from "./utils/form-data.js";
8
+ export { toFormForgeJsonSubmissionPayload, toFormForgeJsonSubmissionValue } from "./utils/submission.js";
9
+ export { normalizeFormForgeSchema } from "./utils/schema.js";
10
+ export {
11
+ normalizeFormForgeCategory,
12
+ normalizeFormForgeCategoryListResponse,
13
+ normalizeFormForgeCategoryOptions
14
+ } from "./utils/category.js";
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export default _default;
3
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1,175 @@
1
+ import { defineNuxtPlugin, useRoute, useRuntimeConfig } from "#imports";
2
+ import { createFormForgeClient } from "./api/index.js";
3
+ function readRouteValue(value) {
4
+ if (typeof value === "string" || typeof value === "number") {
5
+ return value;
6
+ }
7
+ if (Array.isArray(value)) {
8
+ const first = value[0];
9
+ if (typeof first === "string" || typeof first === "number") {
10
+ return first;
11
+ }
12
+ }
13
+ return void 0;
14
+ }
15
+ function mergeRouteValues(primaryValues, secondaryValues) {
16
+ const merged = {};
17
+ for (const [key, value] of Object.entries(secondaryValues ?? {})) {
18
+ const resolvedValue = readRouteValue(value);
19
+ if (resolvedValue !== void 0) {
20
+ merged[key] = resolvedValue;
21
+ }
22
+ }
23
+ for (const [key, value] of Object.entries(primaryValues ?? {})) {
24
+ const resolvedValue = readRouteValue(value);
25
+ if (resolvedValue !== void 0) {
26
+ merged[key] = resolvedValue;
27
+ }
28
+ }
29
+ return merged;
30
+ }
31
+ function templateSegmentKey(value) {
32
+ const matched = value.match(/^\{([a-zA-Z0-9_]+)\}$/);
33
+ return matched?.[1] ?? null;
34
+ }
35
+ function toPathSegments(path) {
36
+ if (typeof path !== "string" || path === "") {
37
+ return [];
38
+ }
39
+ let normalizedPath = path;
40
+ if (path.startsWith("http://") || path.startsWith("https://")) {
41
+ try {
42
+ normalizedPath = new URL(path).pathname;
43
+ } catch {
44
+ normalizedPath = path;
45
+ }
46
+ }
47
+ const withoutQueryOrHash = normalizedPath.split("#")[0]?.split("?")[0] ?? normalizedPath;
48
+ return withoutQueryOrHash.split("/").map((segment) => segment.trim()).filter((segment) => segment !== "").map((segment) => decodeURIComponent(segment));
49
+ }
50
+ function inferParamsFromPath(baseURLTemplate, currentPath) {
51
+ const inferred = {};
52
+ const templateSegments = toPathSegments(baseURLTemplate);
53
+ const currentSegments = toPathSegments(currentPath);
54
+ if (templateSegments.length === 0 || currentSegments.length === 0) {
55
+ return inferred;
56
+ }
57
+ for (let index = 0; index < templateSegments.length; index += 1) {
58
+ const templateSegment = templateSegments[index];
59
+ if (templateSegment === void 0) {
60
+ continue;
61
+ }
62
+ const key = templateSegmentKey(templateSegment);
63
+ if (key === null) {
64
+ continue;
65
+ }
66
+ let candidate;
67
+ const previousTemplate = templateSegments[index - 1];
68
+ const nextTemplate = templateSegments[index + 1];
69
+ const previousLiteral = previousTemplate !== void 0 && templateSegmentKey(previousTemplate) === null ? previousTemplate : void 0;
70
+ const nextLiteral = nextTemplate !== void 0 && templateSegmentKey(nextTemplate) === null ? nextTemplate : void 0;
71
+ if (previousLiteral !== void 0) {
72
+ for (let segmentIndex = 0; segmentIndex < currentSegments.length - 1; segmentIndex += 1) {
73
+ if (currentSegments[segmentIndex] === previousLiteral) {
74
+ candidate = currentSegments[segmentIndex + 1];
75
+ break;
76
+ }
77
+ }
78
+ }
79
+ if (candidate === void 0 && nextLiteral !== void 0) {
80
+ for (let segmentIndex = 1; segmentIndex < currentSegments.length; segmentIndex += 1) {
81
+ if (currentSegments[segmentIndex] === nextLiteral) {
82
+ candidate = currentSegments[segmentIndex - 1];
83
+ break;
84
+ }
85
+ }
86
+ }
87
+ if (candidate !== void 0 && candidate !== "") {
88
+ inferred[key] = candidate;
89
+ }
90
+ }
91
+ return inferred;
92
+ }
93
+ function withInferredMissingValues(base, inferred) {
94
+ const resolved = {
95
+ ...base
96
+ };
97
+ for (const [key, value] of Object.entries(inferred)) {
98
+ if (resolved[key] === void 0 || resolved[key] === "") {
99
+ resolved[key] = value;
100
+ }
101
+ }
102
+ return resolved;
103
+ }
104
+ export default defineNuxtPlugin((nuxtApp) => {
105
+ const runtimeConfig = useRuntimeConfig();
106
+ const route = useRoute();
107
+ const publicConfig = runtimeConfig.public.formforge;
108
+ const hookedNuxtApp = nuxtApp;
109
+ const routeParamsResolver = () => {
110
+ const appRouteQuery = hookedNuxtApp._route?.value?.query;
111
+ const appRouteParams = hookedNuxtApp._route?.value?.params;
112
+ const appRoutePath = hookedNuxtApp._route?.value?.path;
113
+ const composableRouteQuery = route.query;
114
+ const composableRouteParams = route.params;
115
+ const composableRoutePath = route.path;
116
+ const mergedRouteValues = mergeRouteValues(
117
+ {
118
+ ...composableRouteQuery,
119
+ ...composableRouteParams
120
+ },
121
+ {
122
+ ...appRouteQuery,
123
+ ...appRouteParams
124
+ }
125
+ );
126
+ const inferredFromPath = inferParamsFromPath(publicConfig?.baseURL, composableRoutePath || appRoutePath);
127
+ return withInferredMissingValues(mergedRouteValues, inferredFromPath);
128
+ };
129
+ const runtimeBaseURLParams = publicConfig?.baseURLParams;
130
+ const runtimeScopeParams = publicConfig?.scopeParams;
131
+ const resolvedBaseURLParams = (() => {
132
+ if (runtimeBaseURLParams === void 0) {
133
+ return routeParamsResolver;
134
+ }
135
+ if (typeof runtimeBaseURLParams === "function") {
136
+ return () => ({
137
+ ...routeParamsResolver(),
138
+ ...runtimeBaseURLParams()
139
+ });
140
+ }
141
+ return () => ({
142
+ ...routeParamsResolver(),
143
+ ...runtimeBaseURLParams
144
+ });
145
+ })();
146
+ const resolvedScopeParams = (() => {
147
+ if (runtimeScopeParams === void 0) {
148
+ return routeParamsResolver;
149
+ }
150
+ if (typeof runtimeScopeParams === "function") {
151
+ return () => ({
152
+ ...routeParamsResolver(),
153
+ ...runtimeScopeParams()
154
+ });
155
+ }
156
+ return () => ({
157
+ ...routeParamsResolver(),
158
+ ...runtimeScopeParams
159
+ });
160
+ })();
161
+ const client = createFormForgeClient({
162
+ ...publicConfig ?? {},
163
+ baseURLParams: resolvedBaseURLParams,
164
+ scopeParams: resolvedScopeParams,
165
+ beforeRequest: async (context) => {
166
+ await publicConfig?.beforeRequest?.(context);
167
+ await hookedNuxtApp.callHook("formforge:beforeRequest", context);
168
+ }
169
+ });
170
+ return {
171
+ provide: {
172
+ formforge: client
173
+ }
174
+ };
175
+ });