true-pg 0.5.1 → 0.6.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.
@@ -9,6 +9,7 @@ import { type FunctionDetails } from "./kinds/function.ts";
9
9
  import { type DomainDetails } from "./kinds/domain.ts";
10
10
  import { type RangeDetails } from "./kinds/range.ts";
11
11
  import type { PgType } from "./pgtype.ts";
12
+ export { pgTypeKinds, type PgType, type Kind } from "./pgtype.ts";
12
13
  import { Canonical } from "./canonicalise.ts";
13
14
  export { Canonical };
14
15
  export type { TableDetails, ViewDetails, MaterializedViewDetails, EnumDetails, CompositeTypeDetails, FunctionDetails, DomainDetails, RangeDetails, };
@@ -23,14 +24,14 @@ export { FunctionReturnTypeKind } from "./kinds/function.ts";
23
24
  */
24
25
  export type Schema = {
25
26
  name: string;
26
- tables: TableDetails[];
27
- views: ViewDetails[];
28
- materializedViews: MaterializedViewDetails[];
29
- enums: EnumDetails[];
30
- composites: CompositeTypeDetails[];
31
- functions: FunctionDetails[];
32
- domains: DomainDetails[];
33
- ranges: RangeDetails[];
27
+ table: TableDetails[];
28
+ view: ViewDetails[];
29
+ materializedView: MaterializedViewDetails[];
30
+ enum: EnumDetails[];
31
+ composite: CompositeTypeDetails[];
32
+ function: FunctionDetails[];
33
+ domain: DomainDetails[];
34
+ range: RangeDetails[];
34
35
  };
35
36
  export type SchemaType = TableDetails | ViewDetails | MaterializedViewDetails | EnumDetails | CompositeTypeDetails | FunctionDetails | DomainDetails | RangeDetails;
36
37
  /**
@@ -10,18 +10,19 @@ import extractFunction, {} from "./kinds/function.js";
10
10
  import extractDomain, {} from "./kinds/domain.js";
11
11
  import extractRange, {} from "./kinds/range.js";
12
12
  import fetchTypes from "./fetchTypes.js";
13
+ export { pgTypeKinds } from "./pgtype.js";
13
14
  import { canonicalise, Canonical } from "./canonicalise.js";
14
15
  export { Canonical };
15
16
  export { FunctionReturnTypeKind } from "./kinds/function.js";
16
17
  const emptySchema = {
17
- tables: [],
18
- views: [],
19
- materializedViews: [],
20
- enums: [],
21
- composites: [],
22
- functions: [],
23
- domains: [],
24
- ranges: [],
18
+ table: [],
19
+ view: [],
20
+ materializedView: [],
21
+ enum: [],
22
+ composite: [],
23
+ function: [],
24
+ domain: [],
25
+ range: [],
25
26
  };
26
27
  const populatorMap = {
27
28
  table: extractTable,
@@ -133,10 +134,7 @@ export class Extractor {
133
134
  ...emptySchema,
134
135
  };
135
136
  }
136
- schemas[p.schemaName][`${p.kind}s`] = [
137
- ...schemas[p.schemaName][`${p.kind}s`],
138
- p,
139
- ];
137
+ schemas[p.schemaName][p.kind] = [...schemas[p.schemaName][p.kind], p];
140
138
  }
141
139
  const result =
142
140
  // options?.resolveViews
@@ -1,9 +1,9 @@
1
1
  export declare const typeKindMap: {
2
- readonly d: "domain";
3
2
  readonly e: "enum";
3
+ readonly d: "domain";
4
4
  readonly r: "range";
5
5
  };
6
- type TypeKind = (typeof typeKindMap)[keyof typeof typeKindMap];
6
+ export type TypeKind = (typeof typeKindMap)[keyof typeof typeKindMap];
7
7
  export declare const classKindMap: {
8
8
  readonly r: "table";
9
9
  readonly p: "table";
@@ -11,12 +11,13 @@ export declare const classKindMap: {
11
11
  readonly m: "materializedView";
12
12
  readonly c: "composite";
13
13
  };
14
- type ClassKind = (typeof classKindMap)[keyof typeof classKindMap];
14
+ export type ClassKind = (typeof classKindMap)[keyof typeof classKindMap];
15
15
  export declare const routineKindMap: {
16
16
  readonly f: "function";
17
17
  };
18
- type RoutineKind = (typeof routineKindMap)[keyof typeof routineKindMap];
19
- export type Kind = TypeKind | ClassKind | RoutineKind;
18
+ export type RoutineKind = (typeof routineKindMap)[keyof typeof routineKindMap];
19
+ export declare const pgTypeKinds: ("function" | "enum" | "domain" | "range" | "table" | "view" | "materializedView" | "composite")[];
20
+ export type Kind = (typeof pgTypeKinds)[number];
20
21
  /**
21
22
  * Base type for Postgres objects.
22
23
  */
