Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
bbf68e3
feat(postgrest-typegen): scaffold package with public API surface
claude Jun 18, 2026
525e707
feat(postgrest-typegen): port Go and Python type generators
claude Jun 18, 2026
02924b8
feat(postgrest-typegen): port TypeScript and Swift type generators
claude Jun 18, 2026
a7465f8
feat(postgrest-typegen): port introspection SQL builders and int8 nor…
claude Jun 18, 2026
a9eb0c0
feat(postgrest-typegen): port view-relationship expansion logic
claude Jun 18, 2026
fdb5a40
feat(postgrest-typegen): implement introspect() with integration tests
claude Jun 19, 2026
e54f63e
test(postgrest-typegen): add parity gate vs live postgres-meta output
claude Jun 19, 2026
40c9349
chore(postgrest-typegen): add verdaccio publish-local script for pari…
claude Jun 19, 2026
30659f9
ci(postgrest-typegen): wire package into CI, changeset, and agent docs
claude Jun 19, 2026
c8aacb3
feat(postgrest-typegen): make GeneratorMetadata an ArkType schema wit…
claude Jun 20, 2026
53b6178
refactor(postgrest-typegen): drop unused per-table relationships/prim…
claude Jun 20, 2026
74e498f
fix(postgrest-typegen): accept null has_default for OUT/TABLE functio…
claude Jun 20, 2026
f9c14a8
fix(postgrest-typegen): restore deterministic table ordering in intro…
claude Jun 20, 2026
ecfb057
feat(postgrest-typegen): add sortGeneratorMetadata canonical ordering…
claude Jun 20, 2026
1aa77eb
fix(postgrest-typegen): sort metadata by semantic keys, not oid
claude Jun 20, 2026
11ff444
refactor(postgrest-typegen): make sortGeneratorMetadata the source of…
claude Jun 20, 2026
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
5 changes: 5 additions & 0 deletions .changeset/postgrest-typegen-arktype-validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@supabase/postgrest-typegen": minor
---

Back `GeneratorMetadata` with an ArkType schema as the single source of truth (each `Postgres*` type is now derived via `.infer`), and add an opt-in `parseGeneratorMetadata(data)` runtime validator plus the exported `generatorMetadataSchema`. This lets integrators producing `GeneratorMetadata` through a custom/injected introspection adapter validate the result at runtime instead of blindly casting. Validation is intentionally not baked into `introspect()`. The inferred types remain structurally identical to the previous interfaces (pinned by a compile-time equivalence test), so generator output is unchanged.
9 changes: 9 additions & 0 deletions .changeset/postgrest-typegen-drop-table-relationships.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@supabase/postgrest-typegen": minor
---

Drop the unused per-table `relationships` and `primary_keys` fields from `PostgresTable` / `GeneratorMetadata.tables[]`, and remove the corresponding `pg_constraint` JSON-array join and primary-key subquery from the tables introspection SQL.

None of the language generators ever read these per-table fields — TypeScript relationship output is built from the top-level `GeneratorMetadata.relationships` (the PostgREST-shaped `PostgresRelationship`), and Go/Python/Swift emit no relationship metadata at all. Removing them makes `introspect()`'s tables query markedly cheaper (the expensive constraint join is gone) without changing any generator output (byte-parity preserved). The `PostgresRelationshipOld` and `PostgresPrimaryKey` types are removed accordingly.

This trims the `GeneratorMetadata` contract; consumers that produce metadata through a custom adapter no longer need to populate those table fields. postgres-meta's `/tables` REST endpoint is unaffected — it uses its own table types, not this package's.
5 changes: 5 additions & 0 deletions .changeset/postgrest-typegen-initial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@supabase/postgrest-typegen": minor
---

Initial alpha of `@supabase/postgrest-typegen`: type generation for PostgREST extracted from postgres-meta. Provides a hard split between introspection (`introspect(db)` → `GeneratorMetadata`) and pure generation (`generateTypescript`/`generateGo`/`generatePython`/`generateSwift`), with `GeneratorMetadata` as the pluggable contract. Output is byte-identical to postgres-meta's embedded templates.
5 changes: 5 additions & 0 deletions .changeset/postgrest-typegen-null-has-default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@supabase/postgrest-typegen": patch
---

