Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

21
node_modules/zod-to-ts/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Sachin Raja
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

405
node_modules/zod-to-ts/README.md generated vendored Normal file
View File

@@ -0,0 +1,405 @@
# zod-to-ts
generate TypeScript types from your [Zod](https://github.com/colinhacks/zod) schema
## Installation
```
npm install zod-to-ts zod typescript
```
You must be on zod@3 and typescript@4.
## Usage
```ts
import { z } from 'zod'
import { zodToTs } from 'zod-to-ts'
// define your Zod schema
const UserSchema = z.object({
username: z.string(),
age: z.number(),
inventory: z.object({
name: z.string(),
itemId: z.number(),
}).array(),
})
// pass schema and name of type/identifier
const { node } = zodToTs(UserSchema, 'User')
```
result:
<!-- dprint-ignore -->
```ts
{
username: string
age: number
inventory: {
name: string
itemId: number
}[]
}
```
You must pass in the identifier `User` or it will default to `Identifier`. This is necessary to handle cases like recursive types and native enums. `zodToTs()` only returns the type value, not the actual type declaration. If you want to add an identifier to the type and create a type declaration, you can use the `createTypeAlias()` utility:
```ts
import { createTypeAlias, zodToTs } from 'zod-to-ts'
const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const typeAlias = createTypeAlias(
node,
identifier,
// optionally pass a comment
// comment: UserSchema.description
)
```
result:
```ts
type User = {
username: string
}
```
`zodToTs()` and `createTypeAlias()` return a TS AST nodes, so if you want to get the node as a string, you can use the `printNode()` utility.
`zodToTs()`:
```ts
import { printNode, zodToTs } from 'zod-to-ts'
const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const nodeString = printNode(node)
```
result:
<!-- dprint-ignore -->
```
"{
username: string
age: number
inventory: {
name: string
itemId: number
}[]
}"
```
`createTypeAlias()`:
```ts
import { createTypeAlias, printNode, zodToTs } from 'zod-to-ts'
const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const typeAlias = createTypeAlias(node, identifier)
const nodeString = printNode(typeAlias)
```
result:
<!-- dprint-ignore -->
```
"type User = {
username: string
age: number
inventory: {
name: string
itemId: number
}[]
}"
```
## Overriding Types
You can use `withGetType` to override a type, which is useful when more information is needed to determine the actual type. Unfortunately, this means working with the TS AST:
```ts
import { z } from 'zod'
import { withGetType, zodToTs } from 'zod-to-ts'
const DateSchema = withGetType(
z.instanceof(Date),
(ts) => ts.factory.createIdentifier('Date'),
)
const ItemSchema = z.object({
name: z.string(),
date: DateSchema,
})
const { node } = zodToTs(ItemSchema, 'Item')
```
result without `withGetType` override:
```ts
type Item = {
name: string
date: any
}
```
result with override:
```ts
type Item = {
name: string
date: Date
}
```
[TypeScript AST Viewer](https://ts-ast-viewer.com/) can help a lot with this if you are having trouble referencing something. It even provides copy-pastable code!
### Special Cases
#### [z.lazy()](https://github.com/colinhacks/zod#recursive-types)
Lazy types default to referencing the root type (`User` in the following example). It is impossible to determine what it is referencing otherwise.
```ts
// Zod cannot infer types when you use the z.lazy
// so you must define it
import { z } from 'zod'
type User = {
username: string
friends: User[]
}
const UserSchema: z.ZodSchema<User> = z.object({
username: z.string(),
friends: z.lazy(() => UserSchema).array(),
})
const { node } = zodToTs(UserSchema, 'User')
```
result:
```ts
type User = {
username: string
friends: User[]
}
```
But what happens when the schema looks like this?
```ts
type User = {
username: string
item: {
name: string
itemId: string
}
friends: User[]
}
// essentially when you are referencing a different field
// and not the root type
const friendItems = z.lazy(() => UserSchema.item).array()
const UserSchema: z.ZodSchema<User> = z.object({
username: z.string(),
item: z.object({
name: z.string(),
id: z.number(),
}),
friendItems,
})
const { node } = zodToTs(UserSchema, 'User')
```
result:
<!-- dprint-ignore -->
```ts
{
username: string
item: {
name: string
id: number
}
friendItems: User[]
}
```
`friendItems` will still have the `User` type even though it is actually referencing `UserSchema["item"]`. You must provide the actual type using `withGetType`:
```ts
import { z } from 'zod'
import { withGetType } from 'zod-to-ts'
type User = {
username: string
item: {
name: string
id: number
}
friends: User[]
}
const friendItems: z.Schema<User['item'][]> = withGetType(
z.lazy(() => UserSchema.item).array(),
// return a TS AST node
(ts, identifier) =>
ts.factory.createIndexedAccessTypeNode(
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier(identifier),
undefined,
),
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('item')),
),
)
const UserSchema: z.ZodSchema<User> = z.object({
username: z.string(),
item: z.object({
name: z.string(),
id: z.number(),
}),
friendItems,
})
const { node } = zodToTs(UserSchema, 'User')
```
result:
```ts
{
username: string
item: {
name: string
id: number
}
friendItems: User['item'][]
}
```
#### [z.nativeEnum()](https://github.com/colinhacks/zod#native-enums)
`z.enum()` is always preferred, but sometimes `z.nativeEnum()` is necessary. `z.nativeEnum()` works similarly to `z.lazy()` in that the identifier of the enum cannot be determined:
```ts
import { z } from 'zod'
import { withGetType } from 'zod-to-ts'
enum Fruit {
Apple = 'apple',
Banana = 'banana',
Cantaloupe = 'cantaloupe',
}
const fruitNativeEnum: = z.nativeEnum(
Fruit,
)
const TreeSchema = z.object({
fruit: fruitNativeEnum,
})
```
result:
<!-- dprint-ignore -->
```ts
{
fruit: unknown
}
```
There are three ways to solve this: provide an identifier to it or resolve all the enums inside `zodToTs()`.
Option 1 - providing an identifier using `withGetType()`:
```ts
import { z } from 'zod'
import { withGetType, zodToTs } from 'zod-to-ts'
enum Fruit {
Apple = 'apple',
Banana = 'banana',
Cantaloupe = 'cantaloupe',
}
const fruitNativeEnum = withGetType(
z.nativeEnum(
Fruit,
),
// return an identifier that will be used on the enum type
(ts) => ts.factory.createIdentifier('Fruit'),
)
const TreeSchema = z.object({
fruit: fruitNativeEnum,
})
const { node } = zodToTs(TreeSchema)
```
result:
<!-- dprint-ignore -->
```ts
{
fruit: Fruit
}
```
Option 2 - resolve enums. This is the same as before, but you just need to pass an option:
```ts
const TreeTSType = zodToTs(TreeSchema, undefined, { nativeEnums: 'resolve' })
```
result:
<!-- dprint-ignore -->
```ts
{
node: {
fruit: Fruit
},
store: {
nativeEnums: [
enum Fruit {
Apple = 'apple',
Banana = 'banana',
Cantaloupe = 'cantaloupe',
}
]
}
}
```
Note: These are not the actual values, they are TS representation. The actual values are TS AST nodes.
This option allows you to embed the enums before the schema without actually depending on an external enum type.
Option 3 - convert to union. This is the same as how ZodEnum created by z.enum([...]) is handled, but need to pass an option:
```ts
const { node } = zodToTs(TreeSchema, undefined, {
nativeEnums: 'union',
})
```
result:
<!-- dprint-ignore -->
```ts
{
fruit: 'apple' | 'banana' | 'cantaloupe'
}
```
Note: These are not the actual values, they are TS representation. The actual values are TS AST nodes.

332
node_modules/zod-to-ts/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,332 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/index.ts
var _typescript = require('typescript'); var _typescript2 = _interopRequireDefault(_typescript);
// src/types.ts
var resolveOptions = (raw) => {
const resolved = {
nativeEnums: _optionalChain([raw, 'optionalAccess', _ => _.resolveNativeEnums]) ? "resolve" : "identifier"
};
return { ...resolved, ...raw };
};
// src/utils.ts
var { factory: f, SyntaxKind, ScriptKind, ScriptTarget, EmitHint } = _typescript2.default;
var maybeIdentifierToTypeReference = (identifier) => {
if (_typescript2.default.isIdentifier(identifier)) {
return f.createTypeReferenceNode(identifier);
}
return identifier;
};
var createTypeReferenceFromString = (identifier) => f.createTypeReferenceNode(f.createIdentifier(identifier));
var createUnknownKeywordNode = () => f.createKeywordTypeNode(SyntaxKind.UnknownKeyword);
var createTypeAlias = (node, identifier, comment) => {
const typeAlias = f.createTypeAliasDeclaration(
void 0,
f.createIdentifier(identifier),
void 0,
node
);
if (comment) {
addJsDocComment(typeAlias, comment);
}
return typeAlias;
};
var printNode = (node, printerOptions) => {
const sourceFile = _typescript2.default.createSourceFile("print.ts", "", ScriptTarget.Latest, false, ScriptKind.TS);
const printer = _typescript2.default.createPrinter(printerOptions);
return printer.printNode(EmitHint.Unspecified, node, sourceFile);
};
var withGetType = (schema, getType) => {
schema._def.getType = getType;
return schema;
};
var identifierRE = /^[$A-Z_a-z][\w$]*$/;
var getIdentifierOrStringLiteral = (string_) => {
if (identifierRE.test(string_)) {
return f.createIdentifier(string_);
}
return f.createStringLiteral(string_);
};
var addJsDocComment = (node, text) => {
_typescript2.default.addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `* ${text} `, true);
};
// src/index.ts
var { factory: f2, SyntaxKind: SyntaxKind2 } = _typescript2.default;
var callGetType = (zod, identifier, options) => {
let type;
if (zod._def.getType)
type = zod._def.getType(_typescript2.default, identifier, options);
return type;
};
var zodToTs = (zod, identifier, options) => {
const resolvedIdentifier = _nullishCoalesce(identifier, () => ( "Identifier"));
const resolvedOptions = resolveOptions(options);
const store = { nativeEnums: [] };
const node = zodToTsNode(zod, resolvedIdentifier, store, resolvedOptions);
return { node, store };
};
var zodToTsNode = (zod, identifier, store, options) => {
const typeName = zod._def.typeName;
const getTypeType = callGetType(zod, identifier, options);
if (getTypeType && typeName !== "ZodNativeEnum") {
return maybeIdentifierToTypeReference(getTypeType);
}
const otherArguments = [identifier, store, options];
switch (typeName) {
case "ZodString": {
return f2.createKeywordTypeNode(SyntaxKind2.StringKeyword);
}
case "ZodNumber": {
return f2.createKeywordTypeNode(SyntaxKind2.NumberKeyword);
}
case "ZodBigInt": {
return f2.createKeywordTypeNode(SyntaxKind2.BigIntKeyword);
}
case "ZodBoolean": {
return f2.createKeywordTypeNode(SyntaxKind2.BooleanKeyword);
}
case "ZodDate": {
return f2.createTypeReferenceNode(f2.createIdentifier("Date"));
}
case "ZodUndefined": {
return f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword);
}
case "ZodNull": {
return f2.createLiteralTypeNode(f2.createNull());
}
case "ZodVoid": {
return f2.createUnionTypeNode([
f2.createKeywordTypeNode(SyntaxKind2.VoidKeyword),
f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword)
]);
}
case "ZodAny": {
return f2.createKeywordTypeNode(SyntaxKind2.AnyKeyword);
}
case "ZodUnknown": {
return createUnknownKeywordNode();
}
case "ZodNever": {
return f2.createKeywordTypeNode(SyntaxKind2.NeverKeyword);
}
case "ZodLazy": {
if (!getTypeType)
return createTypeReferenceFromString(identifier);
break;
}
case "ZodLiteral": {
let literal;
const literalValue = zod._def.value;
switch (typeof literalValue) {
case "number": {
literal = f2.createNumericLiteral(literalValue);
break;
}
case "boolean": {
literal = literalValue === true ? f2.createTrue() : f2.createFalse();
break;
}
default: {
literal = f2.createStringLiteral(literalValue);
break;
}
}
return f2.createLiteralTypeNode(literal);
}
case "ZodObject": {
const properties = Object.entries(zod._def.shape());
const members = properties.map(([key, value]) => {
const nextZodNode = value;
const type = zodToTsNode(nextZodNode, ...otherArguments);
const { typeName: nextZodNodeTypeName } = nextZodNode._def;
const isOptional = nextZodNodeTypeName === "ZodOptional" || nextZodNode.isOptional();
const propertySignature = f2.createPropertySignature(
void 0,
getIdentifierOrStringLiteral(key),
isOptional ? f2.createToken(SyntaxKind2.QuestionToken) : void 0,
type
);
if (nextZodNode.description) {
addJsDocComment(propertySignature, nextZodNode.description);
}
return propertySignature;
});
return f2.createTypeLiteralNode(members);
}
case "ZodArray": {
const type = zodToTsNode(zod._def.type, ...otherArguments);
const node = f2.createArrayTypeNode(type);
return node;
}
case "ZodEnum": {
const types = zod._def.values.map((value) => f2.createLiteralTypeNode(f2.createStringLiteral(value)));
return f2.createUnionTypeNode(types);
}
case "ZodUnion": {
const options2 = zod._def.options;
const types = options2.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createUnionTypeNode(types);
}
case "ZodDiscriminatedUnion": {
const options2 = [...zod._def.options.values()];
const types = options2.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createUnionTypeNode(types);
}
case "ZodEffects": {
const node = zodToTsNode(zod._def.schema, ...otherArguments);
return node;
}
case "ZodNativeEnum": {
const type = getTypeType;
if (options.nativeEnums === "union") {
if (type)
return maybeIdentifierToTypeReference(type);
const types = Object.values(zod._def.values).map((value) => {
if (typeof value === "number") {
return f2.createLiteralTypeNode(f2.createNumericLiteral(value));
}
return f2.createLiteralTypeNode(f2.createStringLiteral(value));
});
return f2.createUnionTypeNode(types);
}
if (!type)
return createUnknownKeywordNode();
if (options.nativeEnums === "resolve") {
const enumMembers = Object.entries(zod._def.values).map(([key, value]) => {
const literal = typeof value === "number" ? f2.createNumericLiteral(value) : f2.createStringLiteral(value);
return f2.createEnumMember(
getIdentifierOrStringLiteral(key),
literal
);
});
if (_typescript2.default.isIdentifier(type)) {
store.nativeEnums.push(
f2.createEnumDeclaration(
void 0,
type,
enumMembers
)
);
} else {
throw new Error('getType on nativeEnum must return an identifier when nativeEnums is "resolve"');
}
}
return maybeIdentifierToTypeReference(type);
}
case "ZodOptional": {
const innerType = zodToTsNode(zod._def.innerType, ...otherArguments);
return f2.createUnionTypeNode([
innerType,
f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword)
]);
}
case "ZodNullable": {
const innerType = zodToTsNode(zod._def.innerType, ...otherArguments);
return f2.createUnionTypeNode([
innerType,
f2.createLiteralTypeNode(f2.createNull())
]);
}
case "ZodTuple": {
const types = zod._def.items.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createTupleTypeNode(types);
}
case "ZodRecord": {
const valueType = zodToTsNode(zod._def.valueType, ...otherArguments);
const node = f2.createTypeLiteralNode([f2.createIndexSignature(
void 0,
[f2.createParameterDeclaration(
void 0,
void 0,
f2.createIdentifier("x"),
void 0,
f2.createKeywordTypeNode(SyntaxKind2.StringKeyword)
)],
valueType
)]);
return node;
}
case "ZodMap": {
const valueType = zodToTsNode(zod._def.valueType, ...otherArguments);
const keyType = zodToTsNode(zod._def.keyType, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Map"),
[
keyType,
valueType
]
);
return node;
}
case "ZodSet": {
const type = zodToTsNode(zod._def.valueType, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Set"),
[type]
);
return node;
}
case "ZodIntersection": {
const left = zodToTsNode(zod._def.left, ...otherArguments);
const right = zodToTsNode(zod._def.right, ...otherArguments);
const node = f2.createIntersectionTypeNode([left, right]);
return node;
}
case "ZodPromise": {
const type = zodToTsNode(zod._def.type, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Promise"),
[type]
);
return node;
}
case "ZodFunction": {
const argumentTypes = zod._def.args._def.items.map((argument, index) => {
const argumentType = zodToTsNode(argument, ...otherArguments);
return f2.createParameterDeclaration(
void 0,
void 0,
f2.createIdentifier(`args_${index}`),
void 0,
argumentType
);
});
argumentTypes.push(
f2.createParameterDeclaration(
void 0,
f2.createToken(SyntaxKind2.DotDotDotToken),
f2.createIdentifier(`args_${argumentTypes.length}`),
void 0,
f2.createArrayTypeNode(createUnknownKeywordNode())
)
);
const returnType = zodToTsNode(zod._def.returns, ...otherArguments);
const node = f2.createFunctionTypeNode(
void 0,
argumentTypes,
returnType
);
return node;
}
case "ZodDefault": {
const type = zodToTsNode(zod._def.innerType, ...otherArguments);
const filteredNodes = [];
type.forEachChild((node) => {
if (![SyntaxKind2.UndefinedKeyword].includes(node.kind)) {
filteredNodes.push(node);
}
});
type.types = filteredNodes;
return type;
}
}
return f2.createKeywordTypeNode(SyntaxKind2.AnyKeyword);
};
exports.createTypeAlias = createTypeAlias; exports.printNode = printNode; exports.withGetType = withGetType; exports.zodToTs = zodToTs;

