masumi-schema-validator-component 0.1.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 +89 -0
- package/dist/index.d.mts +1202 -0
- package/dist/index.d.ts +1202 -0
- package/dist/index.js +675 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +644 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
- package/src/components/JobInputRenderer.tsx +175 -0
- package/src/components/JobInputsFormRenderer.tsx +185 -0
- package/src/dev/examples.ts +196 -0
- package/src/dev/main.tsx +136 -0
- package/src/index.ts +4 -0
- package/src/lib/job-input-schema.ts +423 -0
- package/src/lib/validation.ts +90 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
var React2 = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var clsx = require('clsx');
|
|
7
|
+
var tailwindMerge = require('tailwind-merge');
|
|
8
|
+
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
12
|
+
var clsx__default = /*#__PURE__*/_interopDefault(clsx);
|
|
13
|
+
|
|
14
|
+
// src/lib/job-input-schema.ts
|
|
15
|
+
var ValidJobInputTypes = /* @__PURE__ */ ((ValidJobInputTypes2) => {
|
|
16
|
+
ValidJobInputTypes2["STRING"] = "string";
|
|
17
|
+
ValidJobInputTypes2["TEXTAREA"] = "textarea";
|
|
18
|
+
ValidJobInputTypes2["NUMBER"] = "number";
|
|
19
|
+
ValidJobInputTypes2["BOOLEAN"] = "boolean";
|
|
20
|
+
ValidJobInputTypes2["OPTION"] = "option";
|
|
21
|
+
ValidJobInputTypes2["FILE"] = "file";
|
|
22
|
+
ValidJobInputTypes2["NONE"] = "none";
|
|
23
|
+
return ValidJobInputTypes2;
|
|
24
|
+
})(ValidJobInputTypes || {});
|
|
25
|
+
var ValidJobInputValidationTypes = /* @__PURE__ */ ((ValidJobInputValidationTypes2) => {
|
|
26
|
+
ValidJobInputValidationTypes2["MIN"] = "min";
|
|
27
|
+
ValidJobInputValidationTypes2["MAX"] = "max";
|
|
28
|
+
ValidJobInputValidationTypes2["FORMAT"] = "format";
|
|
29
|
+
ValidJobInputValidationTypes2["OPTIONAL"] = "optional";
|
|
30
|
+
return ValidJobInputValidationTypes2;
|
|
31
|
+
})(ValidJobInputValidationTypes || {});
|
|
32
|
+
var ValidJobInputFormatValues = /* @__PURE__ */ ((ValidJobInputFormatValues2) => {
|
|
33
|
+
ValidJobInputFormatValues2["URL"] = "url";
|
|
34
|
+
ValidJobInputFormatValues2["EMAIL"] = "email";
|
|
35
|
+
ValidJobInputFormatValues2["INTEGER"] = "integer";
|
|
36
|
+
ValidJobInputFormatValues2["NON_EMPTY"] = "nonempty";
|
|
37
|
+
return ValidJobInputFormatValues2;
|
|
38
|
+
})(ValidJobInputFormatValues || {});
|
|
39
|
+
var optionalValidationSchema = zod.z.object({
|
|
40
|
+
validation: zod.z.enum(["optional" /* OPTIONAL */]),
|
|
41
|
+
value: zod.z.enum(["true", "false"])
|
|
42
|
+
});
|
|
43
|
+
var minValidationSchema = zod.z.object({
|
|
44
|
+
validation: zod.z.enum(["min" /* MIN */]),
|
|
45
|
+
value: zod.z.number({ coerce: true }).int().min(0)
|
|
46
|
+
});
|
|
47
|
+
var maxValidationSchema = zod.z.object({
|
|
48
|
+
validation: zod.z.enum(["max" /* MAX */]),
|
|
49
|
+
value: zod.z.number({ coerce: true }).int().min(0)
|
|
50
|
+
});
|
|
51
|
+
var formatUrlValidationSchema = zod.z.object({
|
|
52
|
+
validation: zod.z.enum(["format" /* FORMAT */]),
|
|
53
|
+
value: zod.z.enum(["url" /* URL */])
|
|
54
|
+
});
|
|
55
|
+
var formatEmailValidationSchema = zod.z.object({
|
|
56
|
+
validation: zod.z.enum(["format" /* FORMAT */]),
|
|
57
|
+
value: zod.z.enum(["email" /* EMAIL */])
|
|
58
|
+
});
|
|
59
|
+
var formatIntegerValidationSchema = zod.z.object({
|
|
60
|
+
validation: zod.z.enum(["format" /* FORMAT */]),
|
|
61
|
+
value: zod.z.enum(["integer" /* INTEGER */])
|
|
62
|
+
});
|
|
63
|
+
var formatNonEmptyValidationSchema = zod.z.object({
|
|
64
|
+
validation: zod.z.enum(["format" /* FORMAT */]),
|
|
65
|
+
value: zod.z.enum(["nonempty" /* NON_EMPTY */])
|
|
66
|
+
});
|
|
67
|
+
var jobInputStringSchema = zod.z.object({
|
|
68
|
+
id: zod.z.string().min(1),
|
|
69
|
+
type: zod.z.enum(["string" /* STRING */]),
|
|
70
|
+
name: zod.z.string().min(1),
|
|
71
|
+
data: zod.z.object({
|
|
72
|
+
placeholder: zod.z.string().optional(),
|
|
73
|
+
description: zod.z.string().optional()
|
|
74
|
+
}).optional(),
|
|
75
|
+
validations: zod.z.array(
|
|
76
|
+
optionalValidationSchema.or(minValidationSchema).or(maxValidationSchema).or(formatNonEmptyValidationSchema).or(formatUrlValidationSchema).or(formatEmailValidationSchema)
|
|
77
|
+
).optional()
|
|
78
|
+
});
|
|
79
|
+
var jobInputTextareaSchema = zod.z.object({
|
|
80
|
+
id: zod.z.string().min(1),
|
|
81
|
+
type: zod.z.enum(["textarea" /* TEXTAREA */]),
|
|
82
|
+
name: zod.z.string().min(1),
|
|
83
|
+
data: zod.z.object({
|
|
84
|
+
placeholder: zod.z.string().optional(),
|
|
85
|
+
description: zod.z.string().optional()
|
|
86
|
+
}).optional(),
|
|
87
|
+
validations: zod.z.array(
|
|
88
|
+
optionalValidationSchema.or(minValidationSchema).or(maxValidationSchema).or(formatNonEmptyValidationSchema)
|
|
89
|
+
).optional()
|
|
90
|
+
});
|
|
91
|
+
var jobInputNumberSchema = zod.z.object({
|
|
92
|
+
id: zod.z.string().min(1),
|
|
93
|
+
type: zod.z.enum(["number" /* NUMBER */]),
|
|
94
|
+
name: zod.z.string().min(1),
|
|
95
|
+
data: zod.z.object({
|
|
96
|
+
placeholder: zod.z.string().optional(),
|
|
97
|
+
description: zod.z.string().optional()
|
|
98
|
+
}).optional(),
|
|
99
|
+
validations: zod.z.array(
|
|
100
|
+
optionalValidationSchema.or(minValidationSchema).or(maxValidationSchema).or(formatIntegerValidationSchema)
|
|
101
|
+
).optional()
|
|
102
|
+
});
|
|
103
|
+
var jobInputBooleanSchema = zod.z.object({
|
|
104
|
+
id: zod.z.string().min(1),
|
|
105
|
+
type: zod.z.enum(["boolean" /* BOOLEAN */]),
|
|
106
|
+
name: zod.z.string().min(1),
|
|
107
|
+
data: zod.z.object({
|
|
108
|
+
placeholder: zod.z.string().optional(),
|
|
109
|
+
description: zod.z.string().optional()
|
|
110
|
+
}).optional(),
|
|
111
|
+
validations: zod.z.array(optionalValidationSchema).optional()
|
|
112
|
+
});
|
|
113
|
+
var jobInputOptionSchema = zod.z.object({
|
|
114
|
+
id: zod.z.string().min(1),
|
|
115
|
+
type: zod.z.enum(["option" /* OPTION */]),
|
|
116
|
+
name: zod.z.string().min(1),
|
|
117
|
+
data: zod.z.object({
|
|
118
|
+
values: zod.z.array(zod.z.string().min(1)).min(1),
|
|
119
|
+
placeholder: zod.z.string().optional(),
|
|
120
|
+
description: zod.z.string().optional()
|
|
121
|
+
}),
|
|
122
|
+
validations: zod.z.array(
|
|
123
|
+
optionalValidationSchema.or(minValidationSchema).or(maxValidationSchema)
|
|
124
|
+
).optional()
|
|
125
|
+
});
|
|
126
|
+
var jobInputFileSchema = zod.z.object({
|
|
127
|
+
id: zod.z.string().min(1),
|
|
128
|
+
type: zod.z.enum(["file" /* FILE */]),
|
|
129
|
+
name: zod.z.string().min(1),
|
|
130
|
+
data: zod.z.object({
|
|
131
|
+
accept: zod.z.string().optional(),
|
|
132
|
+
maxSize: zod.z.string().optional(),
|
|
133
|
+
multiple: zod.z.boolean().optional(),
|
|
134
|
+
description: zod.z.string().optional(),
|
|
135
|
+
outputFormat: zod.z.string().optional()
|
|
136
|
+
}),
|
|
137
|
+
validations: zod.z.array(optionalValidationSchema).optional()
|
|
138
|
+
});
|
|
139
|
+
var jobInputNoneSchema = zod.z.object({
|
|
140
|
+
id: zod.z.string().min(1),
|
|
141
|
+
type: zod.z.enum(["none" /* NONE */]),
|
|
142
|
+
name: zod.z.string().min(1),
|
|
143
|
+
data: zod.z.object({
|
|
144
|
+
description: zod.z.string().min(1).optional()
|
|
145
|
+
}).optional()
|
|
146
|
+
});
|
|
147
|
+
var jobInputSchema = jobInputStringSchema.or(jobInputTextareaSchema).or(jobInputNumberSchema).or(jobInputBooleanSchema).or(jobInputOptionSchema).or(jobInputFileSchema).or(jobInputNoneSchema);
|
|
148
|
+
var makeZodSchemaFromJobInputSchema = (jobInputSchema2) => {
|
|
149
|
+
switch (jobInputSchema2.type) {
|
|
150
|
+
case "string" /* STRING */:
|
|
151
|
+
return makeZodSchemaFromJobInputStringSchema(jobInputSchema2);
|
|
152
|
+
case "textarea" /* TEXTAREA */:
|
|
153
|
+
return makeZodSchemaFromJobInputTextareaSchema(jobInputSchema2);
|
|
154
|
+
case "number" /* NUMBER */:
|
|
155
|
+
return makeZodSchemaFromJobInputNumberSchema(jobInputSchema2);
|
|
156
|
+
case "boolean" /* BOOLEAN */:
|
|
157
|
+
return makeZodSchemaFromJobInputBooleanSchema();
|
|
158
|
+
case "option" /* OPTION */:
|
|
159
|
+
return makeZodSchemaFromJobInputOptionSchema(jobInputSchema2);
|
|
160
|
+
case "file" /* FILE */:
|
|
161
|
+
return makeZodSchemaFromJobInputFileSchema(jobInputSchema2);
|
|
162
|
+
case "none" /* NONE */:
|
|
163
|
+
return zod.z.never().nullable();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var makeZodSchemaFromJobInputStringSchema = (jobInputStringSchema2) => {
|
|
167
|
+
const { validations } = jobInputStringSchema2;
|
|
168
|
+
const defaultSchema = zod.z.string();
|
|
169
|
+
if (!validations) return defaultSchema;
|
|
170
|
+
let canBeOptional = false;
|
|
171
|
+
const schema = validations.reduce((acc, cur) => {
|
|
172
|
+
const { validation, value } = cur;
|
|
173
|
+
switch (validation) {
|
|
174
|
+
case "min" /* MIN */:
|
|
175
|
+
return acc.min(value);
|
|
176
|
+
case "max" /* MAX */:
|
|
177
|
+
return acc.max(value);
|
|
178
|
+
case "format" /* FORMAT */:
|
|
179
|
+
switch (value) {
|
|
180
|
+
case "url" /* URL */:
|
|
181
|
+
return acc.url();
|
|
182
|
+
case "email" /* EMAIL */:
|
|
183
|
+
return acc.email();
|
|
184
|
+
case "nonempty" /* NON_EMPTY */:
|
|
185
|
+
return acc.min(1);
|
|
186
|
+
default:
|
|
187
|
+
return acc;
|
|
188
|
+
}
|
|
189
|
+
case "optional" /* OPTIONAL */:
|
|
190
|
+
canBeOptional = value === "true";
|
|
191
|
+
return acc;
|
|
192
|
+
}
|
|
193
|
+
}, defaultSchema);
|
|
194
|
+
return canBeOptional ? schema.optional() : schema;
|
|
195
|
+
};
|
|
196
|
+
var makeZodSchemaFromJobInputTextareaSchema = (jobInputTextareaSchema2) => {
|
|
197
|
+
const { validations } = jobInputTextareaSchema2;
|
|
198
|
+
const defaultSchema = zod.z.string();
|
|
199
|
+
if (!validations) return defaultSchema;
|
|
200
|
+
let canBeOptional = false;
|
|
201
|
+
const schema = validations.reduce((acc, cur) => {
|
|
202
|
+
const { validation, value } = cur;
|
|
203
|
+
switch (validation) {
|
|
204
|
+
case "min" /* MIN */:
|
|
205
|
+
return acc.min(value);
|
|
206
|
+
case "max" /* MAX */:
|
|
207
|
+
return acc.max(value);
|
|
208
|
+
case "format" /* FORMAT */:
|
|
209
|
+
switch (value) {
|
|
210
|
+
case "nonempty" /* NON_EMPTY */:
|
|
211
|
+
return acc.min(1);
|
|
212
|
+
default:
|
|
213
|
+
return acc;
|
|
214
|
+
}
|
|
215
|
+
case "optional" /* OPTIONAL */:
|
|
216
|
+
canBeOptional = value === "true";
|
|
217
|
+
return acc;
|
|
218
|
+
}
|
|
219
|
+
}, defaultSchema);
|
|
220
|
+
return canBeOptional ? schema.optional() : schema;
|
|
221
|
+
};
|
|
222
|
+
var makeZodSchemaFromJobInputNumberSchema = (jobInputNumberSchema2) => {
|
|
223
|
+
const { validations } = jobInputNumberSchema2;
|
|
224
|
+
const defaultSchema = zod.z.number({ coerce: true });
|
|
225
|
+
if (!validations) return defaultSchema;
|
|
226
|
+
let canBeOptional = false;
|
|
227
|
+
const schema = validations.reduce((acc, cur) => {
|
|
228
|
+
const { validation, value } = cur;
|
|
229
|
+
switch (validation) {
|
|
230
|
+
case "min" /* MIN */:
|
|
231
|
+
return acc.min(value);
|
|
232
|
+
case "max" /* MAX */:
|
|
233
|
+
return acc.max(value);
|
|
234
|
+
case "format" /* FORMAT */:
|
|
235
|
+
switch (value) {
|
|
236
|
+
case "integer" /* INTEGER */:
|
|
237
|
+
return acc.int();
|
|
238
|
+
default:
|
|
239
|
+
return acc;
|
|
240
|
+
}
|
|
241
|
+
case "optional" /* OPTIONAL */:
|
|
242
|
+
canBeOptional = value === "true";
|
|
243
|
+
return acc;
|
|
244
|
+
}
|
|
245
|
+
}, defaultSchema);
|
|
246
|
+
return canBeOptional ? schema.optional() : schema;
|
|
247
|
+
};
|
|
248
|
+
var makeZodSchemaFromJobInputBooleanSchema = () => {
|
|
249
|
+
return zod.z.boolean();
|
|
250
|
+
};
|
|
251
|
+
var makeZodSchemaFromJobInputOptionSchema = (jobInputOptionSchema2) => {
|
|
252
|
+
const {
|
|
253
|
+
data: { values },
|
|
254
|
+
validations
|
|
255
|
+
} = jobInputOptionSchema2;
|
|
256
|
+
const defaultSchema = zod.z.array(
|
|
257
|
+
zod.z.number().int().nonnegative().max(values.length - 1)
|
|
258
|
+
);
|
|
259
|
+
if (!validations) return defaultSchema;
|
|
260
|
+
let canBeOptional = false;
|
|
261
|
+
const schema = validations.reduce((acc, cur) => {
|
|
262
|
+
const { validation, value } = cur;
|
|
263
|
+
switch (validation) {
|
|
264
|
+
case "min" /* MIN */:
|
|
265
|
+
return acc.min(value);
|
|
266
|
+
case "max" /* MAX */:
|
|
267
|
+
return acc.max(value);
|
|
268
|
+
case "optional" /* OPTIONAL */:
|
|
269
|
+
canBeOptional = value === "true";
|
|
270
|
+
return acc;
|
|
271
|
+
}
|
|
272
|
+
}, defaultSchema);
|
|
273
|
+
return canBeOptional ? schema.optional() : schema;
|
|
274
|
+
};
|
|
275
|
+
var makeZodSchemaFromJobInputFileSchema = (jobInputFileSchema2) => {
|
|
276
|
+
const { validations } = jobInputFileSchema2;
|
|
277
|
+
const defaultSchema = zod.z.string();
|
|
278
|
+
if (!validations) return defaultSchema;
|
|
279
|
+
let canBeOptional = false;
|
|
280
|
+
const schema = validations.reduce((acc, cur) => {
|
|
281
|
+
const { validation, value } = cur;
|
|
282
|
+
switch (validation) {
|
|
283
|
+
case "optional" /* OPTIONAL */:
|
|
284
|
+
canBeOptional = value === "true";
|
|
285
|
+
return acc;
|
|
286
|
+
default:
|
|
287
|
+
return acc;
|
|
288
|
+
}
|
|
289
|
+
}, defaultSchema);
|
|
290
|
+
return canBeOptional ? schema.optional() : schema;
|
|
291
|
+
};
|
|
292
|
+
var isOptional = (jobInputSchema2) => {
|
|
293
|
+
if (!("validations" in jobInputSchema2) || !jobInputSchema2.validations)
|
|
294
|
+
return false;
|
|
295
|
+
return jobInputSchema2.validations.some(
|
|
296
|
+
(v) => v.validation === "optional" /* OPTIONAL */ && v.value === "true"
|
|
297
|
+
);
|
|
298
|
+
};
|
|
299
|
+
var isSingleOption = (jobInputSchema2) => {
|
|
300
|
+
if (jobInputSchema2.type !== "option" /* OPTION */) return false;
|
|
301
|
+
if (!("validations" in jobInputSchema2) || !jobInputSchema2.validations)
|
|
302
|
+
return false;
|
|
303
|
+
const minValidation = jobInputSchema2.validations.find(
|
|
304
|
+
(v) => v.validation === "min" /* MIN */
|
|
305
|
+
);
|
|
306
|
+
const maxValidation = jobInputSchema2.validations.find(
|
|
307
|
+
(v) => v.validation === "max" /* MAX */
|
|
308
|
+
);
|
|
309
|
+
return minValidation?.value === 1 && maxValidation?.value === 1;
|
|
310
|
+
};
|
|
311
|
+
var getDefaultValue = (jobInputSchema2) => {
|
|
312
|
+
const { type } = jobInputSchema2;
|
|
313
|
+
switch (type) {
|
|
314
|
+
case "string" /* STRING */:
|
|
315
|
+
return "";
|
|
316
|
+
case "textarea" /* TEXTAREA */:
|
|
317
|
+
return "";
|
|
318
|
+
case "boolean" /* BOOLEAN */:
|
|
319
|
+
return false;
|
|
320
|
+
case "number" /* NUMBER */:
|
|
321
|
+
return null;
|
|
322
|
+
case "option" /* OPTION */:
|
|
323
|
+
return [];
|
|
324
|
+
case "file" /* FILE */:
|
|
325
|
+
return null;
|
|
326
|
+
case "none" /* NONE */:
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// src/lib/validation.ts
|
|
332
|
+
function validateSchemaWithZod(input) {
|
|
333
|
+
let parsed;
|
|
334
|
+
try {
|
|
335
|
+
parsed = JSON.parse(input);
|
|
336
|
+
} catch (e) {
|
|
337
|
+
const match = e.message.match(/at position (\d+)/);
|
|
338
|
+
let line;
|
|
339
|
+
if (match) {
|
|
340
|
+
const pos = parseInt(match[1], 10);
|
|
341
|
+
line = input.slice(0, pos).split("\n").length;
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
valid: false,
|
|
345
|
+
errors: [{ message: "Invalid JSON: " + e.message, line }]
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
const errors = [];
|
|
349
|
+
const schemas = [];
|
|
350
|
+
const getLine = (key) => {
|
|
351
|
+
const idx = input.indexOf('"' + key + '"');
|
|
352
|
+
if (idx === -1) return void 0;
|
|
353
|
+
return input.slice(0, idx).split("\n").length;
|
|
354
|
+
};
|
|
355
|
+
let schemasToValidate;
|
|
356
|
+
if (parsed.input_data && Array.isArray(parsed.input_data)) {
|
|
357
|
+
schemasToValidate = parsed.input_data;
|
|
358
|
+
} else if (Array.isArray(parsed)) {
|
|
359
|
+
schemasToValidate = parsed;
|
|
360
|
+
} else {
|
|
361
|
+
schemasToValidate = [parsed];
|
|
362
|
+
}
|
|
363
|
+
schemasToValidate.forEach((schema, index) => {
|
|
364
|
+
try {
|
|
365
|
+
const validatedSchema = jobInputSchema.parse(schema);
|
|
366
|
+
schemas.push(validatedSchema);
|
|
367
|
+
} catch (zodError) {
|
|
368
|
+
if (zodError.errors) {
|
|
369
|
+
zodError.errors.forEach((error) => {
|
|
370
|
+
errors.push({
|
|
371
|
+
message: `Schema ${index + 1}: ${error.message}`,
|
|
372
|
+
line: getLine(error.path?.[0] || "")
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
} else {
|
|
376
|
+
errors.push({
|
|
377
|
+
message: `Schema ${index + 1}: ${zodError.message}`,
|
|
378
|
+
line: getLine("type")
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
if (errors.length > 0) {
|
|
384
|
+
return { valid: false, errors };
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
valid: true,
|
|
388
|
+
errors: [],
|
|
389
|
+
parsedSchemas: schemas
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
var Label = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("label", { ref, className: cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", className), ...props }));
|
|
393
|
+
Label.displayName = "Label";
|
|
394
|
+
var Input = React2__default.default.forwardRef(({ className, type, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
395
|
+
"input",
|
|
396
|
+
{
|
|
397
|
+
type,
|
|
398
|
+
className: cn(
|
|
399
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
400
|
+
className
|
|
401
|
+
),
|
|
402
|
+
ref,
|
|
403
|
+
...props
|
|
404
|
+
}
|
|
405
|
+
));
|
|
406
|
+
Input.displayName = "Input";
|
|
407
|
+
var Textarea = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
408
|
+
"textarea",
|
|
409
|
+
{
|
|
410
|
+
className: cn(
|
|
411
|
+
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
412
|
+
className
|
|
413
|
+
),
|
|
414
|
+
ref,
|
|
415
|
+
...props
|
|
416
|
+
}
|
|
417
|
+
));
|
|
418
|
+
Textarea.displayName = "Textarea";
|
|
419
|
+
var Checkbox = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("input", { type: "checkbox", ref, className: cn("h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary", className), ...props }));
|
|
420
|
+
Checkbox.displayName = "Checkbox";
|
|
421
|
+
function JobInputRenderer({
|
|
422
|
+
jobInputSchema: jobInputSchema2,
|
|
423
|
+
value,
|
|
424
|
+
onChange,
|
|
425
|
+
disabled
|
|
426
|
+
}) {
|
|
427
|
+
const { id, name, type, data } = jobInputSchema2;
|
|
428
|
+
const description = data?.description;
|
|
429
|
+
const placeholder = "placeholder" in (data || {}) ? data.placeholder : "";
|
|
430
|
+
const renderInput = () => {
|
|
431
|
+
switch (type) {
|
|
432
|
+
case "string" /* STRING */:
|
|
433
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
434
|
+
Input,
|
|
435
|
+
{
|
|
436
|
+
id,
|
|
437
|
+
value: value || "",
|
|
438
|
+
onChange: (e) => onChange(e.target.value),
|
|
439
|
+
placeholder,
|
|
440
|
+
disabled
|
|
441
|
+
}
|
|
442
|
+
);
|
|
443
|
+
case "textarea" /* TEXTAREA */:
|
|
444
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
445
|
+
Textarea,
|
|
446
|
+
{
|
|
447
|
+
id,
|
|
448
|
+
value: value || "",
|
|
449
|
+
onChange: (e) => onChange(e.target.value),
|
|
450
|
+
placeholder,
|
|
451
|
+
disabled
|
|
452
|
+
}
|
|
453
|
+
);
|
|
454
|
+
case "number" /* NUMBER */:
|
|
455
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
456
|
+
Input,
|
|
457
|
+
{
|
|
458
|
+
id,
|
|
459
|
+
type: "number",
|
|
460
|
+
value: value !== null ? String(value) : "",
|
|
461
|
+
onChange: (e) => {
|
|
462
|
+
const val = e.target.value;
|
|
463
|
+
onChange(val === "" ? null : Number(val));
|
|
464
|
+
},
|
|
465
|
+
placeholder,
|
|
466
|
+
disabled
|
|
467
|
+
}
|
|
468
|
+
);
|
|
469
|
+
case "boolean" /* BOOLEAN */:
|
|
470
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
471
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
472
|
+
Checkbox,
|
|
473
|
+
{
|
|
474
|
+
id,
|
|
475
|
+
checked: !!value,
|
|
476
|
+
onChange: (e) => onChange(e.target.checked),
|
|
477
|
+
disabled
|
|
478
|
+
}
|
|
479
|
+
),
|
|
480
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
481
|
+
"label",
|
|
482
|
+
{
|
|
483
|
+
htmlFor: id,
|
|
484
|
+
className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
485
|
+
children: placeholder || "Yes"
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
] });
|
|
489
|
+
case "option" /* OPTION */:
|
|
490
|
+
const options = data.values || [];
|
|
491
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
492
|
+
"select",
|
|
493
|
+
{
|
|
494
|
+
id,
|
|
495
|
+
className: "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
496
|
+
value: Array.isArray(value) && value.length > 0 ? value[0] : "",
|
|
497
|
+
onChange: (e) => {
|
|
498
|
+
const selectedIndex = options.indexOf(e.target.value);
|
|
499
|
+
onChange(selectedIndex >= 0 ? [selectedIndex] : []);
|
|
500
|
+
},
|
|
501
|
+
disabled,
|
|
502
|
+
children: [
|
|
503
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select..." }),
|
|
504
|
+
options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: opt }, opt))
|
|
505
|
+
]
|
|
506
|
+
}
|
|
507
|
+
);
|
|
508
|
+
case "file" /* FILE */:
|
|
509
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
510
|
+
Input,
|
|
511
|
+
{
|
|
512
|
+
id,
|
|
513
|
+
type: "file",
|
|
514
|
+
disabled,
|
|
515
|
+
onChange: () => {
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
);
|
|
519
|
+
default:
|
|
520
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
521
|
+
"Unsupported input type: ",
|
|
522
|
+
type
|
|
523
|
+
] });
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
527
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-1", children: [
|
|
528
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: id, children: [
|
|
529
|
+
name,
|
|
530
|
+
"validations" in jobInputSchema2 && jobInputSchema2.validations?.some((v) => v.validation === "optional" && v.value === "true") && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-normal ml-1", children: "(Optional)" })
|
|
531
|
+
] }),
|
|
532
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
533
|
+
] }),
|
|
534
|
+
renderInput()
|
|
535
|
+
] });
|
|
536
|
+
}
|
|
537
|
+
function cn(...inputs) {
|
|
538
|
+
return tailwindMerge.twMerge(clsx__default.default(inputs));
|
|
539
|
+
}
|
|
540
|
+
var Button = React2__default.default.forwardRef(
|
|
541
|
+
({ className, variant = "default", ...props }, ref) => {
|
|
542
|
+
const variants = {
|
|
543
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
544
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
545
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
546
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
547
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
548
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
549
|
+
};
|
|
550
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
551
|
+
"button",
|
|
552
|
+
{
|
|
553
|
+
ref,
|
|
554
|
+
className: cn(
|
|
555
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-10 px-4 py-2",
|
|
556
|
+
variants[variant],
|
|
557
|
+
className
|
|
558
|
+
),
|
|
559
|
+
...props
|
|
560
|
+
}
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
Button.displayName = "Button";
|
|
565
|
+
var Card = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props }));
|
|
566
|
+
Card.displayName = "Card";
|
|
567
|
+
var CardHeader = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props }));
|
|
568
|
+
CardHeader.displayName = "CardHeader";
|
|
569
|
+
var CardTitle = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props }));
|
|
570
|
+
CardTitle.displayName = "CardTitle";
|
|
571
|
+
var CardContent = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
572
|
+
CardContent.displayName = "CardContent";
|
|
573
|
+
var Separator = React2__default.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("shrink-0 bg-border h-[1px] w-full", className), ...props }));
|
|
574
|
+
Separator.displayName = "Separator";
|
|
575
|
+
function JobInputsFormRenderer({
|
|
576
|
+
jobInputSchemas,
|
|
577
|
+
onFormDataChange,
|
|
578
|
+
disabled = false,
|
|
579
|
+
className
|
|
580
|
+
}) {
|
|
581
|
+
const [formData, setFormData] = React2.useState({});
|
|
582
|
+
React2.useEffect(() => {
|
|
583
|
+
const initialData = {};
|
|
584
|
+
jobInputSchemas.forEach((schema) => {
|
|
585
|
+
initialData[schema.id] = getDefaultValue(schema);
|
|
586
|
+
});
|
|
587
|
+
setFormData(initialData);
|
|
588
|
+
}, [jobInputSchemas]);
|
|
589
|
+
React2.useEffect(() => {
|
|
590
|
+
if (onFormDataChange) {
|
|
591
|
+
onFormDataChange(formData);
|
|
592
|
+
}
|
|
593
|
+
}, [formData, onFormDataChange]);
|
|
594
|
+
const handleFieldChange = (fieldId, value) => {
|
|
595
|
+
setFormData((prev) => ({
|
|
596
|
+
...prev,
|
|
597
|
+
[fieldId]: value
|
|
598
|
+
}));
|
|
599
|
+
};
|
|
600
|
+
const handleClear = () => {
|
|
601
|
+
const clearedData = {};
|
|
602
|
+
jobInputSchemas.forEach((schema) => {
|
|
603
|
+
clearedData[schema.id] = getDefaultValue(schema);
|
|
604
|
+
});
|
|
605
|
+
setFormData(clearedData);
|
|
606
|
+
};
|
|
607
|
+
if (jobInputSchemas.length === 0) {
|
|
608
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "pt-6", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground text-center", children: "No input fields defined in the schema." }) }) });
|
|
609
|
+
}
|
|
610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: cn("bg-muted/20", className), children: [
|
|
611
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { children: [
|
|
612
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "text-lg", children: "Rendered Form" }),
|
|
613
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "This is how the form will appear in Sokosumi" })
|
|
614
|
+
] }),
|
|
615
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-6", children: [
|
|
616
|
+
/* @__PURE__ */ jsxRuntime.jsx("form", { className: "space-y-4", onSubmit: (e) => e.preventDefault(), children: jobInputSchemas.map((schema, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
617
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
618
|
+
JobInputRenderer,
|
|
619
|
+
{
|
|
620
|
+
jobInputSchema: schema,
|
|
621
|
+
value: formData[schema.id],
|
|
622
|
+
onChange: (value) => handleFieldChange(schema.id, value),
|
|
623
|
+
disabled
|
|
624
|
+
}
|
|
625
|
+
),
|
|
626
|
+
index < jobInputSchemas.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-4" })
|
|
627
|
+
] }, schema.id)) }),
|
|
628
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center pt-4", children: [
|
|
629
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
630
|
+
Button,
|
|
631
|
+
{
|
|
632
|
+
type: "button",
|
|
633
|
+
variant: "outline",
|
|
634
|
+
onClick: handleClear,
|
|
635
|
+
disabled,
|
|
636
|
+
children: "Clear Form"
|
|
637
|
+
}
|
|
638
|
+
),
|
|
639
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
640
|
+
Object.keys(formData).length,
|
|
641
|
+
" field",
|
|
642
|
+
Object.keys(formData).length !== 1 ? "s" : ""
|
|
643
|
+
] })
|
|
644
|
+
] })
|
|
645
|
+
] })
|
|
646
|
+
] });
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
exports.JobInputRenderer = JobInputRenderer;
|
|
650
|
+
exports.JobInputsFormRenderer = JobInputsFormRenderer;
|
|
651
|
+
exports.ValidJobInputFormatValues = ValidJobInputFormatValues;
|
|
652
|
+
exports.ValidJobInputTypes = ValidJobInputTypes;
|
|
653
|
+
exports.ValidJobInputValidationTypes = ValidJobInputValidationTypes;
|
|
654
|
+
exports.formatEmailValidationSchema = formatEmailValidationSchema;
|
|
655
|
+
exports.formatIntegerValidationSchema = formatIntegerValidationSchema;
|
|
656
|
+
exports.formatNonEmptyValidationSchema = formatNonEmptyValidationSchema;
|
|
657
|
+
exports.formatUrlValidationSchema = formatUrlValidationSchema;
|
|
658
|
+
exports.getDefaultValue = getDefaultValue;
|
|
659
|
+
exports.isOptional = isOptional;
|
|
660
|
+
exports.isSingleOption = isSingleOption;
|
|
661
|
+
exports.jobInputBooleanSchema = jobInputBooleanSchema;
|
|
662
|
+
exports.jobInputFileSchema = jobInputFileSchema;
|
|
663
|
+
exports.jobInputNoneSchema = jobInputNoneSchema;
|
|
664
|
+
exports.jobInputNumberSchema = jobInputNumberSchema;
|
|
665
|
+
exports.jobInputOptionSchema = jobInputOptionSchema;
|
|
666
|
+
exports.jobInputSchema = jobInputSchema;
|
|
667
|
+
exports.jobInputStringSchema = jobInputStringSchema;
|
|
668
|
+
exports.jobInputTextareaSchema = jobInputTextareaSchema;
|
|
669
|
+
exports.makeZodSchemaFromJobInputSchema = makeZodSchemaFromJobInputSchema;
|
|
670
|
+
exports.maxValidationSchema = maxValidationSchema;
|
|
671
|
+
exports.minValidationSchema = minValidationSchema;
|
|
672
|
+
exports.optionalValidationSchema = optionalValidationSchema;
|
|
673
|
+
exports.validateSchemaWithZod = validateSchemaWithZod;
|
|
674
|
+
//# sourceMappingURL=index.js.map
|
|
675
|
+
//# sourceMappingURL=index.js.map
|