@supabase/postgrest-typegen 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -21
- package/dist/generation/index.d.ts +0 -1
- package/dist/generation/index.js +0 -1
- package/dist/generation/typescript.d.ts +2 -1
- package/dist/generation/typescript.js +70 -288
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/introspection/index.js +3 -1
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.js +223 -0
- package/dist/sort.js +23 -0
- package/dist/types.d.ts +151 -0
- package/dist/types.js +91 -0
- package/package.json +5 -4
- package/src/generation/index.ts +0 -5
- package/src/generation/typescript.ts +99 -383
- package/src/index.ts +1 -0
- package/src/introspection/index.ts +3 -1
- package/src/rpc.ts +299 -0
- package/src/sort.ts +31 -0
- package/src/types.ts +101 -0
- package/dist/generation/constants.d.ts +0 -9
- package/dist/generation/constants.js +0 -10
- package/dist/generation/swift.d.ts +0 -11
- package/dist/generation/swift.js +0 -358
- package/src/generation/constants.ts +0 -11
- package/src/generation/swift.ts +0 -531
package/README.md
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
# @supabase/postgrest-typegen
|
|
2
2
|
|
|
3
3
|
Type generation for [PostgREST](https://postgrest.org) from a PostgreSQL
|
|
4
|
-
schema
|
|
5
|
-
|
|
6
|
-
small, driver-agnostic library.
|
|
4
|
+
schema: the type-generation engine behind `supabase gen types`, as a small,
|
|
5
|
+
driver-agnostic library.
|
|
7
6
|
|
|
8
|
-
> **Status:** alpha. The public API
|
|
9
|
-
> are ported.
|
|
7
|
+
> **Status:** alpha. The public API may still change between minor versions.
|
|
10
8
|
|
|
11
|
-
## Scope: introspection is permanent,
|
|
9
|
+
## Scope: introspection is permanent, three generators are transitional
|
|
12
10
|
|
|
13
11
|
This package's permanent job is introspection and the `GeneratorMetadata`
|
|
14
12
|
contract (see "Out-of-process generators" below): any *new* language's
|
|
15
13
|
generator lives in that language's own SDK repo, consuming this package's
|
|
16
14
|
JSON output, not inside `postgrest-typegen`.
|
|
17
15
|
|
|
18
|
-
The TypeScript, Go,
|
|
16
|
+
The TypeScript, Go, and Python generators bundled here are a
|
|
19
17
|
**deliberate transition**, not the target architecture for new languages.
|
|
20
|
-
They
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
scheduled — sequenced after postgres-meta's cutover to this package settles.
|
|
18
|
+
They move out one language at a time, TypeScript first into supabase-js, then
|
|
19
|
+
Go and Python. Swift's generator is the `supabase-typegen` executable in
|
|
20
|
+
[supabase-swift](https://github.com/supabase/supabase-swift), which
|
|
21
|
+
`supabase gen types --lang swift` runs.
|
|
25
22
|
|
|
26
23
|
> [!IMPORTANT]
|
|
27
|
-
> **We
|
|
28
|
-
> Because each of the
|
|
24
|
+
> **We do not accept contributions that fix the bundled generators.**
|
|
25
|
+
> Because each of the three is moving out to its own language's SDK repository,
|
|
29
26
|
> a fix landed here would have to be made a second time in the destination
|
|
30
27
|
> repository, and postgres-meta and the CLI only pick it up once they bump
|
|
31
28
|
> their pinned version of this package. Please open an issue describing the
|
|
@@ -57,7 +54,7 @@ generators.
|
|
|
57
54
|
|
|
58
55
|
### Stable ordering (`sortGeneratorMetadata`)
|
|
59
56
|
|
|
60
|
-
The Go/Python
|
|
57
|
+
The Go/Python generators emit tables, views, and materialized views in
|
|
61
58
|
`GeneratorMetadata` order, so their output depends on how the producer ordered
|
|
62
59
|
its collections (a SQL introspector returns rows in environment-dependent heap
|
|
63
60
|
order). `sortGeneratorMetadata` is a pure pass that canonically sorts every
|
|
@@ -65,6 +62,42 @@ collection; **apply it after introspection and before any `generate*` call** so
|
|
|
65
62
|
output is deterministic regardless of the producer. Generators expect
|
|
66
63
|
pre-sorted input and do not re-sort it themselves.
|
|
67
64
|
|
|
65
|
+
### RPC functions (`rpcFunctions`, `resolveRpcFunctions`)
|
|
66
|
+
|
|
67
|
+
`functions` is `pg_proc` as introspected. Which of those functions PostgREST
|
|
68
|
+
exposes under `/rpc`, how overloads group, what a call returns and whether a
|
|
69
|
+
function doubles as a computed field or an embeddable relation are PostgREST
|
|
70
|
+
rules, so `introspect()` applies them once and attaches the result as
|
|
71
|
+
`rpcFunctions`. A generator in any language reads that collection instead of
|
|
72
|
+
reimplementing the rules:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
for (const fn of metadata.rpcFunctions ?? resolveRpcFunctions(metadata)) {
|
|
76
|
+
// fn.schema, fn.name, and one entry per overload PostgREST can resolve.
|
|
77
|
+
for (const overload of fn.overloads) {
|
|
78
|
+
overload.args; // input parameters: name, mode, type reference, has_default, relation_id
|
|
79
|
+
overload.returns; // type reference, plus relation_id or RETURNS TABLE columns
|
|
80
|
+
overload.is_set_returning; // the response is an array
|
|
81
|
+
overload.setof_options; // embeddable like a relation: from, to, is_one_to_one
|
|
82
|
+
overload.computed_field_of; // selectable as a column of this relation
|
|
83
|
+
overload.error; // why PostgREST cannot resolve a call, else null
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A type reference carries `type_id`, `format` (the type's name, spelled like
|
|
89
|
+
`PostgresColumn.format`) and `type_schema`, so a generator maps it with the
|
|
90
|
+
same table it uses for columns. An overload's `error` is the message the
|
|
91
|
+
TypeScript generator emits as the `Returns` type of an unresolvable overload:
|
|
92
|
+
two overloads PostgREST cannot tell apart, or a computed field that returns no
|
|
93
|
+
rows. Overloads are ordered by argument list, then by return type; the
|
|
94
|
+
TypeScript generator emits them in that order.
|
|
95
|
+
|
|
96
|
+
`resolveRpcFunctions` is pure and deterministic, so a custom producer attaches
|
|
97
|
+
it the same way, and a document without the collection (produced before it
|
|
98
|
+
existed) still generates: the TypeScript generator falls back to running the
|
|
99
|
+
pass itself.
|
|
100
|
+
|
|
68
101
|
### Runtime validation (opt-in)
|
|
69
102
|
|
|
70
103
|
`GeneratorMetadata` is backed by an [ArkType](https://arktype.io) schema, so a
|
|
@@ -104,10 +137,48 @@ const json = serializeGeneratorMetadata(sortGeneratorMetadata(metadata));
|
|
|
104
137
|
generatorMetadataJsonSchema;
|
|
105
138
|
```
|
|
106
139
|
|
|
107
|
-
`GeneratorMetadata.version`
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
140
|
+
### Contract compatibility (`GeneratorMetadata.version`)
|
|
141
|
+
|
|
142
|
+
`GeneratorMetadata` is read by code that does not install this package: an
|
|
143
|
+
out-of-process generator sees only the serialized document, and postgres-meta
|
|
144
|
+
and the Supabase CLI consume it through a pinned registry version. The shape
|
|
145
|
+
therefore changes under one rule:
|
|
146
|
+
|
|
147
|
+
- **A new field is optional and has a documented fallback.** The fallback
|
|
148
|
+
lives in the consumers that read the field, so a document produced by any
|
|
149
|
+
released version still parses and generates what it generated before. The
|
|
150
|
+
view flags `is_insert_enabled` and `is_update_enabled` are the model: they
|
|
151
|
+
are optional, and the TypeScript generator, the only one that emits view
|
|
152
|
+
write types, falls back to `is_updatable` when they are absent. The
|
|
153
|
+
`rpcFunctions` collection follows the same rule: a generator that does not
|
|
154
|
+
find it runs `resolveRpcFunctions` on the raw `functions` itself.
|
|
155
|
+
- **Anything else moves `GENERATOR_METADATA_VERSION`:** removing or renaming a
|
|
156
|
+
field, making one required, narrowing its type, or changing what an existing
|
|
157
|
+
value means. The version is `1`.
|
|
158
|
+
|
|
159
|
+
`parseGeneratorMetadata` and `generatorMetadataJsonSchema` pin the exact
|
|
160
|
+
version string, so a consumer on another version fails at parse time with a
|
|
161
|
+
clear error instead of misreading the document. An out-of-process generator
|
|
162
|
+
should do the same and exit distinctly when it meets a version it does not
|
|
163
|
+
know; `@supabase/typegen` maps Dart's exit code 65 to `MetadataRejectedError`
|
|
164
|
+
for that reason.
|
|
165
|
+
|
|
166
|
+
The contract version and the package version are independent:
|
|
167
|
+
|
|
168
|
+
- `GENERATOR_METADATA_VERSION` changes only with an incompatible shape change.
|
|
169
|
+
A release that moves it is marked breaking in the changelog, and consumers
|
|
170
|
+
that read the serialized document pin this number, not the npm version.
|
|
171
|
+
- The package follows semantic versioning and is on `0.x`. A minor release
|
|
172
|
+
may change generated output or the TypeScript
|
|
173
|
+
API, with breaking changes called out in the changelog; a patch release
|
|
174
|
+
changes neither on purpose. The four generators' output is part of the
|
|
175
|
+
public surface: any change to it is described in the pull request so it
|
|
176
|
+
reaches the release notes that postgres-meta and the CLI read before bumping.
|
|
177
|
+
|
|
178
|
+
Changes to `src/types.ts` and `src/introspection/` are reviewed by
|
|
179
|
+
[@spydon](https://github.com/spydon), listed in `CODEOWNERS` for this package
|
|
180
|
+
next to the SDK team, so every contract change has one person who checks it
|
|
181
|
+
against this rule.
|
|
111
182
|
|
|
112
183
|
### Generators
|
|
113
184
|
|
|
@@ -116,7 +187,6 @@ import {
|
|
|
116
187
|
generateTypescript, // async (formats its output)
|
|
117
188
|
generateGo,
|
|
118
189
|
generatePython,
|
|
119
|
-
generateSwift,
|
|
120
190
|
} from "@supabase/postgrest-typegen/generation";
|
|
121
191
|
```
|
|
122
192
|
|
|
@@ -125,7 +195,6 @@ import {
|
|
|
125
195
|
| `generateTypescript` | `{ detectOneToOneRelationships?, postgrestVersion?, defaultSchema?, format? }` |
|
|
126
196
|
| `generateGo` | — |
|
|
127
197
|
| `generatePython` | — |
|
|
128
|
-
| `generateSwift` | `{ accessControl?: 'internal' \| 'public' \| 'private' \| 'package' }` |
|
|
129
198
|
|
|
130
199
|
Every generator returns the complete contents of the generated file, ending
|
|
131
200
|
with a single newline, so consumers write the result as-is.
|
|
@@ -138,6 +207,22 @@ worker-pool-backed formatter) and it is never loaded or needed. Calling
|
|
|
138
207
|
`generateTypescript` without `format` when `oxfmt` is missing throws an error
|
|
139
208
|
saying so.
|
|
140
209
|
|
|
210
|
+
## Generating types without database credentials
|
|
211
|
+
|
|
212
|
+
`GeneratorMetadata` is the pluggable contract, so generating types for a
|
|
213
|
+
project without its database password means replacing the introspection
|
|
214
|
+
producer, not touching any generator. No such producer ships in this package.
|
|
215
|
+
|
|
216
|
+
Generating from PostgREST's OpenAPI output needs PostgREST to include the
|
|
217
|
+
introspection details the generators depend on: the standard OpenAPI document
|
|
218
|
+
alone carries about half of what the TypeScript output needs. That is the
|
|
219
|
+
`x-postgrest-typegen-metadata` extension proposed in
|
|
220
|
+
[supabase/postgrest#6](https://github.com/supabase/postgrest/pull/6). A
|
|
221
|
+
producer that reads it and matches `introspect()` byte for byte exists in
|
|
222
|
+
[supabase/pg-toolbelt#303](https://github.com/supabase/pg-toolbelt/pull/303)
|
|
223
|
+
and is the starting point for porting one here once the extension is
|
|
224
|
+
available.
|
|
225
|
+
|
|
141
226
|
## Installation
|
|
142
227
|
|
|
143
228
|
Not yet published; consumed in-repo for now (`packages/postgrest-typegen`).
|
|
@@ -149,6 +234,20 @@ npm install pg
|
|
|
149
234
|
npm install oxfmt@0.66.0
|
|
150
235
|
```
|
|
151
236
|
|
|
237
|
+
## postgrest-js type tests
|
|
238
|
+
|
|
239
|
+
Every pull request that touches this package also runs postgrest-js's type tests against the TypeScript this pull request generates. The `postgrest-js type tests` job in `postgrest-typegen-validate.yml` checks out supabase-js, starts the database fixture in `packages/core/postgrest-js/test/supabase`, writes `test/types.generated.ts` with `bun run generate:postgrest-js-types`, and runs `test:types:ci` over every TypeScript version postgrest-js supports. The assertions are the hand-written `*.test-d.ts` files in supabase-js, so the generated file is allowed to change as long as they keep passing.
|
|
240
|
+
|
|
241
|
+
To run it locally, start that fixture with `supabase --workdir packages/core/postgrest-js/test db start` in a supabase-js checkout, then:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
bun run generate:postgrest-js-types postgresql://postgres:postgres@127.0.0.1:54322/postgres <supabase-js>/packages/core/postgrest-js/test/types.generated.ts
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Then run `node scripts/update-json-type.js`, `pnpm exec prettier --write test/types.generated.ts` and `pnpm run test:types:ci` in `packages/core/postgrest-js`.
|
|
248
|
+
|
|
249
|
+
This job covers TypeScript only. Findings in the Go and Python generators stay with their own unit tests here, and move with those generators to their SDK repositories.
|
|
250
|
+
|
|
152
251
|
## Releasing
|
|
153
252
|
|
|
154
253
|
Unlike the rest of this repo, merging a change here does not open a release pull request on its own. Releases are cut on demand: run the `Release postgrest-typegen` workflow from the Actions tab, which runs release-please against `release-please-config.postgrest-typegen.json` and opens (or updates) the release pull request for this package. Merging that pull request tags the release and publishes to npm. Once npm serves the new version, the same workflow opens a pull request that bumps the exact pin in `packages/typegen`.
|
|
@@ -2,4 +2,3 @@ export { sortGeneratorMetadata } from "../sort.ts";
|
|
|
2
2
|
export { generateGo } from "./go.ts";
|
|
3
3
|
export { generatePython } from "./python.ts";
|
|
4
4
|
export { generateTypescript, type GenerateTypescriptOptions, pgTypeToTsType, type TypeResolutionContext, } from "./typescript.ts";
|
|
5
|
-
export { type AccessControl, generateSwift, type GenerateSwiftOptions, } from "./swift.ts";
|
package/dist/generation/index.js
CHANGED
|
@@ -13,7 +13,8 @@ export interface GenerateTypescriptOptions {
|
|
|
13
13
|
/**
|
|
14
14
|
* Schema treated as the default for the generated `Tables`/`Enums`/etc.
|
|
15
15
|
* helper types. Replaces postgres-meta's `GENERATE_TYPES_DEFAULT_SCHEMA`
|
|
16
|
-
* env read. Default `'public'`.
|
|
16
|
+
* env read. Default `'public'`. When it is not among the generated schemas,
|
|
17
|
+
* the first generated schema is used instead, so the helpers keep resolving.
|
|
17
18
|
*/
|
|
18
19
|
defaultSchema?: string;
|
|
19
20
|
/**
|