34
node_modules/zod-to-ts/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,34 @@
import { ZodTypeAny } from 'zod';
import ts from 'typescript';
type ZodToTsOptions = {
/** @deprecated use `nativeEnums` instead */
resolveNativeEnums?: boolean;
nativeEnums?: 'identifier' | 'resolve' | 'union';
};
declare const resolveOptions: (raw?: ZodToTsOptions) => {
resolveNativeEnums?: boolean | undefined;
nativeEnums: 'identifier' | 'resolve' | 'union';
};
type ResolvedZodToTsOptions = ReturnType<typeof resolveOptions>;
type ZodToTsStore = {
nativeEnums: ts.EnumDeclaration[];
};
type ZodToTsReturn = {
node: ts.TypeNode;
store: ZodToTsStore;
};
type GetTypeFunction = (typescript: typeof ts, identifier: string, options: ResolvedZodToTsOptions) => ts.Identifier | ts.TypeNode;
type GetType = {
_def: {
getType?: GetTypeFunction;
};
};
declare const createTypeAlias: (node: ts.TypeNode, identifier: string, comment?: string) => ts.TypeAliasDeclaration;
declare const printNode: (node: ts.Node, printerOptions?: ts.PrinterOptions) => string;
declare const withGetType: <T extends ZodTypeAny & GetType>(schema: T, getType: GetTypeFunction) => T;
declare const zodToTs: (zod: ZodTypeAny, identifier?: string, options?: ZodToTsOptions) => ZodToTsReturn;
export { GetType, ZodToTsOptions, createTypeAlias, printNode, withGetType, zodToTs };