Accept `null` `has_default` for OUT/TABLE function args in `parseGeneratorMetadata`. The introspection SQL sizes `arg_has_defaults` from the input-arg count (`pronargs`) while `arg_modes`/`arg_types` include output args, so `introspect()` legitimately emits `has_default: null` for the OUT columns of RETURNS TABLE / OUT-arg functions. The opt-in validator previously typed this field as a plain `boolean` and rejected such valid introspector output. The field is now `boolean | null`; generator output is unaffected (the generators already treat `has_default` truthily, so `null` and `false` behave identically).
12 changes: 12 additions & 0 deletions .github/actions/detect-changes/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ outputs:
pg-topo-package-json:
description: Whether pg-topo package.json changed
value: ${{ steps.filter.outputs.pg-topo-package-json }}
postgrest-typegen:
description: Whether postgrest-typegen changed
value: ${{ steps.filter.outputs.postgrest-typegen }}
postgrest-typegen-package-json:
description: Whether postgrest-typegen package.json changed
value: ${{ steps.filter.outputs.postgrest-typegen-package-json }}
root:
description: Whether root config changed
value: ${{ steps.filter.outputs.root }}
Expand Down Expand Up @@ -50,6 +56,10 @@ runs:
- 'packages/pg-topo/**'
pg-topo-package-json:
- 'packages/pg-topo/package.json'
postgrest-typegen:
- 'packages/postgrest-typegen/**'
postgrest-typegen-package-json:
- 'packages/postgrest-typegen/package.json'
root:
- 'package.json'
- 'bunfig.toml'
Expand All @@ -75,6 +85,8 @@ runs:
- "!packages/pg-delta/CHANGELOG.md"
- "!packages/pg-topo/package.json"
- "!packages/pg-topo/CHANGELOG.md"
- "!packages/postgrest-typegen/package.json"
- "!packages/postgrest-typegen/CHANGELOG.md"

- id: release-pr-content
shell: bash
Expand Down
2 changes: 2 additions & 0 deletions .github/agents/pg-toolbelt.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Bun-based monorepo containing PostgreSQL tooling packages.

- **packages/pg-delta** (`@supabase/pg-delta`): PostgreSQL schema diff and migration tool. Compares two live databases and generates DDL migration scripts.
- **packages/pg-topo** (`@supabase/pg-topo`): Topological sorting for SQL DDL statements. Pure library that accepts SQL content strings, extracts dependencies, and produces a deterministic execution order. Includes an optional filesystem adapter for discovering/reading `.sql` files.
- **packages/postgrest-typegen** (`@supabase/postgrest-typegen`): Type generation for PostgREST from a PostgreSQL schema (the engine behind `supabase gen types`, extracted from postgres-meta). Hard split between introspection (`introspect(db)` → `GeneratorMetadata`) and pure generation (`generateTypescript`/`generateGo`/`generatePython`/`generateSwift`); `GeneratorMetadata` is the pluggable contract. `GeneratorMetadata`/`Postgres*` types are derived from ArkType schemas in `src/types.ts` (single source of truth; a compile-time equivalence test pins the inferred types to the frozen interface contract), and `parseGeneratorMetadata` is an opt-in runtime validator — never baked into `introspect()`. Output must stay byte-identical to postgres-meta's templates (prettier pinned exact to 3.5.3) until parity is released.

## Quick Reference

Expand Down Expand Up @@ -165,6 +166,7 @@ The `Lint Pull Request` CI check (see `.github/workflows/lint-pull-request.yml`)
- GitHub Actions with `dorny/paths-filter` detects which packages changed
- Only affected packages are tested
- pg-delta integration tests are sharded across 15 runners x 3 PG versions
- pg-topo and postgrest-typegen each have a single `*-tests` job (Docker required); postgrest-typegen's integration/parity tests spin up a PostgreSQL container via testcontainers
- Changesets automate releases on merge to main

