@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.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/module.cjs +112 -0
- package/dist/module.d.cts +20 -0
- package/dist/module.d.mts +20 -0
- package/dist/module.d.ts +20 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +109 -0
- package/dist/runtime/api/categories.d.ts +9 -0
- package/dist/runtime/api/categories.js +83 -0
- package/dist/runtime/api/client.d.ts +45 -0
- package/dist/runtime/api/client.js +148 -0
- package/dist/runtime/api/drafts.d.ts +6 -0
- package/dist/runtime/api/drafts.js +77 -0
- package/dist/runtime/api/http.d.ts +3 -0
- package/dist/runtime/api/http.js +138 -0
- package/dist/runtime/api/index.d.ts +9 -0
- package/dist/runtime/api/index.js +11 -0
- package/dist/runtime/api/management.d.ts +19 -0
- package/dist/runtime/api/management.js +180 -0
- package/dist/runtime/api/request.d.ts +8 -0
- package/dist/runtime/api/request.js +52 -0
- package/dist/runtime/api/responses.d.ts +6 -0
- package/dist/runtime/api/responses.js +61 -0
- package/dist/runtime/api/schema.d.ts +7 -0
- package/dist/runtime/api/schema.js +56 -0
- package/dist/runtime/api/submission.d.ts +11 -0
- package/dist/runtime/api/submission.js +47 -0
- package/dist/runtime/api/upload.d.ts +8 -0
- package/dist/runtime/api/upload.js +37 -0
- package/dist/runtime/composables/index.d.ts +31 -0
- package/dist/runtime/composables/index.js +16 -0
- package/dist/runtime/composables/useFormForgeApi.d.ts +3 -0
- package/dist/runtime/composables/useFormForgeApi.js +4 -0
- package/dist/runtime/composables/useFormForgeBuilder.d.ts +57 -0
- package/dist/runtime/composables/useFormForgeBuilder.js +515 -0
- package/dist/runtime/composables/useFormForgeCategory.d.ts +61 -0
- package/dist/runtime/composables/useFormForgeCategory.js +248 -0
- package/dist/runtime/composables/useFormForgeClient.d.ts +3 -0
- package/dist/runtime/composables/useFormForgeClient.js +200 -0
- package/dist/runtime/composables/useFormForgeDrafts.d.ts +20 -0
- package/dist/runtime/composables/useFormForgeDrafts.js +78 -0
- package/dist/runtime/composables/useFormForgeForm.d.ts +26 -0
- package/dist/runtime/composables/useFormForgeForm.js +114 -0
- package/dist/runtime/composables/useFormForgeGetForm.d.ts +22 -0
- package/dist/runtime/composables/useFormForgeGetForm.js +36 -0
- package/dist/runtime/composables/useFormForgeI18n.d.ts +250 -0
- package/dist/runtime/composables/useFormForgeI18n.js +324 -0
- package/dist/runtime/composables/useFormForgeManagement.d.ts +40 -0
- package/dist/runtime/composables/useFormForgeManagement.js +153 -0
- package/dist/runtime/composables/useFormForgeResolver.d.ts +28 -0
- package/dist/runtime/composables/useFormForgeResolver.js +88 -0
- package/dist/runtime/composables/useFormForgeResponses.d.ts +45 -0
- package/dist/runtime/composables/useFormForgeResponses.js +206 -0
- package/dist/runtime/composables/useFormForgeSchema.d.ts +24 -0
- package/dist/runtime/composables/useFormForgeSchema.js +69 -0
- package/dist/runtime/composables/useFormForgeSubmission.d.ts +12 -0
- package/dist/runtime/composables/useFormForgeSubmission.js +4 -0
- package/dist/runtime/composables/useFormForgeSubmit.d.ts +29 -0
- package/dist/runtime/composables/useFormForgeSubmit.js +291 -0
- package/dist/runtime/composables/useFormForgeUploads.d.ts +21 -0
- package/dist/runtime/composables/useFormForgeUploads.js +37 -0
- package/dist/runtime/composables/useFormForgeWizard.d.ts +20 -0
- package/dist/runtime/composables/useFormForgeWizard.js +83 -0
- package/dist/runtime/index.d.ts +11 -0
- package/dist/runtime/index.js +14 -0
- package/dist/runtime/plugin.d.ts +3 -0
- package/dist/runtime/plugin.js +175 -0
- package/dist/runtime/renderers/default/FormForgeBuilder.d.vue.ts +40 -0
- package/dist/runtime/renderers/default/FormForgeBuilder.vue +1159 -0
- package/dist/runtime/renderers/default/FormForgeBuilder.vue.d.ts +40 -0
- package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.d.vue.ts +16 -0
- package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.vue +129 -0
- package/dist/runtime/renderers/default/FormForgeCategoryCreateModal.vue.d.ts +16 -0
- package/dist/runtime/renderers/default/FormForgeRenderer.d.vue.ts +72 -0
- package/dist/runtime/renderers/default/FormForgeRenderer.vue +1188 -0
- package/dist/runtime/renderers/default/FormForgeRenderer.vue.d.ts +72 -0
- package/dist/runtime/renderers/default/FormForgeResponse.d.vue.ts +18 -0
- package/dist/runtime/renderers/default/FormForgeResponse.vue +744 -0
- package/dist/runtime/renderers/default/FormForgeResponse.vue.d.ts +18 -0
- package/dist/runtime/renderers/default/index.d.ts +5 -0
- package/dist/runtime/renderers/default/index.js +4 -0
- package/dist/runtime/renderers/index.d.ts +2 -0
- package/dist/runtime/renderers/index.js +1 -0
- package/dist/runtime/types/api.d.ts +129 -0
- package/dist/runtime/types/api.js +0 -0
- package/dist/runtime/types/category.d.ts +42 -0
- package/dist/runtime/types/category.js +0 -0
- package/dist/runtime/types/errors.d.ts +16 -0
- package/dist/runtime/types/errors.js +0 -0
- package/dist/runtime/types/index.d.ts +8 -0
- package/dist/runtime/types/index.js +0 -0
- package/dist/runtime/types/json.d.ts +6 -0
- package/dist/runtime/types/json.js +0 -0
- package/dist/runtime/types/management.d.ts +46 -0
- package/dist/runtime/types/management.js +0 -0
- package/dist/runtime/types/nuxt.d.ts +13 -0
- package/dist/runtime/types/nuxt.js +1 -0
- package/dist/runtime/types/schema.d.ts +93 -0
- package/dist/runtime/types/schema.js +0 -0
- package/dist/runtime/utils/category.d.ts +5 -0
- package/dist/runtime/utils/category.js +101 -0
- package/dist/runtime/utils/form-data.d.ts +8 -0
- package/dist/runtime/utils/form-data.js +64 -0
- package/dist/runtime/utils/object.d.ts +8 -0
- package/dist/runtime/utils/object.js +43 -0
- package/dist/runtime/utils/schema.d.ts +3 -0
- package/dist/runtime/utils/schema.js +309 -0
- package/dist/runtime/utils/submission.d.ts +4 -0
- package/dist/runtime/utils/submission.js +45 -0
- package/dist/runtime/validation/errors.d.ts +5 -0
- package/dist/runtime/validation/errors.js +130 -0
- package/dist/runtime/validation/zod.d.ts +6 -0
- package/dist/runtime/validation/zod.js +203 -0
- package/dist/runtime.cjs +16 -0
- package/dist/runtime.d.cts +1 -0
- package/dist/runtime.d.mts +1 -0
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.mjs +1 -0
- package/dist/types.d.mts +3 -0
- package/package.json +60 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { computed, ref } from "#imports";
|
|
2
|
+
import { useFormForgeClient } from "./useFormForgeClient.js";
|
|
3
|
+
import { normalizeFormForgeCategoryOptions as normalizeCategoryOptions } from "../utils/category.js";
|
|
4
|
+
function isFormForgeClientError(value) {
|
|
5
|
+
if (typeof value !== "object" || value === null) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const candidate = value;
|
|
9
|
+
return typeof candidate.status === "number" && typeof candidate.code === "string" && typeof candidate.message === "string";
|
|
10
|
+
}
|
|
11
|
+
function resolveErrorMessage(caughtError) {
|
|
12
|
+
if (caughtError instanceof Error) {
|
|
13
|
+
return caughtError.message;
|
|
14
|
+
}
|
|
15
|
+
return "Categories request failed";
|
|
16
|
+
}
|
|
17
|
+
export function useFormForgeCategory(options = {}) {
|
|
18
|
+
const client = options.client ?? useFormForgeClient(options.clientConfig);
|
|
19
|
+
const loading = ref(false);
|
|
20
|
+
const error = ref(null);
|
|
21
|
+
const clientError = ref(null);
|
|
22
|
+
const list = ref([]);
|
|
23
|
+
const current = ref(null);
|
|
24
|
+
const lastMeta = ref(void 0);
|
|
25
|
+
const lastLinks = ref(void 0);
|
|
26
|
+
const lastListQuery = ref(options.initialQuery ?? {});
|
|
27
|
+
const lastListEndpoint = ref(options.endpoint);
|
|
28
|
+
const lastListScope = ref(options.scope);
|
|
29
|
+
const lastCategoryKey = ref(null);
|
|
30
|
+
const lastMode = ref(null);
|
|
31
|
+
const immediateLoad = options.immediate ?? true;
|
|
32
|
+
const fieldErrors = computed(() => clientError.value?.fieldErrors ?? {});
|
|
33
|
+
const businessErrorCode = computed(() => clientError.value?.businessCode);
|
|
34
|
+
const isCategoryInUse = computed(() => businessErrorCode.value === "CATEGORY_IN_USE");
|
|
35
|
+
async function withLoading(callback) {
|
|
36
|
+
loading.value = true;
|
|
37
|
+
error.value = null;
|
|
38
|
+
clientError.value = null;
|
|
39
|
+
try {
|
|
40
|
+
return await callback();
|
|
41
|
+
} catch (caughtError) {
|
|
42
|
+
error.value = resolveErrorMessage(caughtError);
|
|
43
|
+
if (isFormForgeClientError(caughtError)) {
|
|
44
|
+
clientError.value = caughtError;
|
|
45
|
+
}
|
|
46
|
+
throw caughtError;
|
|
47
|
+
} finally {
|
|
48
|
+
loading.value = false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function resolveEndpoint(requestOptions = {}) {
|
|
52
|
+
return requestOptions.endpoint ?? options.endpoint;
|
|
53
|
+
}
|
|
54
|
+
function resolveScope(requestOptions = {}) {
|
|
55
|
+
return requestOptions.scope ?? options.scope;
|
|
56
|
+
}
|
|
57
|
+
function withDefaultMutationOptions(mutationOptions = {}) {
|
|
58
|
+
return {
|
|
59
|
+
...mutationOptions,
|
|
60
|
+
endpoint: mutationOptions.endpoint ?? options.endpoint,
|
|
61
|
+
scope: mutationOptions.scope ?? options.scope
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function listCategories(query = {}, requestOptions = {}) {
|
|
65
|
+
return withLoading(async () => {
|
|
66
|
+
const resolvedQuery = {
|
|
67
|
+
...lastListQuery.value,
|
|
68
|
+
...query
|
|
69
|
+
};
|
|
70
|
+
const endpoint = resolveEndpoint(requestOptions);
|
|
71
|
+
const scope = resolveScope(requestOptions);
|
|
72
|
+
const response = await client.listCategories(resolvedQuery, {
|
|
73
|
+
endpoint,
|
|
74
|
+
scope
|
|
75
|
+
});
|
|
76
|
+
list.value = response.data;
|
|
77
|
+
lastMeta.value = response.meta;
|
|
78
|
+
lastLinks.value = response.links;
|
|
79
|
+
lastListQuery.value = resolvedQuery;
|
|
80
|
+
lastListEndpoint.value = endpoint;
|
|
81
|
+
lastListScope.value = scope;
|
|
82
|
+
lastMode.value = "list";
|
|
83
|
+
return response;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async function getCategory(categoryKey, requestOptions = {}) {
|
|
87
|
+
return withLoading(async () => {
|
|
88
|
+
const response = await client.getCategory(categoryKey, {
|
|
89
|
+
endpoint: resolveEndpoint(requestOptions),
|
|
90
|
+
scope: resolveScope(requestOptions)
|
|
91
|
+
});
|
|
92
|
+
current.value = response;
|
|
93
|
+
lastCategoryKey.value = categoryKey;
|
|
94
|
+
lastMode.value = "resource";
|
|
95
|
+
return response;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function createCategory(input, options2 = {}) {
|
|
99
|
+
return withLoading(async () => {
|
|
100
|
+
const created = await client.createCategory(input, withDefaultMutationOptions(options2));
|
|
101
|
+
current.value = created;
|
|
102
|
+
list.value = [created, ...list.value.filter((item) => item.key !== created.key)];
|
|
103
|
+
return created;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async function patchCategory(categoryKey, input, options2 = {}) {
|
|
107
|
+
return withLoading(async () => {
|
|
108
|
+
const updated = await client.patchCategory(categoryKey, input, withDefaultMutationOptions(options2));
|
|
109
|
+
current.value = updated;
|
|
110
|
+
list.value = list.value.map((item) => item.key === updated.key ? updated : item);
|
|
111
|
+
return updated;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async function deleteCategory(categoryKey, options2 = {}) {
|
|
115
|
+
return withLoading(async () => {
|
|
116
|
+
const deleted = await client.deleteCategory(categoryKey, withDefaultMutationOptions(options2));
|
|
117
|
+
list.value = list.value.filter((item) => item.key !== categoryKey);
|
|
118
|
+
if (current.value?.key === categoryKey) {
|
|
119
|
+
current.value = null;
|
|
120
|
+
}
|
|
121
|
+
return deleted;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async function refresh(options2 = {}) {
|
|
125
|
+
const mode = options2.mode ?? "auto";
|
|
126
|
+
const endpoint = options2.endpoint ?? lastListEndpoint.value;
|
|
127
|
+
const scope = options2.scope ?? lastListScope.value;
|
|
128
|
+
if (mode === "list") {
|
|
129
|
+
return listCategories(options2.query ?? lastListQuery.value, {
|
|
130
|
+
endpoint,
|
|
131
|
+
scope
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (mode === "resource") {
|
|
135
|
+
const categoryKey = options2.categoryKey ?? lastCategoryKey.value;
|
|
136
|
+
if (typeof categoryKey === "string" && categoryKey !== "") {
|
|
137
|
+
return getCategory(categoryKey, {
|
|
138
|
+
endpoint,
|
|
139
|
+
scope
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return listCategories(options2.query ?? lastListQuery.value, {
|
|
143
|
+
endpoint,
|
|
144
|
+
scope
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (lastMode.value === "resource") {
|
|
148
|
+
const categoryKey = options2.categoryKey ?? lastCategoryKey.value;
|
|
149
|
+
if (typeof categoryKey === "string" && categoryKey !== "") {
|
|
150
|
+
return getCategory(categoryKey, {
|
|
151
|
+
endpoint,
|
|
152
|
+
scope
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return listCategories(options2.query ?? lastListQuery.value, {
|
|
157
|
+
endpoint,
|
|
158
|
+
scope
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
if (immediateLoad) {
|
|
162
|
+
listCategories(options.initialQuery, {
|
|
163
|
+
endpoint: options.endpoint,
|
|
164
|
+
scope: options.scope
|
|
165
|
+
}).catch(() => {
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
client,
|
|
170
|
+
loading,
|
|
171
|
+
error,
|
|
172
|
+
clientError,
|
|
173
|
+
fieldErrors,
|
|
174
|
+
businessErrorCode,
|
|
175
|
+
isCategoryInUse,
|
|
176
|
+
list,
|
|
177
|
+
current,
|
|
178
|
+
lastMeta,
|
|
179
|
+
lastLinks,
|
|
180
|
+
lastListQuery,
|
|
181
|
+
lastListEndpoint,
|
|
182
|
+
lastListScope,
|
|
183
|
+
lastCategoryKey,
|
|
184
|
+
listCategories,
|
|
185
|
+
getCategory,
|
|
186
|
+
createCategory,
|
|
187
|
+
patchCategory,
|
|
188
|
+
deleteCategory,
|
|
189
|
+
refresh
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function readCategorySourceValue(source) {
|
|
193
|
+
if (typeof source === "function") {
|
|
194
|
+
return source();
|
|
195
|
+
}
|
|
196
|
+
if (source !== null && typeof source === "object" && "value" in source) {
|
|
197
|
+
return source.value;
|
|
198
|
+
}
|
|
199
|
+
return source;
|
|
200
|
+
}
|
|
201
|
+
function pickCategoriesFromRecord(record, key) {
|
|
202
|
+
const candidateKeys = [key, "list", "categories", "data"];
|
|
203
|
+
for (const candidateKey of candidateKeys) {
|
|
204
|
+
const candidate = readCategorySourceValue(record[candidateKey]);
|
|
205
|
+
if (Array.isArray(candidate)) {
|
|
206
|
+
return candidate;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const rawData = readCategorySourceValue(record.data);
|
|
210
|
+
if (rawData !== null && typeof rawData === "object") {
|
|
211
|
+
const nestedData = rawData.data;
|
|
212
|
+
const resolvedNestedData = readCategorySourceValue(nestedData);
|
|
213
|
+
if (Array.isArray(resolvedNestedData)) {
|
|
214
|
+
return resolvedNestedData;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
function resolveHelperCategories(options) {
|
|
220
|
+
const source = options.source ?? options.categories;
|
|
221
|
+
const resolvedSource = readCategorySourceValue(source);
|
|
222
|
+
if (Array.isArray(resolvedSource)) {
|
|
223
|
+
return resolvedSource;
|
|
224
|
+
}
|
|
225
|
+
if (resolvedSource !== null && typeof resolvedSource === "object") {
|
|
226
|
+
const key = options.key ?? "list";
|
|
227
|
+
return pickCategoriesFromRecord(resolvedSource, key);
|
|
228
|
+
}
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
export function normalizeFormForgeCategoryOptions(categories, includeInactive = true) {
|
|
232
|
+
return normalizeCategoryOptions(categories, includeInactive);
|
|
233
|
+
}
|
|
234
|
+
export function useFormForgeCategoryOptions(options = {}) {
|
|
235
|
+
const hasExplicitSource = options.source !== void 0 || options.categories !== void 0;
|
|
236
|
+
const categoryLoader = hasExplicitSource ? null : useFormForgeCategory({
|
|
237
|
+
immediate: options.immediate ?? true,
|
|
238
|
+
initialQuery: options.query,
|
|
239
|
+
endpoint: options.endpoint,
|
|
240
|
+
scope: options.scope,
|
|
241
|
+
client: options.client,
|
|
242
|
+
clientConfig: options.clientConfig
|
|
243
|
+
});
|
|
244
|
+
return computed(() => {
|
|
245
|
+
const categories = hasExplicitSource ? resolveHelperCategories(options) : categoryLoader?.list.value ?? [];
|
|
246
|
+
return normalizeFormForgeCategoryOptions(categories, options.includeInactive ?? true);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { useNuxtApp, useRoute, useRuntimeConfig } from "#imports";
|
|
2
|
+
import { createFormForgeClient } from "../api/index.js";
|
|
3
|
+
function hasConfigOverrides(config) {
|
|
4
|
+
return Object.keys(config).length > 0;
|
|
5
|
+
}
|
|
6
|
+
function readRouteValue(value) {
|
|
7
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
const first = value[0];
|
|
12
|
+
if (typeof first === "string" || typeof first === "number") {
|
|
13
|
+
return first;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
function mergeRouteValues(primaryValues, secondaryValues) {
|
|
19
|
+
const merged = {};
|
|
20
|
+
for (const [key, value] of Object.entries(secondaryValues ?? {})) {
|
|
21
|
+
const resolvedValue = readRouteValue(value);
|
|
22
|
+
if (resolvedValue !== void 0) {
|
|
23
|
+
merged[key] = resolvedValue;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const [key, value] of Object.entries(primaryValues ?? {})) {
|
|
27
|
+
const resolvedValue = readRouteValue(value);
|
|
28
|
+
if (resolvedValue !== void 0) {
|
|
29
|
+
merged[key] = resolvedValue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return merged;
|
|
33
|
+
}
|
|
34
|
+
function templateSegmentKey(value) {
|
|
35
|
+
const matched = value.match(/^\{([a-zA-Z0-9_]+)\}$/);
|
|
36
|
+
return matched?.[1] ?? null;
|
|
37
|
+
}
|
|
38
|
+
function toPathSegments(path) {
|
|
39
|
+
if (typeof path !== "string" || path === "") {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
let normalizedPath = path;
|
|
43
|
+
if (path.startsWith("http://") || path.startsWith("https://")) {
|
|
44
|
+
try {
|
|
45
|
+
normalizedPath = new URL(path).pathname;
|
|
46
|
+
} catch {
|
|
47
|
+
normalizedPath = path;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const withoutQueryOrHash = normalizedPath.split("#")[0]?.split("?")[0] ?? normalizedPath;
|
|
51
|
+
return withoutQueryOrHash.split("/").map((segment) => segment.trim()).filter((segment) => segment !== "").map((segment) => decodeURIComponent(segment));
|
|
52
|
+
}
|
|
53
|
+
function inferParamsFromPath(baseURLTemplate, currentPath) {
|
|
54
|
+
const inferred = {};
|
|
55
|
+
const templateSegments = toPathSegments(baseURLTemplate);
|
|
56
|
+
const currentSegments = toPathSegments(currentPath);
|
|
57
|
+
if (templateSegments.length === 0 || currentSegments.length === 0) {
|
|
58
|
+
return inferred;
|
|
59
|
+
}
|
|
60
|
+
for (let index = 0; index < templateSegments.length; index += 1) {
|
|
61
|
+
const templateSegment = templateSegments[index];
|
|
62
|
+
if (templateSegment === void 0) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const key = templateSegmentKey(templateSegment);
|
|
66
|
+
if (key === null) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
let candidate;
|
|
70
|
+
const previousTemplate = templateSegments[index - 1];
|
|
71
|
+
const nextTemplate = templateSegments[index + 1];
|
|
72
|
+
const previousLiteral = previousTemplate !== void 0 && templateSegmentKey(previousTemplate) === null ? previousTemplate : void 0;
|
|
73
|
+
const nextLiteral = nextTemplate !== void 0 && templateSegmentKey(nextTemplate) === null ? nextTemplate : void 0;
|
|
74
|
+
if (previousLiteral !== void 0) {
|
|
75
|
+
for (let segmentIndex = 0; segmentIndex < currentSegments.length - 1; segmentIndex += 1) {
|
|
76
|
+
if (currentSegments[segmentIndex] === previousLiteral) {
|
|
77
|
+
candidate = currentSegments[segmentIndex + 1];
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (candidate === void 0 && nextLiteral !== void 0) {
|
|
83
|
+
for (let segmentIndex = 1; segmentIndex < currentSegments.length; segmentIndex += 1) {
|
|
84
|
+
if (currentSegments[segmentIndex] === nextLiteral) {
|
|
85
|
+
candidate = currentSegments[segmentIndex - 1];
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (candidate !== void 0 && candidate !== "") {
|
|
91
|
+
inferred[key] = candidate;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return inferred;
|
|
95
|
+
}
|
|
96
|
+
function withInferredMissingValues(base, inferred) {
|
|
97
|
+
const resolved = {
|
|
98
|
+
...base
|
|
99
|
+
};
|
|
100
|
+
for (const [key, value] of Object.entries(inferred)) {
|
|
101
|
+
if (resolved[key] === void 0 || resolved[key] === "") {
|
|
102
|
+
resolved[key] = value;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return resolved;
|
|
106
|
+
}
|
|
107
|
+
export function useFormForgeClient(config = {}) {
|
|
108
|
+
const nuxtApp = useNuxtApp();
|
|
109
|
+
const route = useRoute();
|
|
110
|
+
const injectedClient = nuxtApp.$formforge;
|
|
111
|
+
if (injectedClient !== void 0 && !hasConfigOverrides(config)) {
|
|
112
|
+
return injectedClient;
|
|
113
|
+
}
|
|
114
|
+
const runtimeConfig = useRuntimeConfig();
|
|
115
|
+
const runtimePublicConfig = runtimeConfig.public.formforge;
|
|
116
|
+
const routeParamsResolver = () => {
|
|
117
|
+
const appRouteQuery = nuxtApp._route?.value?.query;
|
|
118
|
+
const appRouteParams = nuxtApp._route?.value?.params;
|
|
119
|
+
const appRoutePath = nuxtApp._route?.value?.path;
|
|
120
|
+
const composableRouteQuery = route.query;
|
|
121
|
+
const composableRouteParams = route.params;
|
|
122
|
+
const composableRoutePath = route.path;
|
|
123
|
+
const mergedRouteValues = mergeRouteValues(
|
|
124
|
+
{
|
|
125
|
+
...composableRouteQuery,
|
|
126
|
+
...composableRouteParams
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
...appRouteQuery,
|
|
130
|
+
...appRouteParams
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
const inferredFromPath = inferParamsFromPath(config.baseURL ?? runtimePublicConfig?.baseURL, composableRoutePath || appRoutePath);
|
|
134
|
+
return withInferredMissingValues(mergedRouteValues, inferredFromPath);
|
|
135
|
+
};
|
|
136
|
+
const baseConfig = runtimePublicConfig;
|
|
137
|
+
const mergedConfig = {
|
|
138
|
+
...baseConfig,
|
|
139
|
+
...config
|
|
140
|
+
};
|
|
141
|
+
const configBaseURLParams = config.baseURLParams;
|
|
142
|
+
const runtimeBaseURLParams = baseConfig?.baseURLParams;
|
|
143
|
+
const configScopeParams = config.scopeParams;
|
|
144
|
+
const runtimeScopeParams = baseConfig?.scopeParams;
|
|
145
|
+
if (configBaseURLParams !== void 0) {
|
|
146
|
+
if (typeof configBaseURLParams === "function") {
|
|
147
|
+
mergedConfig.baseURLParams = () => ({
|
|
148
|
+
...routeParamsResolver(),
|
|
149
|
+
...configBaseURLParams()
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
mergedConfig.baseURLParams = () => ({
|
|
153
|
+
...routeParamsResolver(),
|
|
154
|
+
...configBaseURLParams
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
} else if (runtimeBaseURLParams !== void 0) {
|
|
158
|
+
if (typeof runtimeBaseURLParams === "function") {
|
|
159
|
+
mergedConfig.baseURLParams = () => ({
|
|
160
|
+
...routeParamsResolver(),
|
|
161
|
+
...runtimeBaseURLParams()
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
mergedConfig.baseURLParams = () => ({
|
|
165
|
+
...routeParamsResolver(),
|
|
166
|
+
...runtimeBaseURLParams
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
mergedConfig.baseURLParams = routeParamsResolver;
|
|
171
|
+
}
|
|
172
|
+
if (configScopeParams !== void 0) {
|
|
173
|
+
if (typeof configScopeParams === "function") {
|
|
174
|
+
mergedConfig.scopeParams = () => ({
|
|
175
|
+
...routeParamsResolver(),
|
|
176
|
+
...configScopeParams()
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
mergedConfig.scopeParams = () => ({
|
|
180
|
+
...routeParamsResolver(),
|
|
181
|
+
...configScopeParams
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
} else if (runtimeScopeParams !== void 0) {
|
|
185
|
+
if (typeof runtimeScopeParams === "function") {
|
|
186
|
+
mergedConfig.scopeParams = () => ({
|
|
187
|
+
...routeParamsResolver(),
|
|
188
|
+
...runtimeScopeParams()
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
mergedConfig.scopeParams = () => ({
|
|
192
|
+
...routeParamsResolver(),
|
|
193
|
+
...runtimeScopeParams
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
mergedConfig.scopeParams = routeParamsResolver;
|
|
198
|
+
}
|
|
199
|
+
return createFormForgeClient(mergedConfig);
|
|
200
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FormForgeRequestOptions } from '../api/request.js';
|
|
2
|
+
import type { FormForgeClient, FormForgeClientConfig, FormForgeDraftRecord, FormForgeJsonObject, FormForgeScope, FormForgeSubmissionPayload } from '../types/index.js';
|
|
3
|
+
export interface UseFormForgeDraftsOptions {
|
|
4
|
+
key: string;
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
scope?: FormForgeScope;
|
|
7
|
+
client?: FormForgeClient;
|
|
8
|
+
clientConfig?: FormForgeClientConfig;
|
|
9
|
+
}
|
|
10
|
+
export type FormForgeDraftRequestOptions = FormForgeRequestOptions;
|
|
11
|
+
export declare function useFormForgeDrafts(options: UseFormForgeDraftsOptions): {
|
|
12
|
+
client: FormForgeClient;
|
|
13
|
+
loading: any;
|
|
14
|
+
error: any;
|
|
15
|
+
draft: any;
|
|
16
|
+
saveDraft: (payload: FormForgeSubmissionPayload, meta?: FormForgeJsonObject, requestOptions?: FormForgeDraftRequestOptions) => Promise<FormForgeDraftRecord | null>;
|
|
17
|
+
fetchCurrentDraft: (requestOptions?: FormForgeDraftRequestOptions) => Promise<FormForgeDraftRecord | null>;
|
|
18
|
+
deleteCurrentDraft: (requestOptions?: FormForgeDraftRequestOptions) => Promise<FormForgeDraftRecord | null>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=useFormForgeDrafts.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ref } from "#imports";
|
|
2
|
+
import { toFormForgeJsonSubmissionPayload } from "../utils/submission.js";
|
|
3
|
+
import { useFormForgeClient } from "./useFormForgeClient.js";
|
|
4
|
+
export function useFormForgeDrafts(options) {
|
|
5
|
+
const client = options.client ?? useFormForgeClient(options.clientConfig);
|
|
6
|
+
const loading = ref(false);
|
|
7
|
+
const error = ref(null);
|
|
8
|
+
const draft = ref(null);
|
|
9
|
+
function resolveEndpoint(requestOptions = {}) {
|
|
10
|
+
return requestOptions.endpoint ?? options.endpoint;
|
|
11
|
+
}
|
|
12
|
+
function resolveScope(requestOptions = {}) {
|
|
13
|
+
return requestOptions.scope ?? options.scope;
|
|
14
|
+
}
|
|
15
|
+
async function saveDraft(payload, meta, requestOptions = {}) {
|
|
16
|
+
loading.value = true;
|
|
17
|
+
error.value = null;
|
|
18
|
+
try {
|
|
19
|
+
const response = await client.saveDraft(options.key, {
|
|
20
|
+
payload: toFormForgeJsonSubmissionPayload(payload),
|
|
21
|
+
meta
|
|
22
|
+
}, {
|
|
23
|
+
endpoint: resolveEndpoint(requestOptions),
|
|
24
|
+
scope: resolveScope(requestOptions)
|
|
25
|
+
});
|
|
26
|
+
draft.value = response.data;
|
|
27
|
+
return response.data;
|
|
28
|
+
} catch (caughtError) {
|
|
29
|
+
error.value = caughtError instanceof Error ? caughtError.message : "Failed to save draft";
|
|
30
|
+
throw caughtError;
|
|
31
|
+
} finally {
|
|
32
|
+
loading.value = false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function fetchCurrentDraft(requestOptions = {}) {
|
|
36
|
+
loading.value = true;
|
|
37
|
+
error.value = null;
|
|
38
|
+
try {
|
|
39
|
+
const response = await client.getCurrentDraft(options.key, {
|
|
40
|
+
endpoint: resolveEndpoint(requestOptions),
|
|
41
|
+
scope: resolveScope(requestOptions)
|
|
42
|
+
});
|
|
43
|
+
draft.value = response.data;
|
|
44
|
+
return response.data;
|
|
45
|
+
} catch (caughtError) {
|
|
46
|
+
error.value = caughtError instanceof Error ? caughtError.message : "Failed to fetch draft";
|
|
47
|
+
throw caughtError;
|
|
48
|
+
} finally {
|
|
49
|
+
loading.value = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function deleteCurrentDraft(requestOptions = {}) {
|
|
53
|
+
loading.value = true;
|
|
54
|
+
error.value = null;
|
|
55
|
+
try {
|
|
56
|
+
const response = await client.deleteCurrentDraft(options.key, {
|
|
57
|
+
endpoint: resolveEndpoint(requestOptions),
|
|
58
|
+
scope: resolveScope(requestOptions)
|
|
59
|
+
});
|
|
60
|
+
draft.value = response.data;
|
|
61
|
+
return response.data;
|
|
62
|
+
} catch (caughtError) {
|
|
63
|
+
error.value = caughtError instanceof Error ? caughtError.message : "Failed to delete draft";
|
|
64
|
+
throw caughtError;
|
|
65
|
+
} finally {
|
|
66
|
+
loading.value = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
client,
|
|
71
|
+
loading,
|
|
72
|
+
error,
|
|
73
|
+
draft,
|
|
74
|
+
saveDraft,
|
|
75
|
+
fetchCurrentDraft,
|
|
76
|
+
deleteCurrentDraft
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FormForgeClient, FormForgeClientConfig, FormForgeFormSchema, FormForgeScope, FormForgeSubmissionPayload } from '../types/index.js';
|
|
2
|
+
import type { FormForgeRequestOptions } from '../api/request.js';
|
|
3
|
+
export interface UseFormForgeFormOptions {
|
|
4
|
+
key: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
endpoint?: string;
|
|
7
|
+
scope?: FormForgeScope;
|
|
8
|
+
immediate?: boolean;
|
|
9
|
+
client?: FormForgeClient;
|
|
10
|
+
clientConfig?: FormForgeClientConfig;
|
|
11
|
+
}
|
|
12
|
+
export type FormForgeFormRequestOptions = FormForgeRequestOptions;
|
|
13
|
+
export declare function useFormForgeForm(options: UseFormForgeFormOptions): {
|
|
14
|
+
client: FormForgeClient;
|
|
15
|
+
schema: any;
|
|
16
|
+
state: any;
|
|
17
|
+
loading: any;
|
|
18
|
+
initialized: any;
|
|
19
|
+
error: any;
|
|
20
|
+
zodSchema: any;
|
|
21
|
+
fetchSchema: (requestOptions?: FormForgeFormRequestOptions) => Promise<FormForgeFormSchema>;
|
|
22
|
+
resetState: () => void;
|
|
23
|
+
setFieldValue: (fieldName: string, value: FormForgeSubmissionPayload[string]) => void;
|
|
24
|
+
replaceState: (payload: FormForgeSubmissionPayload) => void;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=useFormForgeForm.d.ts.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ref } from "#imports";
|
|
2
|
+
import { createFormForgeZodSchema } from "../validation/zod.js";
|
|
3
|
+
import { useFormForgeClient } from "./useFormForgeClient.js";
|
|
4
|
+
function clonePayload(payload) {
|
|
5
|
+
if (typeof structuredClone === "function") {
|
|
6
|
+
try {
|
|
7
|
+
return structuredClone(payload);
|
|
8
|
+
} catch {
|
|
9
|
+
return {
|
|
10
|
+
...payload
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
...payload
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createInitialPayload(schema) {
|
|
19
|
+
const payload = {};
|
|
20
|
+
for (const field of schema.fields) {
|
|
21
|
+
if (field.default !== void 0) {
|
|
22
|
+
payload[field.name] = field.default;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (field.type === "checkbox" || field.type === "switch") {
|
|
26
|
+
payload[field.name] = false;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (field.type === "checkbox_group") {
|
|
30
|
+
payload[field.name] = [];
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (field.type === "date_range" || field.type === "datetime_range") {
|
|
34
|
+
payload[field.name] = {
|
|
35
|
+
start: null,
|
|
36
|
+
end: null
|
|
37
|
+
};
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
payload[field.name] = null;
|
|
41
|
+
}
|
|
42
|
+
return payload;
|
|
43
|
+
}
|
|
44
|
+
export function useFormForgeForm(options) {
|
|
45
|
+
const client = options.client ?? useFormForgeClient(options.clientConfig);
|
|
46
|
+
const schema = ref(null);
|
|
47
|
+
const state = ref({});
|
|
48
|
+
const initialState = ref({});
|
|
49
|
+
const loading = ref(false);
|
|
50
|
+
const initialized = ref(false);
|
|
51
|
+
const lastError = ref(null);
|
|
52
|
+
const zodSchema = ref(void 0);
|
|
53
|
+
function resolveEndpoint(requestOptions = {}) {
|
|
54
|
+
return requestOptions.endpoint ?? options.endpoint;
|
|
55
|
+
}
|
|
56
|
+
function resolveScope(requestOptions = {}) {
|
|
57
|
+
return requestOptions.scope ?? options.scope;
|
|
58
|
+
}
|
|
59
|
+
async function fetchSchema(requestOptions = {}) {
|
|
60
|
+
loading.value = true;
|
|
61
|
+
lastError.value = null;
|
|
62
|
+
try {
|
|
63
|
+
const endpoint = resolveEndpoint(requestOptions);
|
|
64
|
+
const scope = resolveScope(requestOptions);
|
|
65
|
+
const nextSchema = options.version !== void 0 && options.version !== "" ? await client.getFormVersion(options.key, options.version, { endpoint, scope }) : await client.getForm(options.key, { endpoint, scope });
|
|
66
|
+
const nextState = createInitialPayload(nextSchema);
|
|
67
|
+
schema.value = nextSchema;
|
|
68
|
+
initialState.value = nextState;
|
|
69
|
+
state.value = clonePayload(nextState);
|
|
70
|
+
zodSchema.value = createFormForgeZodSchema(nextSchema);
|
|
71
|
+
initialized.value = true;
|
|
72
|
+
return nextSchema;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
lastError.value = error instanceof Error ? error.message : "Failed to load form schema";
|
|
75
|
+
throw error;
|
|
76
|
+
} finally {
|
|
77
|
+
loading.value = false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function resetState() {
|
|
81
|
+
if (schema.value === null) {
|
|
82
|
+
state.value = {};
|
|
83
|
+
initialState.value = {};
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
state.value = clonePayload(initialState.value);
|
|
87
|
+
}
|
|
88
|
+
function setFieldValue(fieldName, value) {
|
|
89
|
+
state.value = {
|
|
90
|
+
...state.value,
|
|
91
|
+
[fieldName]: value
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function replaceState(payload) {
|
|
95
|
+
state.value = clonePayload(payload);
|
|
96
|
+
}
|
|
97
|
+
if (options.immediate !== false) {
|
|
98
|
+
fetchSchema().catch(() => {
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
client,
|
|
103
|
+
schema,
|
|
104
|
+
state,
|
|
105
|
+
loading,
|
|
106
|
+
initialized,
|
|
107
|
+
error: lastError,
|
|
108
|
+
zodSchema,
|
|
109
|
+
fetchSchema,
|
|
110
|
+
resetState,
|
|
111
|
+
setFieldValue,
|
|
112
|
+
replaceState
|
|
113
|
+
};
|
|
114
|
+
}
|