332
node_modules/zod-to-ts/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,332 @@
// src/index.ts
import ts2 from "typescript";
// src/types.ts
var resolveOptions = (raw) => {
const resolved = {
nativeEnums: raw?.resolveNativeEnums ? "resolve" : "identifier"
};
return { ...resolved, ...raw };
};
// src/utils.ts
import ts from "typescript";
var { factory: f, SyntaxKind, ScriptKind, ScriptTarget, EmitHint } = ts;
var maybeIdentifierToTypeReference = (identifier) => {
if (ts.isIdentifier(identifier)) {
return f.createTypeReferenceNode(identifier);
}
return identifier;
};
var createTypeReferenceFromString = (identifier) => f.createTypeReferenceNode(f.createIdentifier(identifier));
var createUnknownKeywordNode = () => f.createKeywordTypeNode(SyntaxKind.UnknownKeyword);
var createTypeAlias = (node, identifier, comment) => {
const typeAlias = f.createTypeAliasDeclaration(
void 0,
f.createIdentifier(identifier),
void 0,
node
);
if (comment) {
addJsDocComment(typeAlias, comment);
}
return typeAlias;
};
var printNode = (node, printerOptions) => {
const sourceFile = ts.createSourceFile("print.ts", "", ScriptTarget.Latest, false, ScriptKind.TS);
const printer = ts.createPrinter(printerOptions);
return printer.printNode(EmitHint.Unspecified, node, sourceFile);
};
var withGetType = (schema, getType) => {
schema._def.getType = getType;
return schema;
};
var identifierRE = /^[$A-Z_a-z][\w$]*$/;
var getIdentifierOrStringLiteral = (string_) => {
if (identifierRE.test(string_)) {
return f.createIdentifier(string_);
}
return f.createStringLiteral(string_);
};
var addJsDocComment = (node, text) => {
ts.addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `* ${text} `, true);
};
// src/index.ts
var { factory: f2, SyntaxKind: SyntaxKind2 } = ts2;
var callGetType = (zod, identifier, options) => {
let type;
if (zod._def.getType)
type = zod._def.getType(ts2, identifier, options);
return type;
};
var zodToTs = (zod, identifier, options) => {
const resolvedIdentifier = identifier ?? "Identifier";
const resolvedOptions = resolveOptions(options);
const store = { nativeEnums: [] };
const node = zodToTsNode(zod, resolvedIdentifier, store, resolvedOptions);
return { node, store };
};
var zodToTsNode = (zod, identifier, store, options) => {
const typeName = zod._def.typeName;
const getTypeType = callGetType(zod, identifier, options);
if (getTypeType && typeName !== "ZodNativeEnum") {
return maybeIdentifierToTypeReference(getTypeType);
}
const otherArguments = [identifier, store, options];
switch (typeName) {
case "ZodString": {
return f2.createKeywordTypeNode(SyntaxKind2.StringKeyword);
}
case "ZodNumber": {
return f2.createKeywordTypeNode(SyntaxKind2.NumberKeyword);
}
case "ZodBigInt": {
return f2.createKeywordTypeNode(SyntaxKind2.BigIntKeyword);
}
case "ZodBoolean": {
return f2.createKeywordTypeNode(SyntaxKind2.BooleanKeyword);
}
case "ZodDate": {
return f2.createTypeReferenceNode(f2.createIdentifier("Date"));
}
case "ZodUndefined": {
return f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword);
}
case "ZodNull": {
return f2.createLiteralTypeNode(f2.createNull());
}
case "ZodVoid": {
return f2.createUnionTypeNode([
f2.createKeywordTypeNode(SyntaxKind2.VoidKeyword),
f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword)
]);
}
case "ZodAny": {
return f2.createKeywordTypeNode(SyntaxKind2.AnyKeyword);
}
case "ZodUnknown": {
return createUnknownKeywordNode();
}
case "ZodNever": {
return f2.createKeywordTypeNode(SyntaxKind2.NeverKeyword);
}
case "ZodLazy": {
if (!getTypeType)
return createTypeReferenceFromString(identifier);
break;
}
case "ZodLiteral": {
let literal;
const literalValue = zod._def.value;
switch (typeof literalValue) {
case "number": {
literal = f2.createNumericLiteral(literalValue);
break;
}
case "boolean": {
literal = literalValue === true ? f2.createTrue() : f2.createFalse();
break;
}
default: {
literal = f2.createStringLiteral(literalValue);
break;
}
}
return f2.createLiteralTypeNode(literal);
}
case "ZodObject": {
const properties = Object.entries(zod._def.shape());
const members = properties.map(([key, value]) => {
const nextZodNode = value;
const type = zodToTsNode(nextZodNode, ...otherArguments);
const { typeName: nextZodNodeTypeName } = nextZodNode._def;
const isOptional = nextZodNodeTypeName === "ZodOptional" || nextZodNode.isOptional();
const propertySignature = f2.createPropertySignature(
void 0,
getIdentifierOrStringLiteral(key),
isOptional ? f2.createToken(SyntaxKind2.QuestionToken) : void 0,
type
);
if (nextZodNode.description) {
addJsDocComment(propertySignature, nextZodNode.description);
}
return propertySignature;
});
return f2.createTypeLiteralNode(members);
}
case "ZodArray": {
const type = zodToTsNode(zod._def.type, ...otherArguments);
const node = f2.createArrayTypeNode(type);
return node;
}
case "ZodEnum": {
const types = zod._def.values.map((value) => f2.createLiteralTypeNode(f2.createStringLiteral(value)));
return f2.createUnionTypeNode(types);
}
case "ZodUnion": {
const options2 = zod._def.options;
const types = options2.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createUnionTypeNode(types);
}
case "ZodDiscriminatedUnion": {
const options2 = [...zod._def.options.values()];
const types = options2.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createUnionTypeNode(types);
}
case "ZodEffects": {
const node = zodToTsNode(zod._def.schema, ...otherArguments);
return node;
}
case "ZodNativeEnum": {
const type = getTypeType;
if (options.nativeEnums === "union") {
if (type)
return maybeIdentifierToTypeReference(type);
const types = Object.values(zod._def.values).map((value) => {
if (typeof value === "number") {
return f2.createLiteralTypeNode(f2.createNumericLiteral(value));
}
return f2.createLiteralTypeNode(f2.createStringLiteral(value));
});
return f2.createUnionTypeNode(types);
}
if (!type)
return createUnknownKeywordNode();
if (options.nativeEnums === "resolve") {
const enumMembers = Object.entries(zod._def.values).map(([key, value]) => {
const literal = typeof value === "number" ? f2.createNumericLiteral(value) : f2.createStringLiteral(value);
return f2.createEnumMember(
getIdentifierOrStringLiteral(key),
literal
);
});
if (ts2.isIdentifier(type)) {
store.nativeEnums.push(
f2.createEnumDeclaration(
void 0,
type,
enumMembers
)
);
} else {
throw new Error('getType on nativeEnum must return an identifier when nativeEnums is "resolve"');
}
}
return maybeIdentifierToTypeReference(type);
}
case "ZodOptional": {
const innerType = zodToTsNode(zod._def.innerType, ...otherArguments);
return f2.createUnionTypeNode([
innerType,
f2.createKeywordTypeNode(SyntaxKind2.UndefinedKeyword)
]);
}
case "ZodNullable": {
const innerType = zodToTsNode(zod._def.innerType, ...otherArguments);
return f2.createUnionTypeNode([
innerType,
f2.createLiteralTypeNode(f2.createNull())
]);
}
case "ZodTuple": {
const types = zod._def.items.map((option) => zodToTsNode(option, ...otherArguments));
return f2.createTupleTypeNode(types);
}
case "ZodRecord": {
const valueType = zodToTsNode(zod._def.valueType, ...otherArguments);
const node = f2.createTypeLiteralNode([f2.createIndexSignature(
void 0,
[f2.createParameterDeclaration(
void 0,
void 0,
f2.createIdentifier("x"),
void 0,
f2.createKeywordTypeNode(SyntaxKind2.StringKeyword)
)],
valueType
)]);
return node;
}
case "ZodMap": {
const valueType = zodToTsNode(zod._def.valueType, ...otherArguments);
const keyType = zodToTsNode(zod._def.keyType, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Map"),
[
keyType,
valueType
]
);
return node;
}
case "ZodSet": {
const type = zodToTsNode(zod._def.valueType, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Set"),
[type]
);
return node;
}
case "ZodIntersection": {
const left = zodToTsNode(zod._def.left, ...otherArguments);
const right = zodToTsNode(zod._def.right, ...otherArguments);
const node = f2.createIntersectionTypeNode([left, right]);
return node;
}
case "ZodPromise": {
const type = zodToTsNode(zod._def.type, ...otherArguments);
const node = f2.createTypeReferenceNode(
f2.createIdentifier("Promise"),
[type]
);
return node;
}
case "ZodFunction": {
const argumentTypes = zod._def.args._def.items.map((argument, index) => {
const argumentType = zodToTsNode(argument, ...otherArguments);
return f2.createParameterDeclaration(
void 0,
void 0,
f2.createIdentifier(`args_${index}`),
void 0,
argumentType
);
});
argumentTypes.push(
f2.createParameterDeclaration(
void 0,
f2.createToken(SyntaxKind2.DotDotDotToken),
f2.createIdentifier(`args_${argumentTypes.length}`),
void 0,
f2.createArrayTypeNode(createUnknownKeywordNode())
)
);
const returnType = zodToTsNode(zod._def.returns, ...otherArguments);
const node = f2.createFunctionTypeNode(
void 0,
argumentTypes,
returnType
);
return node;
}
case "ZodDefault": {
const type = zodToTsNode(zod._def.innerType, ...otherArguments);
const filteredNodes = [];
type.forEachChild((node) => {
if (![SyntaxKind2.UndefinedKeyword].includes(node.kind)) {
filteredNodes.push(node);
}
});
type.types = filteredNodes;
return type;
}
}
return f2.createKeywordTypeNode(SyntaxKind2.AnyKeyword);
};
export {
createTypeAlias,
printNode,
withGetType,
zodToTs
};

