@supabase/postgrest-typegen 0.2.5 → 0.3.1

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 CHANGED
@@ -113,19 +113,30 @@ breaks at read time.
113
113
 
114
114
  ```ts
115
115
  import {
116
- generateTypescript, // async (uses prettier)
116
+ generateTypescript, // async (formats its output)
117
117
  generateGo,
118
118
  generatePython,
119
119
  generateSwift,
120
120
  } from "@supabase/postgrest-typegen/generation";
121
121
  ```
122
122
 
123
- | Function | Options |
124
- | -------------------- | ----------------------------------------------------------------------- |
125
- | `generateTypescript` | `{ detectOneToOneRelationships?, postgrestVersion?, defaultSchema? }` |
126
- | `generateGo` | — |
127
- | `generatePython` | — |
128
- | `generateSwift` | `{ accessControl?: 'internal' \| 'public' \| 'private' \| 'package' }` |
123
+ | Function | Options |
124
+ | -------------------- | ------------------------------------------------------------------------------ |
125
+ | `generateTypescript` | `{ detectOneToOneRelationships?, postgrestVersion?, defaultSchema?, format? }` |
126
+ | `generateGo` | — |
127
+ | `generatePython` | — |
128
+ | `generateSwift` | `{ accessControl?: 'internal' \| 'public' \| 'private' \| 'package' }` |
129
+
130
+ Every generator returns the complete contents of the generated file, ending
131
+ with a single newline, so consumers write the result as-is.
132
+
133
+ `generateTypescript` formats its output with `oxfmt` unless `format` is
134
+ supplied. `oxfmt` is an optional peer dependency, imported only when that
135
+ default runs: install it to use the default formatter, or pass your own
136
+ `format` (an identity function, for byte-identical unformatted output, or a
137
+ worker-pool-backed formatter) and it is never loaded or needed. Calling
138
+ `generateTypescript` without `format` when `oxfmt` is missing throws an error
139
+ saying so.
129
140
 
130
141
  ## Installation
131
142
 
@@ -134,11 +145,13 @@ Not yet published; consumed in-repo for now (`packages/postgrest-typegen`).
134
145
  ```bash
135
146
  # pg is a peer of your application, not bundled here
136
147
  npm install pg
148
+ # only if you rely on generateTypescript's default formatter
149
+ npm install oxfmt@0.66.0
137
150
  ```
138
151
 
139
152
  ## Releasing
140
153
 
