@supawatch/target-supabase-types 0.7.1 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +41 -29
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -20,6 +20,8 @@ function tsType(runtime, jsonRef) {
20
20
  return el.includes("|") ? `(${el})[]` : `${el}[]`;
21
21
  }
22
22
  case "enum":
23
+ if (runtime.labels.length === 0)
24
+ return "never";
23
25
  return runtime.labels.map((l) => JSON.stringify(l)).join(" | ");
24
26
  }
25
27
  }
@@ -30,14 +32,6 @@ function bridgeRuntime(col, snapshot) {
30
32
  if (col.runtime.kind === "array") {
31
33
  return arrayRuntimeFor(runtimeFromName(col.runtime.element, snapshot), 1, "supabase-js");
32
34
  }
33
- if (col.runtime.kind === "string" && col.runtime.format === "array-literal") {
34
- // postgres-js collapses enum arrays to a raw literal; PostgREST
35
- // parses them. Recover the element labels via the enum reference.
36
- const e = snapshot.enums.find((x) => x.name === col.enumRef);
37
- if (e) {
38
- return { kind: "array", element: { kind: "enum", labels: e.labels } };
39
- }
40
- }
41
35
  return runtimeFor(col.pgTypeName, kindOf(col, snapshot), { enums: snapshot.enums }, "supabase-js");
42
36
  }