75
node_modules/zod-to-ts/package.json generated vendored Normal file
View File

@@ -0,0 +1,75 @@
{
"name": "zod-to-ts",
"version": "1.2.0",
"type": "module",
"description": "generate TypeScript types from your Zod schema",
"repository": {
"type": "git",
"url": "https://github.com/sachinraja/zod-to-ts.git"
},
"homepage": "https://github.com/sachinraja/zod-to-ts#readme",
"bugs": {
"url": "https://github.com/sachinraja/zod-to-ts/issues"
},
"main": "dist/index.cjs",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./dist/index.js",
"default": "./dist/index.cjs"
}
},
"types": "dist/index.d.ts",
"files": [
"dist"
],
"keywords": [
"zod",
"typescript",
"generator"
],
"peerDependencies": {
"typescript": "^4.9.4 || ^5.0.2",
"zod": "^3"
},
"devDependencies": {
"@sachinraja/eslint-config": "0.2.0",
"@types/node": "18.15.11",
"dprint": "0.35.3",
"eslint": "8.37.0",
"npm-run-all": "4.1.5",
"tsup": "6.7.0",
"tsx": "3.12.6",
"typescript": "5.0.3",
"vite": "4.2.1",
"vitest": "0.29.8",
"zod": "3.21.4"
},
"sideEffects": false,
"tsup": {
"entry": [
"src/index.ts"
],
"format": [
"esm",
"cjs"
],
"dts": {
"resolve": true
},
"splitting": true,
"clean": true
},
"packageManager": "pnpm@8.6.12",
"scripts": {
"build": "tsup",
"watch": "tsup --watch --no-dts",
"format": "dprint fmt",
"lint": "run-p lint:*",
"lint:format": "dprint check",
"lint:types": "tsc",
"lint:js": "eslint .",
"test": "vitest",
"example": "tsx test/example.ts"
}
}