141
- 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.
154
+ 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`.
142
155
 
143
156
  ## License
144
157
 
@@ -8,8 +8,7 @@ export const generateGo = ({ schemas, tables, views, materializedViews, columns,
8
8
  return acc;
9
9
  }, {});
10
10
  const compositeTypes = types.filter((type) => type.attributes.length > 0);
11
- let output = `
12
- package database
11
+ let output = `package database
13
12
 
14
13
  ${tables
15
14
  .filter((table) => schemas.some((schema) => schema.name === table.schema))
@@ -30,8 +29,8 @@ ${compositeTypes
30
29
  .filter((compositeType) => schemas.some((schema) => schema.name === compositeType.schema))
31
30
  .map((compositeType) => generateCompositeTypeStruct(schemas.find((schema) => schema.name === compositeType.schema), compositeType, types))
32
31
  .join("\n\n")}
33
- `.trim();
34
- return output;
32
+ `.trimEnd();
33
+ return `${output}\n`;
35
34
  };
36
35
  /**
37
36
  * Converts a Postgres name to PascalCase.
@@ -16,8 +16,7 @@ export const generatePython = ({ schemas, tables, views, materializedViews, colu
16
16
  .map((type) => ctx.typeToClass(type));
17
17
  const py_views = views.map((view) => ctx.viewToClass(view));
18
18
  const py_matviews = materializedViews.map((matview) => ctx.matViewToClass(matview));
19
- let output = `
20
- from __future__ import annotations
19
+ let output = `from __future__ import annotations
21
20
 
22
21
  import datetime
23
22
  import uuid
@@ -43,8 +42,8 @@ ${concatLines(py_matviews)}
43
42
 
44
43
  ${concatLines(composite_types)}
45
44
 
46
- `.trim();
47
- return output;
45
+ `.trimEnd();
46
+ return `${output}\n`;
48
47
  };
49
48
  class PythonContext {
50
49
  types;
@@ -216,7 +216,7 @@ export const generateSwift = (metadata, opts = {}) => {
216
216
  ];
217
217
  }),
218
218
  ];
219
- return output.join("\n");
219
+ return `${output.join("\n")}\n`;
220
220
  };
221
221
  // TODO: Make this more robust. Currently doesn't handle range types - returns them as string.
222
222
  const pgTypeToSwiftType = (pgType, nullable, { types, views, tables, }) => {
@@ -17,9 +17,11 @@ export interface GenerateTypescriptOptions {
17
17
  */
18
18
  defaultSchema?: string;
19
19
  /**
20
- * Formatter used on the generated output. Defaults to `oxfmt`, called
21
- * inline. Callers on a latency-sensitive request path (e.g. postgres-meta's
22
- * hosted `/generators/typescript` route) can substitute a worker-pool-backed
20
+ * Formatter used on the generated output. Defaults to `oxfmt`, an optional
21
+ * peer dependency that is imported only when this default runs, so callers
22
+ * that always pass their own formatter need not install it. Callers on a
23
+ * latency-sensitive request path (e.g. postgres-meta's hosted
24
+ * `/generators/typescript` route) can substitute a worker-pool-backed
23
25
  * formatter here instead of blocking the event loop on every call.
24
26
  */
25
27
  format?: (code: string) => Promise<string>;
@@ -1,13 +1,16 @@
1
- // oxlint-disable typescript/restrict-template-expressions -- this is a verbatim port of
2
- // postgres-meta's template, which intentionally interpolates arrays/values into template
3
- // literals (relying on Array#toString) to build the output. Preserving that is required for
4
- // byte-parity, and the offending expressions sit inside template literals where a targeted
5
- // disable comment would corrupt the emitted string.
6
- import { format as oxfmtFormat } from "oxfmt";
7
1
  import { VALID_FUNCTION_ARGS_MODE, VALID_UNNAMED_FUNCTION_ARG_TYPES, } from "./constants.js";
8
2
  import { compareStrings } from "../collation.js";
3
+ const loadOxfmt = async () => {
4
+ try {
5
+ return await import("oxfmt");
6
+ }
7
+ catch (error) {
8
+ throw new Error("oxfmt is not installed. It is an optional peer dependency that only the default formatter needs: install it, or pass a `format` option to generateTypescript.", { cause: error });
9
+ }
10
+ };
9
11
  const defaultFormat = async (code) => {
10
- const { code: formatted, errors } = await oxfmtFormat("output.ts", code, {
12
+ const { format } = await loadOxfmt();
13
+ const { code: formatted, errors } = await format("output.ts", code, {
11
14
  semi: false,
12
15
  printWidth: 80,
13
16
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supabase/postgrest-typegen",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "description": "Type generation for PostgREST from PostgreSQL schemas",
5
5
  "keywords": [
6
6
  "codegen",
@@ -62,8 +62,7 @@
62
62
  "test": "bun scripts/run-tests.ts test/"
63
63
  },
64
64
  "dependencies": {
65
- "arktype": "2.2.3",
66
- "oxfmt": "0.66.0"
65
+ "arktype": "2.2.3"
67
66
  },
68
67
  "devDependencies": {
69
68
  "@testcontainers/postgresql": "^12.1.0",
@@ -74,12 +73,21 @@
74
73
  "@types/node": "^26.3.0",
75
74
  "@types/pg": "^8.23.1",
76
75
  "knip": "^6.32.3",
77
- "oxlint": "1.83.0",
76
+ "oxfmt": "0.66.0",
77
+ "oxlint": "1.85.0",
78
78
  "oxlint-tsgolint": "7.0.2002",
79
79
  "pg": "^8.23.0",
80
80
  "testcontainers": "^12.1.0",
81
81
  "typescript": "7.0.2"
82
82
  },
83
+ "peerDependencies": {
84
+ "oxfmt": "0.66.0"
85
+ },
86
+ "peerDependenciesMeta": {
87
+ "oxfmt": {
88
+ "optional": true
89
+ }
90
+ },
83
91
  "engines": {
84
92
  "node": ">=22.12.0"
85
93
  }
@@ -32,8 +32,7 @@ export const generateGo = ({
32
32
 
33
33
  const compositeTypes = types.filter((type) => type.attributes.length > 0);
34
34
 
35
- let output = `
36
- package database
35
+ let output = `package database
37
36
 
38
37
  ${tables
39
38
  .filter((table) => schemas.some((schema) => schema.name === table.schema))
@@ -88,9 +87,9 @@ ${compositeTypes
88
87
  ),
89
88
  )
90
89
  .join("\n\n")}
91
- `.trim();
90
+ `.trimEnd();
92
91
 
93
- return output;
92
+ return `${output}\n`;
94
93
  };
95
94
 
96
95
  /**
@@ -38,8 +38,7 @@ export const generatePython = ({
38
38
  ctx.matViewToClass(matview),
39
39
  );
40
40
 
41
- let output = `
42
- from __future__ import annotations
41
+ let output = `from __future__ import annotations
43
42
 
44
43
  import datetime
45
44
  import uuid
@@ -65,9 +64,9 @@ ${concatLines(py_matviews)}
65
64
 
66
65
  ${concatLines(composite_types)}
67
66
 
68
- `.trim();
67
+ `.trimEnd();
69
68
 
70
- return output;
69
+ return `${output}\n`;
71
70
  };
72
71
 
73
72
  interface Serializable {
@@ -375,7 +375,7 @@ export const generateSwift = (
375
375
  }),
376
376
  ];
377
377
 
378
- return output.join("\n");
378
+ return `${output.join("\n")}\n`;
379
379
  };
380
380
 
381
381
  // TODO: Make this more robust. Currently doesn't handle range types - returns them as string.
@@ -3,7 +3,6 @@
3
3
  // literals (relying on Array#toString) to build the output. Preserving that is required for
4
4
  // byte-parity, and the offending expressions sit inside template literals where a targeted
5
5
  // disable comment would corrupt the emitted string.
6
- import { format as oxfmtFormat } from "oxfmt";
7
6
  import type {
8
7
  GeneratorMetadata,
9
8
  PostgresColumn,
@@ -39,16 +38,30 @@ export interface GenerateTypescriptOptions {
39
38
  */
40
39
  defaultSchema?: string;
41
40
  /**
42
- * Formatter used on the generated output. Defaults to `oxfmt`, called
43
- * inline. Callers on a latency-sensitive request path (e.g. postgres-meta's
44
- * hosted `/generators/typescript` route) can substitute a worker-pool-backed
41
+ * Formatter used on the generated output. Defaults to `oxfmt`, an optional
42
+ * peer dependency that is imported only when this default runs, so callers
43
+ * that always pass their own formatter need not install it. Callers on a
44
+ * latency-sensitive request path (e.g. postgres-meta's hosted
45
+ * `/generators/typescript` route) can substitute a worker-pool-backed
45
46
  * formatter here instead of blocking the event loop on every call.
46
47
  */
47
48
  format?: (code: string) => Promise<string>;
48
49
  }
49
50
 
51
+ const loadOxfmt = async () => {
52
+ try {
53
+ return await import("oxfmt");
54
+ } catch (error) {
55
+ throw new Error(
56
+ "oxfmt is not installed. It is an optional peer dependency that only the default formatter needs: install it, or pass a `format` option to generateTypescript.",
57
+ { cause: error },
58
+ );
59
+ }
60
+ };
61
+
50
62
  const defaultFormat = async (code: string): Promise<string> => {
51
- const { code: formatted, errors } = await oxfmtFormat("output.ts", code, {
63
+ const { format } = await loadOxfmt();
64
+ const { code: formatted, errors } = await format("output.ts", code, {
52
65
  semi: false,
53
66
  printWidth: 80,
54
67
  });