43
37
  function kindOf(col, snapshot) {
@@ -50,6 +44,11 @@ function kindOf(col, snapshot) {
50
44
  function runtimeFromName(element, _snapshot) {
51
45
  return element;
52
46
  }
47
+ // Database identifiers are free-form ("Order Log", "café", "select");
48
+ // quote any key that is not a plain TS identifier.
49
+ function tsKey(name) {
50
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
51
+ }
53
52
  function writableColumns(table) {
54
53
  return table.columns.filter((c) => !c.generated && c.identity !== "always");
55
54
  }
@@ -61,7 +60,7 @@ function fieldLine(col, snapshot, optional, indent) {
61
60
  let t = tsType(runtime, "Json");
62
61
  if (col.nullable && t !== "unknown")
63
62
  t = `${t} | null`;
64
- return `${indent}${col.name}${optional ? "?" : ""}: ${t}`;
63
+ return `${indent}${tsKey(col.name)}${optional ? "?" : ""}: ${t}`;
65
64
  }
66
65
  export class SupabaseTypesTarget {
67
66
  name = "supabase-types";
@@ -89,14 +88,15 @@ export class SupabaseTypesTarget {
89
88
  "export interface Database {",
90
89
  ];
91
90
  for (const schema of schemas) {
92
- const tables = snapshot.tables.filter((t) => t.schema === schema && t.kind === "table");
91
+ // PostgREST exposes foreign tables beside plain ones.
92
+ const tables = snapshot.tables.filter((t) => t.schema === schema && t.kind !== "view");
93
93
  const views = snapshot.tables.filter((t) => t.schema === schema && t.kind === "view");
94
94
  const enums = snapshot.enums.filter((e) => e.schema === schema);
95
95
  const composites = snapshot.composites.filter((c) => c.schema === schema);
96
- lines.push(` ${schema}: {`);
96
+ lines.push(` ${tsKey(schema)}: {`);
97
97
  lines.push(" Tables: {");
98
98
  for (const table of tables) {
99
- lines.push(` ${table.name}: {`);
99
+ lines.push(` ${tsKey(table.name)}: {`);
100
100
  lines.push(" Row: {");
101
101
  for (const col of table.columns) {
102
102
  lines.push(fieldLine(col, snapshot, false, " ") + ";");
@@ -128,7 +128,7 @@ export class SupabaseTypesTarget {
128
128
  lines.push(" };");
129
129
  lines.push(" Views: {");
130
130
  for (const view of views) {
131
- lines.push(` ${view.name}: {`);
131
+ lines.push(` ${tsKey(view.name)}: {`);
132
132
  lines.push(" Row: {");
133
133
  for (const col of view.columns) {
134
134
  lines.push(fieldLine(col, snapshot, false, " ") + ";");
@@ -143,36 +143,48 @@ export class SupabaseTypesTarget {
143
143
  }
144
144
  else {
145
145
  lines.push(" Functions: {");
146
+ // Overloaded names share one key: Args and Returns become unions
147
+ // of the signatures, never duplicate keys (invalid TS).
148
+ const byName = new Map();
146
149
  for (const fn of fns) {
147
- lines.push(` ${fn.name}: {`);
148
- if (fn.args.length === 0) {
149
- lines.push(" Args: Record<string, never>;");
150
- }
151
- else {
152
- lines.push(" Args: {");
153
- for (const arg of fn.args) {
150
+ const group = byName.get(fn.name) ?? [];
151
+ group.push(fn);
152
+ byName.set(fn.name, group);
153
+ }
154
+ for (const [name, group] of byName) {
155
+ const argShapes = group.map((fn) => {
156
+ if (fn.args.length === 0)
157
+ return "Record<string, never>";
158
+ const fields = fn.args.map((arg) => {
154
159
  const t = tsType(runtimeFor(arg.pgTypeName, "b", { enums: snapshot.enums }, "supabase-js"), "Json");
155
- lines.push(` ${arg.name}${arg.hasDefault ? "?" : ""}: ${t};`);
156
- }
157
- lines.push(" };");
158
- }
159
- const ret = tsType(runtimeFor(fn.returns.pgTypeName, "b", { enums: snapshot.enums }, "supabase-js"), "Json");
160
- lines.push(` Returns: ${fn.returns.isSet ? `(${ret})[]` : ret};`);
160
+ return `${tsKey(arg.name)}${arg.hasDefault ? "?" : ""}: ${t}`;
161
+ });
162
+ return `{ ${fields.join("; ")} }`;
163
+ });
164
+ const returnShapes = [
165
+ ...new Set(group.map((fn) => {
166
+ const ret = tsType(runtimeFor(fn.returns.pgTypeName, "b", { enums: snapshot.enums }, "supabase-js"), "Json");
167
+ return fn.returns.isSet ? `(${ret})[]` : ret;
168
+ })),
169
+ ];
170
+ lines.push(` ${tsKey(name)}: {`);
171
+ lines.push(` Args: ${[...new Set(argShapes)].join(" | ")};`);
172
+ lines.push(` Returns: ${returnShapes.join(" | ")};`);
161
173
  lines.push(" };");
162
174
  }
163
175
  lines.push(" };");
164
176
  }
165
177
  lines.push(" Enums: {");
166
178
  for (const e of enums) {
167
- lines.push(` ${e.name}: ${e.labels.map((l) => JSON.stringify(l)).join(" | ")};`);
179
+ lines.push(` ${tsKey(e.name)}: ${e.labels.length === 0 ? "never" : e.labels.map((l) => JSON.stringify(l)).join(" | ")};`);
168
180
  }
169
181
  lines.push(" };");
170
182
  lines.push(" CompositeTypes: {");
171
183
  for (const c of composites) {
172
- lines.push(` ${c.name}: {`);
184
+ lines.push(` ${tsKey(c.name)}: {`);
173
185
  for (const f of c.fields) {
174
186
  const t = tsType(f.runtime, "Json");
175
- lines.push(` ${f.name}: ${t} | null;`);
187
+ lines.push(` ${tsKey(f.name)}: ${t} | null;`);
176
188
  }
177
189
  lines.push(" };");
178
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supawatch/target-supabase-types",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "description": "A supabase-js compatible Database interface generated from live Postgres by supawatch, foreign-key relationships included.",
5
5
  "keywords": [
6
6
  "supabase",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@supawatch/core": "0.7.1"
36
+ "@supawatch/core": "0.9.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^22.20.1",