1 | import type { Formatter } from '@dprint/formatter'
|
2 | import _ from 'json-bigint'
|
3 | import fs from 'node:fs/promises'
|
4 | import * as Path from 'node:path'
|
5 | import type { OptionsInput } from './generateCode.js'
|
6 | import { generateCode, type Input as GenerateInput } from './generateCode.js'
|
7 | import { fileExists } from './prelude.js'
|
8 |
|
9 | export interface Input {
|
10 | name?: string
|
11 | outputDirPath: string
|
12 | code?: Omit<GenerateInput, 'schemaSource' | 'sourceDirPath' | 'options'>
|
13 | sourceDirPath?: string
|
14 | sourceCustomScalarCodecsFilePath?: string
|
15 | schemaPath?: string
|
16 | format?: boolean
|
17 | errorTypeNamePattern?: OptionsInput['errorTypeNamePattern']
|
18 | }
|
19 |
|
20 | const getTypeScriptFormatter = async (): Promise<Formatter | undefined> => {
|
21 | try {
|
22 | const { createFromBuffer } = await import(`@dprint/formatter`)
|
23 | const { getPath } = await import(`@dprint/typescript`)
|
24 | return createFromBuffer(await fs.readFile(getPath()))
|
25 | } catch (error) {
|
26 | return undefined
|
27 | }
|
28 | }
|
29 |
|
30 | export const generateFiles = async (input: Input) => {
|
31 | const sourceDirPath = input.sourceDirPath ?? process.cwd()
|
32 | const schemaPath = input.schemaPath ?? Path.join(sourceDirPath, `schema.graphql`)
|
33 | const schemaSource = await fs.readFile(schemaPath, `utf8`)
|
34 |
|
35 |
|
36 | const customScalarCodecsFilePath = input.sourceCustomScalarCodecsFilePath
|
37 | ?? Path.join(sourceDirPath, `customScalarCodecs.ts`)
|
38 | const customScalarCodecsImportPath = Path.relative(
|
39 | input.outputDirPath,
|
40 | customScalarCodecsFilePath.replace(/\.ts$/, `.js`),
|
41 | )
|
42 | const customScalarCodecsPathExists = await fileExists(customScalarCodecsFilePath)
|
43 | const typeScriptFormatter = (input.format ?? true) ? await getTypeScriptFormatter() : undefined
|
44 |
|
45 | const codes = generateCode({
|
46 | name: input.name,
|
47 | schemaSource,
|
48 | importPaths: {
|
49 | customScalarCodecs: customScalarCodecsImportPath,
|
50 | },
|
51 | ...input.code,
|
52 | options: {
|
53 | formatter: typeScriptFormatter,
|
54 | customScalars: customScalarCodecsPathExists,
|
55 | errorTypeNamePattern: input.errorTypeNamePattern,
|
56 | },
|
57 | })
|
58 |
|
59 | await fs.mkdir(input.outputDirPath, { recursive: true })
|
60 | await Promise.all(
|
61 | codes.map((code) => {
|
62 | return fs.writeFile(`${input.outputDirPath}/${code.moduleName}.ts`, code.code, { encoding: `utf8` })
|
63 | }),
|
64 | )
|
65 | }
|