import { TypeModelObject , TypeModel } from "ts-type-visitor" ; import ts from "typescript" ; export const createSuperStructDotStructPropAccess = ( ) => ts . createPropertyAccess ( ts . createIdentifier ( "superstruct" ) , "struct" ) ; export const createSuperStructDotSuperstructPropAccess = ( ) => ts . createPropertyAccess ( ts . createIdentifier ( "superstruct" ) , "superstruct" ) ; type SuperstructType = "any" | "arguments" | "array" | "boolean" | "buffer" | "date" | "error" | "function" | "generatorfunction" | "map" | "null" | "number" | "object" | "promise" | "regexp" | "set" | "string" | "symbol" | "undefined" | "weakmap" | "weakset" ; type SuperstructFunc = "array" | "enum" | "function" | "instance" | "interface" | "intersection" | "lazy" | "dynamic" | "literal" | "object" | "optional" | "pick" | "record" | "scalar" | "tuple" | "union" ; const createSuperstructObjectLiteralFromProps = ( { props , strictNullChecks } ) => ts . createObjectLiteral ( props . map ( prop => ts . createPropertyAssignment ( prop . name , createSuperStructValidatorForm ( prop , prop . optional , strictNullChecks ) ) ) , true ) ; const createSuperstructLiteral = ( { type : name } ) => ts . createStringLiteral ( name ) ; const wrapOptional = ( { exp , optional } ) => optional ? createSuperstructCall ( { func : "optional" , args : [ exp ] } ) : exp ; const wrapNonStrictNullChecks = ( { exp , strictNullChecks } ) => ! strictNullChecks ? createSuperstructCall ( { func : "union" , args : [ ts . createArrayLiteral ( [ createSuperstructLiteral ( { type : "null" } ) , exp ] ) ] } ) : exp ; const wrapOptionalOrNonStrictNullCheck = ( { exp , optional , strictNullChecks } ) => wrapOptional ( { exp : wrapNonStrictNullChecks ( { exp , strictNullChecks } ) , optional } ) ; const createSuperstructCall = ( { func , args } ) => ts . createCall ( ts . createPropertyAccess ( createSuperStructDotStructPropAccess ( ) , func ) , undefined , args ) ; export const createSuperStructValidatorForm = ( typeModel , optional , strictNullChecks , customValidators ? ) : ts . Expression => { const funcName = typeModel . originalType && customValidators ?. get ( typeModel . originalType ) ; if ( funcName ) { return ts . createStringLiteral ( funcName ) ; } switch ( typeModel . kind ) { case "any" : case "unknown" : case "esSymbol" : case "uniqueEsSymbol" : case "void" : case "never" : case "typeParameter" : case "bigintLiteral" : case "bigint" : case "bigintLiteral" : return createSuperstructLiteral ( { type : "any" } ) ; case "enum" : case "enumLiteral" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "union" , args : [ ts . createArrayLiteral ( typeModel . values . map ( t => createSuperStructValidatorForm ( t , false , strictNullChecks ) ) ) ] } ) , optional , strictNullChecks } ) ; case "string" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructLiteral ( { type : "string" } ) , optional , strictNullChecks } ) ; case "number" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructLiteral ( { type : "number" } ) , optional , strictNullChecks } ) ; case "boolean" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructLiteral ( { type : "boolean" } ) , optional , strictNullChecks } ) ; case "stringLiteral" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "literal" , args : [ ts . createLiteral ( typeModel . value ) ] } ) , optional , strictNullChecks } ) ; case "numberLiteral" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "literal" , args : [ ts . createLiteral ( typeModel . value ) ] } ) , optional , strictNullChecks } ) ; case "booleanLiteral" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "literal" , args : [ ts . createLiteral ( typeModel . value ) ] } ) , optional , strictNullChecks } ) ; case "undefined" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructLiteral ( { type : "undefined" } ) , optional , strictNullChecks } ) ; case "null" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructLiteral ( { type : "null" } ) , optional , strictNullChecks } ) ; case "objectWithIndex" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "intersection" , args : [ ts . createArrayLiteral ( [ createSuperstructCall ( { func : "interface" , args : [ createSuperstructObjectLiteralFromProps ( { props : typeModel . props , strictNullChecks } ) ] } ) , createSuperStructValidatorForm ( typeModel . index , false , strictNullChecks ) ] ) ] } ) , optional , strictNullChecks } ) ; case "object" : { return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructObjectLiteralFromProps ( { props : typeModel . props , strictNullChecks } ) , optional , strictNullChecks } ) ; } case "union" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "union" , args : [ ts . createArrayLiteral ( typeModel . types . map ( t => createSuperStructValidatorForm ( t , false , strictNullChecks ) ) ) ] } ) , optional , strictNullChecks } ) ; case "index" : if ( typeModel . keyType . kind === "number" ) { return createSuperstructLiteral ( { type : "any" } ) ; } else { return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "record" , args : [ ts . createArrayLiteral ( [ createSuperStructValidatorForm ( typeModel . keyType , false , true ) , createSuperStructValidatorForm ( typeModel . valueType , false , strictNullChecks ) ] ) ] } ) , optional , strictNullChecks } ) ; } case "intersection" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "intersection" , args : [ ts . createArrayLiteral ( typeModel . types . map ( t => createSuperStructValidatorForm ( t , false , strictNullChecks ) ) ) ] } ) , optional , strictNullChecks } ) ; case "indexedAccess" : throw new Error ( "implement indexedAccess superstruct" ) ; case "conditional" : throw new Error ( "implement conditional superstruct" ) ; case "substitution" : throw new Error ( "implement substitution superstruct" ) ; case "nonPrimitive" : throw new Error ( "implement nonPrimitive superstruct" ) ; case "unidentified" : return ts . createStringLiteral ( "any" ) ; case "array" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "array" , args : [ ts . createArrayLiteral ( [ createSuperStructValidatorForm ( typeModel . type , false , strictNullChecks ) ] ) ] } ) , optional , strictNullChecks } ) ; case "tuple" : return wrapOptionalOrNonStrictNullCheck ( { exp : createSuperstructCall ( { func : "tuple" , args : [ ts . createArrayLiteral ( typeModel . types . map ( t => createSuperStructValidatorForm ( t , false , strictNullChecks ) ) ) ] } ) , optional , strictNullChecks } ) ; } const _exhaustiveCheck = typeModel ; } ;