@outfitter/contracts 0.3.0 → 0.4.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/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import "./shared/@outfitter/contracts-qaccq0gf";
|
|
2
|
+
import { combine2, combine3, expect, orElse, unwrapOrElse } from "./shared/@outfitter/contracts-ar0etwtx";
|
|
1
3
|
import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-sf1z80yc";
|
|
2
4
|
import { ACTION_CAPABILITIES, ActionCapability, CAPABILITY_SURFACES, CapabilitySurface, DEFAULT_ACTION_SURFACES, capability, capabilityAll, getActionsForSurface } from "./shared/@outfitter/contracts-bb4hjt8g";
|
|
3
5
|
import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-j08e95jw";
|
|
6
|
+
import { JsonSchema, zodToJsonSchema } from "./shared/@outfitter/contracts-hbbxbwkt";
|
|
4
7
|
import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-25bkj17f";
|
|
5
8
|
import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./shared/@outfitter/contracts-18vcxecr";
|
|
6
|
-
import "./shared/@outfitter/contracts-qaccq0gf";
|
|
7
|
-
import { combine2, combine3, expect, orElse, unwrapOrElse } from "./shared/@outfitter/contracts-ar0etwtx";
|
|
8
9
|
import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-jggbn5tn";
|
|
9
10
|
import { AdapterAuthError, AuthAdapter, CacheAdapter, CacheError, IndexAdapter, IndexError, IndexStats, SearchOptions, SearchResult, StorageAdapter, StorageError } from "./shared/@outfitter/contracts-93dx53mt";
|
|
10
11
|
import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-evxky148";
|
|
@@ -16,4 +17,4 @@ import { LogLevel, LogMetadata, LogMethod, Logger, LoggerAdapter, LoggerFactory,
|
|
|
16
17
|
import { DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS, RedactionCallback, RedactionEvent, Redactor, RedactorConfig, createRedactor } from "./shared/@outfitter/contracts-e70qdasg";
|
|
17
18
|
import { TaggedErrorClass } from "better-result";
|
|
18
19
|
import { Result, TaggedError } from "better-result";
|
|
19
|
-
export { withTimeout, validateInput, unwrapOrElse, toHttpResponse, toEnvelope, statusCodeMap, shouldRetry, serializeError, safeStringify, safeParse, retry, orElse, isRetryable, isRecoverable, isNonEmptyArray, getStatusCode, getExitCode, getBackoffDelay, getActionsForSurface, generateRequestId, expect, exitCodeMap, deserializeError, defineAction, createValidator, createRedactor, createLoggerFactory, createContext, createActionRegistry, combine3, combine2, capabilityAll, capability, assertNonEmpty, assertMatches, assertDefined, ValidationError, TimeoutOptions, TimeoutError, TaggedErrorClass, TaggedError, SyncHandler, SuccessEnvelope, StorageError, StorageAdapter, SerializedError, SerializeErrorOptions, SearchResult, SearchOptions, RetryOptions, Result, ResolvedConfig, RedactorConfig, Redactor, RedactionEvent, RedactionCallback, RateLimitError, PermissionError, PaginationMeta, OutfitterError, NotFoundError, NonEmptyArray, NetworkError, LoggerFactoryConfig, LoggerFactory, LoggerAdapter, Logger, LogMethod, LogMetadata, LogLevel, KitErrorProps, InternalError, IndexStats, IndexError, IndexAdapter, HttpResponse, HttpMethod, HandlerContext, Handler, ErrorEnvelope, ErrorCode, ErrorCategory, EnvelopeMeta, Envelope, ERROR_CODES, DEFAULT_SENSITIVE_KEYS, DEFAULT_REGISTRY_SURFACES, DEFAULT_PATTERNS, DEFAULT_ACTION_SURFACES, CreateContextOptions, ConflictError, CapabilitySurface, CancelledError, CacheError, CacheAdapter, CAPABILITY_SURFACES, BackoffOptions, AuthError, AuthAdapter, AssertionError, AnyKitError, AnyActionSpec, AmbiguousError, AlreadyExistsError, AdapterAuthError, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionCapability, ActionApiSpec, ACTION_SURFACES, ACTION_CAPABILITIES };
|
|
20
|
+
export { zodToJsonSchema, withTimeout, validateInput, unwrapOrElse, toHttpResponse, toEnvelope, statusCodeMap, shouldRetry, serializeError, safeStringify, safeParse, retry, orElse, isRetryable, isRecoverable, isNonEmptyArray, getStatusCode, getExitCode, getBackoffDelay, getActionsForSurface, generateRequestId, expect, exitCodeMap, deserializeError, defineAction, createValidator, createRedactor, createLoggerFactory, createContext, createActionRegistry, combine3, combine2, capabilityAll, capability, assertNonEmpty, assertMatches, assertDefined, ValidationError, TimeoutOptions, TimeoutError, TaggedErrorClass, TaggedError, SyncHandler, SuccessEnvelope, StorageError, StorageAdapter, SerializedError, SerializeErrorOptions, SearchResult, SearchOptions, RetryOptions, Result, ResolvedConfig, RedactorConfig, Redactor, RedactionEvent, RedactionCallback, RateLimitError, PermissionError, PaginationMeta, OutfitterError, NotFoundError, NonEmptyArray, NetworkError, LoggerFactoryConfig, LoggerFactory, LoggerAdapter, Logger, LogMethod, LogMetadata, LogLevel, KitErrorProps, JsonSchema, InternalError, IndexStats, IndexError, IndexAdapter, HttpResponse, HttpMethod, HandlerContext, Handler, ErrorEnvelope, ErrorCode, ErrorCategory, EnvelopeMeta, Envelope, ERROR_CODES, DEFAULT_SENSITIVE_KEYS, DEFAULT_REGISTRY_SURFACES, DEFAULT_PATTERNS, DEFAULT_ACTION_SURFACES, CreateContextOptions, ConflictError, CapabilitySurface, CancelledError, CacheError, CacheAdapter, CAPABILITY_SURFACES, BackoffOptions, AuthError, AuthAdapter, AssertionError, AnyKitError, AnyActionSpec, AmbiguousError, AlreadyExistsError, AdapterAuthError, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionCapability, ActionApiSpec, ACTION_SURFACES, ACTION_CAPABILITIES };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import"./shared/@outfitter/contracts-37gpc56f.js";
|
|
3
|
+
import {
|
|
4
|
+
combine2,
|
|
5
|
+
combine3,
|
|
6
|
+
expect,
|
|
7
|
+
orElse,
|
|
8
|
+
unwrapOrElse
|
|
9
|
+
} from "./shared/@outfitter/contracts-zx72gyh1.js";
|
|
2
10
|
import {
|
|
3
11
|
ACTION_SURFACES,
|
|
4
12
|
DEFAULT_REGISTRY_SURFACES,
|
|
@@ -13,20 +21,15 @@ import {
|
|
|
13
21
|
capabilityAll,
|
|
14
22
|
getActionsForSurface
|
|
15
23
|
} from "./shared/@outfitter/contracts-d0tq2adf.js";
|
|
24
|
+
import {
|
|
25
|
+
zodToJsonSchema
|
|
26
|
+
} from "./shared/@outfitter/contracts-wfht4q2b.js";
|
|
16
27
|
import {
|
|
17
28
|
assertDefined,
|
|
18
29
|
assertMatches,
|
|
19
30
|
assertNonEmpty,
|
|
20
31
|
isNonEmptyArray
|
|
21
32
|
} from "./shared/@outfitter/contracts-cp5c6dws.js";
|
|
22
|
-
import"./shared/@outfitter/contracts-37gpc56f.js";
|
|
23
|
-
import {
|
|
24
|
-
combine2,
|
|
25
|
-
combine3,
|
|
26
|
-
expect,
|
|
27
|
-
orElse,
|
|
28
|
-
unwrapOrElse
|
|
29
|
-
} from "./shared/@outfitter/contracts-zx72gyh1.js";
|
|
30
33
|
import {
|
|
31
34
|
toEnvelope,
|
|
32
35
|
toHttpResponse
|
|
@@ -87,6 +90,7 @@ import {
|
|
|
87
90
|
// packages/contracts/src/index.ts
|
|
88
91
|
import { Result, TaggedError } from "better-result";
|
|
89
92
|
export {
|
|
93
|
+
zodToJsonSchema,
|
|
90
94
|
withTimeout,
|
|
91
95
|
validateInput,
|
|
92
96
|
unwrapOrElse,
|
package/dist/schema.d.ts
ADDED
package/dist/schema.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* JSON Schema representation.
|
|
4
|
+
*/
|
|
5
|
+
interface JsonSchema {
|
|
6
|
+
type?: string;
|
|
7
|
+
properties?: Record<string, JsonSchema>;
|
|
8
|
+
required?: string[];
|
|
9
|
+
items?: JsonSchema | JsonSchema[];
|
|
10
|
+
description?: string;
|
|
11
|
+
default?: unknown;
|
|
12
|
+
minimum?: number;
|
|
13
|
+
maximum?: number;
|
|
14
|
+
exclusiveMinimum?: number;
|
|
15
|
+
exclusiveMaximum?: number;
|
|
16
|
+
minLength?: number;
|
|
17
|
+
maxLength?: number;
|
|
18
|
+
pattern?: string;
|
|
19
|
+
format?: string;
|
|
20
|
+
enum?: unknown[];
|
|
21
|
+
const?: unknown;
|
|
22
|
+
anyOf?: JsonSchema[];
|
|
23
|
+
oneOf?: JsonSchema[];
|
|
24
|
+
allOf?: JsonSchema[];
|
|
25
|
+
not?: JsonSchema | Record<string, never>;
|
|
26
|
+
$ref?: string;
|
|
27
|
+
$schema?: string;
|
|
28
|
+
$defs?: Record<string, JsonSchema>;
|
|
29
|
+
definitions?: Record<string, JsonSchema>;
|
|
30
|
+
additionalProperties?: boolean | JsonSchema;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert a Zod schema to JSON Schema format.
|
|
34
|
+
*
|
|
35
|
+
* This is a simplified converter that handles common Zod types.
|
|
36
|
+
* For complex schemas, consider using a full zod-to-json-schema library.
|
|
37
|
+
*
|
|
38
|
+
* @param schema - Zod schema to convert
|
|
39
|
+
* @returns JSON Schema representation
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const zodSchema = z.object({
|
|
44
|
+
* name: z.string(),
|
|
45
|
+
* age: z.number().optional(),
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* const jsonSchema = zodToJsonSchema(zodSchema);
|
|
49
|
+
* // {
|
|
50
|
+
* // type: "object",
|
|
51
|
+
* // properties: {
|
|
52
|
+
* // name: { type: "string" },
|
|
53
|
+
* // age: { type: "number" },
|
|
54
|
+
* // },
|
|
55
|
+
* // required: ["name"],
|
|
56
|
+
* // }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
declare function zodToJsonSchema(schema: z.ZodType<unknown>): JsonSchema;
|
|
60
|
+
export { JsonSchema, zodToJsonSchema };
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/contracts/src/schema.ts
|
|
3
|
+
function zodToJsonSchema(schema) {
|
|
4
|
+
return convertZodType(schema);
|
|
5
|
+
}
|
|
6
|
+
function getDef(schemaOrDef) {
|
|
7
|
+
if (!schemaOrDef) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (schemaOrDef._def) {
|
|
11
|
+
return schemaOrDef._def;
|
|
12
|
+
}
|
|
13
|
+
if (schemaOrDef.def) {
|
|
14
|
+
return schemaOrDef.def;
|
|
15
|
+
}
|
|
16
|
+
return schemaOrDef;
|
|
17
|
+
}
|
|
18
|
+
function getDescription(schema, def) {
|
|
19
|
+
if (typeof schema?.description === "string") {
|
|
20
|
+
return schema.description;
|
|
21
|
+
}
|
|
22
|
+
if (typeof def?.description === "string") {
|
|
23
|
+
return def.description;
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
function convertZodType(schema) {
|
|
28
|
+
const def = getDef(schema);
|
|
29
|
+
if (!def) {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
const typeName = def.typeName ?? def.type;
|
|
33
|
+
let jsonSchema;
|
|
34
|
+
switch (typeName) {
|
|
35
|
+
case "ZodString":
|
|
36
|
+
case "string":
|
|
37
|
+
jsonSchema = convertString(def);
|
|
38
|
+
break;
|
|
39
|
+
case "ZodNumber":
|
|
40
|
+
case "number":
|
|
41
|
+
jsonSchema = convertNumber(def);
|
|
42
|
+
break;
|
|
43
|
+
case "ZodBoolean":
|
|
44
|
+
case "boolean":
|
|
45
|
+
jsonSchema = { type: "boolean" };
|
|
46
|
+
break;
|
|
47
|
+
case "ZodNull":
|
|
48
|
+
case "null":
|
|
49
|
+
jsonSchema = { type: "null" };
|
|
50
|
+
break;
|
|
51
|
+
case "ZodUndefined":
|
|
52
|
+
case "undefined":
|
|
53
|
+
jsonSchema = {};
|
|
54
|
+
break;
|
|
55
|
+
case "ZodArray":
|
|
56
|
+
case "array":
|
|
57
|
+
jsonSchema = convertArray(def);
|
|
58
|
+
break;
|
|
59
|
+
case "ZodObject":
|
|
60
|
+
case "object":
|
|
61
|
+
jsonSchema = convertObject(def);
|
|
62
|
+
break;
|
|
63
|
+
case "ZodOptional":
|
|
64
|
+
case "optional":
|
|
65
|
+
jsonSchema = convertZodType(def.innerType);
|
|
66
|
+
break;
|
|
67
|
+
case "ZodNullable":
|
|
68
|
+
case "nullable":
|
|
69
|
+
jsonSchema = {
|
|
70
|
+
anyOf: [convertZodType(def.innerType), { type: "null" }]
|
|
71
|
+
};
|
|
72
|
+
break;
|
|
73
|
+
case "ZodDefault":
|
|
74
|
+
case "default": {
|
|
75
|
+
const defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
|
|
76
|
+
jsonSchema = {
|
|
77
|
+
...convertZodType(def.innerType),
|
|
78
|
+
default: defaultValue
|
|
79
|
+
};
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "ZodEnum":
|
|
83
|
+
case "enum": {
|
|
84
|
+
const values = def.values ?? Object.values(def.entries ?? {});
|
|
85
|
+
jsonSchema = {
|
|
86
|
+
type: "string",
|
|
87
|
+
enum: values
|
|
88
|
+
};
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "ZodNativeEnum":
|
|
92
|
+
jsonSchema = {
|
|
93
|
+
enum: Object.values(def.values ?? def.entries ?? {})
|
|
94
|
+
};
|
|
95
|
+
break;
|
|
96
|
+
case "ZodLiteral":
|
|
97
|
+
case "literal": {
|
|
98
|
+
const literalValues = Array.isArray(def.values) ? def.values : [def.value].filter((value) => value !== undefined);
|
|
99
|
+
if (literalValues.length > 1) {
|
|
100
|
+
jsonSchema = {
|
|
101
|
+
enum: literalValues
|
|
102
|
+
};
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
jsonSchema = literalValues.length ? {
|
|
106
|
+
const: literalValues[0]
|
|
107
|
+
} : {};
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "ZodUnion":
|
|
111
|
+
case "union":
|
|
112
|
+
jsonSchema = {
|
|
113
|
+
anyOf: def.options.map(convertZodType)
|
|
114
|
+
};
|
|
115
|
+
break;
|
|
116
|
+
case "ZodIntersection":
|
|
117
|
+
case "intersection":
|
|
118
|
+
jsonSchema = {
|
|
119
|
+
allOf: [convertZodType(def.left), convertZodType(def.right)]
|
|
120
|
+
};
|
|
121
|
+
break;
|
|
122
|
+
case "ZodRecord":
|
|
123
|
+
case "record":
|
|
124
|
+
jsonSchema = {
|
|
125
|
+
type: "object",
|
|
126
|
+
additionalProperties: def.valueType ? convertZodType(def.valueType) : {}
|
|
127
|
+
};
|
|
128
|
+
break;
|
|
129
|
+
case "ZodTuple":
|
|
130
|
+
case "tuple":
|
|
131
|
+
jsonSchema = {
|
|
132
|
+
type: "array",
|
|
133
|
+
items: def.items.map(convertZodType)
|
|
134
|
+
};
|
|
135
|
+
break;
|
|
136
|
+
case "ZodAny":
|
|
137
|
+
case "any":
|
|
138
|
+
jsonSchema = {};
|
|
139
|
+
break;
|
|
140
|
+
case "ZodUnknown":
|
|
141
|
+
case "unknown":
|
|
142
|
+
jsonSchema = {};
|
|
143
|
+
break;
|
|
144
|
+
case "ZodVoid":
|
|
145
|
+
case "void":
|
|
146
|
+
jsonSchema = {};
|
|
147
|
+
break;
|
|
148
|
+
case "ZodNever":
|
|
149
|
+
case "never":
|
|
150
|
+
jsonSchema = { not: {} };
|
|
151
|
+
break;
|
|
152
|
+
case "ZodEffects":
|
|
153
|
+
jsonSchema = convertZodType(def.schema);
|
|
154
|
+
break;
|
|
155
|
+
case "ZodPipeline":
|
|
156
|
+
case "pipe": {
|
|
157
|
+
const outputDef = getDef(def.out);
|
|
158
|
+
const outputType = outputDef?.typeName ?? outputDef?.type;
|
|
159
|
+
jsonSchema = outputType === "transform" ? convertZodType(def.in) : convertZodType(def.out);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "ZodLazy":
|
|
163
|
+
case "lazy":
|
|
164
|
+
jsonSchema = {};
|
|
165
|
+
break;
|
|
166
|
+
default:
|
|
167
|
+
jsonSchema = {};
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
const description = getDescription(schema, def);
|
|
171
|
+
if (description && !jsonSchema.description) {
|
|
172
|
+
jsonSchema.description = description;
|
|
173
|
+
}
|
|
174
|
+
return jsonSchema;
|
|
175
|
+
}
|
|
176
|
+
function convertString(def) {
|
|
177
|
+
const schema = { type: "string" };
|
|
178
|
+
if (def.checks) {
|
|
179
|
+
for (const check of def.checks) {
|
|
180
|
+
const normalizedCheck = check?._zod?.def ?? check?.def ?? check;
|
|
181
|
+
if (normalizedCheck?.kind) {
|
|
182
|
+
switch (normalizedCheck.kind) {
|
|
183
|
+
case "min":
|
|
184
|
+
schema.minLength = normalizedCheck.value;
|
|
185
|
+
break;
|
|
186
|
+
case "max":
|
|
187
|
+
schema.maxLength = normalizedCheck.value;
|
|
188
|
+
break;
|
|
189
|
+
case "length":
|
|
190
|
+
schema.minLength = normalizedCheck.value;
|
|
191
|
+
schema.maxLength = normalizedCheck.value;
|
|
192
|
+
break;
|
|
193
|
+
case "email":
|
|
194
|
+
schema.pattern = "^[^@]+@[^@]+\\.[^@]+$";
|
|
195
|
+
break;
|
|
196
|
+
case "url":
|
|
197
|
+
schema.pattern = "^https?://";
|
|
198
|
+
break;
|
|
199
|
+
case "uuid":
|
|
200
|
+
schema.pattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";
|
|
201
|
+
break;
|
|
202
|
+
case "regex":
|
|
203
|
+
schema.pattern = normalizedCheck.regex?.source ?? normalizedCheck.pattern?.source ?? (typeof normalizedCheck.pattern === "string" ? normalizedCheck.pattern : undefined);
|
|
204
|
+
break;
|
|
205
|
+
default:
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (!normalizedCheck?.check) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
switch (normalizedCheck.check) {
|
|
214
|
+
case "min_length":
|
|
215
|
+
schema.minLength = normalizedCheck.minimum;
|
|
216
|
+
break;
|
|
217
|
+
case "max_length":
|
|
218
|
+
schema.maxLength = normalizedCheck.maximum;
|
|
219
|
+
break;
|
|
220
|
+
case "string_format":
|
|
221
|
+
if (normalizedCheck.pattern) {
|
|
222
|
+
schema.pattern = typeof normalizedCheck.pattern === "string" ? normalizedCheck.pattern : normalizedCheck.pattern.source;
|
|
223
|
+
}
|
|
224
|
+
if (normalizedCheck.format && normalizedCheck.format !== "regex") {
|
|
225
|
+
schema.format = normalizedCheck.format;
|
|
226
|
+
}
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return schema;
|
|
234
|
+
}
|
|
235
|
+
function convertNumber(def) {
|
|
236
|
+
const schema = { type: "number" };
|
|
237
|
+
if (def.checks) {
|
|
238
|
+
for (const check of def.checks) {
|
|
239
|
+
const normalizedCheck = check?._zod?.def ?? check?.def ?? check;
|
|
240
|
+
if (normalizedCheck?.kind) {
|
|
241
|
+
switch (normalizedCheck.kind) {
|
|
242
|
+
case "min":
|
|
243
|
+
schema.minimum = normalizedCheck.value;
|
|
244
|
+
break;
|
|
245
|
+
case "max":
|
|
246
|
+
schema.maximum = normalizedCheck.value;
|
|
247
|
+
break;
|
|
248
|
+
case "int":
|
|
249
|
+
schema.type = "integer";
|
|
250
|
+
break;
|
|
251
|
+
default:
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (!normalizedCheck?.check) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
switch (normalizedCheck.check) {
|
|
260
|
+
case "greater_than":
|
|
261
|
+
if (normalizedCheck.inclusive) {
|
|
262
|
+
schema.minimum = normalizedCheck.value;
|
|
263
|
+
} else {
|
|
264
|
+
schema.exclusiveMinimum = normalizedCheck.value;
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
case "less_than":
|
|
268
|
+
if (normalizedCheck.inclusive) {
|
|
269
|
+
schema.maximum = normalizedCheck.value;
|
|
270
|
+
} else {
|
|
271
|
+
schema.exclusiveMaximum = normalizedCheck.value;
|
|
272
|
+
}
|
|
273
|
+
break;
|
|
274
|
+
case "number_format":
|
|
275
|
+
if (normalizedCheck.format === "int" || normalizedCheck.format === "safeint") {
|
|
276
|
+
schema.type = "integer";
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
default:
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return schema;
|
|
285
|
+
}
|
|
286
|
+
function convertArray(def) {
|
|
287
|
+
const element = def.element ?? def.type;
|
|
288
|
+
const schema = {
|
|
289
|
+
type: "array",
|
|
290
|
+
items: element ? convertZodType(element) : {}
|
|
291
|
+
};
|
|
292
|
+
return schema;
|
|
293
|
+
}
|
|
294
|
+
function isFieldOptional(fieldDef) {
|
|
295
|
+
if (!(fieldDef?.typeName || fieldDef?.type)) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
const typeName = fieldDef.typeName ?? fieldDef.type;
|
|
299
|
+
if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "optional" || typeName === "default") {
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
if (typeName === "ZodEffects") {
|
|
303
|
+
return isFieldOptional(getDef(fieldDef.schema));
|
|
304
|
+
}
|
|
305
|
+
if (typeName === "ZodPipeline" || typeName === "pipe") {
|
|
306
|
+
const inputOptional = isFieldOptional(getDef(fieldDef.in));
|
|
307
|
+
const outputDef = getDef(fieldDef.out);
|
|
308
|
+
const outputType = outputDef?.typeName ?? outputDef?.type;
|
|
309
|
+
if (outputType === "transform") {
|
|
310
|
+
return inputOptional;
|
|
311
|
+
}
|
|
312
|
+
const outputOptional = isFieldOptional(outputDef);
|
|
313
|
+
return inputOptional && outputOptional;
|
|
314
|
+
}
|
|
315
|
+
if (typeName === "ZodNullable" || typeName === "nullable") {
|
|
316
|
+
return isFieldOptional(getDef(fieldDef.innerType));
|
|
317
|
+
}
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
function convertObject(def) {
|
|
321
|
+
const properties = {};
|
|
322
|
+
const required = [];
|
|
323
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
324
|
+
for (const [key, value] of Object.entries(shape ?? {})) {
|
|
325
|
+
properties[key] = convertZodType(value);
|
|
326
|
+
const fieldDef = getDef(value);
|
|
327
|
+
if (!isFieldOptional(fieldDef)) {
|
|
328
|
+
required.push(key);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const schema = {
|
|
332
|
+
type: "object",
|
|
333
|
+
properties
|
|
334
|
+
};
|
|
335
|
+
if (required.length > 0) {
|
|
336
|
+
schema.required = required;
|
|
337
|
+
}
|
|
338
|
+
return schema;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { zodToJsonSchema };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outfitter/contracts",
|
|
3
3
|
"description": "Result/Error patterns, error taxonomy, and handler contracts for Outfitter",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -100,6 +100,12 @@
|
|
|
100
100
|
"default": "./dist/result/utilities.js"
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
|
+
"./schema": {
|
|
104
|
+
"import": {
|
|
105
|
+
"types": "./dist/schema.d.ts",
|
|
106
|
+
"default": "./dist/schema.js"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
103
109
|
"./serialization": {
|
|
104
110
|
"import": {
|
|
105
111
|
"types": "./dist/serialization.d.ts",
|