Skip to content

Commit

Permalink
typegen config
Browse files Browse the repository at this point in the history
  • Loading branch information
mmkal committed Sep 17, 2024
1 parent 6dae7e8 commit bf9e081
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 15 deletions.
5 changes: 2 additions & 3 deletions packages/pgkit/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {type Options as TypegenOptions} from '@pgkit/typegen'
import * as fs from 'fs'
import * as path from 'path'

export type Config = {
client: {
connectionString: string
}
typegen?: {
connectionString?: string
}
typegen?: Partial<TypegenOptions>
migrator?: {
connectionString?: string
/** @default '${cwd}/migrations' */
Expand Down
40 changes: 37 additions & 3 deletions packages/pgkit/src/router.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Client, createClient} from '@pgkit/client'
import {Migrator, createMigratorRouter} from '@pgkit/migrator'
import {confirm} from '@pgkit/migrator/dist/cli'
import {router as typegenRouter} from '@pgkit/typegen'
import {generate} from '@pgkit/typegen'
import express from 'express'
import * as trpcCli from 'trpc-cli'
import {z} from 'trpc-cli'
Expand All @@ -18,7 +18,7 @@ const procedureWithClient = t.procedure.use(async ({ctx, next}) => {
migrationTableName: config.migrator?.migrationTableName,
}))
return next({
ctx: {...ctx, client, migrator},
ctx: {...ctx, client, migrator, config},
})
})

Expand All @@ -33,7 +33,41 @@ export const router = t.router({
return next({ctx: {...ctx, confirm}})
}),
),
...typegenRouter._def.procedures,
generate: procedureWithClient
.use(async ({rawInput, ctx, next}) => {
const inputObject = typeof rawInput === 'object' ? Object.keys(rawInput || {}) : []
return next({
ctx: {...ctx, inputKeys: new Set(Object.keys(inputObject))},
})
})
.input(
z.object({
watch: z
.boolean()
.optional()
.describe(
'Run the type checker in watch mode. Files will be run through the code generator when changed or added.',
),
lazy: z.boolean().optional().describe('Skip initial processing of input files. Implies --watch.'),
}),
)
.mutation(async ({ctx, input: {watch, ...input}}) => {
watch = watch ?? input.lazy
if (input.lazy && !watch) throw new Error('Cannot specify --watch=false and --lazy')

const run = await generate({
connectionString: ctx.client,
...input,
...(ctx.config.typegen &&
Object.fromEntries(
Object.entries(ctx.config.typegen).filter(([key]) => !ctx.inputKeys.has(key)), // don't override options explicitly passed, do override defaults
)),
})

if (watch) {
await run.watch()
}
}),
admin: procedureWithClient
.input(
z.object({
Expand Down
8 changes: 6 additions & 2 deletions packages/typegen/src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export const resolveOptions = (partial: Partial<Options>): Options => {
defaultType = defaultTypeScriptType,
extractQueries = defaultExtractQueries,
writeTypes = defaultWriteTypes(),
poolConfig = getWithWarning<Options['poolConfig']>(logger, `Using default client config.`, {}),
poolConfig = typeof connectionString === 'string'
? getWithWarning<Options['poolConfig']>(logger, `Using default client config`, {})
: connectionString.options,
typeParsers = defaultTypeParsers(poolConfig.applyTypeParsers),
migrate = undefined,
checkClean = defaultCheckClean,
Expand All @@ -68,7 +70,9 @@ export const resolveOptions = (partial: Partial<Options>): Options => {
logger.warn(`Unexpected configuration keys: ${Object.keys(rest).join(', ')}`)
}

assert.ok(!connectionString.includes(' \'"'), `Connection string should not contain spaces or quotes`)
if (typeof connectionString === 'string') {
assert.ok(!connectionString.includes(' \'"'), `Connection string should not contain spaces or quotes`)
}

return {
connectionString,
Expand Down
11 changes: 7 additions & 4 deletions packages/typegen/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as path from 'path'
import * as defaults from './defaults'
import {migrateLegacyCode} from './migrate'
import {getEnumTypes, getRegtypeToPgTypnameMapping, psqlClient} from './pg'
import {getColumnInfo, getTypeability, removeSimpleComments} from './query'
import {getColumnInfo, getTypeability} from './query'
import {getParameterTypes} from './query/parameters'
import {ExtractedQuery, Options, QueryField, QueryParameter} from './types'
import {changedFiles, checkClean, containsIgnoreComment, globList} from './util'
Expand All @@ -21,10 +21,13 @@ export const generate = async (inputOptions: Partial<Options>) => {
const options = defaults.resolveOptions(inputOptions)
const logger = options.logger

const pool = createClient(options.connectionString, options.poolConfig)
const pool =
typeof options.connectionString === 'string'
? createClient(options.connectionString, options.poolConfig)
: options.connectionString

const _gdesc = (inputSql: string, searchPath?: string) => {
let connectionString = options.connectionString
let connectionString = pool.connectionString()
if (searchPath) {
const url = new URL(connectionString)
const optionsString = url.searchParams.get('options')
Expand Down Expand Up @@ -127,7 +130,7 @@ export const generate = async (inputOptions: Partial<Options>) => {
const logMsgInclude = `pattern${options.include.length > 1 ? 's' : ''} ${options.include.join(', ')}`
const logMsgExclude = options.exclude.length > 0 ? ` excluding ${options.exclude.join(', ')}` : ''
const logMsgSince = options.since ? ` since ${options.since}` : ''
logger.info(`Matching files in ${getLogPath(cwd)} with ${logMsgInclude}${logMsgExclude}${logMsgSince}`)
logger.info(`Matching files in ${cwd} with ${logMsgInclude}${logMsgExclude}${logMsgSince}`)

const getLogQueryReference = (query: {file: string; line: number}) => `${getLogPath(query.file)}:${query.line}`

Expand Down
3 changes: 2 additions & 1 deletion packages/typegen/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {generate, Options} from './generate'

const trpc = trpcServer.initTRPC.meta<TrpcCliMeta>().create()

const CliOptions = z
// todo: deprecate in favour of inputs more like the ones in pgkit
export const CliOptions = z
.object({
config: z
.string()
Expand Down
4 changes: 2 additions & 2 deletions packages/typegen/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ClientOptions} from '@pgkit/client'
import {Client, ClientOptions} from '@pgkit/client'

/**
* Options that can be specified in `typegen.config.js`. Each is optional (has a default value).
Expand All @@ -11,7 +11,7 @@ export interface Options {
*
* Note: It's not recommended to run this tool against a production database, even though it doesn't perform any dynamic queries.
*/
connectionString: string
connectionString: string | Client
/**
* How to execute `psql` from the machine running this tool.
*
Expand Down
4 changes: 4 additions & 0 deletions pgkit.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ export default {
client: {
connectionString: 'postgresql://postgres:postgres@localhost:5432/postgres',
},
typegen: {
psqlCommand: 'docker-compose exec -T postgres psql',
checkClean: [],
}
} satisfies import('./packages/pgkit/src/config').Config

0 comments on commit bf9e081

Please sign in to comment.