Skip to content

feat(typegen): Go Type Gen #687

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

Merged
merged 12 commits into from
May 24, 2024
Merged
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
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ To start developing, run `npm run dev`. It will set up the database with Docker

If you are fixing a bug, you should create a new test case. To test your changes, add the `-u` flag to `vitest` on the `test:run` script, run `npm run test`, and then review the git diff of the snapshots. Depending on your change, you may see `id` fields being changed - this is expected and you are free to commit it, as long as it passes the CI. Don't forget to remove the `-u` flag when committing.

To make changes to the TypeScript type generation, run `npm run gen:types:typescript` while you have `npm run dev` running.
To make changes to the type generation, run `npm run gen:types:<lang>` while you have `npm run dev` running,
where `<lang>` is one of:

- `typescript`
- `go`

To use your own database connection string instead of the provided test database, run:
`PG_META_DB_URL=postgresql://postgres:postgres@localhost:5432/postgres npm run gen:types:typescript`
`PG_META_DB_URL=postgresql://postgres:postgres@localhost:5432/postgres npm run gen:types:<lang>`

## Licence

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"build": "tsc -p tsconfig.json && cpy 'src/lib/sql/*.sql' dist/lib/sql",
"docs:export": "PG_META_EXPORT_DOCS=true node --loader ts-node/esm src/server/server.ts > openapi.json",
"gen:types:typescript": "PG_META_GENERATE_TYPES=typescript node --loader ts-node/esm src/server/server.ts",
"gen:types:go": "PG_META_GENERATE_TYPES=go node --loader ts-node/esm src/server/server.ts",
"start": "node dist/server/server.js",
"dev": "trap 'npm run db:clean' INT && run-s db:clean db:run && nodemon --exec node --loader ts-node/esm src/server/server.ts | pino-pretty --colorize",
"test": "run-s db:clean db:run test:run db:clean",
Expand Down
35 changes: 35 additions & 0 deletions src/server/routes/generators/go.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { FastifyInstance } from 'fastify'
import { PostgresMeta } from '../../../lib/index.js'
import { DEFAULT_POOL_CONFIG } from '../../constants.js'
import { extractRequestForLogging } from '../../utils.js'
import { apply as applyGoTemplate } from '../../templates/go.js'
import { getGeneratorMetadata } from '../../../lib/generators.js'

export default async (fastify: FastifyInstance) => {
fastify.get<{
Headers: { pg: string }
Querystring: {
excluded_schemas?: string
included_schemas?: string
}
}>('/', async (request, reply) => {
const connectionString = request.headers.pg
const excludedSchemas =
request.query.excluded_schemas?.split(',').map((schema) => schema.trim()) ?? []
const includedSchemas =
request.query.included_schemas?.split(',').map((schema) => schema.trim()) ?? []

const pgMeta: PostgresMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
const { data: generatorMeta, error: generatorMetaError } = await getGeneratorMetadata(pgMeta, {
includedSchemas,
excludedSchemas,
})
if (generatorMetaError) {
request.log.error({ error: generatorMetaError, request: extractRequestForLogging(request) })
reply.code(500)
return { error: generatorMetaError.message }
}

return applyGoTemplate(generatorMeta)
})
}
6 changes: 4 additions & 2 deletions src/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import TablesRoute from './tables.js'
import TriggersRoute from './triggers.js'
import TypesRoute from './types.js'
import ViewsRoute from './views.js'
import TypeGenRoute from './generators/typescript.js'
import TypeScriptTypeGenRoute from './generators/typescript.js'
import GoTypeGenRoute from './generators/go.js'
import { PG_CONNECTION, CRYPTO_KEY } from '../constants.js'

export default async (fastify: FastifyInstance) => {
Expand Down Expand Up @@ -62,5 +63,6 @@ export default async (fastify: FastifyInstance) => {
fastify.register(TriggersRoute, { prefix: '/triggers' })
fastify.register(TypesRoute, { prefix: '/types' })
fastify.register(ViewsRoute, { prefix: '/views' })
fastify.register(TypeGenRoute, { prefix: '/generators/typescript' })
fastify.register(TypeScriptTypeGenRoute, { prefix: '/generators/typescript' })
fastify.register(GoTypeGenRoute, { prefix: '/generators/go' })
}
38 changes: 38 additions & 0 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
PG_META_PORT,
} from './constants.js'
import { apply as applyTypescriptTemplate } from './templates/typescript.js'
import { apply as applyGoTemplate } from './templates/go.js'
import { getGeneratorMetadata } from '../lib/generators.js'

const logger = pino({
formatters: {
Expand All @@ -27,6 +29,37 @@ const logger = pino({
const app = buildApp({ logger })
const adminApp = buildAdminApp({ logger })

async function getTypeOutput(): Promise<string | null> {
const pgMeta: PostgresMeta = new PostgresMeta({
...DEFAULT_POOL_CONFIG,
connectionString: PG_CONNECTION,
})
const { data: generatorMetadata, error: generatorMetadataError } = await getGeneratorMetadata(
pgMeta,
{
includedSchemas: GENERATE_TYPES_INCLUDED_SCHEMAS,
}
)
if (generatorMetadataError) {
throw new Error(generatorMetadataError.message)
}

let output: string | null = null
switch (GENERATE_TYPES) {
case 'typescript':
output = await applyTypescriptTemplate({
...generatorMetadata,
detectOneToOneRelationships: GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS,
})
break
case 'go':
output = applyGoTemplate(generatorMetadata)
break
}

return output
}

if (EXPORT_DOCS) {
// TODO: Move to a separate script.
await app.ready()
Expand Down Expand Up @@ -154,3 +187,8 @@ if (EXPORT_DOCS) {
adminApp.listen({ port: adminPort, host: PG_META_HOST })
})
}

app.listen({ port: PG_META_PORT, host: PG_META_HOST }, () => {
const adminPort = PG_META_PORT + 1
adminApp.listen({ port: adminPort, host: PG_META_HOST })
})
Loading