Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds running the puzzmo codebase inside the tests in order to figure out whats slow #22

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/formatDTS.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// https://prettier.io/docs/en/api.html

let hasPrettierInstalled = false
let prettier = null
try {
hasPrettierInstalled = !!require.resolve("prettier")
prettier = require("prettier")
} catch (error) {}

export const formatDTS = async (path: string, content: string): Promise<string> => {
if (!hasPrettierInstalled) return content

try {
const prettier = await import("prettier")
if (!prettier) return content
return prettier.format(content, { filepath: path })
} catch (error) {
Expand Down
21 changes: 9 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export * from "./types.js"

import { basename, join } from "node:path"

import { makeStep } from "./utils.js"

export interface SDLCodeGenReturn {
// Optional way to start up a watcher mode for the codegen
createWatcher: () => { fileChanged: (path: string) => Promise<void> }
Expand All @@ -22,7 +24,10 @@ export interface SDLCodeGenReturn {
}

/** The API specifically for the Redwood preset */
export async function runFullCodegen(preset: "redwood", config: { paths: RedwoodPaths; verbose?: true }): Promise<SDLCodeGenReturn>
export async function runFullCodegen(
preset: "redwood",
config: { paths: RedwoodPaths; sys?: typescript.System; verbose?: true }
): Promise<SDLCodeGenReturn>

export async function runFullCodegen(preset: string, config: unknown): Promise<SDLCodeGenReturn>

Expand Down Expand Up @@ -84,15 +89,15 @@ export async function runFullCodegen(preset: string, config: unknown): Promise<S

// Create the two shared schema files
await step("Create shared schema files", async () => {
const sharedDTSes = await createSharedSchemaFiles(appContext)
const sharedDTSes = await createSharedSchemaFiles(appContext, verbose)
filepaths.push(...sharedDTSes)
})

let knownServiceFiles: string[] = []
const createDTSFilesForAllServices = async () => {
// TODO: Maybe Redwood has an API for this? Its grabbing all the services
const serviceFiles = appContext.sys.readDirectory(appContext.pathSettings.apiServicesPath)
knownServiceFiles = serviceFiles.filter(isRedwoodServiceFile)

for (const path of knownServiceFiles) {
const dts = await lookAtServiceFile(path, appContext)
if (dts) filepaths.push(dts)
Expand All @@ -118,7 +123,7 @@ export async function runFullCodegen(preset: string, config: unknown): Promise<S

if (verbose) console.log("[sdl-codegen] SDL Schema changed")
await step("GraphQL schema changed", () => getGraphQLSDLFromFile(appContext.pathSettings))
await step("Create all shared schema files", () => createSharedSchemaFiles(appContext))
await step("Create all shared schema files", () => createSharedSchemaFiles(appContext, verbose))
await step("Create all service files", createDTSFilesForAllServices)
} else if (path === appContext.pathSettings.prismaDSLPath) {
await step("Prisma schema changed", () => getPrismaSchemaFromFile(appContext.pathSettings))
Expand Down Expand Up @@ -149,11 +154,3 @@ const isRedwoodServiceFile = (file: string) => {
if (file.endsWith("scenarios.ts") || file.endsWith("scenarios.js")) return false
return file.endsWith(".ts") || file.endsWith(".tsx") || file.endsWith(".js")
}

const makeStep = (verbose: boolean) => async (msg: string, fn: () => Promise<unknown> | Promise<void> | void) => {
if (!verbose) return fn()
console.log("[sdl-codegen] " + msg)
console.time("[sdl-codegen] " + msg)
await fn()
console.timeEnd("[sdl-codegen] " + msg)
}
3 changes: 2 additions & 1 deletion src/serviceFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const lookAtServiceFile = async (file: string, context: AppContext) => {

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const mutationType = gql.getMutationType()!

if (!mutationType) throw new Error("No mutation type")

const externalMapper = typeMapper(context, { preferPrismaModels: true })
Expand Down Expand Up @@ -201,6 +200,8 @@ export const lookAtServiceFile = async (file: string, context: AppContext) => {
],
returnType,
})

interfaceDeclaration.forget()
}

/** Ideally, we want to be able to write the type for just the object */
Expand Down
72 changes: 48 additions & 24 deletions src/sharedSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@ import * as tsMorph from "ts-morph"

import { AppContext } from "./context.js"
import { formatDTS } from "./formatDTS.js"
import { createSharedExternalSchemaFileViaStructure } from "./sharedSchemaStructures.js"
import { createSharedExternalSchemaFileViaTSC } from "./sharedSchemaTSC.js"
import { typeMapper } from "./typeMap.js"
import { makeStep } from "./utils.js"

export const createSharedSchemaFiles = async (context: AppContext) => {
await createSharedExternalSchemaFile(context)
await createSharedReturnPositionSchemaFile(context)
export const createSharedSchemaFiles = async (context: AppContext, verbose: boolean) => {
const step = makeStep(verbose)

await step("Creating shared schema files", () => createSharedExternalSchemaFile(context))
await step("Creating shared schema files via tsc", () => createSharedExternalSchemaFileViaTSC(context))
await step("Creating shared schema files via structure", () => createSharedExternalSchemaFileViaStructure(context))

await step("Creating shared return position schema files", () => createSharedReturnPositionSchemaFile(context))

return [
context.join(context.pathSettings.typesFolderRoot, context.pathSettings.sharedFilename),
context.join(context.pathSettings.typesFolderRoot, context.pathSettings.sharedInternalFilename),
]
}

async function createSharedExternalSchemaFile(context: AppContext) {
function createSharedExternalSchemaFile(context: AppContext) {
const gql = context.gql
const types = gql.getTypeMap()
const knownPrimitives = ["String", "Boolean", "Int"]
Expand All @@ -27,6 +35,9 @@ async function createSharedExternalSchemaFile(context: AppContext) {

const externalTSFile = context.tsProject.createSourceFile(`/source/${context.pathSettings.sharedFilename}`, "")

const interfaces = [] as tsMorph.InterfaceDeclarationStructure[]
const typeAliases = [] as tsMorph.TypeAliasDeclarationStructure[]

Object.keys(types).forEach((name) => {
if (name.startsWith("__")) {
return
Expand All @@ -50,7 +61,8 @@ async function createSharedExternalSchemaFile(context: AppContext) {
docs.push(type.description)
}

externalTSFile.addInterface({
interfaces.push({
kind: tsMorph.StructureKind.Interface,
name: type.name,
isExported: true,
docs: [],
Expand Down Expand Up @@ -87,9 +99,10 @@ async function createSharedExternalSchemaFile(context: AppContext) {
}

if (graphql.isEnumType(type)) {
externalTSFile.addTypeAlias({
typeAliases.push({
name: type.name,
isExported: true,
kind: tsMorph.StructureKind.TypeAlias,
type:
'"' +
type
Expand All @@ -101,9 +114,10 @@ async function createSharedExternalSchemaFile(context: AppContext) {
}

if (graphql.isUnionType(type)) {
externalTSFile.addTypeAlias({
typeAliases.push({
name: type.name,
isExported: true,
kind: tsMorph.StructureKind.TypeAlias,
type: type
.getTypes()
.map((m) => m.name)
Expand All @@ -112,21 +126,22 @@ async function createSharedExternalSchemaFile(context: AppContext) {
}
})

context.tsProject.forgetNodesCreatedInBlock(() => {
externalTSFile.addInterfaces(interfaces)
})

context.tsProject.forgetNodesCreatedInBlock(() => {
externalTSFile.addTypeAliases(typeAliases)
})

const { scalars } = mapper.getReferencedGraphQLThingsInMapping()
if (scalars.length) {
externalTSFile.addTypeAliases(
scalars.map((s) => ({
name: s,
type: "any",
}))
)
}
if (scalars.length) externalTSFile.addTypeAliases(scalars.map((s) => ({ name: s, type: "any" })))

const fullPath = context.join(context.pathSettings.typesFolderRoot, context.pathSettings.sharedFilename)
const formatted = await formatDTS(fullPath, externalTSFile.getText())
const text = externalTSFile.getText()

const prior = context.sys.readFile(fullPath)
if (prior !== formatted) context.sys.writeFile(fullPath, formatted)
if (prior !== text) context.sys.writeFile(fullPath, text)
}

async function createSharedReturnPositionSchemaFile(context: AppContext) {
Expand All @@ -153,6 +168,9 @@ async function createSharedReturnPositionSchemaFile(context: AppContext) {
`
)

const interfaces = [] as tsMorph.InterfaceDeclarationStructure[]
const typeAliases = [] as tsMorph.TypeAliasDeclarationStructure[]

Object.keys(types).forEach((name) => {
if (name.startsWith("__")) {
return
Expand All @@ -173,8 +191,9 @@ async function createSharedReturnPositionSchemaFile(context: AppContext) {
return
}

externalTSFile.addInterface({
interfaces.push({
name: type.name,
kind: tsMorph.StructureKind.Interface,
isExported: true,
docs: [],
properties: [
Expand All @@ -200,9 +219,10 @@ async function createSharedReturnPositionSchemaFile(context: AppContext) {
}

if (graphql.isEnumType(type)) {
externalTSFile.addTypeAlias({
typeAliases.push({
name: type.name,
isExported: true,
kind: tsMorph.StructureKind.TypeAlias,
type:
'"' +
type
Expand All @@ -214,8 +234,9 @@ async function createSharedReturnPositionSchemaFile(context: AppContext) {
}

if (graphql.isUnionType(type)) {
externalTSFile.addTypeAlias({
typeAliases.push({
name: type.name,
kind: tsMorph.StructureKind.TypeAlias,
isExported: true,
type: type
.getTypes()
Expand Down Expand Up @@ -243,15 +264,18 @@ async function createSharedReturnPositionSchemaFile(context: AppContext) {
namedImports: allPrismaModels.map((p) => `${p} as P${p}`),
})

allPrismaModels.forEach((p) => {
externalTSFile.addTypeAlias({
externalTSFile.addTypeAliases(
allPrismaModels.map((p) => ({
isExported: true,
name: p,
type: `P${p}`,
})
})
}))
)
}

externalTSFile.addInterfaces(interfaces)
externalTSFile.addTypeAliases(typeAliases)

const fullPath = context.join(context.pathSettings.typesFolderRoot, context.pathSettings.sharedInternalFilename)
const formatted = await formatDTS(fullPath, externalTSFile.getText())

Expand Down
Loading
Loading