From b5a855c7d83da2fa43d6ba615bcf908351cb6be3 Mon Sep 17 00:00:00 2001 From: scottrippey Date: Thu, 5 Oct 2023 04:11:05 -0600 Subject: [PATCH] `types(groq-builder): added `ts-simplify-sanity-schema` --- .../bin/ts-simplify-sanity-schema.ts | 27 ++++++ packages/ts-simplify/src/simplify-types.ts | 97 ++++++++++--------- packages/ts-simplify/src/utils/unindent.ts | 5 + 3 files changed, 81 insertions(+), 48 deletions(-) create mode 100644 packages/ts-simplify/bin/ts-simplify-sanity-schema.ts create mode 100644 packages/ts-simplify/src/utils/unindent.ts diff --git a/packages/ts-simplify/bin/ts-simplify-sanity-schema.ts b/packages/ts-simplify/bin/ts-simplify-sanity-schema.ts new file mode 100644 index 0000000..f01ef76 --- /dev/null +++ b/packages/ts-simplify/bin/ts-simplify-sanity-schema.ts @@ -0,0 +1,27 @@ +import { compileTypes, simplifyTypes } from "../src/simplify-types"; +import { unindent } from "../src/utils/unindent"; + +declare const process: { argv: string[] }; +const [_, __, sanityConfig, outputFile] = process.argv; +const outputText = compileSanityTypes({ sanityConfigFile: sanityConfig }); +console.log(outputText); + +function compileSanityTypes(config: { sanityConfigFile: string }) { + return compileTypes({ + sourceFile: config.sanityConfigFile, + transform({}) { + return unindent(` + import sanityConfig from './${config.sanityConfigFile}'; + import { InferSchemaValues } from '@sanity-typed/types'; + + type SimplifyDeep = T extends object + ? T extends infer O + ? { [K in keyof O]: SimplifyDeep } + : never + : T; + + export type SanitySchema = SimplifyDeep>; + `); + }, + }); +} diff --git a/packages/ts-simplify/src/simplify-types.ts b/packages/ts-simplify/src/simplify-types.ts index 5614a62..9c4ab1f 100644 --- a/packages/ts-simplify/src/simplify-types.ts +++ b/packages/ts-simplify/src/simplify-types.ts @@ -1,5 +1,6 @@ import debug from "debug"; -import { Project, TypeFormatFlags } from "ts-morph"; +import { Project, SourceFile, TypeAliasDeclaration, TypeFormatFlags } from "ts-morph"; +import { unindent } from "./utils/unindent"; namespace logger { const base = debug("ts-simplify"); @@ -9,6 +10,40 @@ namespace logger { } export function simplifyTypes(config: { sourceFile: string }) { + return compileTypes({ + sourceFile: config.sourceFile, + transform({ sourceFile }) { + const sourceTypes = sourceFile.getTypeAliases().filter((t) => t.isExported()); + + logger.info(`Source file exports ${sourceTypes.length} types: ${sourceTypes.map((t) => t.getName()).join(", ")}`); + + return unindent(` + import * as SOURCES from './${config.sourceFile}'; + + type SimplifyDeep = T extends object + ? T extends infer O + ? { [K in keyof O]: SimplifyDeep } + : never + : T; + + ${sourceTypes + .map((type) => { + const name = type.getName(); + return unindent(` + export type ${name} = SimplifyDeep; + `); + }) + .join("")} + `); + }, + }); +} + +export type CompileConfig = { + sourceFile: string; + transform: (info: { sourceFile: SourceFile }) => string; +}; +export function compileTypes(config: CompileConfig) { const project = new Project({ tsConfigFilePath: "tsconfig.json", skipAddingFilesFromTsConfig: true, @@ -17,52 +52,25 @@ export function simplifyTypes(config: { sourceFile: string }) { const sourceFile = project.addSourceFileAtPath(config.sourceFile); - const sourceTypes = sourceFile.getTypeAliases().filter((type) => type.isExported()); - - logger.info(`Source file exports ${sourceTypes.length} types: ${sourceTypes.map((t) => t.getName()).join(", ")}`); - - const simplifiedFile = project.createSourceFile( - "./virtual/simplified.ts", - unindent(` - import * as SOURCES from '../${config.sourceFile}'; + const transformedText = config.transform({ sourceFile }); + const transformedFile = project.createSourceFile("./transformed.ts", transformedText); + const outputFile = project.createSourceFile("./output.ts"); - type SimplifyDeep = T extends object - ? T extends infer O - ? { [K in keyof O]: SimplifyDeep } - : never - : T; - - ${sourceTypes - .map((type) => { - const name = type.getName(); - return unindent(` - export type ${name} = SimplifyDeep; - `); - }) - .join("")} - `) - ); - - const outputFile = project.createSourceFile( - "./virtual/output.ts", - ` - // Generated by ts-simplify - `, - { overwrite: true } + const transformedTypes = transformedFile.getTypeAliases().filter((type) => type.isExported()); + logger.info( + `Creating ${transformedTypes.length} output types: ${transformedTypes.map((t) => t.getName()).join(", ")}` ); - - const simplifiedTypes = simplifiedFile.getTypeAliases().filter((type) => type.isExported()); - for (const simplifiedType of simplifiedTypes) { - const expandedType = simplifiedType + for (const transformedType of transformedTypes) { + const compiledType = transformedType .getType() .getText(undefined, TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | TypeFormatFlags.NoTruncation); outputFile.addTypeAlias({ - name: simplifiedType.getName(), - isExported: simplifiedType.isExported(), - isDefaultExport: simplifiedType.isDefaultExport(), - hasDeclareKeyword: simplifiedType.hasDeclareKeyword(), - type: expandedType, + name: transformedType.getName(), + isExported: transformedType.isExported(), + isDefaultExport: transformedType.isDefaultExport(), + hasDeclareKeyword: transformedType.hasDeclareKeyword(), + type: compiledType, }); } @@ -71,12 +79,5 @@ export function simplifyTypes(config: { sourceFile: string }) { // Original source: ${config.sourceFile} ${outputFile.getText()} `); - return outputText; } - -function unindent(str: string) { - const lines = str.split("\n"); - const indent = lines[1].match(/^\s*/)![0]; - return lines.map((line) => line.replace(indent, "")).join("\n"); -} diff --git a/packages/ts-simplify/src/utils/unindent.ts b/packages/ts-simplify/src/utils/unindent.ts new file mode 100644 index 0000000..72641dd --- /dev/null +++ b/packages/ts-simplify/src/utils/unindent.ts @@ -0,0 +1,5 @@ +export function unindent(str: string) { + const lines = str.split("\n"); + const indent = lines[1].match(/^\s*/)![0]; + return lines.map((line) => line.replace(indent, "")).join("\n"); +}