Files

333 lines
12 KiB
JavaScript

"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;