When changing shard count or PG versions, update all of these locations:
Expand Down
43 changes: 41 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
pg-delta-package-json: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.pg-delta-package-json }}
pg-topo: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.pg-topo }}
pg-topo-package-json: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.pg-topo-package-json }}
postgrest-typegen: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.postgrest-typegen }}
postgrest-typegen-package-json: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.postgrest-typegen-package-json }}
root: ${{ github.event_name == 'merge_group' && 'true' || steps.changes.outputs.root }}
# 'true' only when the PR is authored by the changesets release bot AND
# every changed file is in the release-PR whitelist (CHANGELOGs,
Expand Down Expand Up @@ -115,6 +117,9 @@ jobs:
- name: Check types (pg-topo)
if: needs.detect-changes.outputs.pg-topo == 'true' || needs.detect-changes.outputs.root == 'true'
run: bun run --filter '@supabase/pg-topo' check-types
- name: Check types (postgrest-typegen)
if: needs.detect-changes.outputs.postgrest-typegen == 'true' || needs.detect-changes.outputs.root == 'true'
run: bun run --filter '@supabase/postgrest-typegen' check-types

format-and-lint:
if: >-
Expand Down Expand Up @@ -149,6 +154,9 @@ jobs:
- name: Knip (pg-topo)
if: needs.detect-changes.outputs.pg-topo == 'true' || needs.detect-changes.outputs.root == 'true'
run: bun run --filter '@supabase/pg-topo' knip
- name: Knip (postgrest-typegen)
if: needs.detect-changes.outputs.postgrest-typegen == 'true' || needs.detect-changes.outputs.root == 'true'
run: bun run --filter '@supabase/postgrest-typegen' knip

pg-delta-unit:
if: >-
Expand Down Expand Up @@ -443,12 +451,13 @@ jobs:
coverage:
if: >-
!cancelled() &&
(needs.pg-delta-unit.result != 'skipped' || needs.pg-delta-integration.result != 'skipped' || needs.pg-topo-tests.result != 'skipped')
(needs.pg-delta-unit.result != 'skipped' || needs.pg-delta-integration.result != 'skipped' || needs.pg-topo-tests.result != 'skipped' || needs.postgrest-typegen-tests.result != 'skipped')
continue-on-error: true
needs:
- pg-delta-unit
- pg-delta-integration
- pg-topo-tests
- postgrest-typegen-tests
name: "Coverage report"
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -541,6 +550,35 @@ jobs:
retention-days: 1
include-hidden-files: true

postgrest-typegen-tests:
if: >-
needs.detect-changes.outputs.is-release-pr != 'true' &&
(github.event_name != 'pull_request' || github.event.pull_request.draft == false) &&
(needs.detect-changes.outputs.postgrest-typegen == 'true' || needs.detect-changes.outputs.root == 'true')
needs: detect-changes
name: "postgrest-typegen: Tests"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup
uses: ./.github/actions/setup
- name: Run tests
working-directory: packages/postgrest-typegen
env:
BUN_COVERAGE: "1"
NYC_OUTPUT_DIR: ${{ github.workspace }}/packages/postgrest-typegen/.nyc_output
run: bun run test
- name: Upload coverage
if: always()
continue-on-error: true
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: coverage-postgrest-typegen
path: packages/postgrest-typegen/.nyc_output/
retention-days: 1
include-hidden-files: true

deno2-library-e2e:
if: >-
needs.detect-changes.outputs.is-release-pr != 'true' &&
Expand Down Expand Up @@ -575,6 +613,7 @@ jobs:
- pg-delta-integration-pg15-compat
- pg-delta-integration-pg17-compat
- pg-topo-tests
- postgrest-typegen-tests
- deno2-library-e2e
if: always() && !cancelled() && needs.detect-changes.outputs.is-release-pr != 'true'
name: Release preview
Expand All @@ -587,4 +626,4 @@ jobs:
- name: Build all packages
run: bun run build
- name: Release preview
run: bunx pkg-pr-new publish ./packages/pg-delta ./packages/pg-topo
run: bunx pkg-pr-new publish ./packages/pg-delta ./packages/pg-topo ./packages/postgrest-typegen
47 changes: 44 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"test:pg-topo": "bun run --filter '@supabase/pg-topo' test",
"verdaccio:start": "verdaccio --config ./verdaccio/config.yaml",
"pg-delta:publish-local": "bun scripts/verdaccio-publish-pg-delta.ts",
"postgrest-typegen:publish-local": "bun scripts/verdaccio-publish-postgrest-typegen.ts",
"version": "changeset version"
},
"devDependencies": {
Expand Down
Loading
Loading