type-predicates-generator
Version:
Predicate and assert functions generator from type definitions.
1 lines • 56.4 kB
Source Map (JSON)
{"version":3,"sources":["../src/cli.ts","../src/generate/index.ts","../src/compiler-api/compiler-api-handler.ts","../src/type-object.ts","../src/utils.ts","../src/compiler-api/adaptor.ts","../src/compiler-api/program.ts","../src/generate/generate-type-predicates.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { resolve } from \"path\"\nimport { Command } from \"commander\"\nimport type { ArrayCheckOption } from \"./generate/index\"\nimport { run } from \"./generate/index\"\n\nconst program = new Command()\nprogram\n .option(\n \"-p, --project <type>\",\n \"Path for project tsconfig.json\",\n \"tsconfig.json\"\n )\n .option(\"-f, --file-glob <type>\", \"file glob pattern target types\", \"**/*.ts\")\n .option(\"-o, --output <type>\", \"output file path\", \"type-predicates.ts\")\n .option(\"-b, --base-path <type>\", \"project base path\", \"./\")\n .option(\"-a, --asserts\", \"generate assert functions or not\", false)\n .option(\"-w, --watch\", \"watch or not\", false)\n .option(\n \"--default-array-check-option\",\n \"how to check child element type. 'all' or 'first'\",\n \"all\"\n )\n .option(\"-c, --comment\", \"generate JSDoc comments or not\", false)\n .option(\"--whitelist\", \"not allow non listed properties\")\n .parse(process.argv)\n\nconst option = program.opts<{\n project: string\n fileGlob: string\n output: string\n basePath: string\n asserts: boolean\n watch: boolean\n defaultArrayCheckOption: ArrayCheckOption\n comment: boolean\n whitelist: boolean\n}>()\n\nconst cwd = process.cwd()\n\nrun({\n tsconfigPath: resolve(cwd, option.project),\n fileGlobs: [option.fileGlob],\n output: resolve(cwd, option.output),\n basePath: resolve(cwd, option.basePath),\n option: {\n asserts: option.asserts,\n watch: option.watch,\n defaultArrayCheckOption: option.defaultArrayCheckOption,\n comment: option.comment,\n whitelist: option.whitelist,\n },\n})\n","import { writeFileSync } from \"fs\"\nimport { resolve, relative } from \"path\"\nimport * as glob from \"glob\"\nimport { WatchFileKind } from \"typescript\"\nimport type * as to from \"../type-object\"\nimport type * as ts from \"typescript\"\nimport { CompilerApiHandler } from \"../compiler-api/compiler-api-handler\"\nimport { createProgram, watchCompiler } from \"../compiler-api/program\"\nimport { generateTypePredicates } from \"../generate/generate-type-predicates\"\nimport { isNg } from \"../utils\"\n\nexport type ArrayCheckOption = \"all\" | \"first\"\n\ntype GenerateOption = {\n asserts: boolean\n watch: boolean\n defaultArrayCheckOption: ArrayCheckOption\n comment: boolean\n whitelist: boolean\n}\n\nexport async function run({\n tsconfigPath,\n fileGlobs,\n output,\n basePath,\n option,\n}: {\n tsconfigPath: string\n fileGlobs: string[]\n output: string\n basePath: string\n option: GenerateOption\n}) {\n const files = fileGlobs\n .flatMap((fileGlob) =>\n glob.sync(fileGlob, {\n sync: true,\n cwd: basePath,\n ignore: [\"**/node_modules/**/*\", output],\n })\n )\n .map((filePath) => resolve(basePath, filePath))\n .filter((filePath) => filePath !== output)\n\n let program: ts.Program\n if (option.watch) {\n let onUpdate: (() => void) | undefined = undefined\n const watcher = watchCompiler(\n tsconfigPath,\n files,\n () => {\n if (onUpdate) {\n onUpdate()\n }\n },\n {\n watchFile: WatchFileKind.UseFsEvents,\n excludeFiles: [output],\n },\n // デフォルトのメソッドを打ち消すため\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n () => {},\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n () => {}\n )\n\n onUpdate = () => {\n const updatedProgram = watcher.getProgram().getProgram()\n generateAndWriteCodes(updatedProgram, files, output, option)\n\n console.log(\"File changes are detected, and successfully regenerated.\")\n }\n program = watcher.getProgram().getProgram()\n\n console.log(\"start watching ...\")\n } else {\n program = createProgram(tsconfigPath)\n }\n\n generateAndWriteCodes(program, files, output, option)\n console.log(`successfully generated: ${output}`)\n}\n\ntype ExtractFileTypesResult = {\n importPath: string\n types: {\n typeName: string\n type: to.TypeObject\n }[]\n}\n\nconst generateAndWriteCodes = (\n program: ts.Program,\n files: string[],\n output: string,\n { asserts, defaultArrayCheckOption, comment, whitelist }: GenerateOption\n) => {\n const handler = new CompilerApiHandler(program)\n\n const types = files.flatMap((filePath): ExtractFileTypesResult[] => {\n const result = handler.extractTypes(filePath)\n const importPath =\n \"./\" +\n relative(resolve(output, \"..\"), filePath)\n .replace(\".d.ts\", \"\")\n .replace(\".ts\", \"\")\n\n if (isNg(result)) {\n console.warn(\n `Failed to extract types from ${filePath} for reason ${result.ng.reason}`\n )\n return []\n }\n\n return [\n {\n importPath,\n types: result.ok.filter(\n (\n type\n ): type is {\n typeName: string\n type: to.TypeObject\n } => typeof type.typeName === \"string\"\n ),\n },\n ]\n })\n\n const generatedCode = generateTypePredicates(\n types,\n asserts,\n defaultArrayCheckOption,\n comment,\n whitelist\n )\n writeFileSync(output, generatedCode)\n}\n","import * as ts from \"typescript\"\nimport { forEachChild, unescapeLeadingUnderscores } from \"typescript\"\nimport type * as to from \"../type-object\"\nimport type { Result } from \"../utils\"\nimport { primitive, special, skip } from \"../type-object\"\nimport { isNg } from \"../utils\"\nimport { ok, ng, switchExpression, isOk } from \"../utils\"\nimport { NodeAdaptor, TypeAdaptor } from \"./adaptor\"\n\nexport class CompilerApiHandler {\n #program: ts.Program\n #typeChecker: ts.TypeChecker\n\n constructor(program: ts.Program) {\n this.#program = program\n this.#typeChecker = this.#program.getTypeChecker()\n }\n\n public extractTypes(filePath: string): Result<\n { typeName: string | undefined; type: to.TypeObject }[],\n | { reason: \"fileNotFound\" }\n | {\n reason: \"exportError\"\n meta:\n | \"fileNotFound\"\n | \"resolvedModulesNotFound\"\n | \"moduleNotFound\"\n | \"moduleFileNotFound\"\n | \"notNamedExport\"\n | \"unknown\"\n }\n > {\n const sourceFile = this.#program.getSourceFile(filePath)\n\n if (!sourceFile) {\n return ng({\n reason: \"fileNotFound\",\n })\n }\n\n const nodes = this.#extractNodes(sourceFile)\n .filter(\n (\n node\n ): node is\n | ts.TypeAliasDeclaration\n | ts.InterfaceDeclaration\n | ts.EnumDeclaration\n | ts.ExportDeclaration =>\n ts.isExportDeclaration(node) ||\n ts.isEnumDeclaration(node) ||\n ((ts.isInterfaceDeclaration(node) ||\n ts.isTypeAliasDeclaration(node)) &&\n // @ts-expect-error exclude not exported type def\n typeof node?.localSymbol !== \"undefined\")\n )\n .filter((node) =>\n this.#isTypeParametersResolved(\n this.#typeChecker.getTypeAtLocation(node)\n )\n )\n\n return ok(\n nodes\n .map((node) => new NodeAdaptor(node))\n .flatMap((node) => {\n // export {} from 'path'\n if (ts.isExportDeclaration(node.base)) {\n const nodes = this.#extractTypesFromExportDeclaration(node.base)\n if (isOk(nodes)) {\n return nodes.ok\n } else {\n return ng({\n reason: \"exportError\" as const,\n meta: nodes.ng.reason,\n })\n }\n }\n\n // export declaration\n return {\n typeName:\n typeof node?.symbol?.escapedName !== \"undefined\"\n ? String(node?.symbol?.escapedName)\n : undefined,\n type: this.#convertType(\n this.#typeChecker.getTypeAtLocation(node.base)\n ),\n }\n })\n .filter(\n (\n result\n ): result is {\n typeName: string | undefined\n type: to.TypeObject\n } => {\n if (\"__type\" in result && isNg(result)) {\n console.log(`Skip reason: ${result.ng.meta}`)\n return false\n }\n\n return true\n }\n )\n )\n }\n\n // Only support named-export\n #extractTypesFromExportDeclaration(declare: ts.ExportDeclaration): Result<\n { typeName: string | undefined; type: to.TypeObject }[],\n {\n reason:\n | \"fileNotFound\"\n | \"resolvedModulesNotFound\"\n | \"moduleNotFound\"\n | \"moduleFileNotFound\"\n | \"notNamedExport\"\n | \"unknown\"\n }\n > {\n const path = declare.moduleSpecifier?.getText()\n if (!path)\n return ng({\n reason: \"fileNotFound\",\n })\n\n const sourceFile = declare.getSourceFile()\n const moduleMap =\n // @ts-expect-error: type def wrong\n sourceFile.resolvedModules as\n | ts.UnderscoreEscapedMap<ts.ResolvedModule>\n | undefined\n\n if (!moduleMap)\n return ng({\n reason: \"resolvedModulesNotFound\",\n })\n\n const module = moduleMap.get(\n ts.escapeLeadingUnderscores(path.replace(/'/g, \"\").replace(/\"/g, \"\"))\n )\n\n if (!module)\n return ng({\n reason: \"moduleNotFound\",\n })\n\n const types = this.extractTypes(module.resolvedFileName)\n if (isNg(types)) return ng({ reason: \"moduleFileNotFound\" })\n\n const clause = declare.exportClause\n if (!clause)\n return ng({\n reason: \"unknown\",\n })\n\n if (ts.isNamedExports(clause)) {\n return ok(\n clause.elements\n .map((node) => new NodeAdaptor(node))\n .map(({ symbol }) => symbol?.getEscapedName())\n .filter((str): str is ts.__String => typeof str !== \"undefined\")\n .map((str) => ts.unescapeLeadingUnderscores(str))\n .map(\n (key) =>\n types.ok.find(({ typeName }) => typeName === key) ?? {\n typeName: key,\n type: skip(),\n }\n )\n )\n }\n\n return ng({\n reason: \"notNamedExport\",\n })\n }\n\n #extractNodes(sourceFile: ts.SourceFile): ts.Node[] {\n const nodes: ts.Node[] = []\n forEachChild(sourceFile, (node) => {\n nodes.push(node)\n })\n\n return nodes\n }\n\n #createObjectType(tsType: ts.Type): to.ObjectTO {\n return {\n __type: \"ObjectTO\",\n tsType,\n typeName: this.#typeToString(tsType),\n getProps: () =>\n this.#typeChecker\n .getPropertiesOfType(tsType)\n .map(\n (\n symbol\n ): {\n propName: string\n type: to.TypeObject\n } => {\n const declare = (symbol.declarations ?? [])[0]\n const type = declare\n ? this.#typeChecker.getTypeOfSymbolAtLocation(symbol, declare)\n : undefined\n\n return {\n propName: String(symbol.escapedName),\n type: type\n ? this.#isCallable(type)\n ? skip()\n : this.#convertType(type)\n : {\n __type: \"UnknownTO\",\n kind: \"prop\",\n },\n }\n }\n )\n .filter((typeObject) => typeObject.type.__type !== \"SkipTO\"),\n }\n }\n\n #extractArrayTFromTypeNode(typeNode: ts.ArrayTypeNode): to.TypeObject {\n return this.#convertType(\n this.#typeChecker.getTypeAtLocation(typeNode.elementType)\n )\n }\n\n #extractArrayT(\n rawType: ts.Type\n ): Result<\n to.TypeObject,\n { reason: \"node_not_defined\" | \"not_array_type_node\" | \"cannot_resolve\" }\n > {\n const type = new TypeAdaptor(rawType)\n const maybeArrayT = (type.resolvedTypeArguments ?? [])[0]\n if (\n type.base.symbol.getEscapedName() === \"Array\" &&\n typeof maybeArrayT !== \"undefined\"\n ) {\n return ok(this.#convertType(maybeArrayT))\n }\n\n const maybeNode = type?.node\n if (!maybeNode) {\n return ng({\n reason: \"node_not_defined\",\n })\n }\n\n // Array<T> で定義されているとき\n if (ts.isTypeReferenceNode(maybeNode)) {\n const [typeArg1] = this.#extractTypeArgumentsFromTypeRefNode(maybeNode)\n\n return typeof typeArg1 !== \"undefined\"\n ? ok(typeArg1)\n : ng({\n reason: \"cannot_resolve\",\n })\n }\n\n if (!ts.isArrayTypeNode(maybeNode)) {\n return ng({\n reason: \"not_array_type_node\",\n })\n }\n\n return ok(this.#extractArrayTFromTypeNode(maybeNode))\n }\n\n #extractTypeArgumentsFromTypeRefNode(\n node: ts.TypeReferenceNode\n ): to.TypeObject[] {\n return Array.from(node.typeArguments ?? []).map((arg) =>\n this.#convertType(this.#typeChecker.getTypeFromTypeNode(arg))\n )\n }\n\n #hasUnresolvedTypeParameter(type: to.TypeObject): boolean {\n if (!(\"typeName\" in type)) {\n return type.__type === \"TypeParameterTO\"\n }\n\n const deps: to.TypeObject[] =\n type.__type === \"ObjectTO\"\n ? type.getProps().map((prop) => prop.type)\n : type.__type === \"ArrayTO\"\n ? [type.child]\n : type.__type === \"UnionTO\"\n ? type.unions\n : []\n\n return deps.reduce(\n (s: boolean, t: to.TypeObject) =>\n s ||\n t.__type === \"TypeParameterTO\" ||\n (\"typeName\" in t &&\n t.typeName !== type.typeName &&\n this.#hasUnresolvedTypeParameter(t)),\n false\n )\n }\n\n #convertType(rawType: ts.Type): to.TypeObject {\n const type = new TypeAdaptor(rawType)\n\n return switchExpression({\n type,\n typeNode: type.node,\n typeText: this.#typeToString(type.base),\n })\n .case<to.UnionTO>(\n ({ type }) => type.base.isUnion(),\n ({ typeText }) => ({\n __type: \"UnionTO\",\n typeName: typeText,\n unions: (type?.types ?? []).map((type) => this.#convertType(type)),\n })\n )\n .case<to.TypeParameterTO>(\n ({ type }) => type.base.isTypeParameter(),\n ({ typeText }) => ({\n __type: \"TypeParameterTO\",\n name: typeText,\n })\n )\n .case<to.TupleTO, { typeNode: ts.TupleTypeNode }>(\n ({ typeNode }) =>\n typeof typeNode !== \"undefined\" && ts.isTupleTypeNode(typeNode),\n ({ typeText, typeNode }) => ({\n __type: \"TupleTO\",\n typeName: typeText,\n items: typeNode.elements.map((typeNode) =>\n this.#convertType(this.#typeChecker.getTypeFromTypeNode(typeNode))\n ),\n })\n )\n .case<to.LiteralTO>(\n ({ type }) => type.base.isLiteral(),\n ({ type }) => ({\n __type: \"LiteralTO\",\n value: type.value,\n })\n )\n .case<to.LiteralTO>(\n ({ typeText }) => [\"true\", \"false\"].includes(typeText),\n ({ typeText }) => ({\n __type: \"LiteralTO\",\n value: typeText === \"true\" ? true : false,\n })\n )\n .case<to.PrimitiveTO>(\n ({ typeText }) => typeText === \"string\",\n () => primitive(\"string\")\n )\n .case<to.PrimitiveTO>(\n ({ typeText }) => typeText === \"number\",\n () => primitive(\"number\")\n )\n .case<to.PrimitiveTO>(\n ({ typeText }) => typeText === \"bigint\",\n () => primitive(\"bigint\")\n )\n .case<to.PrimitiveTO>(\n ({ typeText }) => typeText === \"boolean\",\n () => primitive(\"boolean\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"null\",\n () => special(\"null\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"undefined\",\n () => special(\"undefined\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"void\",\n () => special(\"void\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"any\",\n () => special(\"any\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"unknown\",\n () => special(\"unknown\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"never\",\n () => special(\"never\")\n )\n .case<to.SpecialTO>(\n ({ typeText }) => typeText === \"Date\",\n () => special(\"Date\")\n )\n .case<to.ArrayTO>(\n ({ type, typeText }) =>\n typeText.endsWith(\"[]\") || type.base.symbol?.escapedName === \"Array\",\n ({ type, typeText }) => ({\n __type: \"ArrayTO\",\n typeName: typeText,\n child: (() => {\n const resultT = this.#extractArrayT(type.base)\n return isOk(resultT)\n ? resultT.ok\n : ({ __type: \"UnknownTO\", kind: \"arrayT\" } as const)\n })(),\n })\n )\n .case<to.ObjectTO>(\n ({ type }) =>\n this.#typeChecker.getPropertiesOfType(type.base).length !== 0,\n ({ type }) => this.#createObjectType(type.base)\n )\n .default<to.UnknownTO>(({ typeText }) => ({\n __type: \"UnknownTO\",\n kind: \"convert\",\n typeText,\n }))\n }\n\n #isCallable(type: ts.Type): boolean {\n return (\n this.#getMembers(type).findIndex(\n (member) =>\n unescapeLeadingUnderscores(member.getEscapedName()) === \"__call\"\n ) >= 0\n )\n }\n\n #getMembers(type: ts.Type): ts.Symbol[] {\n const members: ts.Symbol[] = []\n\n type.getSymbol()?.members?.forEach((memberSymbol) => {\n members.push(memberSymbol)\n })\n\n return members\n }\n\n #isTypeParametersResolved(type: ts.Type): boolean {\n return (\n (type.aliasTypeArguments ?? []).length === 0 ||\n // @ts-expect-error: wrong type def\n type.typeParameter !== undefined\n )\n }\n\n #typeToString(type: ts.Type) {\n return this.#typeChecker.typeToString(type).replace(\"typeof \", \"\")\n }\n}\n","import type * as ts from \"typescript\"\n\nexport type TypeObject =\n | PrimitiveTO\n | LiteralTO\n | SpecialTO\n | ArrayTO\n | TupleTO\n | ObjectTO\n | UnionTO\n | EnumTO\n | TypeParameterTO\n | UnknownTO\n | SkipTO\n\ntype TypeNameTrait = {\n typeName: string\n}\n\nexport type PrimitiveTO = {\n __type: \"PrimitiveTO\"\n kind: \"string\" | \"number\" | \"bigint\" | \"boolean\"\n}\n\nexport type SpecialTO = {\n __type: \"SpecialTO\"\n kind: \"null\" | \"undefined\" | \"any\" | \"unknown\" | \"never\" | \"void\" | \"Date\"\n}\n\nexport type LiteralTO = {\n __type: \"LiteralTO\"\n value: unknown\n}\n\nexport type ArrayTO = TypeNameTrait & {\n __type: \"ArrayTO\"\n child: TypeObject\n}\n\nexport type TupleTO = TypeNameTrait & {\n __type: \"TupleTO\"\n items: TypeObject[]\n}\n\nexport type ObjectTO = TypeNameTrait & {\n __type: \"ObjectTO\"\n tsType: ts.Type // 再帰型を後から解決するため\n getProps: () => {\n propName: string\n type: TypeObject\n }[]\n}\n\nexport type UnionTO = TypeNameTrait & {\n __type: \"UnionTO\"\n unions: TypeObject[]\n}\n\n// Unresolved Type Parameter\nexport type TypeParameterTO = {\n __type: \"TypeParameterTO\"\n name: string\n}\n\nexport type EnumTO = TypeNameTrait & {\n __type: \"EnumTO\"\n enums: {\n name: string\n type: LiteralTO\n }[]\n}\n\n// サポートしてない型(スキップする)\nexport type SkipTO = {\n __type: \"SkipTO\"\n}\n\n// 分岐を抜けた未知の型\nexport type UnknownTO = {\n __type: \"UnknownTO\"\n kind: \"arrayT\" | \"prop\" | \"convert\"\n typeText?: string\n}\n\nexport function primitive(kind: PrimitiveTO[\"kind\"]): PrimitiveTO {\n return {\n __type: \"PrimitiveTO\",\n kind,\n }\n}\n\nexport function special(kind: SpecialTO[\"kind\"]): SpecialTO {\n return {\n __type: \"SpecialTO\",\n kind,\n }\n}\n\nexport function skip(): SkipTO {\n return {\n __type: \"SkipTO\",\n }\n}\n","export type Result<S, T> = ResultOk<S> | ResultNg<T>\nexport type ResultOk<T> = {\n __type: \"ok\"\n ok: T\n}\nexport type ResultNg<T> = {\n __type: \"ng\"\n ng: T\n}\n\nexport function isOk<T, E>(result: Result<T, E>): result is ResultOk<T> {\n return result.__type === \"ok\"\n}\n\nexport function isNg<T, E>(result: Result<T, E>): result is ResultNg<E> {\n return result.__type === \"ng\"\n}\n\nexport function ok<T>(value: T): ResultOk<T> {\n return {\n __type: \"ok\",\n ok: value,\n }\n}\n\nexport function ng<T>(value: T): ResultNg<T> {\n return {\n __type: \"ng\",\n ng: value,\n }\n}\n\ntype IsMatch<T> = (target: T) => boolean\ntype SwitchResolve<Arg, R> = (arg: Arg) => R\n\ntype SwitchResult<T, R> = {\n case: <\n CaseR,\n // eslint-disable-next-line @typescript-eslint/ban-types\n Predicate = {},\n Resolved = Omit<T, keyof Predicate> & Predicate\n >(\n isMatch: (target: T) => boolean,\n resolve: SwitchResolve<Resolved, CaseR>\n ) => SwitchResult<T, R | CaseR>\n default: <Default>(resolve: SwitchResolve<T, Default>) => R | Default\n resolved: R | undefined\n}\n\nconst toResult = <T, R, ExtractT = T>(\n target: T,\n isParentMatch: IsMatch<T>,\n resolveParent: SwitchResolve<ExtractT, R>,\n parentResolved: R | undefined\n): SwitchResult<T, R> => {\n const resolved =\n typeof parentResolved === \"undefined\"\n ? isParentMatch(target)\n ? resolveParent(target as unknown as ExtractT)\n : undefined\n : parentResolved\n\n return {\n resolved,\n default: <Default>(resolveDefault: (arg: T) => Default): R | Default =>\n resolved ?? resolveDefault(target),\n case: <\n CaseR,\n Predicate extends {\n [K in keyof T]?: T[K]\n // eslint-disable-next-line @typescript-eslint/ban-types\n } = {},\n Resolved = Omit<T, keyof Predicate> & Predicate\n >(\n isMatch: (target: T) => boolean,\n resolve: SwitchResolve<Resolved, CaseR>\n ): SwitchResult<T, R | CaseR> =>\n toResult<T, R | CaseR, Resolved>(target, isMatch, resolve, resolved),\n }\n}\n\nexport const switchExpression = <T>(target: T): SwitchResult<T, never> => {\n return {\n resolved: undefined,\n default: <Default>(resolveDefault: (arg: T) => Default): Default =>\n resolveDefault(target),\n case: <\n CaseR,\n // eslint-disable-next-line @typescript-eslint/ban-types\n Predicate = {},\n Resolved = Omit<T, keyof Predicate> & Predicate\n >(\n isMatch: IsMatch<T>,\n resolve: SwitchResolve<Resolved, CaseR>\n ): SwitchResult<T, CaseR> =>\n toResult<T, CaseR, Resolved>(target, isMatch, resolve, undefined),\n }\n}\n","import type * as ts from \"typescript\"\n\n/**\n * There are some properties that do not grow in the compiler API interface but do in reality.\n * This is the Adaptor layer to use these.\n * Since type checking is broken, it is necessary to check the implementation, especially when the version is upgraded.\n */\n\nexport class NodeAdaptor<T extends ts.Node> {\n public constructor(public readonly base: T) {}\n\n public get type(): ts.TypeNode | undefined {\n return \"type\" in this.base ? (this.base.type as ts.TypeNode) : undefined\n }\n public get symbol(): ts.Symbol | undefined {\n return \"symbol\" in this.base ? (this.base.symbol as ts.Symbol) : undefined\n }\n}\n\nexport class TypeAdaptor<T extends ts.Type> {\n public constructor(public readonly base: T) {}\n\n public get types(): ts.Type[] {\n return \"types\" in this.base ? (this.base.types as ts.Type[]) : []\n }\n\n public get resolvedTypeArguments(): ts.Type[] {\n return \"resolvedTypeArguments\" in this.base\n ? (this.base.resolvedTypeArguments as ts.Type[])\n : []\n }\n\n public get value(): unknown {\n return \"value\" in this.base ? this.base.value : undefined\n }\n\n public get node(): ts.Node | undefined {\n return \"node\" in this.base ? (this.base.node as ts.Node) : undefined\n }\n}\n","import { resolve } from \"path\"\nimport {\n sys,\n readConfigFile,\n parseJsonConfigFileContent,\n createProgram as baseCreateProgram,\n createWatchProgram,\n createWatchCompilerHost,\n createEmitAndSemanticDiagnosticsBuilderProgram,\n} from \"typescript\"\nimport type * as ts from \"typescript\"\n\nexport const createProgram = (tsConfigPath: string): ts.Program => {\n const configFile = readConfigFile(tsConfigPath, sys.readFile)\n if (typeof configFile.error !== \"undefined\") {\n throw new Error(`Failed to load tsconfig: ${configFile.error}`)\n }\n\n const { options, fileNames } = parseJsonConfigFileContent(\n configFile.config,\n {\n fileExists: sys.fileExists,\n readFile: sys.readFile,\n readDirectory: sys.readDirectory,\n useCaseSensitiveFileNames: true,\n },\n resolve(tsConfigPath, \"..\")\n )\n\n return baseCreateProgram({\n rootNames: fileNames,\n options,\n })\n}\n\n// const watcher = watchCompiler(...)\n// watcher.getProgram().getProgram() => ts.Program\n// watch しなくて良いときは createProgram から\nexport function watchCompiler(\n tsConfigPath: string,\n watchFiles: string[] = [],\n onFileChanged: ts.FileWatcherCallback,\n watchOption?: ts.WatchOptions,\n reportDiagnostic?: ts.DiagnosticReporter,\n reportWatchStatus?: ts.WatchStatusReporter\n): ts.WatchOfConfigFile<ts.EmitAndSemanticDiagnosticsBuilderProgram> {\n const createProgram = createEmitAndSemanticDiagnosticsBuilderProgram\n const host = createWatchCompilerHost(\n tsConfigPath,\n {\n noEmit: true,\n },\n sys,\n createProgram,\n reportDiagnostic,\n reportWatchStatus,\n watchOption\n )\n watchFiles.forEach((file) => {\n host.watchFile(file, onFileChanged)\n })\n return createWatchProgram(host)\n}\n","import { uniq } from \"ramda\"\nimport type { ArrayCheckOption } from \"./index\"\nimport type * as to from \"../type-object\"\n\nconst primitiveTypePredicateNameMap = {\n string: \"isString\",\n number: \"isNumber\",\n bigint: \"isBigint\",\n boolean: \"isBoolean\",\n}\n\nconst specialTypePredicateNameMap = {\n null: \"isNull\",\n undefined: \"isUndefined\",\n any: \"isAny\",\n unknown: \"isUnknown\",\n never: \"isNever\",\n void: \"isVoid\",\n Date: \"isDate\",\n}\n\nconst reservedNames = [\n \"String\",\n \"Number\",\n \"Bigint\",\n \"Boolean\",\n \"Null\",\n \"Undefined\",\n \"Any\",\n \"Unknown\",\n \"Never\",\n \"Void\",\n \"Date\",\n \"Object\",\n \"Array\",\n \"Union\",\n]\n\nconst primitiveTypePredicateMap = {\n string:\n \"const isString = (value: unknown): value is string => typeof value === 'string';\",\n number:\n \"const isNumber = (value: unknown): value is number => typeof value === 'number';\",\n bigint:\n \"const isBigint = (value: unknown): value is bigint => typeof value === 'bigint';\",\n boolean:\n \"const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';\",\n}\n\nconst specialTypePredicateMap = {\n null: \"const isNull = (value: unknown): value is null => value === null;\",\n undefined:\n \"const isUndefined = (value: unknown): value is undefined => typeof value === 'undefined';\",\n any: \"const isAny = (value: unknown): value is any => true;\",\n unknown: \"const isUnknown = (value: unknown): value is unknown => true;\",\n never: \"const isNever = (value: unknown): value is never => false;\",\n void: \"const isVoid = (value: unknown): value is void => false;\",\n Date: `const isDate = (value: unknown): value is Date =>\n value instanceof Date || Object.prototype.toString.call(value) === '[Object Date]'`,\n}\n\nconst utilTypePredicateMap = {\n object: `const isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);`,\n array: (option: ArrayCheckOption) =>\n `type ArrayCheckOption = 'all' | 'first';\\n` +\n `const isArray = <T>(\n childCheckFn:\n | ((value: unknown) => value is T)\n | ((value: unknown) => boolean),\n checkOption: ArrayCheckOption = '${option}'\n) => (array: unknown): boolean =>\n Array.isArray(array) &&\n (checkOption === 'all'\n ? ((array) => {\n for (const val of array) {\n if (!childCheckFn(val)) return false\n }\n return true;\n })(array)\n : typeof array[0] === \"undefined\" || childCheckFn(array[0]));`,\n union: `const isUnion = (unionChecks: ((value: unknown) => boolean)[]) =>\n (value: unknown): boolean =>\n unionChecks.reduce((s: boolean, isT) => s || isT(value), false)`,\n hasNotUnlistedProperties: `const hasNotUnlistedProperties = (listedKeys: string[]) =>\n (value: Record<string, unknown>): boolean =>\n Object.keys(value).every(key => listedKeys.includes(key))`,\n}\n\nfunction isPossibleUseTypeName(\n value: to.TypeObject\n): value is to.ArrayTO | to.ObjectTO | to.UnionTO {\n return [\"ArrayTO\", \"ObjectTO\", \"UnionTO\"].includes(value.__type)\n}\n\nfunction generateDeclare(\n argName: string,\n typeName?: string,\n additionalArgs: { name: string; type: string }[] = []\n) {\n return `(${argName}: unknown${\n additionalArgs.length !== 0\n ? \", \" +\n additionalArgs.map(({ name, type }) => `${name}: ${type}`).join(\", \")\n : \"\"\n }): ${typeName ? `${argName} is ${typeName}` : \"boolean\"} => `\n}\n\nexport function isMaybeUndefined(type: to.TypeObject): boolean {\n return (\n (type.__type === \"SpecialTO\" && type.kind === \"undefined\") ||\n (type.__type === \"UnionTO\" &&\n typeof type.unions.find(\n (union) => union.__type === \"SpecialTO\" && union.kind === \"undefined\"\n ) !== \"undefined\")\n )\n}\n\nexport function generateTypePredicates(\n files: {\n importPath: string\n types: {\n typeName: string\n type: to.TypeObject\n }[]\n }[],\n asserts = false,\n defaultArrayCheckOption: ArrayCheckOption = \"all\",\n comment = false,\n whitelist = false\n): string {\n const usedPrimitives: to.PrimitiveTO[\"kind\"][] = []\n const usedSpecials: to.SpecialTO[\"kind\"][] = []\n const usedUtils: (keyof typeof utilTypePredicateMap)[] = []\n const typeNames = files.flatMap(({ types }) =>\n types.map(({ typeName }) => typeName)\n )\n\n const generateCheckFn = ({\n type,\n typeName,\n parentArgCount,\n }: {\n type: to.TypeObject\n typeName?: string\n parentArgCount: number\n }): string => {\n const argCount = parentArgCount + 1\n const argName = () => `arg_${argCount}`\n const isToplevel = typeof typeName === \"string\"\n\n if (\n !isToplevel &&\n isPossibleUseTypeName(type) &&\n typeNames.includes(type.typeName)\n ) {\n return `is${type.typeName}`\n }\n\n if (type.__type === \"PrimitiveTO\") {\n usedPrimitives.push(type.kind)\n return primitiveTypePredicateNameMap[type.kind]\n } else if (type.__type === \"SpecialTO\") {\n usedSpecials.push(type.kind)\n return specialTypePredicateNameMap[type.kind]\n } else if (type.__type === \"LiteralTO\") {\n return `${generateDeclare(argName(), typeName)}${argName()} === ${\n typeof type.value === \"string\" ? '\"' + type.value + '\"' : type.value\n }`\n } else if (type.__type === \"UnionTO\") {\n usedUtils.push(\"union\")\n return `${generateDeclare(argName(), typeName)}isUnion([${type.unions\n .map((unionType) =>\n generateCheckFn({ type: unionType, parentArgCount: argCount })\n )\n .join(\", \")}])(${argName()})`\n } else if (type.__type === \"ArrayTO\") {\n usedUtils.push(\"array\")\n const checkChildFn = generateCheckFn({\n type: type.child,\n parentArgCount: argCount,\n })\n const checkOptionArgName = \"checkOpt\"\n\n return `${generateDeclare(\n argName(),\n typeName,\n isToplevel\n ? [\n {\n name: checkOptionArgName,\n type: \"ArrayCheckOption = 'all'\",\n },\n ]\n : []\n )}isArray(${checkChildFn}${\n isToplevel ? `, ${checkOptionArgName}` : \"\"\n })(${argName()})`\n } else if (type.__type === \"ObjectTO\") {\n usedUtils.push(\"object\")\n if (whitelist) usedUtils.push(\"hasNotUnlistedProperties\")\n return `${generateDeclare(\n argName(),\n typeName\n )}isObject(${argName()}) && ${\n whitelist\n ? `hasNotUnlistedProperties([${type\n .getProps()\n .map((prop) => `'${prop.propName}'`)\n .join(\", \")}])(${argName()}) &&`\n : ``\n }\n ${type\n .getProps()\n .map(\n ({ propName, type }) =>\n `(${\n isMaybeUndefined(type) ? `` : `'${propName}' in ${argName()} && `\n }(${generateCheckFn({\n type,\n parentArgCount: argCount,\n })})(${argName()}['${propName}']))`\n )\n .join(\" && \")}`\n } else if (type.__type === \"TypeParameterTO\") {\n return `(_) => true`\n } else if (type.__type === \"TupleTO\") {\n return `${generateDeclare(\n argName(),\n typeName\n )}Array.isArray(${argName()}) && (${type.items\n .map(\n (item, index) =>\n `(${generateCheckFn({\n type: item,\n parentArgCount: argCount,\n })})(${argName()}[${index}])`\n )\n .join(\" && \")})`\n }\n\n console.warn(\n `An unsupported or unknown type was detected. The generated function will skip the check (TypeName: ${\n typeName ?? \"unknown\"\n })`\n )\n return `/* WARN: Not Supported Type */ (value: unknown)${\n typeof typeName === \"string\" ? `:value is ${typeName}` : \"\"\n } => {\n console.warn(\\`check was skipped because \\${value} is not supported type.\\`);\n return true;\n }`\n }\n\n const generateJSDocComment = ({\n type,\n typeName,\n isAssertion,\n }: {\n type: to.TypeObject\n typeName: string\n isAssertion: boolean\n }): string => {\n return isAssertion\n ? `\\\n/**\n * Assert if a variable is of type {@link ${typeName}} and throws a TypeError if the assertion fails.\n * This function is automatically generated using [type-predicates-generator](https://www.npmjs.com/package/type-predicates-generator).\n * @param value Argument to inspect.\n * @throw TypeError if the given argument is not compatible with the type {@link ${typeName}}.\n */\n`\n : `\\\n/**\n * Check if a variable is of type {@link ${typeName}} and narrow it down to that type if the check passes.\n * This function is automatically generated using [type-predicates-generator](https://www.npmjs.com/package/type-predicates-generator).\n * @param arg_0 Argument to inspect.${\n type.__type === \"ArrayTO\"\n ? \"\\n * @param checkOpt Whether to check all elements of the array or only the first one.\"\n : \"\"\n }\n * @return \\`true\\` if the argument is of type {@link ${typeName}}, \\`false\\` otherwise.\n */\n`\n }\n\n const generatedTypeNames: string[] = []\n const skipImports: {\n typeName: string\n importPath: string\n }[] = []\n\n const checkFns = files\n .flatMap((file) =>\n file.types.map((type) => ({ ...type, importPath: file.importPath }))\n )\n .map(({ type, typeName, importPath }) => {\n // Do not generate reserved function name\n if (reservedNames.includes(typeName)) {\n console.log(`is${typeName} is reserved word, so skip generation.`)\n skipImports.push({\n typeName,\n importPath,\n })\n return ``\n }\n\n // Do not generate predicates for top-level unknown type\n if (generatedTypeNames.includes(typeName)) {\n console.warn(\n `${typeName} skips generation because duplicated. If it isn't caused by re-export, there may be a problem with the predicate function that uses is${typeName}.`\n )\n skipImports.push({\n typeName,\n importPath,\n })\n return ``\n }\n\n // Prevent re-generate predicates\n if (type.__type === \"UnknownTO\") {\n console.warn(`Unsupported type ${typeName} is skipped.`)\n skipImports.push({\n typeName,\n importPath,\n })\n return ``\n }\n\n generatedTypeNames.push(typeName)\n\n return `${\n comment\n ? generateJSDocComment({ type, typeName, isAssertion: false })\n : \"\"\n }export const is${typeName} = ${generateCheckFn({\n type,\n typeName,\n parentArgCount: -1,\n })};\n${\n asserts\n ? `${\n comment\n ? generateJSDocComment({ type, typeName, isAssertion: true })\n : \"\"\n }export function assertIs${typeName}(value: unknown): asserts value is ${typeName} {\n if (!is${typeName}(value)) throw new TypeError(\\`value must be ${typeName} but received \\${value}\\`)\n};`\n : \"\"\n}`\n })\n\n const corePredicates = uniq(\n [\n usedPrimitives.map((kind) => primitiveTypePredicateMap[kind]),\n usedSpecials.map((kind) => specialTypePredicateMap[kind]),\n usedUtils.map((name) =>\n name === \"array\"\n ? utilTypePredicateMap[name](defaultArrayCheckOption)\n : utilTypePredicateMap[name]\n ),\n ].flat()\n )\n\n return (\n \"// @ts-nocheck\\n\" +\n \"/* eslint-disable */\\n\" +\n `${files\n .filter(\n ({ types, importPath }) =>\n types.length -\n skipImports.filter(\n ({ importPath: skipImportPath }) => skipImportPath === importPath\n ).length !==\n 0\n )\n .map(\n ({ importPath, types }) =>\n `import type { ${types\n .filter(\n ({ typeName }) =>\n !skipImports.find(\n ({ typeName: skipTypeName, importPath: skipImportPath }) =>\n skipTypeName === typeName && skipImportPath === importPath\n )\n )\n .map(({ typeName }) => typeName)\n .join(\", \")} } from '${importPath}'`\n )\n .join(\";\\n\")};\n\n${corePredicates.join(\"\\n\")}\n\n${checkFns.map((checkFn) => checkFn).join(\"\\n\")}`\n )\n}\n"],"mappings":"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