@@ -38,4 +39,3 @@ export type PgType<K extends Kind = Kind> = {
38
39
  */
39
40
  comment: string | null;
40
41
  };
41
- export {};
@@ -1,6 +1,6 @@
1
1
  export const typeKindMap = {
2
- d: "domain",
3
2
  e: "enum",
3
+ d: "domain",
4
4
  r: "range",
5
5
  // Not supported (yet):
6
6
  // m: 'multiRange',
@@ -28,3 +28,9 @@ export const routineKindMap = {
28
28
  // a: 'aggregate',
29
29
  // w: 'windowFunction',
30
30
  };
31
+ const unique = (arr) => [...new Set(arr)];
32
+ export const pgTypeKinds = unique([
33
+ ...Object.values(classKindMap),
34
+ ...Object.values(typeKindMap),
35
+ ...Object.values(routineKindMap),
36
+ ]);
package/lib/imports.d.ts CHANGED
@@ -1,11 +1,16 @@
1
1
  import type { Canonical } from "./extractor/index.ts";
2
2
  import type { FunctionReturnType } from "./extractor/index.ts";
3
- import type { FolderStructure } from "./types.ts";
3
+ import type { allowed_kind_names, FolderStructure } from "./types.ts";
4
4
  export interface ImportIdentifier {
5
5
  name: string;
6
6
  alias?: string;
7
7
  typeOnly?: boolean;
8
8
  }
9
+ type Supported<T> = {
10
+ [key in allowed_kind_names]: T extends {
11
+ kind: key;
12
+ } ? T : never;
13
+ }[allowed_kind_names];
9
14
  export declare class Import {
10
15
  from: string | ((files: FolderStructure) => string);
11
16
  namedImports?: (string | ImportIdentifier)[];
@@ -21,7 +26,7 @@ export declare class Import {
21
26
  });
22
27
  static fromInternal(opts: {
23
28
  source: string;
24
- type: Canonical | FunctionReturnType.ExistingTable;
29
+ type: Supported<Canonical | FunctionReturnType.ExistingTable>;
25
30
  withName?: string;
26
31
  typeOnly?: boolean;
27
32
  }): Import;
@@ -33,3 +38,4 @@ export declare class ImportList {
33
38
  add(item: Import): void;
34
39
  stringify(files: FolderStructure): string;
35
40
  }
41
+ export {};
package/lib/imports.js CHANGED
@@ -18,9 +18,9 @@ export class Import {
18
18
  return new Import({
19
19
  from: files => {
20
20
  const schema = files.children[t.schema];
21
- const kind = schema.children[`${t.kind}s`];
21
+ const kind = schema.children[t.kind];
22
22
  const type = kind.children[t.name];
23
- const path = `${files.name}/${schema.name}/${kind.kind}/${type.name}.ts`;
23
+ const path = `${files.name}/${schema.name}/${kind.kind}s/${type.name}.ts`;
24
24
  return relative(dirname(opts.source), path);
25
25
  },
26
26
  namedImports: [opts.withName ?? t.name],
package/lib/index.js CHANGED
@@ -115,9 +115,9 @@ const multifile = async (generators, schemas, opts) => {
115
115
  for (const schema of Object.values(schemas)) {
116
116
  console.log("Selected schema '%s':\n", schema.name);
117
117
  const schemaDir = joinpath(out, schema.name);
118
- const [unique_functions, overloaded_functions] = filter_overloaded_functions(schema.functions);
118
+ const [unique_functions, overloaded_functions] = filter_overloaded_functions(schema.function);
119
119
  const [supported_functions, unsupported_functions] = filter_unsupported_functions(unique_functions);
120
- schema.functions = supported_functions;
120
+ schema.function = supported_functions;
121
121
  {
122
122
  const skipped = unsupported_functions.map(f => ` - ${f.name}`);
123
123
  if (skipped.length) {
@@ -136,11 +136,12 @@ const multifile = async (generators, schemas, opts) => {
136
136
  if (schema[kind].length < 1)
137
137
  continue;
138
138
  createIndex = true;
139
- await mkdir(joinpath(schemaDir, kind), { recursive: true });
140
- console.log(" Creating %s:\n", kind);
139
+ const kindDir = joinpath(schemaDir, kind + "s");
140
+ await mkdir(kindDir, { recursive: true });
141
+ console.log(" Creating %s:\n", kind + "s");
141
142
  for (const [i, item] of schema[kind].entries()) {
142
143
  const index = "[" + (i + 1 + "]").padEnd(3, " ");
143
- const filename = joinpath(schemaDir, kind, def_gen.formatSchemaMemberName(item) + ".ts");
144
+ const filename = joinpath(kindDir, def_gen.formatSchemaMemberName(item) + ".ts");
144
145
  const exists = await existsSync(filename);
145
146
  if (exists) {
146
147
  warnings.add(`Skipping ${item.kind} "${item.name}": formatted name clashes. Wanted to create ${filename}`);
@@ -159,7 +160,7 @@ const multifile = async (generators, schemas, opts) => {
159
160
  {
160
161
  const start = performance.now();
161
162
  const imports = new ImportList();
162
- const fileName = joinpath(schemaDir, kind, "index.ts");
163
+ const fileName = joinpath(kindDir, "index.ts");
163
164
  const kindIndex = join(gens.map(gen => gen.schemaKindIndex({ source: fileName, imports }, schema, kind, def_gen)));
164
165
  const file = join([imports.stringify(files), kindIndex]);
165
166
  await write(fileName, file);
@@ -33,7 +33,6 @@ export const Kysely = createGenerator(opts => {
33
33
  }
34
34
  let out = col.comment ? `/** ${col.comment} */\n\t` : "";
35
35
  out += quoteI(col.name);
36
- // TODO: update imports for non-primitive types
37
36
  out += `: ${qualified}`;
38
37
  return `\t${out};\n`;
39
38
  };
@@ -56,21 +55,27 @@ export const Kysely = createGenerator(opts => {
56
55
  let base;
57
56
  if (type.kind === FunctionReturnTypeKind.ExistingTable) {
58
57
  base = toPascalCase(type.name);
58
+ ctx.imports.add(Import.fromInternal({
59
+ source: ctx.source,
60
+ type,
61
+ withName: base,
62
+ typeOnly: true,
63
+ }));
59
64
  }
60
- else if (type.schema === "pg_catalog") {
65
+ else if (type.schema === "pg_catalog" ||
66
+ type.kind === Canonical.Kind.Base ||
67
+ type.kind === Canonical.Kind.Pseudo) {
61
68
  const name = type.canonical_name;
62
69
  const format = builtins[name];
63
70
  if (format)
64
71
  base = format;
65
72
  else {
66
- opts?.warnings?.add(`(kysely) Unknown builtin type: ${name}. Pass 'kysely.builtinMap' to map this type. Defaulting to "unknown".`);
73
+ opts?.warnings?.add(`(kysely) Unknown base type: ${name}. Pass 'kysely.builtinMap' to map this type. Defaulting to "unknown".`);
67
74
  base = "unknown";
68
75
  }
69
76
  }
70
- else
77
+ else {
71
78
  base = toPascalCase(type.name);
72
- if (type.schema !== "pg_catalog") {
73
- // before adding modifiers, add the import
74
79
  ctx.imports.add(Import.fromInternal({
75
80
  source: ctx.source,
76
81
  type,
@@ -222,14 +227,14 @@ export const Kysely = createGenerator(opts => {
222
227
  schemaIndex(ctx, schema) {
223
228
  const actual_kinds = allowed_kind_names.filter(kind => schema[kind].length);
224
229
  // we could in theory use the imports from GeneratorContext here, but this works fine
225
- let out = actual_kinds.map(kind => `import type * as ${kind} from "./${kind}/index.ts";`).join("\n");
230
+ let out = actual_kinds.map(kind => `import type * as ${kind}s from "./${kind}s/index.ts";`).join("\n");
226
231
  out += "\n\n";
227
232
  out += `export interface ${this.formatSchemaName(schema.name)} {\n`;
228
233
  for (const kind of actual_kinds) {
229
234
  const items = schema[kind];
230
235
  if (items.length === 0)
231
236
  continue;
232
- out += `\t${kind}: {\n`;
237
+ out += `\t${kind}s: {\n`;
233
238
  const formatted = items
234
239
  .map(each => {
235
240
  const formatted = generator.formatSchemaMemberName(each);
@@ -257,7 +262,7 @@ export const Kysely = createGenerator(opts => {
257
262
  iface += schemas
258
263
  .map(schema => {
259
264
  // only tables, views, and materialized views are queryable
260
- const tables = [...schema.tables, ...schema.views, ...schema.materializedViews];
265
+ const tables = [...schema.table, ...schema.view, ...schema.materializedView];
261
266
  let out = "";
262
267
  const seen = new Set();
263
268
  const formatted = tables
package/lib/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Canonical, type TableDetails, type ViewDetails, type MaterializedViewDetails, type EnumDetails, type CompositeTypeDetails, type DomainDetails, type RangeDetails, type FunctionDetails, type SchemaType, type Schema, type FunctionReturnType } from "./extractor/index.ts";
2
2
  import type { ImportList } from "./imports.ts";
3
- export declare const allowed_kind_names: readonly ["tables", "views", "materializedViews", "enums", "composites", "functions", "domains", "ranges"];
3
+ export declare const allowed_kind_names: ("function" | "enum" | "domain" | "range" | "table" | "view" | "materializedView" | "composite")[];
4
4
  export type allowed_kind_names = (typeof allowed_kind_names)[number];
5
5
  export interface FolderStructure {
6
6
  name: string;
@@ -10,8 +10,8 @@ export interface FolderStructure {
10
10
  name: string;
11
11
  type: "schema";
12
12
  children: {
13
- [kind: string]: {
14
- kind: allowed_kind_names;
13
+ [kind in allowed_kind_names]: {
14
+ kind: kind;
15
15
  type: "kind";
16
16
  children: {
17
17
  [realname: string]: {
package/lib/types.js CHANGED
@@ -1,14 +1,5 @@
1
- import { Canonical, } from "./extractor/index.js";
1
+ import { Canonical, pgTypeKinds, } from "./extractor/index.js";
2
2
  // To be updated when we add support for other kinds
3
- export const allowed_kind_names = [
4
- "tables",
5
- "views",
6
- "materializedViews",
7
- "enums",
8
- "composites",
9
- "functions",
10
- "domains",
11
- "ranges",
12
- ];
3
+ export const allowed_kind_names = pgTypeKinds;
13
4
  /* convenience function to create a generator with type inference */
14
5
  export const createGenerator = (generatorCreator) => generatorCreator;
package/lib/zod/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { FunctionReturnTypeKind, } from "../extractor/index.js";
1
+ import { Canonical, FunctionReturnTypeKind, } from "../extractor/index.js";
2
2
  import { allowed_kind_names, createGenerator } from "../types.js";
3
3
  import { Import } from "../imports.js";
4
4
  import { builtins } from "./builtins.js";
@@ -45,27 +45,31 @@ export const Zod = createGenerator(opts => {
45
45
  let base;
46
46
  if (type.kind === FunctionReturnTypeKind.ExistingTable) {
47
47
  base = to_snake_case(type.name);
48
+ ctx.imports.add(Import.fromInternal({
49
+ source: ctx.source,
50
+ type,
51
+ withName: base,
52
+ typeOnly: false,
53
+ }));
48
54
  }
49
- else if (type.schema === "pg_catalog") {
55
+ else if (type.schema === "pg_catalog" ||
56
+ type.kind === Canonical.Kind.Base ||
57
+ type.kind === Canonical.Kind.Pseudo) {
50
58
  const name = type.canonical_name;
51
59
  const format = builtins[name];
52
60
  if (format)
53
61
  base = format;
54
62
  else {
55
- opts?.warnings?.add(`(zod) Unknown builtin type: ${name}. Pass 'zod.builtinMap' to map this type. Defaulting to "z.unknown()".`);
63
+ opts?.warnings?.add(`(zod) Unknown base type: ${name}. Pass 'zod.builtinMap' to map this type. Defaulting to "z.unknown()".`);
56
64
  base = "z.unknown()";
57
65
  }
58
- }
59
- else
60
- base = to_snake_case(type.name);
61
- if (type.schema === "pg_catalog") {
62
66
  ctx.imports.add(new Import({
63
67
  from: "zod",
64
68
  namedImports: ["z"],
65
69
  }));
66
70
  }
67
71
  else {
68
- // before adding modifiers, add the import
72
+ base = to_snake_case(type.name);
69
73
  ctx.imports.add(Import.fromInternal({
70
74
  source: ctx.source,
71
75
  type,
@@ -217,14 +221,14 @@ export const Zod = createGenerator(opts => {
217
221
  schemaIndex(ctx, schema, main_generator) {
218
222
  const actual_kinds = allowed_kind_names.filter(kind => schema[kind].length);
219
223
  // we could in theory use the imports from GeneratorContext here, but this works fine
220
- let out = actual_kinds.map(kind => `import * as zod_${kind} from "./${kind}/index.ts";`).join("\n");
224
+ let out = actual_kinds.map(kind => `import * as zod_${kind}s from "./${kind}s/index.ts";`).join("\n");
221
225
  out += "\n\n";
222
226
  out += `export const ${this.formatSchemaName(schema.name)} = {\n`;
223
227
  for (const kind of actual_kinds) {
224
228
  const items = schema[kind];
225
229
  if (items.length === 0)
226
230
  continue;
227
- out += `\t${kind}: {\n`;
231
+ out += `\t${kind}s: {\n`;
228
232
  const formatted = items
229
233
  .map(each => {
230
234
  const formatted = this.formatSchemaMemberName(each);
@@ -267,7 +271,7 @@ export const Zod = createGenerator(opts => {
267
271
  if (!formatted.length)
268
272
  return "";
269
273
  let out = "";
270
- out += "\t// " + kind + "\n";
274
+ out += "\t// " + kind + "s\n";
271
275
  out += join(formatted.map(t => {
272
276
  const isDefault = defaultSchema === schema.name;
273
277
  let qualified = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "true-pg",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "module": "lib/index.js",
6
6
  "main": "lib/index.js",