@ember-home/unbound-styleguide 0.0.14 → 0.0.16
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/dist/chunk-TQJLZ37G.js +429 -0
- package/dist/chunk-VFB4PT2U.js +9693 -0
- package/dist/forms-server.d.ts +166 -0
- package/dist/forms-server.js +20 -0
- package/dist/forms.d.ts +2387 -0
- package/dist/forms.js +3799 -0
- package/dist/index.d.ts +117 -112
- package/dist/index.js +248 -9279
- package/dist/theme.css +27 -3
- package/dist/types-BCKM7WCg.d.ts +698 -0
- package/dist/types-CBstEZ_h.d.ts +102 -0
- package/package.json +19 -8
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
// src/@styleguide/forms/schema/define-form-schema.ts
|
|
2
|
+
function defineFormSchema() {
|
|
3
|
+
return function define(config) {
|
|
4
|
+
const sortedFields = [...config.fields].sort((a, b) => {
|
|
5
|
+
const orderA = a.ui?.order ?? Number.MAX_SAFE_INTEGER;
|
|
6
|
+
const orderB = b.ui?.order ?? Number.MAX_SAFE_INTEGER;
|
|
7
|
+
return orderA - orderB;
|
|
8
|
+
});
|
|
9
|
+
const sortedSections = config.sections ? [...config.sections].sort((a, b) => {
|
|
10
|
+
const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
|
|
11
|
+
const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
|
|
12
|
+
return orderA - orderB;
|
|
13
|
+
}) : void 0;
|
|
14
|
+
return {
|
|
15
|
+
fields: sortedFields,
|
|
16
|
+
sections: sortedSections,
|
|
17
|
+
crossFieldValidation: config.crossFieldValidation
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function field() {
|
|
22
|
+
return function defineField(name, kind, config) {
|
|
23
|
+
return {
|
|
24
|
+
name,
|
|
25
|
+
kind,
|
|
26
|
+
...config
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function textField() {
|
|
31
|
+
return function defineTextField(name, config) {
|
|
32
|
+
return { name, kind: "text", ...config };
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function selectField() {
|
|
36
|
+
return function defineSelectField(name, options, config) {
|
|
37
|
+
return {
|
|
38
|
+
name,
|
|
39
|
+
kind: "select",
|
|
40
|
+
...config,
|
|
41
|
+
ui: { ...config?.ui, options }
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function checkboxField() {
|
|
46
|
+
return function defineCheckboxField(name, config) {
|
|
47
|
+
return { name, kind: "checkbox", ...config };
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function arrayField() {
|
|
51
|
+
return function defineArrayField(name, itemSchema, config) {
|
|
52
|
+
const { config: arrayConfig, ...rest } = config ?? {};
|
|
53
|
+
return {
|
|
54
|
+
name,
|
|
55
|
+
kind: "array",
|
|
56
|
+
arrayItemSchema: itemSchema,
|
|
57
|
+
arrayConfig,
|
|
58
|
+
...rest
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function getFieldsForSection(schema, sectionId) {
|
|
63
|
+
return schema.fields.filter((field2) => field2.ui?.section === sectionId);
|
|
64
|
+
}
|
|
65
|
+
function getUnsectionedFields(schema) {
|
|
66
|
+
return schema.fields.filter((field2) => !field2.ui?.section);
|
|
67
|
+
}
|
|
68
|
+
function getFieldByName(schema, name) {
|
|
69
|
+
return schema.fields.find((field2) => field2.name === name);
|
|
70
|
+
}
|
|
71
|
+
function getArrayItemFieldByName(schema, name) {
|
|
72
|
+
const normalizedName = name.replace(/\.\d+\./g, ".0.");
|
|
73
|
+
for (const field2 of schema.fields) {
|
|
74
|
+
if (field2.kind === "array" && field2.arrayItemSchema) {
|
|
75
|
+
const match = field2.arrayItemSchema.find(
|
|
76
|
+
(item) => item.name === normalizedName
|
|
77
|
+
);
|
|
78
|
+
if (match) {
|
|
79
|
+
return { ...match, name };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
function buildDefaultValues(schema) {
|
|
86
|
+
const defaults = {};
|
|
87
|
+
for (const field2 of schema.fields) {
|
|
88
|
+
if (field2.defaultValue !== void 0) {
|
|
89
|
+
setNestedValue(defaults, field2.name, field2.defaultValue);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return defaults;
|
|
93
|
+
}
|
|
94
|
+
function isArrayIndex(key) {
|
|
95
|
+
return /^\d+$/.test(key);
|
|
96
|
+
}
|
|
97
|
+
function setNestedValue(obj, path, value) {
|
|
98
|
+
const keys = path.split(".");
|
|
99
|
+
let current = obj;
|
|
100
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
101
|
+
const key = keys[i];
|
|
102
|
+
const nextKey = keys[i + 1];
|
|
103
|
+
const nextNeedsArray = isArrayIndex(nextKey);
|
|
104
|
+
if (isArrayIndex(key)) {
|
|
105
|
+
const index = parseInt(key, 10);
|
|
106
|
+
const arr = current;
|
|
107
|
+
while (arr.length <= index) {
|
|
108
|
+
arr.push(void 0);
|
|
109
|
+
}
|
|
110
|
+
if (arr[index] === void 0 || typeof arr[index] !== "object") {
|
|
111
|
+
arr[index] = nextNeedsArray ? [] : {};
|
|
112
|
+
}
|
|
113
|
+
current = arr[index];
|
|
114
|
+
} else {
|
|
115
|
+
const record = current;
|
|
116
|
+
if (!(key in record) || typeof record[key] !== "object" || record[key] === null) {
|
|
117
|
+
record[key] = nextNeedsArray ? [] : {};
|
|
118
|
+
}
|
|
119
|
+
current = record[key];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const finalKey = keys[keys.length - 1];
|
|
123
|
+
if (isArrayIndex(finalKey)) {
|
|
124
|
+
const arr = current;
|
|
125
|
+
const index = parseInt(finalKey, 10);
|
|
126
|
+
while (arr.length <= index) {
|
|
127
|
+
arr.push(void 0);
|
|
128
|
+
}
|
|
129
|
+
arr[index] = value;
|
|
130
|
+
} else {
|
|
131
|
+
current[finalKey] = value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function mergeSchemas(base, override) {
|
|
135
|
+
const fieldMap = new Map(base.fields.map((f) => [f.name, f]));
|
|
136
|
+
if (override.fields) {
|
|
137
|
+
for (const field2 of override.fields) {
|
|
138
|
+
fieldMap.set(field2.name, field2);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const sectionMap = new Map(
|
|
142
|
+
(base.sections ?? []).map((s) => [s.id, s])
|
|
143
|
+
);
|
|
144
|
+
if (override.sections) {
|
|
145
|
+
for (const section of override.sections) {
|
|
146
|
+
sectionMap.set(section.id, section);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const crossFieldRules = [
|
|
150
|
+
...base.crossFieldValidation ?? [],
|
|
151
|
+
...override.crossFieldValidation ?? []
|
|
152
|
+
];
|
|
153
|
+
return {
|
|
154
|
+
fields: Array.from(fieldMap.values()),
|
|
155
|
+
sections: sectionMap.size > 0 ? Array.from(sectionMap.values()) : void 0,
|
|
156
|
+
crossFieldValidation: crossFieldRules.length > 0 ? crossFieldRules : void 0
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/@styleguide/forms/server/server-schema-validator.ts
|
|
161
|
+
import { z } from "zod";
|
|
162
|
+
var validationRuleWithMessage = z.union([
|
|
163
|
+
z.number(),
|
|
164
|
+
z.object({
|
|
165
|
+
value: z.number(),
|
|
166
|
+
message: z.string()
|
|
167
|
+
})
|
|
168
|
+
]);
|
|
169
|
+
var patternRule = z.union([
|
|
170
|
+
z.string(),
|
|
171
|
+
z.object({
|
|
172
|
+
value: z.string(),
|
|
173
|
+
message: z.string()
|
|
174
|
+
})
|
|
175
|
+
]);
|
|
176
|
+
var serverFieldValidationSchema = z.object({
|
|
177
|
+
required: z.union([z.boolean(), z.string()]).optional(),
|
|
178
|
+
min: validationRuleWithMessage.optional(),
|
|
179
|
+
max: validationRuleWithMessage.optional(),
|
|
180
|
+
minLength: validationRuleWithMessage.optional(),
|
|
181
|
+
maxLength: validationRuleWithMessage.optional(),
|
|
182
|
+
pattern: patternRule.optional(),
|
|
183
|
+
asyncValidatorUrl: z.string().optional(),
|
|
184
|
+
asyncDebounceMs: z.number().optional()
|
|
185
|
+
}).optional();
|
|
186
|
+
var fieldOptionSchema = z.object({
|
|
187
|
+
value: z.string(),
|
|
188
|
+
label: z.string(),
|
|
189
|
+
disabled: z.boolean().optional()
|
|
190
|
+
});
|
|
191
|
+
var serverFieldUISchema = z.object({
|
|
192
|
+
label: z.string().optional(),
|
|
193
|
+
placeholder: z.string().optional(),
|
|
194
|
+
description: z.string().optional(),
|
|
195
|
+
tooltip: z.string().optional(),
|
|
196
|
+
order: z.number().optional(),
|
|
197
|
+
section: z.string().optional(),
|
|
198
|
+
width: z.enum(["full", "half", "third", "quarter"]).optional(),
|
|
199
|
+
className: z.string().optional(),
|
|
200
|
+
options: z.array(fieldOptionSchema).optional(),
|
|
201
|
+
allowCreate: z.boolean().optional(),
|
|
202
|
+
searchable: z.boolean().optional(),
|
|
203
|
+
inputType: z.string().optional(),
|
|
204
|
+
autoCapitalize: z.string().optional(),
|
|
205
|
+
autoComplete: z.string().optional(),
|
|
206
|
+
maxRows: z.number().optional(),
|
|
207
|
+
minRows: z.number().optional()
|
|
208
|
+
}).optional();
|
|
209
|
+
var serverFieldVisibilitySchema = z.object({
|
|
210
|
+
dependsOn: z.array(z.string()).optional(),
|
|
211
|
+
showWhen: z.record(z.string(), z.unknown()).optional(),
|
|
212
|
+
hideWhen: z.record(z.string(), z.unknown()).optional(),
|
|
213
|
+
requiredWhen: z.record(z.string(), z.unknown()).optional(),
|
|
214
|
+
disabledWhen: z.record(z.string(), z.unknown()).optional()
|
|
215
|
+
}).optional();
|
|
216
|
+
var arrayConfigSchema = z.object({
|
|
217
|
+
minItems: z.number().optional(),
|
|
218
|
+
maxItems: z.number().optional(),
|
|
219
|
+
defaultItem: z.record(z.string(), z.unknown()).optional(),
|
|
220
|
+
allowReorder: z.boolean().optional(),
|
|
221
|
+
addButtonLabel: z.string().optional(),
|
|
222
|
+
removeButtonLabel: z.string().optional(),
|
|
223
|
+
showItemNumber: z.boolean().optional(),
|
|
224
|
+
itemHeaderTemplate: z.string().optional(),
|
|
225
|
+
removeConfirmMessage: z.string().optional(),
|
|
226
|
+
collapsible: z.boolean().optional(),
|
|
227
|
+
defaultCollapsed: z.boolean().optional()
|
|
228
|
+
}).optional();
|
|
229
|
+
var baseServerFieldSchema = z.object({
|
|
230
|
+
name: z.string().min(1, "Field name is required"),
|
|
231
|
+
kind: z.string().min(1, "Field kind is required"),
|
|
232
|
+
ui: serverFieldUISchema,
|
|
233
|
+
validation: serverFieldValidationSchema,
|
|
234
|
+
visibility: serverFieldVisibilitySchema,
|
|
235
|
+
defaultValue: z.unknown().optional(),
|
|
236
|
+
readOnly: z.boolean().optional(),
|
|
237
|
+
arrayConfig: arrayConfigSchema,
|
|
238
|
+
meta: z.record(z.string(), z.unknown()).optional()
|
|
239
|
+
});
|
|
240
|
+
var serverFieldSchema = baseServerFieldSchema.extend({
|
|
241
|
+
arrayItemSchema: z.lazy(() => z.array(serverFieldSchema)).optional()
|
|
242
|
+
});
|
|
243
|
+
var sectionSchema = z.object({
|
|
244
|
+
id: z.string().min(1, "Section id is required"),
|
|
245
|
+
title: z.string().optional(),
|
|
246
|
+
description: z.string().optional(),
|
|
247
|
+
collapsible: z.boolean().optional(),
|
|
248
|
+
defaultCollapsed: z.boolean().optional(),
|
|
249
|
+
order: z.number().optional()
|
|
250
|
+
});
|
|
251
|
+
var serverFormSchema = z.object({
|
|
252
|
+
fields: z.array(serverFieldSchema).min(1, "At least one field is required"),
|
|
253
|
+
sections: z.array(sectionSchema).optional()
|
|
254
|
+
});
|
|
255
|
+
function validateServerSchema(data) {
|
|
256
|
+
const result = serverFormSchema.safeParse(data);
|
|
257
|
+
if (result.success) {
|
|
258
|
+
return { success: true, data: result.data };
|
|
259
|
+
}
|
|
260
|
+
const issues = result.error.issues.map((issue) => {
|
|
261
|
+
const path = issue.path.join(".");
|
|
262
|
+
return ` - ${path || "root"}: ${issue.message}`;
|
|
263
|
+
});
|
|
264
|
+
const message = `Invalid server schema:
|
|
265
|
+
${issues.join("\n")}`;
|
|
266
|
+
return {
|
|
267
|
+
success: false,
|
|
268
|
+
error: result.error,
|
|
269
|
+
message
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function assertServerSchema(data) {
|
|
273
|
+
const result = validateServerSchema(data);
|
|
274
|
+
if (!result.success) {
|
|
275
|
+
throw new Error(result.message);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/@styleguide/forms/server/fetchServerSchema.ts
|
|
280
|
+
function parseServerField(serverField) {
|
|
281
|
+
const field2 = {
|
|
282
|
+
name: serverField.name,
|
|
283
|
+
kind: serverField.kind
|
|
284
|
+
};
|
|
285
|
+
if (serverField.ui) {
|
|
286
|
+
field2.ui = { ...serverField.ui };
|
|
287
|
+
}
|
|
288
|
+
if (serverField.defaultValue !== void 0) {
|
|
289
|
+
field2.defaultValue = serverField.defaultValue;
|
|
290
|
+
}
|
|
291
|
+
if (serverField.readOnly !== void 0) {
|
|
292
|
+
field2.readOnly = serverField.readOnly;
|
|
293
|
+
}
|
|
294
|
+
if (serverField.meta) {
|
|
295
|
+
field2.meta = serverField.meta;
|
|
296
|
+
}
|
|
297
|
+
if (serverField.validation) {
|
|
298
|
+
const validation = serverField.validation;
|
|
299
|
+
field2.validation = {};
|
|
300
|
+
if (validation.required !== void 0) {
|
|
301
|
+
field2.validation.required = validation.required;
|
|
302
|
+
}
|
|
303
|
+
if (validation.min !== void 0) {
|
|
304
|
+
field2.validation.min = validation.min;
|
|
305
|
+
}
|
|
306
|
+
if (validation.max !== void 0) {
|
|
307
|
+
field2.validation.max = validation.max;
|
|
308
|
+
}
|
|
309
|
+
if (validation.minLength !== void 0) {
|
|
310
|
+
field2.validation.minLength = validation.minLength;
|
|
311
|
+
}
|
|
312
|
+
if (validation.maxLength !== void 0) {
|
|
313
|
+
field2.validation.maxLength = validation.maxLength;
|
|
314
|
+
}
|
|
315
|
+
if (validation.pattern !== void 0) {
|
|
316
|
+
try {
|
|
317
|
+
if (typeof validation.pattern === "string") {
|
|
318
|
+
field2.validation.pattern = new RegExp(validation.pattern);
|
|
319
|
+
} else if (typeof validation.pattern === "object") {
|
|
320
|
+
field2.validation.pattern = {
|
|
321
|
+
value: new RegExp(validation.pattern.value),
|
|
322
|
+
message: validation.pattern.message
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
} catch (error) {
|
|
326
|
+
console.error(
|
|
327
|
+
`Invalid regex pattern for field "${serverField.name}": ${typeof validation.pattern === "string" ? validation.pattern : validation.pattern.value}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (validation.asyncValidatorUrl) {
|
|
332
|
+
field2.validation.asyncValidatorUrl = validation.asyncValidatorUrl;
|
|
333
|
+
}
|
|
334
|
+
if (validation.asyncDebounceMs !== void 0) {
|
|
335
|
+
field2.validation.asyncDebounceMs = validation.asyncDebounceMs;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (serverField.visibility) {
|
|
339
|
+
const visibility = serverField.visibility;
|
|
340
|
+
field2.visibility = {
|
|
341
|
+
dependsOn: visibility.dependsOn,
|
|
342
|
+
showWhen: visibility.showWhen,
|
|
343
|
+
hideWhen: visibility.hideWhen,
|
|
344
|
+
requiredWhen: visibility.requiredWhen,
|
|
345
|
+
disabledWhen: visibility.disabledWhen
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
if (serverField.arrayItemSchema) {
|
|
349
|
+
field2.arrayItemSchema = serverField.arrayItemSchema.map(
|
|
350
|
+
(item) => parseServerField(item)
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
if (serverField.arrayConfig) {
|
|
354
|
+
field2.arrayConfig = serverField.arrayConfig;
|
|
355
|
+
}
|
|
356
|
+
return field2;
|
|
357
|
+
}
|
|
358
|
+
function parseServerSchema(serverSchema, options) {
|
|
359
|
+
if (options?.strict) {
|
|
360
|
+
const validationResult = validateServerSchema(serverSchema);
|
|
361
|
+
if (!validationResult.success) {
|
|
362
|
+
throw new Error(validationResult.message);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
fields: serverSchema.fields.map((field2) => parseServerField(field2)),
|
|
367
|
+
sections: serverSchema.sections
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function parseServerSchemaSafe(data) {
|
|
371
|
+
const validationResult = validateServerSchema(data);
|
|
372
|
+
if (!validationResult.success) {
|
|
373
|
+
return {
|
|
374
|
+
success: false,
|
|
375
|
+
error: validationResult
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
const schema = parseServerSchema(
|
|
379
|
+
validationResult.data
|
|
380
|
+
);
|
|
381
|
+
return { success: true, schema };
|
|
382
|
+
}
|
|
383
|
+
async function fetchServerSchema(url, options) {
|
|
384
|
+
const response = await fetch(url, {
|
|
385
|
+
...options?.fetchOptions,
|
|
386
|
+
headers: {
|
|
387
|
+
"Content-Type": "application/json",
|
|
388
|
+
...options?.fetchOptions?.headers
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
if (!response.ok) {
|
|
392
|
+
throw new Error(`Failed to load schema: ${response.status}`);
|
|
393
|
+
}
|
|
394
|
+
let data = await response.json();
|
|
395
|
+
if (options?.transformResponse) {
|
|
396
|
+
data = options.transformResponse(data);
|
|
397
|
+
}
|
|
398
|
+
const serverSchema = parseServerSchema(data);
|
|
399
|
+
return options?.baseSchema ? mergeSchemas(options.baseSchema, serverSchema) : serverSchema;
|
|
400
|
+
}
|
|
401
|
+
function buildSchemaResponse(schema) {
|
|
402
|
+
return {
|
|
403
|
+
fields: schema.fields,
|
|
404
|
+
sections: schema.sections
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export {
|
|
409
|
+
defineFormSchema,
|
|
410
|
+
field,
|
|
411
|
+
textField,
|
|
412
|
+
selectField,
|
|
413
|
+
checkboxField,
|
|
414
|
+
arrayField,
|
|
415
|
+
getFieldsForSection,
|
|
416
|
+
getUnsectionedFields,
|
|
417
|
+
getFieldByName,
|
|
418
|
+
getArrayItemFieldByName,
|
|
419
|
+
buildDefaultValues,
|
|
420
|
+
mergeSchemas,
|
|
421
|
+
serverFieldSchema,
|
|
422
|
+
serverFormSchema,
|
|
423
|
+
validateServerSchema,
|
|
424
|
+
assertServerSchema,
|
|
425
|
+
parseServerSchema,
|
|
426
|
+
parseServerSchemaSafe,
|
|
427
|
+
fetchServerSchema,
|
|
428
|
+
buildSchemaResponse
|
|
429
|
+
};
|