@vite-hub/workflow 0.0.4 → 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/README.md +34 -14
- package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
- package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
- package/dist/client-DsGM3M4U.js +389 -0
- package/dist/cloudflare-env-BNrYo29x.js +113 -0
- package/dist/{cloudflare-D0Di-QYL.js → cloudflare-nF4abPd4.js} +20 -4
- package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
- package/dist/{cloudflare-vite-BkDgB6Sr.js → cloudflare-vite-B3IabBsv.js} +5 -4
- package/dist/{config-BHknO_rT.js → config-IJMb0eeZ.js} +38 -30
- package/dist/error-diagnostics-A_8Kp-48.js +116 -0
- package/dist/error-diagnostics-pwNFvAHP.js +67 -0
- package/dist/index.d.ts +20 -21
- package/dist/index.js +25 -369
- package/dist/inspect-B72iFyj-.js +70 -0
- package/dist/operations-B_rYG71W.js +230 -0
- package/dist/operations-tNUdj3G4.d.ts +212 -0
- package/dist/operations.d.ts +37 -0
- package/dist/operations.js +887 -0
- package/dist/out-CsaJxg8m.js +21755 -0
- package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
- package/dist/runtime/cloudflare-runner.d.ts +5 -15
- package/dist/runtime/cloudflare-runner.js +40 -5
- package/dist/runtime/cloudflare-shared.d.ts +1 -0
- package/dist/runtime/cloudflare-shared.js +1 -1
- package/dist/runtime/cloudflare-vite.d.ts +8 -10
- package/dist/runtime/cloudflare-vite.js +1 -1
- package/dist/runtime/execute.d.ts +8 -7
- package/dist/runtime/execute.js +28 -5
- package/dist/runtime/openworkflow-worker.d.ts +6 -8
- package/dist/runtime/openworkflow-worker.js +5 -4
- package/dist/runtime/openworkflow.d.ts +8 -10
- package/dist/runtime/openworkflow.js +23 -17
- package/dist/runtime/state.d.ts +20 -21
- package/dist/runtime/state.js +90 -20
- package/dist/runtime/vercel-vite.d.ts +10 -12
- package/dist/runtime/vercel-vite.js +2 -2
- package/dist/runtime-type-DBCvIh5x.js +7 -0
- package/dist/{types-B9RdRkKh.d.ts → types-D82WmfZa.d.ts} +23 -12
- package/dist/{vercel-B0MuIVgJ.js → vercel-D-ZNtB_u.js} +34 -9
- package/dist/vite.d.ts +325 -11
- package/dist/vite.js +1267 -691
- package/package.json +79 -29
- package/dist/cloudflare-env-DjxQNbrx.js +0 -58
- package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
- package/dist/runtime-type-DGUn8Ple.js +0 -37
|
@@ -0,0 +1,887 @@
|
|
|
1
|
+
import { t as internalErrorDiagnostics } from "./error-diagnostics-A_8Kp-48.js";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
//#region ../internal/src/standard-schema.ts
|
|
4
|
+
function readOwn(value, key) {
|
|
5
|
+
if (value === null || Object(value) !== value) return;
|
|
6
|
+
try {
|
|
7
|
+
return Reflect.get(Object(value), key);
|
|
8
|
+
} catch {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function isRecord(value) {
|
|
13
|
+
return value !== null && Object(value) === value && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Read a Standard JSON Schema projection without throwing.
|
|
17
|
+
*
|
|
18
|
+
* Returns `undefined` when the schema has no `~standard.jsonSchema`, when the library cannot represent the type
|
|
19
|
+
* (Zod throws for `Date`), or when the projection is not an object. Callers decide how to fall back.
|
|
20
|
+
*/
|
|
21
|
+
function standardJsonSchema(schema, direction, target = "draft-2020-12", libraryOptions) {
|
|
22
|
+
const jsonSchema = readOwn(readOwn(schema, "~standard"), "jsonSchema");
|
|
23
|
+
const project = readOwn(jsonSchema, direction);
|
|
24
|
+
if (typeof project !== "function") return;
|
|
25
|
+
try {
|
|
26
|
+
const result = project.call(jsonSchema, libraryOptions ? {
|
|
27
|
+
target,
|
|
28
|
+
libraryOptions
|
|
29
|
+
} : { target });
|
|
30
|
+
return isRecord(result) ? result : void 0;
|
|
31
|
+
} catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region ../../node_modules/.pnpm/@valibot+to-json-schema@1.8.0_valibot@1.5.0_typescript@6.0.3_/node_modules/@valibot/to-json-schema/dist/index.mjs
|
|
37
|
+
/**
|
|
38
|
+
* Adds an error message to the errors array.
|
|
39
|
+
*
|
|
40
|
+
* @param errors The array of error messages.
|
|
41
|
+
* @param message The error message to add.
|
|
42
|
+
*
|
|
43
|
+
* @returns The new errors.
|
|
44
|
+
*/
|
|
45
|
+
function addError(errors, message) {
|
|
46
|
+
if (errors) {
|
|
47
|
+
errors.push(message);
|
|
48
|
+
return errors;
|
|
49
|
+
}
|
|
50
|
+
return [message];
|
|
51
|
+
}
|
|
52
|
+
const ESCAPE_REGEX = /[.*+?^${}()|[\]\\]/g;
|
|
53
|
+
/**
|
|
54
|
+
* Escapes special regex characters in a string.
|
|
55
|
+
*
|
|
56
|
+
* @param string The string to escape.
|
|
57
|
+
*
|
|
58
|
+
* @returns The escaped string.
|
|
59
|
+
*/
|
|
60
|
+
function escapeRegExp(string) {
|
|
61
|
+
return string.replace(ESCAPE_REGEX, "\\$&");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Throws an error or logs a warning based on the configuration.
|
|
65
|
+
*
|
|
66
|
+
* @param message The message to throw or log.
|
|
67
|
+
* @param config The conversion configuration.
|
|
68
|
+
*/
|
|
69
|
+
function handleError(message, config) {
|
|
70
|
+
switch (config?.errorMode) {
|
|
71
|
+
case "ignore": break;
|
|
72
|
+
case "warn":
|
|
73
|
+
console.warn(message);
|
|
74
|
+
break;
|
|
75
|
+
default: throw new Error(message);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether a value is JSON compatible for a const keyword.
|
|
80
|
+
*
|
|
81
|
+
* @param value The value to check.
|
|
82
|
+
*
|
|
83
|
+
* @returns Whether the value is JSON compatible.
|
|
84
|
+
*/
|
|
85
|
+
function isJsonConstValue(value) {
|
|
86
|
+
return typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string";
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Whether values are JSON compatible for an enum keyword.
|
|
90
|
+
*
|
|
91
|
+
* @param values The values to check.
|
|
92
|
+
*
|
|
93
|
+
* @returns Whether the values are JSON compatible.
|
|
94
|
+
*/
|
|
95
|
+
function isJsonEnumValues(values) {
|
|
96
|
+
return values.every(isJsonConstValue);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Schema reference map with collision-free reference ID allocation.
|
|
100
|
+
*/
|
|
101
|
+
var ReferenceMap = class extends Map {
|
|
102
|
+
/**
|
|
103
|
+
* Creates an empty schema reference map.
|
|
104
|
+
*/
|
|
105
|
+
constructor() {
|
|
106
|
+
super();
|
|
107
|
+
this.count = 0;
|
|
108
|
+
this.usedIds = /* @__PURE__ */ new Set();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Adds a schema reference and reserves its ID.
|
|
112
|
+
*
|
|
113
|
+
* @param schema The Valibot schema.
|
|
114
|
+
* @param referenceId The reference ID.
|
|
115
|
+
*
|
|
116
|
+
* @returns The reference map.
|
|
117
|
+
*/
|
|
118
|
+
set(schema, referenceId) {
|
|
119
|
+
this.usedIds.add(referenceId);
|
|
120
|
+
return super.set(schema, referenceId);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Creates a reference ID that is not yet used.
|
|
124
|
+
*
|
|
125
|
+
* @param definitions The JSON Schema definitions.
|
|
126
|
+
*
|
|
127
|
+
* @returns The unused reference ID.
|
|
128
|
+
*/
|
|
129
|
+
createId(definitions) {
|
|
130
|
+
while (this.usedIds.has(`${this.count}`) || `${this.count}` in definitions) this.count++;
|
|
131
|
+
return `${this.count++}`;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Returns the stricter lower bound.
|
|
136
|
+
*
|
|
137
|
+
* @param current The current lower bound.
|
|
138
|
+
* @param value The new lower bound.
|
|
139
|
+
*
|
|
140
|
+
* @returns The stricter lower bound.
|
|
141
|
+
*/
|
|
142
|
+
function getLowerBound(current, value) {
|
|
143
|
+
if (typeof current !== "number" || !Number.isFinite(current) || value > current) return value;
|
|
144
|
+
return current;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Returns the stricter upper bound.
|
|
148
|
+
*
|
|
149
|
+
* @param current The current upper bound.
|
|
150
|
+
* @param value The new upper bound.
|
|
151
|
+
*
|
|
152
|
+
* @returns The stricter upper bound.
|
|
153
|
+
*/
|
|
154
|
+
function getUpperBound(current, value) {
|
|
155
|
+
if (typeof current !== "number" || !Number.isFinite(current) || value < current) return value;
|
|
156
|
+
return current;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Returns the combined not restriction.
|
|
160
|
+
*
|
|
161
|
+
* @param current The current not restriction.
|
|
162
|
+
* @param value The new not restriction.
|
|
163
|
+
*
|
|
164
|
+
* @returns The combined not restriction.
|
|
165
|
+
*/
|
|
166
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
167
|
+
function getNotRestriction(current, value) {
|
|
168
|
+
return current !== void 0 ? { anyOf: [current, value] } : value;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Intersects allowed values with an existing enum restriction.
|
|
172
|
+
*
|
|
173
|
+
* @param jsonSchema The JSON Schema object.
|
|
174
|
+
* @param values The allowed values.
|
|
175
|
+
*/
|
|
176
|
+
function intersectEnum(jsonSchema, values) {
|
|
177
|
+
let enumValues = jsonSchema.enum ?? values;
|
|
178
|
+
if (jsonSchema.enum) {
|
|
179
|
+
const valueSet = new Set(values);
|
|
180
|
+
enumValues = enumValues.filter((value) => valueSet.has(value));
|
|
181
|
+
}
|
|
182
|
+
if (enumValues.length) jsonSchema.enum = [...new Set(enumValues)];
|
|
183
|
+
else {
|
|
184
|
+
delete jsonSchema.enum;
|
|
185
|
+
jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, {});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Converts any supported Valibot action to the JSON Schema format.
|
|
190
|
+
*
|
|
191
|
+
* @param jsonSchema The JSON Schema object.
|
|
192
|
+
* @param valibotAction The Valibot action object.
|
|
193
|
+
* @param config The conversion configuration.
|
|
194
|
+
*
|
|
195
|
+
* @returns The converted JSON Schema.
|
|
196
|
+
*/
|
|
197
|
+
function convertAction(jsonSchema, valibotAction, config) {
|
|
198
|
+
if (config?.ignoreActions?.includes(valibotAction.type)) return jsonSchema;
|
|
199
|
+
let errors;
|
|
200
|
+
switch (valibotAction.type) {
|
|
201
|
+
case "base64":
|
|
202
|
+
jsonSchema.contentEncoding = "base64";
|
|
203
|
+
break;
|
|
204
|
+
case "bic":
|
|
205
|
+
case "cuid2":
|
|
206
|
+
case "decimal":
|
|
207
|
+
case "digits":
|
|
208
|
+
case "domain":
|
|
209
|
+
case "emoji":
|
|
210
|
+
case "hash":
|
|
211
|
+
case "hexadecimal":
|
|
212
|
+
case "hex_color":
|
|
213
|
+
case "isrc":
|
|
214
|
+
case "iso_time_second":
|
|
215
|
+
case "iso_week":
|
|
216
|
+
case "ksuid":
|
|
217
|
+
case "mac":
|
|
218
|
+
case "mac48":
|
|
219
|
+
case "mac64":
|
|
220
|
+
case "nanoid":
|
|
221
|
+
case "octal":
|
|
222
|
+
case "slug":
|
|
223
|
+
case "ulid":
|
|
224
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
225
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
226
|
+
break;
|
|
227
|
+
case "description":
|
|
228
|
+
jsonSchema.description = valibotAction.description;
|
|
229
|
+
break;
|
|
230
|
+
case "email":
|
|
231
|
+
case "rfc_email":
|
|
232
|
+
jsonSchema.format = "email";
|
|
233
|
+
break;
|
|
234
|
+
case "ends_with":
|
|
235
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
236
|
+
else jsonSchema.pattern = `${escapeRegExp(valibotAction.requirement)}$`;
|
|
237
|
+
break;
|
|
238
|
+
case "empty":
|
|
239
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = 0;
|
|
240
|
+
else {
|
|
241
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
242
|
+
jsonSchema.maxLength = 0;
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
case "entries":
|
|
246
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
247
|
+
errors = addError(errors, "The requirement of the \"entries\" action must be a non-negative integer.");
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
jsonSchema.minProperties = getLowerBound(jsonSchema.minProperties, valibotAction.requirement);
|
|
251
|
+
jsonSchema.maxProperties = getUpperBound(jsonSchema.maxProperties, valibotAction.requirement);
|
|
252
|
+
break;
|
|
253
|
+
case "examples":
|
|
254
|
+
if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.examples];
|
|
255
|
+
else jsonSchema.examples = valibotAction.examples;
|
|
256
|
+
break;
|
|
257
|
+
case "gt_value":
|
|
258
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
259
|
+
errors = addError(errors, `The "gt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
263
|
+
errors = addError(errors, "The requirement of the \"gt_value\" action is not JSON compatible.");
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
if (config?.target === "openapi-3.0") {
|
|
267
|
+
errors = addError(errors, "The \"gt_value\" action is not supported for OpenAPI 3.0.");
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
jsonSchema.exclusiveMinimum = getLowerBound(jsonSchema.exclusiveMinimum, valibotAction.requirement);
|
|
271
|
+
break;
|
|
272
|
+
case "includes":
|
|
273
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
274
|
+
else jsonSchema.pattern = escapeRegExp(valibotAction.requirement);
|
|
275
|
+
break;
|
|
276
|
+
case "integer":
|
|
277
|
+
jsonSchema.type = "integer";
|
|
278
|
+
break;
|
|
279
|
+
case "ipv4":
|
|
280
|
+
jsonSchema.format = "ipv4";
|
|
281
|
+
break;
|
|
282
|
+
case "ipv6":
|
|
283
|
+
jsonSchema.format = "ipv6";
|
|
284
|
+
break;
|
|
285
|
+
case "iso_date":
|
|
286
|
+
jsonSchema.format = "date";
|
|
287
|
+
break;
|
|
288
|
+
case "iso_date_time":
|
|
289
|
+
case "iso_timestamp":
|
|
290
|
+
jsonSchema.format = "date-time";
|
|
291
|
+
break;
|
|
292
|
+
case "iso_time":
|
|
293
|
+
jsonSchema.format = "time";
|
|
294
|
+
break;
|
|
295
|
+
case "jws_compact":
|
|
296
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
297
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
298
|
+
break;
|
|
299
|
+
case "length":
|
|
300
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
301
|
+
errors = addError(errors, "The requirement of the \"length\" action must be a non-negative integer.");
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
if (jsonSchema.type === "array") {
|
|
305
|
+
jsonSchema.minItems = getLowerBound(jsonSchema.minItems, valibotAction.requirement);
|
|
306
|
+
jsonSchema.maxItems = getUpperBound(jsonSchema.maxItems, valibotAction.requirement);
|
|
307
|
+
} else {
|
|
308
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
309
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, valibotAction.requirement);
|
|
310
|
+
jsonSchema.maxLength = getUpperBound(jsonSchema.maxLength, valibotAction.requirement);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
case "lt_value":
|
|
314
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
315
|
+
errors = addError(errors, `The "lt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
319
|
+
errors = addError(errors, "The requirement of the \"lt_value\" action is not JSON compatible.");
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
if (config?.target === "openapi-3.0") {
|
|
323
|
+
errors = addError(errors, "The \"lt_value\" action is not supported for OpenAPI 3.0.");
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
jsonSchema.exclusiveMaximum = getUpperBound(jsonSchema.exclusiveMaximum, valibotAction.requirement);
|
|
327
|
+
break;
|
|
328
|
+
case "max_entries":
|
|
329
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
330
|
+
errors = addError(errors, "The requirement of the \"max_entries\" action must be a non-negative integer.");
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
jsonSchema.maxProperties = getUpperBound(jsonSchema.maxProperties, valibotAction.requirement);
|
|
334
|
+
break;
|
|
335
|
+
case "max_length":
|
|
336
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
337
|
+
errors = addError(errors, "The requirement of the \"max_length\" action must be a non-negative integer.");
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = getUpperBound(jsonSchema.maxItems, valibotAction.requirement);
|
|
341
|
+
else {
|
|
342
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
343
|
+
jsonSchema.maxLength = getUpperBound(jsonSchema.maxLength, valibotAction.requirement);
|
|
344
|
+
}
|
|
345
|
+
break;
|
|
346
|
+
case "max_value":
|
|
347
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
348
|
+
errors = addError(errors, `The "max_value" action is not supported on type "${jsonSchema.type}".`);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
352
|
+
errors = addError(errors, "The requirement of the \"max_value\" action is not JSON compatible.");
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
jsonSchema.maximum = getUpperBound(jsonSchema.maximum, valibotAction.requirement);
|
|
356
|
+
break;
|
|
357
|
+
case "metadata":
|
|
358
|
+
if (typeof valibotAction.metadata.title === "string") jsonSchema.title = valibotAction.metadata.title;
|
|
359
|
+
if (typeof valibotAction.metadata.description === "string") jsonSchema.description = valibotAction.metadata.description;
|
|
360
|
+
if (Array.isArray(valibotAction.metadata.examples)) if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.metadata.examples];
|
|
361
|
+
else jsonSchema.examples = valibotAction.metadata.examples;
|
|
362
|
+
for (const key of Object.keys(valibotAction.metadata)) if (key !== "title" && key !== "description" && key !== "examples" && key !== "__proto__") jsonSchema[key] = valibotAction.metadata[key];
|
|
363
|
+
break;
|
|
364
|
+
case "min_entries":
|
|
365
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
366
|
+
errors = addError(errors, "The requirement of the \"min_entries\" action must be a non-negative integer.");
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
jsonSchema.minProperties = getLowerBound(jsonSchema.minProperties, valibotAction.requirement);
|
|
370
|
+
break;
|
|
371
|
+
case "min_length":
|
|
372
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
373
|
+
errors = addError(errors, "The requirement of the \"min_length\" action must be a non-negative integer.");
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = getLowerBound(jsonSchema.minItems, valibotAction.requirement);
|
|
377
|
+
else {
|
|
378
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
379
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, valibotAction.requirement);
|
|
380
|
+
}
|
|
381
|
+
break;
|
|
382
|
+
case "min_value":
|
|
383
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
384
|
+
errors = addError(errors, `The "min_value" action is not supported on type "${jsonSchema.type}".`);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
388
|
+
errors = addError(errors, "The requirement of the \"min_value\" action is not JSON compatible.");
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
jsonSchema.minimum = getLowerBound(jsonSchema.minimum, valibotAction.requirement);
|
|
392
|
+
break;
|
|
393
|
+
case "multiple_of":
|
|
394
|
+
jsonSchema.multipleOf = valibotAction.requirement;
|
|
395
|
+
break;
|
|
396
|
+
case "non_empty":
|
|
397
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = getLowerBound(jsonSchema.minItems, 1);
|
|
398
|
+
else {
|
|
399
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
400
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, 1);
|
|
401
|
+
}
|
|
402
|
+
break;
|
|
403
|
+
case "not_value":
|
|
404
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
405
|
+
errors = addError(errors, "The requirement of the \"not_value\" action is not JSON compatible.");
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, config?.target === "openapi-3.0" ? { enum: [valibotAction.requirement] } : { const: valibotAction.requirement });
|
|
409
|
+
break;
|
|
410
|
+
case "not_values":
|
|
411
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
412
|
+
errors = addError(errors, "A requirement of the \"not_values\" action is not JSON compatible.");
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
if (valibotAction.requirement.length) jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, { enum: [...new Set(valibotAction.requirement)] });
|
|
416
|
+
break;
|
|
417
|
+
case "regex":
|
|
418
|
+
if (valibotAction.requirement.flags) errors = addError(errors, "RegExp flags are not supported by JSON Schema.");
|
|
419
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
420
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
421
|
+
break;
|
|
422
|
+
case "safe_integer":
|
|
423
|
+
jsonSchema.type = "integer";
|
|
424
|
+
jsonSchema.minimum = getLowerBound(jsonSchema.minimum, Number.MIN_SAFE_INTEGER);
|
|
425
|
+
jsonSchema.maximum = getUpperBound(jsonSchema.maximum, Number.MAX_SAFE_INTEGER);
|
|
426
|
+
break;
|
|
427
|
+
case "starts_with":
|
|
428
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
429
|
+
else jsonSchema.pattern = `^${escapeRegExp(valibotAction.requirement)}`;
|
|
430
|
+
break;
|
|
431
|
+
case "title":
|
|
432
|
+
jsonSchema.title = valibotAction.title;
|
|
433
|
+
break;
|
|
434
|
+
case "url":
|
|
435
|
+
jsonSchema.format = "uri";
|
|
436
|
+
break;
|
|
437
|
+
case "uuid":
|
|
438
|
+
jsonSchema.format = "uuid";
|
|
439
|
+
break;
|
|
440
|
+
case "value":
|
|
441
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
442
|
+
errors = addError(errors, "The requirement of the \"value\" action is not JSON compatible.");
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
if (config?.target === "openapi-3.0") intersectEnum(jsonSchema, [valibotAction.requirement]);
|
|
446
|
+
else if ("const" in jsonSchema && jsonSchema.const !== valibotAction.requirement) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with a different "const" restriction.`);
|
|
447
|
+
else jsonSchema.const = valibotAction.requirement;
|
|
448
|
+
break;
|
|
449
|
+
case "values":
|
|
450
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
451
|
+
errors = addError(errors, "A requirement of the \"values\" action is not JSON compatible.");
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
intersectEnum(jsonSchema, valibotAction.requirement);
|
|
455
|
+
break;
|
|
456
|
+
default: errors = addError(errors, `The "${valibotAction.type}" action cannot be converted to JSON Schema.`);
|
|
457
|
+
}
|
|
458
|
+
if (config?.overrideAction) {
|
|
459
|
+
const actionOverride = config.overrideAction({
|
|
460
|
+
valibotAction,
|
|
461
|
+
jsonSchema,
|
|
462
|
+
errors
|
|
463
|
+
});
|
|
464
|
+
if (actionOverride) return { ...actionOverride };
|
|
465
|
+
}
|
|
466
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
467
|
+
return jsonSchema;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Flattens a Valibot pipe by recursively expanding nested pipes.
|
|
471
|
+
*
|
|
472
|
+
* @param pipe The pipeline to flatten.
|
|
473
|
+
*
|
|
474
|
+
* @returns A flat pipeline.
|
|
475
|
+
*/
|
|
476
|
+
function flattenPipe(pipe) {
|
|
477
|
+
return pipe.flatMap((item) => "pipe" in item ? flattenPipe(item.pipe) : item);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Returns the JSON Pointer reference for a definition key.
|
|
481
|
+
*
|
|
482
|
+
* @param referenceId The unescaped definition key.
|
|
483
|
+
*
|
|
484
|
+
* @returns The encoded JSON Pointer fragment.
|
|
485
|
+
*/
|
|
486
|
+
function getDefinitionRef(referenceId) {
|
|
487
|
+
return `#/$defs/${referenceId.replaceAll("~", "~0").replaceAll("/", "~1")}`;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Converts any supported Valibot schema to the JSON Schema format.
|
|
491
|
+
*
|
|
492
|
+
* @param jsonSchema The JSON Schema object.
|
|
493
|
+
* @param valibotSchema The Valibot schema object.
|
|
494
|
+
* @param config The conversion configuration.
|
|
495
|
+
* @param context The conversion context.
|
|
496
|
+
* @param skipRef Whether to skip using a reference.
|
|
497
|
+
*
|
|
498
|
+
* @returns The converted JSON Schema.
|
|
499
|
+
*/
|
|
500
|
+
function convertSchema(jsonSchema, valibotSchema, config, context, skipRef = false) {
|
|
501
|
+
if (!skipRef) {
|
|
502
|
+
const referenceId = context.referenceMap.get(valibotSchema);
|
|
503
|
+
if (referenceId) {
|
|
504
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
505
|
+
if (config?.overrideRef) {
|
|
506
|
+
const refOverride = config.overrideRef({
|
|
507
|
+
...context,
|
|
508
|
+
referenceId,
|
|
509
|
+
valibotSchema,
|
|
510
|
+
jsonSchema
|
|
511
|
+
});
|
|
512
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
513
|
+
}
|
|
514
|
+
return jsonSchema;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if ("pipe" in valibotSchema) {
|
|
518
|
+
const flatPipe = flattenPipe(valibotSchema.pipe);
|
|
519
|
+
let startIndex = 0;
|
|
520
|
+
let stopIndex = flatPipe.length - 1;
|
|
521
|
+
if (config?.typeMode === "input") {
|
|
522
|
+
const inputStopIndex = flatPipe.slice(1).findIndex((item) => item.kind === "schema" || item.kind === "transformation" && (item.type === "find_item" || item.type === "parse_json" || item.type === "raw_transform" || item.type === "reduce_items" || item.type === "stringify_json" || item.type === "to_bigint" || item.type === "to_boolean" || item.type === "to_date" || item.type === "to_number" || item.type === "to_string" || item.type === "transform"));
|
|
523
|
+
if (inputStopIndex !== -1) stopIndex = inputStopIndex;
|
|
524
|
+
} else if (config?.typeMode === "output") {
|
|
525
|
+
const outputStartIndex = flatPipe.findLastIndex((item) => item.kind === "schema");
|
|
526
|
+
if (outputStartIndex !== -1) startIndex = outputStartIndex;
|
|
527
|
+
}
|
|
528
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
529
|
+
const valibotPipeItem = flatPipe[index];
|
|
530
|
+
if (valibotPipeItem.kind === "schema") {
|
|
531
|
+
if (index > startIndex) handleError("Set the \"typeMode\" config to \"input\" or \"output\" to convert pipelines with multiple schemas.", config);
|
|
532
|
+
jsonSchema = convertSchema(jsonSchema, valibotPipeItem, config, context, true);
|
|
533
|
+
} else jsonSchema = convertAction(jsonSchema, valibotPipeItem, config);
|
|
534
|
+
}
|
|
535
|
+
return jsonSchema;
|
|
536
|
+
}
|
|
537
|
+
let errors;
|
|
538
|
+
switch (valibotSchema.type) {
|
|
539
|
+
case "boolean":
|
|
540
|
+
jsonSchema.type = "boolean";
|
|
541
|
+
break;
|
|
542
|
+
case "null":
|
|
543
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [null];
|
|
544
|
+
else jsonSchema.type = "null";
|
|
545
|
+
break;
|
|
546
|
+
case "number":
|
|
547
|
+
jsonSchema.type = "number";
|
|
548
|
+
break;
|
|
549
|
+
case "string":
|
|
550
|
+
jsonSchema.type = "string";
|
|
551
|
+
break;
|
|
552
|
+
case "array":
|
|
553
|
+
jsonSchema.type = "array";
|
|
554
|
+
jsonSchema.items = convertSchema({}, valibotSchema.item, config, context);
|
|
555
|
+
break;
|
|
556
|
+
case "tuple":
|
|
557
|
+
case "tuple_with_rest":
|
|
558
|
+
case "loose_tuple":
|
|
559
|
+
case "strict_tuple":
|
|
560
|
+
jsonSchema.type = "array";
|
|
561
|
+
if (config?.target === "openapi-3.0") {
|
|
562
|
+
jsonSchema.items = { anyOf: [] };
|
|
563
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
564
|
+
for (const item of valibotSchema.items) jsonSchema.items.anyOf.push(convertSchema({}, item, config, context));
|
|
565
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items.anyOf.push(convertSchema({}, valibotSchema.rest, config, context));
|
|
566
|
+
else if (valibotSchema.type === "strict_tuple" || valibotSchema.type === "tuple") jsonSchema.maxItems = valibotSchema.items.length;
|
|
567
|
+
} else if (config?.target === "draft-2020-12") {
|
|
568
|
+
jsonSchema.prefixItems = [];
|
|
569
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
570
|
+
for (const item of valibotSchema.items) jsonSchema.prefixItems.push(convertSchema({}, item, config, context));
|
|
571
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items = convertSchema({}, valibotSchema.rest, config, context);
|
|
572
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.items = false;
|
|
573
|
+
} else {
|
|
574
|
+
jsonSchema.items = [];
|
|
575
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
576
|
+
for (const item of valibotSchema.items) jsonSchema.items.push(convertSchema({}, item, config, context));
|
|
577
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.additionalItems = convertSchema({}, valibotSchema.rest, config, context);
|
|
578
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.additionalItems = false;
|
|
579
|
+
}
|
|
580
|
+
break;
|
|
581
|
+
case "object":
|
|
582
|
+
case "object_with_rest":
|
|
583
|
+
case "loose_object":
|
|
584
|
+
case "strict_object":
|
|
585
|
+
jsonSchema.type = "object";
|
|
586
|
+
jsonSchema.properties = {};
|
|
587
|
+
jsonSchema.required = [];
|
|
588
|
+
for (const key in valibotSchema.entries) {
|
|
589
|
+
const entry = valibotSchema.entries[key];
|
|
590
|
+
jsonSchema.properties[key] = convertSchema({}, entry, config, context);
|
|
591
|
+
if (entry.type !== "exact_optional" && entry.type !== "nullish" && entry.type !== "optional") jsonSchema.required.push(key);
|
|
592
|
+
}
|
|
593
|
+
if (valibotSchema.type === "object_with_rest") jsonSchema.additionalProperties = convertSchema({}, valibotSchema.rest, config, context);
|
|
594
|
+
else if (valibotSchema.type === "strict_object") jsonSchema.additionalProperties = false;
|
|
595
|
+
break;
|
|
596
|
+
case "record":
|
|
597
|
+
if (config?.target === "openapi-3.0" && "pipe" in valibotSchema.key) errors = addError(errors, "The \"record\" schema with a schema for the key that contains a \"pipe\" cannot be converted to JSON Schema.");
|
|
598
|
+
if (valibotSchema.key.type !== "string") errors = addError(errors, `The "record" schema with the "${valibotSchema.key.type}" schema for the key cannot be converted to JSON Schema.`);
|
|
599
|
+
jsonSchema.type = "object";
|
|
600
|
+
if (config?.target !== "openapi-3.0") jsonSchema.propertyNames = convertSchema({}, valibotSchema.key, config, context);
|
|
601
|
+
jsonSchema.additionalProperties = convertSchema({}, valibotSchema.value, config, context);
|
|
602
|
+
break;
|
|
603
|
+
case "any":
|
|
604
|
+
case "unknown": break;
|
|
605
|
+
case "never":
|
|
606
|
+
jsonSchema.not = {};
|
|
607
|
+
break;
|
|
608
|
+
case "nullable":
|
|
609
|
+
case "nullish":
|
|
610
|
+
if (config?.target === "openapi-3.0") {
|
|
611
|
+
const innerSchema = convertSchema({}, valibotSchema.wrapped, config, context);
|
|
612
|
+
Object.assign(jsonSchema, innerSchema);
|
|
613
|
+
jsonSchema.nullable = true;
|
|
614
|
+
} else jsonSchema.anyOf = [convertSchema({}, valibotSchema.wrapped, config, context), { type: "null" }];
|
|
615
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
616
|
+
break;
|
|
617
|
+
case "exact_optional":
|
|
618
|
+
case "optional":
|
|
619
|
+
case "undefinedable":
|
|
620
|
+
jsonSchema = convertSchema(jsonSchema, valibotSchema.wrapped, config, context);
|
|
621
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
622
|
+
break;
|
|
623
|
+
case "literal":
|
|
624
|
+
if (!isJsonConstValue(valibotSchema.literal)) {
|
|
625
|
+
errors = addError(errors, "The value of the \"literal\" schema is not JSON compatible.");
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotSchema.literal];
|
|
629
|
+
else jsonSchema.const = valibotSchema.literal;
|
|
630
|
+
break;
|
|
631
|
+
case "enum":
|
|
632
|
+
case "picklist": {
|
|
633
|
+
const options = valibotSchema.options;
|
|
634
|
+
if (!options.every((option) => typeof option === "string" || typeof option === "number" && Number.isFinite(option))) {
|
|
635
|
+
errors = addError(errors, `An option of the "${valibotSchema.type}" schema is not JSON compatible.`);
|
|
636
|
+
break;
|
|
637
|
+
}
|
|
638
|
+
jsonSchema.enum = options;
|
|
639
|
+
if (options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
640
|
+
else if (options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
641
|
+
else if (config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
case "union":
|
|
645
|
+
jsonSchema.anyOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
646
|
+
break;
|
|
647
|
+
case "variant":
|
|
648
|
+
jsonSchema.oneOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
649
|
+
break;
|
|
650
|
+
case "intersect":
|
|
651
|
+
jsonSchema.allOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
652
|
+
break;
|
|
653
|
+
case "lazy": {
|
|
654
|
+
let wrappedValibotSchema = context.getterMap.get(valibotSchema.getter);
|
|
655
|
+
if (!wrappedValibotSchema) {
|
|
656
|
+
wrappedValibotSchema = valibotSchema.getter(void 0);
|
|
657
|
+
context.getterMap.set(valibotSchema.getter, wrappedValibotSchema);
|
|
658
|
+
}
|
|
659
|
+
let referenceId = context.referenceMap.get(wrappedValibotSchema);
|
|
660
|
+
if (!referenceId) {
|
|
661
|
+
referenceId = context.referenceMap.createId(context.definitions);
|
|
662
|
+
context.referenceMap.set(wrappedValibotSchema, referenceId);
|
|
663
|
+
context.definitions[referenceId] = convertSchema({}, wrappedValibotSchema, config, context, true);
|
|
664
|
+
}
|
|
665
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
666
|
+
if (config?.overrideRef) {
|
|
667
|
+
const refOverride = config.overrideRef({
|
|
668
|
+
...context,
|
|
669
|
+
referenceId,
|
|
670
|
+
valibotSchema: wrappedValibotSchema,
|
|
671
|
+
jsonSchema
|
|
672
|
+
});
|
|
673
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
674
|
+
}
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
default: errors = addError(errors, `The "${valibotSchema.type}" schema cannot be converted to JSON Schema.`);
|
|
678
|
+
}
|
|
679
|
+
if (config?.overrideSchema) {
|
|
680
|
+
const schemaOverride = config.overrideSchema({
|
|
681
|
+
...context,
|
|
682
|
+
referenceId: context.referenceMap.get(valibotSchema),
|
|
683
|
+
valibotSchema,
|
|
684
|
+
jsonSchema,
|
|
685
|
+
errors
|
|
686
|
+
});
|
|
687
|
+
if (schemaOverride) return { ...schemaOverride };
|
|
688
|
+
}
|
|
689
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
690
|
+
return jsonSchema;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Converts a Valibot schema to the JSON Schema format.
|
|
694
|
+
*
|
|
695
|
+
* @param schema The Valibot schema object.
|
|
696
|
+
* @param config The JSON Schema configuration.
|
|
697
|
+
*
|
|
698
|
+
* @returns The converted JSON Schema.
|
|
699
|
+
*/
|
|
700
|
+
function toJsonSchema(schema, config) {
|
|
701
|
+
const context = {
|
|
702
|
+
definitions: {},
|
|
703
|
+
referenceMap: new ReferenceMap(),
|
|
704
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
705
|
+
};
|
|
706
|
+
const definitions = config?.definitions ?? void 0;
|
|
707
|
+
if (definitions) {
|
|
708
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
709
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
710
|
+
}
|
|
711
|
+
const jsonSchema = convertSchema({}, schema, config, context);
|
|
712
|
+
const target = config?.target ?? "draft-07";
|
|
713
|
+
if (target === "draft-2020-12") jsonSchema.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
714
|
+
else if (target === "draft-07") jsonSchema.$schema = "http://json-schema.org/draft-07/schema#";
|
|
715
|
+
if (context.referenceMap.size) jsonSchema.$defs = context.definitions;
|
|
716
|
+
return jsonSchema;
|
|
717
|
+
}
|
|
718
|
+
//#endregion
|
|
719
|
+
//#region ../internal/src/valibot.ts
|
|
720
|
+
const valibotTargets = /* @__PURE__ */ new Set([
|
|
721
|
+
"draft-07",
|
|
722
|
+
"draft-2020-12",
|
|
723
|
+
"openapi-3.0"
|
|
724
|
+
]);
|
|
725
|
+
function isValibotTarget(value) {
|
|
726
|
+
return valibotTargets.has(String(value));
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Add Standard JSON Schema conversion to a plain Valibot schema. Valibot schemas validate as Standard Schema but carry
|
|
730
|
+
* no JSON Schema, so forms, tools, and model providers would get no shape for them. Other schemas, Valibot schemas that
|
|
731
|
+
* already convert, and async Valibot schemas return unchanged. The copy keeps every Valibot property, so validation
|
|
732
|
+
* does not change.
|
|
733
|
+
*
|
|
734
|
+
* `target` fixes the JSON Schema dialect. Without it, each conversion uses the dialect that the caller asks for.
|
|
735
|
+
*/
|
|
736
|
+
function withValibotJsonSchema(schema, options = {}) {
|
|
737
|
+
const standard = schema["~standard"];
|
|
738
|
+
if (standard.vendor !== "valibot" || Reflect.get(schema, "async") === true) return schema;
|
|
739
|
+
if (Object.hasOwn(standard, "jsonSchema") && standard.jsonSchema) return schema;
|
|
740
|
+
const convert = (typeMode) => (request) => {
|
|
741
|
+
const target = options.target ?? request.target;
|
|
742
|
+
if (!isValibotTarget(target)) throw new Error(`[vitehub] Valibot cannot convert a schema to the ${String(target)} JSON Schema target.`);
|
|
743
|
+
return toJsonSchema(schema, {
|
|
744
|
+
target,
|
|
745
|
+
typeMode,
|
|
746
|
+
errorMode: "ignore"
|
|
747
|
+
});
|
|
748
|
+
};
|
|
749
|
+
return {
|
|
750
|
+
...schema,
|
|
751
|
+
"~standard": {
|
|
752
|
+
...standard,
|
|
753
|
+
jsonSchema: {
|
|
754
|
+
input: convert("input"),
|
|
755
|
+
output: convert("output")
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
//#endregion
|
|
761
|
+
//#region ../internal/src/operations.ts
|
|
762
|
+
const nameFormat = /^[a-z][a-z0-9-]*\.[a-z][a-z0-9-]*$/;
|
|
763
|
+
const kinds = /* @__PURE__ */ new Set([
|
|
764
|
+
"read",
|
|
765
|
+
"write",
|
|
766
|
+
"destructive"
|
|
767
|
+
]);
|
|
768
|
+
function isObject(value) {
|
|
769
|
+
return value !== null && Object(value) === value && !Array.isArray(value);
|
|
770
|
+
}
|
|
771
|
+
function invalidDefinition(name, reason) {
|
|
772
|
+
return internalErrorDiagnostics.INTERNAL_R0020({ message: `[vitehub] Operation ${JSON.stringify(name)} is invalid: ${reason}` });
|
|
773
|
+
}
|
|
774
|
+
function checkDefinition(definition) {
|
|
775
|
+
if (!isObject(definition)) throw invalidDefinition(void 0, "defineOperation() takes an object.");
|
|
776
|
+
const { name } = definition;
|
|
777
|
+
if (String(name) !== name || !nameFormat.test(name)) throw invalidDefinition(name, "the name must look like `section.verb`, in lower case.");
|
|
778
|
+
if (String(definition.description) !== definition.description || !definition.description) throw invalidDefinition(name, "add a one sentence description.");
|
|
779
|
+
const { section } = definition;
|
|
780
|
+
if (section !== false && !(section instanceof Function) && (String(section) !== section || !section)) throw invalidDefinition(name, "section must be a Console section id, a function, or false.");
|
|
781
|
+
if (!kinds.has(String(definition.kind))) throw invalidDefinition(name, "kind must be \"read\", \"write\", or \"destructive\".");
|
|
782
|
+
const input = definition.input;
|
|
783
|
+
if (!isObject(input) || !isObject(input["~standard"]) || !(input["~standard"].validate instanceof Function)) throw invalidDefinition(name, "input must be a Standard Schema, such as a valibot object.");
|
|
784
|
+
if (!(definition.run instanceof Function)) throw invalidDefinition(name, "run must be a function.");
|
|
785
|
+
const { maxRequestBytes } = definition;
|
|
786
|
+
if (maxRequestBytes !== void 0 && (!Number.isInteger(maxRequestBytes) || Number(maxRequestBytes) < 65536)) throw invalidDefinition(name, `maxRequestBytes can only raise the limit above ${defaultRequestBytes} bytes (64 KiB).`);
|
|
787
|
+
if (definition.readOnlyWhen !== void 0 && !(definition.readOnlyWhen instanceof Function)) throw invalidDefinition(name, "readOnlyWhen must be a function.");
|
|
788
|
+
}
|
|
789
|
+
/** The default limit of a call, in bytes. */
|
|
790
|
+
const defaultRequestBytes = 65536;
|
|
791
|
+
/** Input keys that the generated CLI commands read themselves. */
|
|
792
|
+
const reservedOperationFlags = [
|
|
793
|
+
"input",
|
|
794
|
+
"json",
|
|
795
|
+
"timeout",
|
|
796
|
+
"url",
|
|
797
|
+
"yes"
|
|
798
|
+
];
|
|
799
|
+
/**
|
|
800
|
+
* Define one operation. The Console, the CLI, MCP, and agent tools call the same definition. Contribute it with
|
|
801
|
+
* `vitehub: { operations: [{ module, export }] }` on a Vite plugin.
|
|
802
|
+
*/
|
|
803
|
+
function defineOperation(definition) {
|
|
804
|
+
checkDefinition(definition);
|
|
805
|
+
const defined = {
|
|
806
|
+
...definition,
|
|
807
|
+
input: withValibotJsonSchema(definition.input)
|
|
808
|
+
};
|
|
809
|
+
const properties = operationInputJsonSchema(defined).properties;
|
|
810
|
+
const clashes = isObject(properties) ? Object.keys(properties).filter((key) => reservedOperationFlags.includes(key)) : [];
|
|
811
|
+
if (clashes.length) throw invalidDefinition(definition.name, `the input key ${clashes.map((key) => JSON.stringify(key)).join(", ")} is a CLI flag of every command (${reservedOperationFlags.join(", ")}). Rename it.`);
|
|
812
|
+
return defined;
|
|
813
|
+
}
|
|
814
|
+
/** JSON Schema of the input, for CLI flags and MCP tool schemas. Falls back to an open object. */
|
|
815
|
+
function operationInputJsonSchema(operation) {
|
|
816
|
+
return standardJsonSchema(operation.input, "input") ?? { type: "object" };
|
|
817
|
+
}
|
|
818
|
+
//#endregion
|
|
819
|
+
//#region src/operations.ts
|
|
820
|
+
const runtime = () => import("./operations-B_rYG71W.js");
|
|
821
|
+
const name = v.pipe(v.string(), v.check((value) => value.trim() !== "", "Name a Workflow."));
|
|
822
|
+
const runId = v.pipe(v.string(), v.check((value) => value.trim() !== "", "Pass the id of a run."));
|
|
823
|
+
const maxRequestBytes = 1048576;
|
|
824
|
+
function defineWorkflowOperation(definition) {
|
|
825
|
+
return defineOperation({
|
|
826
|
+
...definition,
|
|
827
|
+
cli: {
|
|
828
|
+
namespace: "workflow",
|
|
829
|
+
...definition.cli
|
|
830
|
+
},
|
|
831
|
+
section: "workflows",
|
|
832
|
+
user: false
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
/** The `workflow.*` operations: start, get, cancel, and resume. The Console, `vitehub workflow`, and agents run them. */
|
|
836
|
+
const workflowOperations = [
|
|
837
|
+
defineWorkflowOperation({
|
|
838
|
+
cli: { positional: ["workflow"] },
|
|
839
|
+
description: "Start a Workflow run by name. The payload is any JSON value.",
|
|
840
|
+
input: v.object({
|
|
841
|
+
payload: v.optional(v.unknown()),
|
|
842
|
+
workflow: name
|
|
843
|
+
}),
|
|
844
|
+
invoke: true,
|
|
845
|
+
kind: "write",
|
|
846
|
+
maxRequestBytes,
|
|
847
|
+
name: "workflow.start",
|
|
848
|
+
run: async (input) => (await runtime()).runWorkflowOperation("start", input)
|
|
849
|
+
}),
|
|
850
|
+
defineWorkflowOperation({
|
|
851
|
+
cli: { positional: ["runId"] },
|
|
852
|
+
description: "Show the status and result of a Workflow run. Pass `workflow` for a run that this runtime did not start.",
|
|
853
|
+
input: v.object({
|
|
854
|
+
runId,
|
|
855
|
+
workflow: v.optional(name)
|
|
856
|
+
}),
|
|
857
|
+
kind: "read",
|
|
858
|
+
name: "workflow.get",
|
|
859
|
+
run: async (input) => (await runtime()).runWorkflowOperation("get", input)
|
|
860
|
+
}),
|
|
861
|
+
defineWorkflowOperation({
|
|
862
|
+
cli: { positional: ["runId"] },
|
|
863
|
+
description: "Cancel a Workflow run. Only providers that support cancellation accept it.",
|
|
864
|
+
input: v.object({
|
|
865
|
+
runId,
|
|
866
|
+
workflow: v.optional(name)
|
|
867
|
+
}),
|
|
868
|
+
kind: "destructive",
|
|
869
|
+
name: "workflow.cancel",
|
|
870
|
+
run: async (input) => (await runtime()).runWorkflowOperation("cancel", input)
|
|
871
|
+
}),
|
|
872
|
+
defineWorkflowOperation({
|
|
873
|
+
cli: { positional: ["token"] },
|
|
874
|
+
description: "Resume a Workflow signal with its opaque token. The payload is any JSON value.",
|
|
875
|
+
input: v.object({
|
|
876
|
+
payload: v.optional(v.unknown()),
|
|
877
|
+
token: v.pipe(v.string(), v.check((value) => value.trim() !== "", "Pass the signal token."))
|
|
878
|
+
}),
|
|
879
|
+
invoke: true,
|
|
880
|
+
kind: "write",
|
|
881
|
+
maxRequestBytes,
|
|
882
|
+
name: "workflow.resume",
|
|
883
|
+
run: async (input) => (await runtime()).runWorkflowOperation("resume", input)
|
|
884
|
+
})
|
|
885
|
+
];
|
|
886
|
+
//#endregion
|
|
887
|
+
export { workflowOperations };
|