@ykdz/template 0.0.38 → 0.0.40
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/application.d.ts +1 -52
- package/dist/application.js +0 -81
- package/dist/cli.js +14 -28
- package/dist/input-schemas.d.ts +30 -0
- package/dist/input-schemas.js +75 -0
- package/dist/main.d.ts +3 -14
- package/dist/main.js +496 -378
- package/dist/result-schemas.d.ts +222 -0
- package/dist/result-schemas.js +74 -0
- package/dist/standard-schema.d.ts +3 -0
- package/dist/standard-schema.js +29 -0
- package/node_modules/@standard-schema/spec/LICENSE +21 -0
- package/node_modules/@standard-schema/spec/README.md +198 -0
- package/node_modules/@standard-schema/spec/dist/index.cjs +18 -0
- package/node_modules/@standard-schema/spec/dist/index.d.cts +119 -0
- package/node_modules/@standard-schema/spec/dist/index.d.ts +119 -0
- package/node_modules/@standard-schema/spec/dist/index.js +0 -0
- package/node_modules/@standard-schema/spec/package.json +52 -0
- package/node_modules/@types/node/LICENSE +21 -0
- package/node_modules/@types/node/README.md +15 -0
- package/node_modules/@types/node/assert/strict.d.ts +111 -0
- package/node_modules/@types/node/assert.d.ts +1115 -0
- package/node_modules/@types/node/async_hooks.d.ts +619 -0
- package/node_modules/@types/node/buffer.buffer.d.ts +477 -0
- package/node_modules/@types/node/buffer.d.ts +1941 -0
- package/node_modules/@types/node/child_process.d.ts +1480 -0
- package/node_modules/@types/node/cluster.d.ts +578 -0
- package/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
- package/node_modules/@types/node/console.d.ts +453 -0
- package/node_modules/@types/node/constants.d.ts +21 -0
- package/node_modules/@types/node/crypto.d.ts +5484 -0
- package/node_modules/@types/node/dgram.d.ts +715 -0
- package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
- package/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/node_modules/@types/node/dns.d.ts +923 -0
- package/node_modules/@types/node/domain.d.ts +166 -0
- package/node_modules/@types/node/events.d.ts +967 -0
- package/node_modules/@types/node/fs/promises.d.ts +1354 -0
- package/node_modules/@types/node/fs.d.ts +4777 -0
- package/node_modules/@types/node/globals.d.ts +170 -0
- package/node_modules/@types/node/globals.typedarray.d.ts +41 -0
- package/node_modules/@types/node/http.d.ts +2246 -0
- package/node_modules/@types/node/http2.d.ts +2882 -0
- package/node_modules/@types/node/https.d.ts +585 -0
- package/node_modules/@types/node/index.d.ts +101 -0
- package/node_modules/@types/node/inspector.d.ts +323 -0
- package/node_modules/@types/node/inspector.generated.d.ts +4406 -0
- package/node_modules/@types/node/module.d.ts +844 -0
- package/node_modules/@types/node/net.d.ts +1197 -0
- package/node_modules/@types/node/os.d.ts +507 -0
- package/node_modules/@types/node/package.json +140 -0
- package/node_modules/@types/node/path.d.ts +200 -0
- package/node_modules/@types/node/perf_hooks.d.ts +1054 -0
- package/node_modules/@types/node/process.d.ts +2101 -0
- package/node_modules/@types/node/punycode.d.ts +117 -0
- package/node_modules/@types/node/querystring.d.ts +152 -0
- package/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/node_modules/@types/node/readline.d.ts +600 -0
- package/node_modules/@types/node/repl.d.ts +438 -0
- package/node_modules/@types/node/sea.d.ts +162 -0
- package/node_modules/@types/node/sqlite.d.ts +1182 -0
- package/node_modules/@types/node/stream/consumers.d.ts +45 -0
- package/node_modules/@types/node/stream/promises.d.ts +90 -0
- package/node_modules/@types/node/stream/web.d.ts +596 -0
- package/node_modules/@types/node/stream.d.ts +1707 -0
- package/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/node_modules/@types/node/test.d.ts +2656 -0
- package/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/node_modules/@types/node/timers.d.ts +285 -0
- package/node_modules/@types/node/tls.d.ts +1314 -0
- package/node_modules/@types/node/trace_events.d.ts +197 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +473 -0
- package/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
- package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +103 -0
- package/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +103 -0
- package/node_modules/@types/node/tty.d.ts +209 -0
- package/node_modules/@types/node/url.d.ts +1103 -0
- package/node_modules/@types/node/util.d.ts +2376 -0
- package/node_modules/@types/node/v8.d.ts +1010 -0
- package/node_modules/@types/node/vm.d.ts +1160 -0
- package/node_modules/@types/node/wasi.d.ts +202 -0
- package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
- package/node_modules/@types/node/web-globals/crypto.d.ts +32 -0
- package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/node_modules/@types/node/web-globals/events.d.ts +97 -0
- package/node_modules/@types/node/web-globals/fetch.d.ts +62 -0
- package/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
- package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
- package/node_modules/@types/node/worker_threads.d.ts +894 -0
- package/node_modules/@types/node/zlib.d.ts +768 -0
- package/node_modules/@valibot/to-json-schema/LICENSE.md +9 -0
- package/node_modules/@valibot/to-json-schema/README.md +475 -0
- package/node_modules/@valibot/to-json-schema/dist/index.cjs +800 -0
- package/node_modules/@valibot/to-json-schema/dist/index.d.cts +991 -0
- package/node_modules/@valibot/to-json-schema/dist/index.d.mts +991 -0
- package/node_modules/@valibot/to-json-schema/dist/index.min.cjs +1 -0
- package/node_modules/@valibot/to-json-schema/dist/index.min.mjs +1 -0
- package/node_modules/@valibot/to-json-schema/dist/index.mjs +795 -0
- package/node_modules/@valibot/to-json-schema/package.json +75 -0
- package/node_modules/@ykdz/cli-contract/LICENSE +21 -0
- package/node_modules/@ykdz/cli-contract/dist/atomic-variant-compiler.d.ts +17 -0
- package/node_modules/@ykdz/cli-contract/dist/atomic-variant-compiler.js +55 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-contract.d.ts +1164 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-contract.js +1408 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-execution.d.ts +54 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-execution.js +708 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-invocation.d.ts +174 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-invocation.js +524 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-write-error.d.ts +10 -0
- package/node_modules/@ykdz/cli-contract/dist/cli-write-error.js +14 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-definition-error.d.ts +260 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-definition-error.js +130 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-execution-error.d.ts +63 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-execution-error.js +17 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-schema-compiler.d.ts +6 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-schema-compiler.js +532 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-schema.d.ts +14 -0
- package/node_modules/@ykdz/cli-contract/dist/contract-schema.js +1 -0
- package/node_modules/@ykdz/cli-contract/dist/description.d.ts +2 -0
- package/node_modules/@ykdz/cli-contract/dist/description.js +13 -0
- package/node_modules/@ykdz/cli-contract/dist/index.d.ts +8 -0
- package/node_modules/@ykdz/cli-contract/dist/index.js +7 -0
- package/node_modules/@ykdz/cli-contract/dist/json-value.d.ts +4 -0
- package/node_modules/@ykdz/cli-contract/dist/json-value.js +64 -0
- package/node_modules/@ykdz/cli-contract/dist/node.d.ts +21 -0
- package/node_modules/@ykdz/cli-contract/dist/node.js +109 -0
- package/node_modules/@ykdz/cli-contract/dist/outcome-fact.d.ts +162 -0
- package/node_modules/@ykdz/cli-contract/dist/outcome-fact.js +113 -0
- package/node_modules/@ykdz/cli-contract/dist/outcome-wire.d.ts +53 -0
- package/node_modules/@ykdz/cli-contract/dist/outcome-wire.js +189 -0
- package/node_modules/@ykdz/cli-contract/dist/stream-variant-compiler.d.ts +16 -0
- package/node_modules/@ykdz/cli-contract/dist/stream-variant-compiler.js +45 -0
- package/node_modules/@ykdz/cli-contract/package.json +69 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +20 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +5 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +19 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +2 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +9 -5
- package/node_modules/@ykdz/template-builtin-presets/package.json +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +128 -59
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +80 -8
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +7 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +9 -19
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +144 -60
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/standard-schema.ts +37 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/lookup.journey.ts +71 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +118 -59
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +2 -1
- package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +15 -0
- package/node_modules/@ykdz/template-core/dist/project-blueprint.js +1 -1
- package/node_modules/undici-types/LICENSE +21 -0
- package/node_modules/undici-types/README.md +6 -0
- package/node_modules/undici-types/agent.d.ts +32 -0
- package/node_modules/undici-types/api.d.ts +43 -0
- package/node_modules/undici-types/balanced-pool.d.ts +30 -0
- package/node_modules/undici-types/cache-interceptor.d.ts +179 -0
- package/node_modules/undici-types/cache.d.ts +36 -0
- package/node_modules/undici-types/client-stats.d.ts +15 -0
- package/node_modules/undici-types/client.d.ts +123 -0
- package/node_modules/undici-types/connector.d.ts +36 -0
- package/node_modules/undici-types/content-type.d.ts +21 -0
- package/node_modules/undici-types/cookies.d.ts +30 -0
- package/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
- package/node_modules/undici-types/dispatcher.d.ts +279 -0
- package/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
- package/node_modules/undici-types/errors.d.ts +177 -0
- package/node_modules/undici-types/eventsource.d.ts +66 -0
- package/node_modules/undici-types/fetch.d.ts +211 -0
- package/node_modules/undici-types/formdata.d.ts +108 -0
- package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/node_modules/undici-types/global-origin.d.ts +7 -0
- package/node_modules/undici-types/h2c-client.d.ts +73 -0
- package/node_modules/undici-types/handlers.d.ts +15 -0
- package/node_modules/undici-types/header.d.ts +160 -0
- package/node_modules/undici-types/index.d.ts +91 -0
- package/node_modules/undici-types/interceptors.d.ts +80 -0
- package/node_modules/undici-types/mock-agent.d.ts +68 -0
- package/node_modules/undici-types/mock-call-history.d.ts +111 -0
- package/node_modules/undici-types/mock-client.d.ts +27 -0
- package/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/node_modules/undici-types/mock-interceptor.d.ts +94 -0
- package/node_modules/undici-types/mock-pool.d.ts +27 -0
- package/node_modules/undici-types/package.json +55 -0
- package/node_modules/undici-types/patch.d.ts +29 -0
- package/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/node_modules/undici-types/pool.d.ts +41 -0
- package/node_modules/undici-types/proxy-agent.d.ts +29 -0
- package/node_modules/undici-types/readable.d.ts +68 -0
- package/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/node_modules/undici-types/retry-handler.d.ts +125 -0
- package/node_modules/undici-types/round-robin-pool.d.ts +41 -0
- package/node_modules/undici-types/snapshot-agent.d.ts +109 -0
- package/node_modules/undici-types/socks5-proxy-agent.d.ts +25 -0
- package/node_modules/undici-types/util.d.ts +18 -0
- package/node_modules/undici-types/utility.d.ts +7 -0
- package/node_modules/undici-types/webidl.d.ts +347 -0
- package/node_modules/undici-types/websocket.d.ts +188 -0
- package/package.json +5 -3
- package/dist/command-result.d.ts +0 -9
- package/dist/command-result.js +0 -231
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/journeys/greet.journey.ts +0 -46
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/greet.test.ts +0 -15
- package/node_modules/commander/LICENSE +0 -22
- package/node_modules/commander/Readme.md +0 -1172
- package/node_modules/commander/index.js +0 -21
- package/node_modules/commander/lib/argument.js +0 -147
- package/node_modules/commander/lib/command.js +0 -2790
- package/node_modules/commander/lib/error.js +0 -36
- package/node_modules/commander/lib/help.js +0 -731
- package/node_modules/commander/lib/option.js +0 -377
- package/node_modules/commander/lib/suggestSimilar.js +0 -99
- package/node_modules/commander/package-support.json +0 -19
- package/node_modules/commander/package.json +0 -64
- package/node_modules/commander/typings/index.d.ts +0 -1113
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/addError.ts
|
|
3
|
+
/**
|
|
4
|
+
* Adds an error message to the errors array.
|
|
5
|
+
*
|
|
6
|
+
* @param errors The array of error messages.
|
|
7
|
+
* @param message The error message to add.
|
|
8
|
+
*
|
|
9
|
+
* @returns The new errors.
|
|
10
|
+
*/
|
|
11
|
+
function addError(errors, message) {
|
|
12
|
+
if (errors) {
|
|
13
|
+
errors.push(message);
|
|
14
|
+
return errors;
|
|
15
|
+
}
|
|
16
|
+
return [message];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/utils/escapeRegExp.ts
|
|
21
|
+
const ESCAPE_REGEX = /[.*+?^${}()|[\]\\]/g;
|
|
22
|
+
/**
|
|
23
|
+
* Escapes special regex characters in a string.
|
|
24
|
+
*
|
|
25
|
+
* @param string The string to escape.
|
|
26
|
+
*
|
|
27
|
+
* @returns The escaped string.
|
|
28
|
+
*/
|
|
29
|
+
function escapeRegExp(string) {
|
|
30
|
+
return string.replace(ESCAPE_REGEX, "\\$&");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/utils/handleError.ts
|
|
35
|
+
/**
|
|
36
|
+
* Throws an error or logs a warning based on the configuration.
|
|
37
|
+
*
|
|
38
|
+
* @param message The message to throw or log.
|
|
39
|
+
* @param config The conversion configuration.
|
|
40
|
+
*/
|
|
41
|
+
function handleError(message, config) {
|
|
42
|
+
switch (config?.errorMode) {
|
|
43
|
+
case "ignore": break;
|
|
44
|
+
case "warn":
|
|
45
|
+
console.warn(message);
|
|
46
|
+
break;
|
|
47
|
+
default: throw new Error(message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/utils/isJsonConstValue.ts
|
|
53
|
+
/**
|
|
54
|
+
* Whether a value is JSON compatible for a const keyword.
|
|
55
|
+
*
|
|
56
|
+
* @param value The value to check.
|
|
57
|
+
*
|
|
58
|
+
* @returns Whether the value is JSON compatible.
|
|
59
|
+
*/
|
|
60
|
+
function isJsonConstValue(value) {
|
|
61
|
+
return typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/utils/isJsonEnumValues.ts
|
|
66
|
+
/**
|
|
67
|
+
* Whether values are JSON compatible for an enum keyword.
|
|
68
|
+
*
|
|
69
|
+
* @param values The values to check.
|
|
70
|
+
*
|
|
71
|
+
* @returns Whether the values are JSON compatible.
|
|
72
|
+
*/
|
|
73
|
+
function isJsonEnumValues(values) {
|
|
74
|
+
return values.every(isJsonConstValue);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/utils/ReferenceMap.ts
|
|
79
|
+
/**
|
|
80
|
+
* Schema reference map with collision-free reference ID allocation.
|
|
81
|
+
*/
|
|
82
|
+
var ReferenceMap = class extends Map {
|
|
83
|
+
/**
|
|
84
|
+
* Creates an empty schema reference map.
|
|
85
|
+
*/
|
|
86
|
+
constructor() {
|
|
87
|
+
super();
|
|
88
|
+
this.count = 0;
|
|
89
|
+
this.usedIds = /* @__PURE__ */ new Set();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Adds a schema reference and reserves its ID.
|
|
93
|
+
*
|
|
94
|
+
* @param schema The Valibot schema.
|
|
95
|
+
* @param referenceId The reference ID.
|
|
96
|
+
*
|
|
97
|
+
* @returns The reference map.
|
|
98
|
+
*/
|
|
99
|
+
set(schema, referenceId) {
|
|
100
|
+
this.usedIds.add(referenceId);
|
|
101
|
+
return super.set(schema, referenceId);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates a reference ID that is not yet used.
|
|
105
|
+
*
|
|
106
|
+
* @param definitions The JSON Schema definitions.
|
|
107
|
+
*
|
|
108
|
+
* @returns The unused reference ID.
|
|
109
|
+
*/
|
|
110
|
+
createId(definitions) {
|
|
111
|
+
while (this.usedIds.has(`${this.count}`) || `${this.count}` in definitions) this.count++;
|
|
112
|
+
return `${this.count++}`;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/converters/convertAction/convertAction.ts
|
|
118
|
+
/**
|
|
119
|
+
* Returns the stricter lower bound.
|
|
120
|
+
*
|
|
121
|
+
* @param current The current lower bound.
|
|
122
|
+
* @param value The new lower bound.
|
|
123
|
+
*
|
|
124
|
+
* @returns The stricter lower bound.
|
|
125
|
+
*/
|
|
126
|
+
function getLowerBound(current, value) {
|
|
127
|
+
if (typeof current !== "number" || !Number.isFinite(current) || value > current) return value;
|
|
128
|
+
return current;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Returns the stricter upper bound.
|
|
132
|
+
*
|
|
133
|
+
* @param current The current upper bound.
|
|
134
|
+
* @param value The new upper bound.
|
|
135
|
+
*
|
|
136
|
+
* @returns The stricter upper bound.
|
|
137
|
+
*/
|
|
138
|
+
function getUpperBound(current, value) {
|
|
139
|
+
if (typeof current !== "number" || !Number.isFinite(current) || value < current) return value;
|
|
140
|
+
return current;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns the combined not restriction.
|
|
144
|
+
*
|
|
145
|
+
* @param current The current not restriction.
|
|
146
|
+
* @param value The new not restriction.
|
|
147
|
+
*
|
|
148
|
+
* @returns The combined not restriction.
|
|
149
|
+
*/
|
|
150
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
151
|
+
function getNotRestriction(current, value) {
|
|
152
|
+
return current !== void 0 ? { anyOf: [current, value] } : value;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Intersects allowed values with an existing enum restriction.
|
|
156
|
+
*
|
|
157
|
+
* @param jsonSchema The JSON Schema object.
|
|
158
|
+
* @param values The allowed values.
|
|
159
|
+
*/
|
|
160
|
+
function intersectEnum(jsonSchema, values) {
|
|
161
|
+
let enumValues = jsonSchema.enum ?? values;
|
|
162
|
+
if (jsonSchema.enum) {
|
|
163
|
+
const valueSet = new Set(values);
|
|
164
|
+
enumValues = enumValues.filter((value) => valueSet.has(value));
|
|
165
|
+
}
|
|
166
|
+
if (enumValues.length) jsonSchema.enum = [...new Set(enumValues)];
|
|
167
|
+
else {
|
|
168
|
+
delete jsonSchema.enum;
|
|
169
|
+
jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, {});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Converts any supported Valibot action to the JSON Schema format.
|
|
174
|
+
*
|
|
175
|
+
* @param jsonSchema The JSON Schema object.
|
|
176
|
+
* @param valibotAction The Valibot action object.
|
|
177
|
+
* @param config The conversion configuration.
|
|
178
|
+
*
|
|
179
|
+
* @returns The converted JSON Schema.
|
|
180
|
+
*/
|
|
181
|
+
function convertAction(jsonSchema, valibotAction, config) {
|
|
182
|
+
if (config?.ignoreActions?.includes(valibotAction.type)) return jsonSchema;
|
|
183
|
+
let errors;
|
|
184
|
+
switch (valibotAction.type) {
|
|
185
|
+
case "base64":
|
|
186
|
+
jsonSchema.contentEncoding = "base64";
|
|
187
|
+
break;
|
|
188
|
+
case "bic":
|
|
189
|
+
case "cuid2":
|
|
190
|
+
case "decimal":
|
|
191
|
+
case "digits":
|
|
192
|
+
case "domain":
|
|
193
|
+
case "emoji":
|
|
194
|
+
case "hash":
|
|
195
|
+
case "hexadecimal":
|
|
196
|
+
case "hex_color":
|
|
197
|
+
case "isrc":
|
|
198
|
+
case "iso_time_second":
|
|
199
|
+
case "iso_week":
|
|
200
|
+
case "ksuid":
|
|
201
|
+
case "mac":
|
|
202
|
+
case "mac48":
|
|
203
|
+
case "mac64":
|
|
204
|
+
case "nanoid":
|
|
205
|
+
case "octal":
|
|
206
|
+
case "slug":
|
|
207
|
+
case "ulid":
|
|
208
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
209
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
210
|
+
break;
|
|
211
|
+
case "description":
|
|
212
|
+
jsonSchema.description = valibotAction.description;
|
|
213
|
+
break;
|
|
214
|
+
case "email":
|
|
215
|
+
case "rfc_email":
|
|
216
|
+
jsonSchema.format = "email";
|
|
217
|
+
break;
|
|
218
|
+
case "ends_with":
|
|
219
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
220
|
+
else jsonSchema.pattern = `${escapeRegExp(valibotAction.requirement)}$`;
|
|
221
|
+
break;
|
|
222
|
+
case "empty":
|
|
223
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = 0;
|
|
224
|
+
else {
|
|
225
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
226
|
+
jsonSchema.maxLength = 0;
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
case "entries":
|
|
230
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
231
|
+
errors = addError(errors, "The requirement of the \"entries\" action must be a non-negative integer.");
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
jsonSchema.minProperties = getLowerBound(jsonSchema.minProperties, valibotAction.requirement);
|
|
235
|
+
jsonSchema.maxProperties = getUpperBound(jsonSchema.maxProperties, valibotAction.requirement);
|
|
236
|
+
break;
|
|
237
|
+
case "examples":
|
|
238
|
+
if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.examples];
|
|
239
|
+
else jsonSchema.examples = valibotAction.examples;
|
|
240
|
+
break;
|
|
241
|
+
case "gt_value":
|
|
242
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
243
|
+
errors = addError(errors, `The "gt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
247
|
+
errors = addError(errors, "The requirement of the \"gt_value\" action is not JSON compatible.");
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
if (config?.target === "openapi-3.0") {
|
|
251
|
+
errors = addError(errors, "The \"gt_value\" action is not supported for OpenAPI 3.0.");
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
jsonSchema.exclusiveMinimum = getLowerBound(jsonSchema.exclusiveMinimum, valibotAction.requirement);
|
|
255
|
+
break;
|
|
256
|
+
case "includes":
|
|
257
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
258
|
+
else jsonSchema.pattern = escapeRegExp(valibotAction.requirement);
|
|
259
|
+
break;
|
|
260
|
+
case "integer":
|
|
261
|
+
jsonSchema.type = "integer";
|
|
262
|
+
break;
|
|
263
|
+
case "ipv4":
|
|
264
|
+
jsonSchema.format = "ipv4";
|
|
265
|
+
break;
|
|
266
|
+
case "ipv6":
|
|
267
|
+
jsonSchema.format = "ipv6";
|
|
268
|
+
break;
|
|
269
|
+
case "iso_date":
|
|
270
|
+
jsonSchema.format = "date";
|
|
271
|
+
break;
|
|
272
|
+
case "iso_date_time":
|
|
273
|
+
case "iso_timestamp":
|
|
274
|
+
jsonSchema.format = "date-time";
|
|
275
|
+
break;
|
|
276
|
+
case "iso_time":
|
|
277
|
+
jsonSchema.format = "time";
|
|
278
|
+
break;
|
|
279
|
+
case "jws_compact":
|
|
280
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
281
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
282
|
+
break;
|
|
283
|
+
case "length":
|
|
284
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
285
|
+
errors = addError(errors, "The requirement of the \"length\" action must be a non-negative integer.");
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
if (jsonSchema.type === "array") {
|
|
289
|
+
jsonSchema.minItems = getLowerBound(jsonSchema.minItems, valibotAction.requirement);
|
|
290
|
+
jsonSchema.maxItems = getUpperBound(jsonSchema.maxItems, valibotAction.requirement);
|
|
291
|
+
} else {
|
|
292
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
293
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, valibotAction.requirement);
|
|
294
|
+
jsonSchema.maxLength = getUpperBound(jsonSchema.maxLength, valibotAction.requirement);
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
case "lt_value":
|
|
298
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
299
|
+
errors = addError(errors, `The "lt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
303
|
+
errors = addError(errors, "The requirement of the \"lt_value\" action is not JSON compatible.");
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
if (config?.target === "openapi-3.0") {
|
|
307
|
+
errors = addError(errors, "The \"lt_value\" action is not supported for OpenAPI 3.0.");
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
jsonSchema.exclusiveMaximum = getUpperBound(jsonSchema.exclusiveMaximum, valibotAction.requirement);
|
|
311
|
+
break;
|
|
312
|
+
case "max_entries":
|
|
313
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
314
|
+
errors = addError(errors, "The requirement of the \"max_entries\" action must be a non-negative integer.");
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
jsonSchema.maxProperties = getUpperBound(jsonSchema.maxProperties, valibotAction.requirement);
|
|
318
|
+
break;
|
|
319
|
+
case "max_length":
|
|
320
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
321
|
+
errors = addError(errors, "The requirement of the \"max_length\" action must be a non-negative integer.");
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = getUpperBound(jsonSchema.maxItems, valibotAction.requirement);
|
|
325
|
+
else {
|
|
326
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
327
|
+
jsonSchema.maxLength = getUpperBound(jsonSchema.maxLength, valibotAction.requirement);
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
case "max_value":
|
|
331
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
332
|
+
errors = addError(errors, `The "max_value" action is not supported on type "${jsonSchema.type}".`);
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
336
|
+
errors = addError(errors, "The requirement of the \"max_value\" action is not JSON compatible.");
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
jsonSchema.maximum = getUpperBound(jsonSchema.maximum, valibotAction.requirement);
|
|
340
|
+
break;
|
|
341
|
+
case "metadata":
|
|
342
|
+
if (typeof valibotAction.metadata.title === "string") jsonSchema.title = valibotAction.metadata.title;
|
|
343
|
+
if (typeof valibotAction.metadata.description === "string") jsonSchema.description = valibotAction.metadata.description;
|
|
344
|
+
if (Array.isArray(valibotAction.metadata.examples)) if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.metadata.examples];
|
|
345
|
+
else jsonSchema.examples = valibotAction.metadata.examples;
|
|
346
|
+
for (const key of Object.keys(valibotAction.metadata)) if (key !== "title" && key !== "description" && key !== "examples" && key !== "__proto__") jsonSchema[key] = valibotAction.metadata[key];
|
|
347
|
+
break;
|
|
348
|
+
case "min_entries":
|
|
349
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
350
|
+
errors = addError(errors, "The requirement of the \"min_entries\" action must be a non-negative integer.");
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
jsonSchema.minProperties = getLowerBound(jsonSchema.minProperties, valibotAction.requirement);
|
|
354
|
+
break;
|
|
355
|
+
case "min_length":
|
|
356
|
+
if (!Number.isInteger(valibotAction.requirement) || valibotAction.requirement < 0) {
|
|
357
|
+
errors = addError(errors, "The requirement of the \"min_length\" action must be a non-negative integer.");
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = getLowerBound(jsonSchema.minItems, valibotAction.requirement);
|
|
361
|
+
else {
|
|
362
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
363
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, valibotAction.requirement);
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
case "min_value":
|
|
367
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") {
|
|
368
|
+
errors = addError(errors, `The "min_value" action is not supported on type "${jsonSchema.type}".`);
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
if (!Number.isFinite(valibotAction.requirement)) {
|
|
372
|
+
errors = addError(errors, "The requirement of the \"min_value\" action is not JSON compatible.");
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
jsonSchema.minimum = getLowerBound(jsonSchema.minimum, valibotAction.requirement);
|
|
376
|
+
break;
|
|
377
|
+
case "multiple_of":
|
|
378
|
+
jsonSchema.multipleOf = valibotAction.requirement;
|
|
379
|
+
break;
|
|
380
|
+
case "non_empty":
|
|
381
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = getLowerBound(jsonSchema.minItems, 1);
|
|
382
|
+
else {
|
|
383
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
384
|
+
jsonSchema.minLength = getLowerBound(jsonSchema.minLength, 1);
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
case "not_value":
|
|
388
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
389
|
+
errors = addError(errors, "The requirement of the \"not_value\" action is not JSON compatible.");
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, config?.target === "openapi-3.0" ? { enum: [valibotAction.requirement] } : { const: valibotAction.requirement });
|
|
393
|
+
break;
|
|
394
|
+
case "not_values":
|
|
395
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
396
|
+
errors = addError(errors, "A requirement of the \"not_values\" action is not JSON compatible.");
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
if (valibotAction.requirement.length) jsonSchema.not = /* @__PURE__ */ getNotRestriction(jsonSchema.not, { enum: [...new Set(valibotAction.requirement)] });
|
|
400
|
+
break;
|
|
401
|
+
case "regex":
|
|
402
|
+
if (valibotAction.requirement.flags) errors = addError(errors, "RegExp flags are not supported by JSON Schema.");
|
|
403
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
404
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
405
|
+
break;
|
|
406
|
+
case "safe_integer":
|
|
407
|
+
jsonSchema.type = "integer";
|
|
408
|
+
jsonSchema.minimum = getLowerBound(jsonSchema.minimum, Number.MIN_SAFE_INTEGER);
|
|
409
|
+
jsonSchema.maximum = getUpperBound(jsonSchema.maximum, Number.MAX_SAFE_INTEGER);
|
|
410
|
+
break;
|
|
411
|
+
case "starts_with":
|
|
412
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
413
|
+
else jsonSchema.pattern = `^${escapeRegExp(valibotAction.requirement)}`;
|
|
414
|
+
break;
|
|
415
|
+
case "title":
|
|
416
|
+
jsonSchema.title = valibotAction.title;
|
|
417
|
+
break;
|
|
418
|
+
case "url":
|
|
419
|
+
jsonSchema.format = "uri";
|
|
420
|
+
break;
|
|
421
|
+
case "uuid":
|
|
422
|
+
jsonSchema.format = "uuid";
|
|
423
|
+
break;
|
|
424
|
+
case "value":
|
|
425
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
426
|
+
errors = addError(errors, "The requirement of the \"value\" action is not JSON compatible.");
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
if (config?.target === "openapi-3.0") intersectEnum(jsonSchema, [valibotAction.requirement]);
|
|
430
|
+
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.`);
|
|
431
|
+
else jsonSchema.const = valibotAction.requirement;
|
|
432
|
+
break;
|
|
433
|
+
case "values":
|
|
434
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
435
|
+
errors = addError(errors, "A requirement of the \"values\" action is not JSON compatible.");
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
intersectEnum(jsonSchema, valibotAction.requirement);
|
|
439
|
+
break;
|
|
440
|
+
default: errors = addError(errors, `The "${valibotAction.type}" action cannot be converted to JSON Schema.`);
|
|
441
|
+
}
|
|
442
|
+
if (config?.overrideAction) {
|
|
443
|
+
const actionOverride = config.overrideAction({
|
|
444
|
+
valibotAction,
|
|
445
|
+
jsonSchema,
|
|
446
|
+
errors
|
|
447
|
+
});
|
|
448
|
+
if (actionOverride) return { ...actionOverride };
|
|
449
|
+
}
|
|
450
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
451
|
+
return jsonSchema;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
//#endregion
|
|
455
|
+
//#region src/converters/convertSchema/convertSchema.ts
|
|
456
|
+
/**
|
|
457
|
+
* Flattens a Valibot pipe by recursively expanding nested pipes.
|
|
458
|
+
*
|
|
459
|
+
* @param pipe The pipeline to flatten.
|
|
460
|
+
*
|
|
461
|
+
* @returns A flat pipeline.
|
|
462
|
+
*/
|
|
463
|
+
function flattenPipe(pipe) {
|
|
464
|
+
return pipe.flatMap((item) => "pipe" in item ? flattenPipe(item.pipe) : item);
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Returns the JSON Pointer reference for a definition key.
|
|
468
|
+
*
|
|
469
|
+
* @param referenceId The unescaped definition key.
|
|
470
|
+
*
|
|
471
|
+
* @returns The encoded JSON Pointer fragment.
|
|
472
|
+
*/
|
|
473
|
+
function getDefinitionRef(referenceId) {
|
|
474
|
+
return `#/$defs/${referenceId.replaceAll("~", "~0").replaceAll("/", "~1")}`;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Converts any supported Valibot schema to the JSON Schema format.
|
|
478
|
+
*
|
|
479
|
+
* @param jsonSchema The JSON Schema object.
|
|
480
|
+
* @param valibotSchema The Valibot schema object.
|
|
481
|
+
* @param config The conversion configuration.
|
|
482
|
+
* @param context The conversion context.
|
|
483
|
+
* @param skipRef Whether to skip using a reference.
|
|
484
|
+
*
|
|
485
|
+
* @returns The converted JSON Schema.
|
|
486
|
+
*/
|
|
487
|
+
function convertSchema(jsonSchema, valibotSchema, config, context, skipRef = false) {
|
|
488
|
+
if (!skipRef) {
|
|
489
|
+
const referenceId = context.referenceMap.get(valibotSchema);
|
|
490
|
+
if (referenceId) {
|
|
491
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
492
|
+
if (config?.overrideRef) {
|
|
493
|
+
const refOverride = config.overrideRef({
|
|
494
|
+
...context,
|
|
495
|
+
referenceId,
|
|
496
|
+
valibotSchema,
|
|
497
|
+
jsonSchema
|
|
498
|
+
});
|
|
499
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
500
|
+
}
|
|
501
|
+
return jsonSchema;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
if ("pipe" in valibotSchema) {
|
|
505
|
+
const flatPipe = flattenPipe(valibotSchema.pipe);
|
|
506
|
+
let startIndex = 0;
|
|
507
|
+
let stopIndex = flatPipe.length - 1;
|
|
508
|
+
if (config?.typeMode === "input") {
|
|
509
|
+
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"));
|
|
510
|
+
if (inputStopIndex !== -1) stopIndex = inputStopIndex;
|
|
511
|
+
} else if (config?.typeMode === "output") {
|
|
512
|
+
const outputStartIndex = flatPipe.findLastIndex((item) => item.kind === "schema");
|
|
513
|
+
if (outputStartIndex !== -1) startIndex = outputStartIndex;
|
|
514
|
+
}
|
|
515
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
516
|
+
const valibotPipeItem = flatPipe[index];
|
|
517
|
+
if (valibotPipeItem.kind === "schema") {
|
|
518
|
+
if (index > startIndex) handleError("Set the \"typeMode\" config to \"input\" or \"output\" to convert pipelines with multiple schemas.", config);
|
|
519
|
+
jsonSchema = convertSchema(jsonSchema, valibotPipeItem, config, context, true);
|
|
520
|
+
} else jsonSchema = convertAction(jsonSchema, valibotPipeItem, config);
|
|
521
|
+
}
|
|
522
|
+
return jsonSchema;
|
|
523
|
+
}
|
|
524
|
+
let errors;
|
|
525
|
+
switch (valibotSchema.type) {
|
|
526
|
+
case "boolean":
|
|
527
|
+
jsonSchema.type = "boolean";
|
|
528
|
+
break;
|
|
529
|
+
case "null":
|
|
530
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [null];
|
|
531
|
+
else jsonSchema.type = "null";
|
|
532
|
+
break;
|
|
533
|
+
case "number":
|
|
534
|
+
jsonSchema.type = "number";
|
|
535
|
+
break;
|
|
536
|
+
case "string":
|
|
537
|
+
jsonSchema.type = "string";
|
|
538
|
+
break;
|
|
539
|
+
case "array":
|
|
540
|
+
jsonSchema.type = "array";
|
|
541
|
+
jsonSchema.items = convertSchema({}, valibotSchema.item, config, context);
|
|
542
|
+
break;
|
|
543
|
+
case "tuple":
|
|
544
|
+
case "tuple_with_rest":
|
|
545
|
+
case "loose_tuple":
|
|
546
|
+
case "strict_tuple":
|
|
547
|
+
jsonSchema.type = "array";
|
|
548
|
+
if (config?.target === "openapi-3.0") {
|
|
549
|
+
jsonSchema.items = { anyOf: [] };
|
|
550
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
551
|
+
for (const item of valibotSchema.items) jsonSchema.items.anyOf.push(convertSchema({}, item, config, context));
|
|
552
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items.anyOf.push(convertSchema({}, valibotSchema.rest, config, context));
|
|
553
|
+
else if (valibotSchema.type === "strict_tuple" || valibotSchema.type === "tuple") jsonSchema.maxItems = valibotSchema.items.length;
|
|
554
|
+
} else if (config?.target === "draft-2020-12") {
|
|
555
|
+
jsonSchema.prefixItems = [];
|
|
556
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
557
|
+
for (const item of valibotSchema.items) jsonSchema.prefixItems.push(convertSchema({}, item, config, context));
|
|
558
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items = convertSchema({}, valibotSchema.rest, config, context);
|
|
559
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.items = false;
|
|
560
|
+
} else {
|
|
561
|
+
jsonSchema.items = [];
|
|
562
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
563
|
+
for (const item of valibotSchema.items) jsonSchema.items.push(convertSchema({}, item, config, context));
|
|
564
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.additionalItems = convertSchema({}, valibotSchema.rest, config, context);
|
|
565
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.additionalItems = false;
|
|
566
|
+
}
|
|
567
|
+
break;
|
|
568
|
+
case "object":
|
|
569
|
+
case "object_with_rest":
|
|
570
|
+
case "loose_object":
|
|
571
|
+
case "strict_object":
|
|
572
|
+
jsonSchema.type = "object";
|
|
573
|
+
jsonSchema.properties = {};
|
|
574
|
+
jsonSchema.required = [];
|
|
575
|
+
for (const key in valibotSchema.entries) {
|
|
576
|
+
const entry = valibotSchema.entries[key];
|
|
577
|
+
jsonSchema.properties[key] = convertSchema({}, entry, config, context);
|
|
578
|
+
if (entry.type !== "exact_optional" && entry.type !== "nullish" && entry.type !== "optional") jsonSchema.required.push(key);
|
|
579
|
+
}
|
|
580
|
+
if (valibotSchema.type === "object_with_rest") jsonSchema.additionalProperties = convertSchema({}, valibotSchema.rest, config, context);
|
|
581
|
+
else if (valibotSchema.type === "strict_object") jsonSchema.additionalProperties = false;
|
|
582
|
+
break;
|
|
583
|
+
case "record":
|
|
584
|
+
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.");
|
|
585
|
+
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.`);
|
|
586
|
+
jsonSchema.type = "object";
|
|
587
|
+
if (config?.target !== "openapi-3.0") jsonSchema.propertyNames = convertSchema({}, valibotSchema.key, config, context);
|
|
588
|
+
jsonSchema.additionalProperties = convertSchema({}, valibotSchema.value, config, context);
|
|
589
|
+
break;
|
|
590
|
+
case "any":
|
|
591
|
+
case "unknown": break;
|
|
592
|
+
case "never":
|
|
593
|
+
jsonSchema.not = {};
|
|
594
|
+
break;
|
|
595
|
+
case "nullable":
|
|
596
|
+
case "nullish":
|
|
597
|
+
if (config?.target === "openapi-3.0") {
|
|
598
|
+
const innerSchema = convertSchema({}, valibotSchema.wrapped, config, context);
|
|
599
|
+
Object.assign(jsonSchema, innerSchema);
|
|
600
|
+
jsonSchema.nullable = true;
|
|
601
|
+
} else jsonSchema.anyOf = [convertSchema({}, valibotSchema.wrapped, config, context), { type: "null" }];
|
|
602
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
603
|
+
break;
|
|
604
|
+
case "exact_optional":
|
|
605
|
+
case "optional":
|
|
606
|
+
case "undefinedable":
|
|
607
|
+
jsonSchema = convertSchema(jsonSchema, valibotSchema.wrapped, config, context);
|
|
608
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
609
|
+
break;
|
|
610
|
+
case "literal":
|
|
611
|
+
if (!isJsonConstValue(valibotSchema.literal)) {
|
|
612
|
+
errors = addError(errors, "The value of the \"literal\" schema is not JSON compatible.");
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotSchema.literal];
|
|
616
|
+
else jsonSchema.const = valibotSchema.literal;
|
|
617
|
+
break;
|
|
618
|
+
case "enum":
|
|
619
|
+
case "picklist": {
|
|
620
|
+
const options = valibotSchema.options;
|
|
621
|
+
if (!options.every((option) => typeof option === "string" || typeof option === "number" && Number.isFinite(option))) {
|
|
622
|
+
errors = addError(errors, `An option of the "${valibotSchema.type}" schema is not JSON compatible.`);
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
jsonSchema.enum = options;
|
|
626
|
+
if (options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
627
|
+
else if (options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
628
|
+
else if (config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
case "union":
|
|
632
|
+
jsonSchema.anyOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
633
|
+
break;
|
|
634
|
+
case "variant":
|
|
635
|
+
jsonSchema.oneOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
636
|
+
break;
|
|
637
|
+
case "intersect":
|
|
638
|
+
jsonSchema.allOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
639
|
+
break;
|
|
640
|
+
case "lazy": {
|
|
641
|
+
let wrappedValibotSchema = context.getterMap.get(valibotSchema.getter);
|
|
642
|
+
if (!wrappedValibotSchema) {
|
|
643
|
+
wrappedValibotSchema = valibotSchema.getter(void 0);
|
|
644
|
+
context.getterMap.set(valibotSchema.getter, wrappedValibotSchema);
|
|
645
|
+
}
|
|
646
|
+
let referenceId = context.referenceMap.get(wrappedValibotSchema);
|
|
647
|
+
if (!referenceId) {
|
|
648
|
+
referenceId = context.referenceMap.createId(context.definitions);
|
|
649
|
+
context.referenceMap.set(wrappedValibotSchema, referenceId);
|
|
650
|
+
context.definitions[referenceId] = convertSchema({}, wrappedValibotSchema, config, context, true);
|
|
651
|
+
}
|
|
652
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
653
|
+
if (config?.overrideRef) {
|
|
654
|
+
const refOverride = config.overrideRef({
|
|
655
|
+
...context,
|
|
656
|
+
referenceId,
|
|
657
|
+
valibotSchema: wrappedValibotSchema,
|
|
658
|
+
jsonSchema
|
|
659
|
+
});
|
|
660
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
661
|
+
}
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
default: errors = addError(errors, `The "${valibotSchema.type}" schema cannot be converted to JSON Schema.`);
|
|
665
|
+
}
|
|
666
|
+
if (config?.overrideSchema) {
|
|
667
|
+
const schemaOverride = config.overrideSchema({
|
|
668
|
+
...context,
|
|
669
|
+
referenceId: context.referenceMap.get(valibotSchema),
|
|
670
|
+
valibotSchema,
|
|
671
|
+
jsonSchema,
|
|
672
|
+
errors
|
|
673
|
+
});
|
|
674
|
+
if (schemaOverride) return { ...schemaOverride };
|
|
675
|
+
}
|
|
676
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
677
|
+
return jsonSchema;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
//#endregion
|
|
681
|
+
//#region src/storages/globalDefs/globalDefs.ts
|
|
682
|
+
let store;
|
|
683
|
+
/**
|
|
684
|
+
* Adds new definitions to the global schema definitions.
|
|
685
|
+
*
|
|
686
|
+
* @param definitions The schema definitions.
|
|
687
|
+
*
|
|
688
|
+
* @beta
|
|
689
|
+
*/
|
|
690
|
+
function addGlobalDefs(definitions) {
|
|
691
|
+
store = {
|
|
692
|
+
...store ?? {},
|
|
693
|
+
...definitions
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Returns the current global schema definitions.
|
|
698
|
+
*
|
|
699
|
+
* @returns The schema definitions.
|
|
700
|
+
*
|
|
701
|
+
* @beta
|
|
702
|
+
*/
|
|
703
|
+
function getGlobalDefs() {
|
|
704
|
+
return store;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
//#endregion
|
|
708
|
+
//#region src/functions/toJsonSchema/toJsonSchema.ts
|
|
709
|
+
/**
|
|
710
|
+
* Converts a Valibot schema to the JSON Schema format.
|
|
711
|
+
*
|
|
712
|
+
* @param schema The Valibot schema object.
|
|
713
|
+
* @param config The JSON Schema configuration.
|
|
714
|
+
*
|
|
715
|
+
* @returns The converted JSON Schema.
|
|
716
|
+
*/
|
|
717
|
+
function toJsonSchema(schema, config) {
|
|
718
|
+
const context = {
|
|
719
|
+
definitions: {},
|
|
720
|
+
referenceMap: new ReferenceMap(),
|
|
721
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
722
|
+
};
|
|
723
|
+
const definitions = config?.definitions ?? getGlobalDefs();
|
|
724
|
+
if (definitions) {
|
|
725
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
726
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
727
|
+
}
|
|
728
|
+
const jsonSchema = convertSchema({}, schema, config, context);
|
|
729
|
+
const target = config?.target ?? "draft-07";
|
|
730
|
+
if (target === "draft-2020-12") jsonSchema.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
731
|
+
else if (target === "draft-07") jsonSchema.$schema = "http://json-schema.org/draft-07/schema#";
|
|
732
|
+
if (context.referenceMap.size) jsonSchema.$defs = context.definitions;
|
|
733
|
+
return jsonSchema;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/functions/toJsonSchemaDefs/toJsonSchemaDefs.ts
|
|
738
|
+
/**
|
|
739
|
+
* Converts Valibot schema definitions to JSON Schema definitions.
|
|
740
|
+
*
|
|
741
|
+
* @param definitions The Valibot schema definitions.
|
|
742
|
+
* @param config The JSON Schema configuration.
|
|
743
|
+
*
|
|
744
|
+
* @returns The converted JSON Schema definitions.
|
|
745
|
+
*/
|
|
746
|
+
function toJsonSchemaDefs(definitions, config) {
|
|
747
|
+
const context = {
|
|
748
|
+
definitions: {},
|
|
749
|
+
referenceMap: new ReferenceMap(),
|
|
750
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
751
|
+
};
|
|
752
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
753
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
754
|
+
return context.definitions;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/functions/toStandardJsonSchema/toStandardJsonSchema.ts
|
|
759
|
+
const SUPPORTED_TARGETS = [
|
|
760
|
+
"draft-07",
|
|
761
|
+
"draft-2020-12",
|
|
762
|
+
"openapi-3.0"
|
|
763
|
+
];
|
|
764
|
+
/**
|
|
765
|
+
* Converts a Valibot schema to the Standard JSON Schema format.
|
|
766
|
+
*
|
|
767
|
+
* @param schema The Valibot schema object.
|
|
768
|
+
*
|
|
769
|
+
* @returns The Standard JSON Schema.
|
|
770
|
+
*/
|
|
771
|
+
function toStandardJsonSchema(schema) {
|
|
772
|
+
return { "~standard": {
|
|
773
|
+
...schema["~standard"],
|
|
774
|
+
jsonSchema: {
|
|
775
|
+
input(options) {
|
|
776
|
+
if (SUPPORTED_TARGETS.includes(options.target)) return toJsonSchema(schema, {
|
|
777
|
+
typeMode: "input",
|
|
778
|
+
target: options.target,
|
|
779
|
+
...options.libraryOptions
|
|
780
|
+
});
|
|
781
|
+
throw new Error(`Unsupported target: ${options.target}`);
|
|
782
|
+
},
|
|
783
|
+
output(options) {
|
|
784
|
+
if (SUPPORTED_TARGETS.includes(options.target)) return toJsonSchema(schema, {
|
|
785
|
+
typeMode: "output",
|
|
786
|
+
target: options.target,
|
|
787
|
+
...options.libraryOptions
|
|
788
|
+
});
|
|
789
|
+
throw new Error(`Unsupported target: ${options.target}`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
} };
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
//#endregion
|
|
796
|
+
exports.addGlobalDefs = addGlobalDefs;
|
|
797
|
+
exports.getGlobalDefs = getGlobalDefs;
|
|
798
|
+
exports.toJsonSchema = toJsonSchema;
|
|
799
|
+
exports.toJsonSchemaDefs = toJsonSchemaDefs;
|
|
800
|
+
exports.toStandardJsonSchema = toStandardJsonSchema;
|