@typesql/pg 0.0.3 → 0.1.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/CHANGELOG.md +32 -0
- package/README.md +41 -23
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -0
- package/dist/client.d.ts +7 -29
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +44 -73
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/introspect/cli.d.ts +24 -0
- package/dist/introspect/cli.d.ts.map +1 -0
- package/dist/introspect/cli.js +121 -0
- package/dist/introspect/cli.js.map +1 -0
- package/dist/introspect/emit.d.ts +30 -0
- package/dist/introspect/emit.d.ts.map +1 -0
- package/dist/introspect/emit.js +144 -0
- package/dist/introspect/emit.js.map +1 -0
- package/dist/introspect/index.d.ts +5 -0
- package/dist/introspect/index.d.ts.map +1 -0
- package/dist/introspect/index.js +5 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/introspect/introspect.d.ts +67 -0
- package/dist/introspect/introspect.d.ts.map +1 -0
- package/dist/introspect/introspect.js +109 -0
- package/dist/introspect/introspect.js.map +1 -0
- package/dist/introspect/nullability.d.ts +60 -0
- package/dist/introspect/nullability.d.ts.map +1 -0
- package/dist/introspect/nullability.js +354 -0
- package/dist/introspect/nullability.js.map +1 -0
- package/dist/type-map.d.ts +42 -14
- package/dist/type-map.d.ts.map +1 -1
- package/package.json +10 -3
- package/src/bin.ts +5 -0
- package/src/client.ts +45 -77
- package/src/index.ts +14 -14
- package/src/introspect/cli.ts +138 -0
- package/src/introspect/emit.ts +168 -0
- package/src/introspect/index.ts +12 -0
- package/src/introspect/introspect.ts +221 -0
- package/src/introspect/nullability.ts +356 -0
- package/src/type-map.ts +42 -14
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IntrospectedColumn, IntrospectedDatabase, IntrospectedRelation } from "./introspect.js";
|
|
2
|
+
export interface GenerateOptions {
|
|
3
|
+
/** Name of the exported schema interface. Default `"DB"`. */
|
|
4
|
+
readonly typeName?: string;
|
|
5
|
+
/** Module the column helpers are imported from. Default `"@typesql/core"`. */
|
|
6
|
+
readonly importFrom?: string;
|
|
7
|
+
/** Extra lines after the helper import, e.g. `import type { HistoryItem } from "./json.js";`. */
|
|
8
|
+
readonly imports?: readonly string[];
|
|
9
|
+
/**
|
|
10
|
+
* TypeScript types of `json` / `jsonb` columns: a map keyed `"table.column"` (public) or
|
|
11
|
+
* `"schema.table.column"`, or a function returning the TS type source for a column (or
|
|
12
|
+
* `undefined`). Such a column is declared as `Json<T>`: still jsonb to the SQL, read as `T`,
|
|
13
|
+
* written with `sql.json(value)`. Other columns are an error (use `column` for those).
|
|
14
|
+
*/
|
|
15
|
+
readonly columnTypes?: Readonly<Record<string, string>> | ((column: IntrospectedColumn, relation: IntrospectedRelation) => string | undefined);
|
|
16
|
+
/**
|
|
17
|
+
* Full control over one column: return the TypeScript source of its descriptor
|
|
18
|
+
* (`Col<"jsonb">`, a helper of your own, ...) or `undefined` to keep the default.
|
|
19
|
+
*/
|
|
20
|
+
readonly column?: (column: IntrospectedColumn, relation: IntrospectedRelation) => string | undefined;
|
|
21
|
+
/** Emit table and column comments and notes as JSDoc. Default `true`. */
|
|
22
|
+
readonly comments?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* TypeScript source declaring the typesql schema of an introspected database: `public`
|
|
26
|
+
* relations at the top level, other schemas nested (`DB["auth"]["sessions"]`), views and
|
|
27
|
+
* materialized views as `View<…>`, enums under `$types`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateSource(db: IntrospectedDatabase, options?: GenerateOptions): string;
|
|
30
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/introspect/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtG,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EACjB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAChC,CAAC,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACzF;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC;IACrG,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AA2BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,oBAAoB,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CA8G9F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2
|
+
const key = (name) => (IDENT.test(name) ? name : JSON.stringify(name));
|
|
3
|
+
const str = (s) => JSON.stringify(s);
|
|
4
|
+
function doc(lines, indent) {
|
|
5
|
+
const text = lines.flatMap((l) => l.split("\n")).map((l) => l.replace(/\*\//g, "*\\/").trimEnd());
|
|
6
|
+
if (text.length === 0)
|
|
7
|
+
return "";
|
|
8
|
+
if (text.length === 1)
|
|
9
|
+
return `${indent}/** ${text[0]} */\n`;
|
|
10
|
+
return `${indent}/**\n${text.map((l) => `${indent} *${l ? ` ${l}` : ""}`).join("\n")}\n${indent} */\n`;
|
|
11
|
+
}
|
|
12
|
+
const helperFor = (nullable, hasDefault) => nullable ? (hasDefault ? "NullableGenerated" : "Nullable") : hasDefault ? "Generated" : "Col";
|
|
13
|
+
function columnNotes(c) {
|
|
14
|
+
const notes = [];
|
|
15
|
+
if (c.comment)
|
|
16
|
+
notes.push(c.comment);
|
|
17
|
+
if (c.domain)
|
|
18
|
+
notes.push(`Domain \`${c.domain}\`.`);
|
|
19
|
+
else if (c.declaredType === "citext")
|
|
20
|
+
notes.push("`citext`: typed as `text`.");
|
|
21
|
+
if (c.generated !== null)
|
|
22
|
+
notes.push(`\`GENERATED ALWAYS AS (${c.generated}) STORED\`: cannot be written.`);
|
|
23
|
+
if (c.identity === "always")
|
|
24
|
+
notes.push("`GENERATED ALWAYS AS IDENTITY`: written only with `OVERRIDING SYSTEM VALUE`.");
|
|
25
|
+
return notes;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* TypeScript source declaring the typesql schema of an introspected database: `public`
|
|
29
|
+
* relations at the top level, other schemas nested (`DB["auth"]["sessions"]`), views and
|
|
30
|
+
* materialized views as `View<…>`, enums under `$types`.
|
|
31
|
+
*/
|
|
32
|
+
export function generateSource(db, options = {}) {
|
|
33
|
+
const typeName = options.typeName ?? "DB";
|
|
34
|
+
const comments = options.comments ?? true;
|
|
35
|
+
const columnTypes = options.columnTypes ?? {};
|
|
36
|
+
const used = new Set();
|
|
37
|
+
const usedKeys = new Set();
|
|
38
|
+
/** The TS type `columnTypes` gives a column, if any. */
|
|
39
|
+
const customType = (rel, col) => {
|
|
40
|
+
const qualified = `${rel.schema}.${rel.name}.${col.name}`;
|
|
41
|
+
const short = `${rel.name}.${col.name}`;
|
|
42
|
+
let ts;
|
|
43
|
+
if (typeof columnTypes === "function")
|
|
44
|
+
ts = columnTypes(col, rel);
|
|
45
|
+
else {
|
|
46
|
+
const k = qualified in columnTypes ? qualified : rel.schema === "public" && short in columnTypes ? short : undefined;
|
|
47
|
+
if (k !== undefined) {
|
|
48
|
+
usedKeys.add(k);
|
|
49
|
+
ts = columnTypes[k];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (ts !== undefined && col.type !== "json" && col.type !== "jsonb") {
|
|
53
|
+
throw new Error(`columnTypes: ${JSON.stringify(rel.schema === "public" ? short : qualified)} has type ${col.type}; columnTypes only types json / jsonb columns (use the column hook for others)`);
|
|
54
|
+
}
|
|
55
|
+
return ts;
|
|
56
|
+
};
|
|
57
|
+
/** `Json<T>`, `Json<T, { nullable: true }>`, `Json<T, {}, "json">`, … */
|
|
58
|
+
const jsonDescriptor = (col, ts) => {
|
|
59
|
+
const flags = [...(col.nullable ? ["nullable: true"] : []), ...(col.hasDefault ? ["hasDefault: true"] : [])];
|
|
60
|
+
const flagSource = flags.length > 0 ? `{ ${flags.join("; ")} }` : "{}";
|
|
61
|
+
used.add("Json");
|
|
62
|
+
if (col.type === "json")
|
|
63
|
+
return `Json<${ts}, ${flagSource}, "json">`;
|
|
64
|
+
return flags.length > 0 ? `Json<${ts}, ${flagSource}>` : `Json<${ts}>`;
|
|
65
|
+
};
|
|
66
|
+
const relation = (rel, indent) => {
|
|
67
|
+
const isView = rel.kind === "view" || rel.kind === "materialized view";
|
|
68
|
+
const cols = rel.columns.map((c) => {
|
|
69
|
+
let descriptor = options.column?.(c, rel);
|
|
70
|
+
if (descriptor === undefined) {
|
|
71
|
+
const custom = customType(rel, c);
|
|
72
|
+
if (custom !== undefined)
|
|
73
|
+
descriptor = jsonDescriptor(c, custom);
|
|
74
|
+
else {
|
|
75
|
+
const helper = helperFor(c.nullable, c.hasDefault);
|
|
76
|
+
used.add(helper);
|
|
77
|
+
descriptor = `${helper}<${str(c.type)}>`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return `${comments ? doc(columnNotes(c), `${indent} `) : ""}${indent} ${key(c.name)}: ${descriptor};`;
|
|
81
|
+
});
|
|
82
|
+
const body = `{\n${cols.join("\n")}\n${indent}}`;
|
|
83
|
+
if (!isView)
|
|
84
|
+
return body;
|
|
85
|
+
used.add("View");
|
|
86
|
+
return `View<${body}>`;
|
|
87
|
+
};
|
|
88
|
+
const relDoc = (rel, indent) => {
|
|
89
|
+
if (!comments)
|
|
90
|
+
return "";
|
|
91
|
+
const kind = rel.kind === "table" ? [] : [`${rel.kind[0].toUpperCase()}${rel.kind.slice(1)}.`];
|
|
92
|
+
return doc([...(rel.comment ? [rel.comment] : []), ...kind], indent);
|
|
93
|
+
};
|
|
94
|
+
const topLevel = new Set(db.relations.filter((r) => r.schema === "public").map((r) => r.name));
|
|
95
|
+
const lines = [];
|
|
96
|
+
const namespaces = new Map();
|
|
97
|
+
for (const rel of db.relations) {
|
|
98
|
+
if (rel.schema === "public")
|
|
99
|
+
lines.push(`${relDoc(rel, " ")} ${key(rel.name)}: ${relation(rel, " ")};`);
|
|
100
|
+
else
|
|
101
|
+
namespaces.set(rel.schema, [...(namespaces.get(rel.schema) ?? []), rel]);
|
|
102
|
+
}
|
|
103
|
+
for (const [schema, rels] of namespaces) {
|
|
104
|
+
if (topLevel.has(schema)) {
|
|
105
|
+
throw new Error(`schema "${schema}" has the same name as the table "public.${schema}": typesql keeps public relations and schemas in one object`);
|
|
106
|
+
}
|
|
107
|
+
const body = rels.map((r) => `${relDoc(r, " ")} ${key(r.name)}: ${relation(r, " ")};`);
|
|
108
|
+
lines.push(` ${key(schema)}: {\n${body.join("\n")}\n };`);
|
|
109
|
+
}
|
|
110
|
+
if (db.enums.length > 0) {
|
|
111
|
+
// typesql's enum registry is flat (`Col<"mood">`, schema qualifiers are dropped), so enums
|
|
112
|
+
// of the same name in different schemas share an entry.
|
|
113
|
+
const byName = new Map();
|
|
114
|
+
for (const e of db.enums) {
|
|
115
|
+
const entry = byName.get(e.name) ?? { values: new Set(), schemas: [] };
|
|
116
|
+
for (const v of e.values)
|
|
117
|
+
entry.values.add(v);
|
|
118
|
+
entry.schemas.push(e.schema);
|
|
119
|
+
byName.set(e.name, entry);
|
|
120
|
+
}
|
|
121
|
+
const entries = [...byName].map(([name, { values, schemas }]) => {
|
|
122
|
+
const notes = comments && schemas.length > 1 ? doc([`Enums of the same name in ${schemas.map((s) => `\`${s}\``).join(", ")}.`], " ") : "";
|
|
123
|
+
return `${notes} ${key(name)}: ${[...values].map(str).join(" | ") || "never"};`;
|
|
124
|
+
});
|
|
125
|
+
lines.push(` $types: {\n${entries.join("\n")}\n };`);
|
|
126
|
+
}
|
|
127
|
+
const helpers = ["Col", "Generated", "Json", "Nullable", "NullableGenerated", "View"].filter((h) => used.has(h));
|
|
128
|
+
const out = [
|
|
129
|
+
`// Generated by \`typesql introspect\` (@typesql/pg) from PostgreSQL ${db.version.split(/[.\s]/)[0]}. Do not edit.`,
|
|
130
|
+
...(helpers.length > 0 ? [`import type { ${helpers.join(", ")} } from ${str(options.importFrom ?? "@typesql/core")};`] : []),
|
|
131
|
+
...(options.imports ?? []),
|
|
132
|
+
"",
|
|
133
|
+
`export interface ${key(typeName)} {`,
|
|
134
|
+
...lines,
|
|
135
|
+
"}",
|
|
136
|
+
"",
|
|
137
|
+
];
|
|
138
|
+
const unknownKeys = typeof columnTypes === "function" ? [] : Object.keys(columnTypes).filter((k) => !usedKeys.has(k));
|
|
139
|
+
if (unknownKeys.length > 0 && options.column === undefined) {
|
|
140
|
+
throw new Error(`columnTypes: no column ${unknownKeys.map((k) => JSON.stringify(k)).join(", ")} (keys are "table.column" for public tables, else "schema.table.column")`);
|
|
141
|
+
}
|
|
142
|
+
return out.join("\n");
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/introspect/emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { introspect, type IntrospectOptions, type IntrospectedDatabase, type IntrospectedRelation, type IntrospectedColumn, type IntrospectedEnum, type RelationKind, } from "./introspect.js";
|
|
2
|
+
export { generateSource, type GenerateOptions } from "./emit.js";
|
|
3
|
+
export { ViewNullability, parseNodeTree, type NullabilityOptions, type QueryFn } from "./nullability.js";
|
|
4
|
+
export { main, type IntrospectConfig } from "./cli.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/introspect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,IAAI,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/introspect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,GAOX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAwB,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAyC,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,IAAI,EAAyB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { PgQueryable } from "../client.js";
|
|
2
|
+
import { type NullabilityOptions } from "./nullability.js";
|
|
3
|
+
export type RelationKind = "table" | "partitioned table" | "view" | "materialized view" | "foreign table";
|
|
4
|
+
export interface IntrospectedColumn {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/**
|
|
7
|
+
* Canonical Postgres type name as typesql spells it: `int4`, `timestamptz`, `varchar`, an enum
|
|
8
|
+
* name, `${T}[]` for arrays. Domains are replaced by their base type; `citext` is `text`.
|
|
9
|
+
*/
|
|
10
|
+
readonly type: string;
|
|
11
|
+
/** The column's type as Postgres prints it (`character varying(40)`, a domain name, ...). */
|
|
12
|
+
readonly declaredType: string;
|
|
13
|
+
/** The domain the column is declared with, if any (`public.positive`). */
|
|
14
|
+
readonly domain: string | null;
|
|
15
|
+
readonly nullable: boolean;
|
|
16
|
+
/** Optional on INSERT: a DEFAULT, serial, identity or generated column. Always false for views. */
|
|
17
|
+
readonly hasDefault: boolean;
|
|
18
|
+
/** `GENERATED ALWAYS AS IDENTITY` / `GENERATED BY DEFAULT AS IDENTITY`. */
|
|
19
|
+
readonly identity: "always" | "by default" | null;
|
|
20
|
+
/** The expression of a `GENERATED ALWAYS AS (…) STORED` column. */
|
|
21
|
+
readonly generated: string | null;
|
|
22
|
+
/** The DEFAULT expression. */
|
|
23
|
+
readonly default: string | null;
|
|
24
|
+
readonly comment: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface IntrospectedRelation {
|
|
27
|
+
readonly schema: string;
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly kind: RelationKind;
|
|
30
|
+
readonly comment: string | null;
|
|
31
|
+
readonly columns: readonly IntrospectedColumn[];
|
|
32
|
+
}
|
|
33
|
+
export interface IntrospectedEnum {
|
|
34
|
+
readonly schema: string;
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/** Labels in sort order. */
|
|
37
|
+
readonly values: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
export interface IntrospectedDatabase {
|
|
40
|
+
/** `server_version`, e.g. `17.2`. */
|
|
41
|
+
readonly version: string;
|
|
42
|
+
/** Schemas that were read, in order. */
|
|
43
|
+
readonly schemas: readonly string[];
|
|
44
|
+
readonly relations: readonly IntrospectedRelation[];
|
|
45
|
+
/** Enums of the read schemas and enums their columns use. */
|
|
46
|
+
readonly enums: readonly IntrospectedEnum[];
|
|
47
|
+
}
|
|
48
|
+
export interface IntrospectOptions {
|
|
49
|
+
/** Schemas to read. Default: every schema except `pg_catalog`, `information_schema` and `pg_*`. */
|
|
50
|
+
readonly schemas?: readonly string[];
|
|
51
|
+
/**
|
|
52
|
+
* Relations to leave out: names (`kysely_migration`) or `schema.name`, with `*` matching any
|
|
53
|
+
* run of characters (`kysely_migration*`, `audit.*`).
|
|
54
|
+
*/
|
|
55
|
+
readonly exclude?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* View columns to treat as NOT NULL when the analysis cannot prove it, called with the view's
|
|
58
|
+
* name and the column's name.
|
|
59
|
+
*/
|
|
60
|
+
readonly viewNotNull?: NullabilityOptions["notNull"];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read tables, views, materialized views, foreign tables and enums of a live database through
|
|
64
|
+
* any node-postgres-style client (`Client`, `Pool`, `PoolClient`).
|
|
65
|
+
*/
|
|
66
|
+
export declare function introspect(client: PgQueryable, options?: IntrospectOptions): Promise<IntrospectedDatabase>;
|
|
67
|
+
//# sourceMappingURL=introspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../src/introspect/introspect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,mBAAmB,GAAG,MAAM,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAE1G,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,mGAAmG;IACnG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,GAAG,IAAI,CAAC;IAClD,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACpD,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,mGAAmG;IACnG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CACtD;AAuDD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA+FpH"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ViewNullability } from "./nullability.js";
|
|
2
|
+
const globToRegExp = (glob) => new RegExp(`^${glob.split("*").map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*")}$`);
|
|
3
|
+
const KINDS = {
|
|
4
|
+
r: "table",
|
|
5
|
+
p: "partitioned table",
|
|
6
|
+
v: "view",
|
|
7
|
+
m: "materialized view",
|
|
8
|
+
f: "foreign table",
|
|
9
|
+
};
|
|
10
|
+
/** Postgres type names typesql spells differently. */
|
|
11
|
+
const TYPE_ALIASES = { citext: "text" };
|
|
12
|
+
function resolver(types) {
|
|
13
|
+
const resolve = (oid) => {
|
|
14
|
+
const t = types.get(oid);
|
|
15
|
+
if (!t)
|
|
16
|
+
return { type: "unknown", notnull: false, enumOid: null, domain: null };
|
|
17
|
+
if (t.typtype === "d") {
|
|
18
|
+
const base = resolve(t.basetype);
|
|
19
|
+
return { ...base, notnull: base.notnull || t.notnull, domain: `${t.schema}.${t.name}` };
|
|
20
|
+
}
|
|
21
|
+
const elem = t.elem !== "0" ? types.get(t.elem) : undefined;
|
|
22
|
+
if (elem && elem.array === t.oid) {
|
|
23
|
+
const inner = resolve(elem.oid);
|
|
24
|
+
return { type: inner.type.endsWith("[]") ? inner.type : `${inner.type}[]`, notnull: false, enumOid: inner.enumOid, domain: null };
|
|
25
|
+
}
|
|
26
|
+
return { type: TYPE_ALIASES[t.name] ?? t.name, notnull: false, enumOid: t.typtype === "e" ? t.oid : null, domain: null };
|
|
27
|
+
};
|
|
28
|
+
return resolve;
|
|
29
|
+
}
|
|
30
|
+
/** Default schema filter: everything but the system schemas. */
|
|
31
|
+
const USER_SCHEMAS = `n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg\\_%'`;
|
|
32
|
+
/**
|
|
33
|
+
* Read tables, views, materialized views, foreign tables and enums of a live database through
|
|
34
|
+
* any node-postgres-style client (`Client`, `Pool`, `PoolClient`).
|
|
35
|
+
*/
|
|
36
|
+
export async function introspect(client, options = {}) {
|
|
37
|
+
const q = async (text, values) => (await client.query(text, values)).rows;
|
|
38
|
+
const [{ version }] = (await q(`SELECT current_setting('server_version') AS version`));
|
|
39
|
+
const schemaRows = options.schemas
|
|
40
|
+
? await q(`SELECT n.nspname AS name FROM unnest($1::text[]) WITH ORDINALITY AS s(name, i)
|
|
41
|
+
JOIN pg_namespace n ON n.nspname = s.name ORDER BY s.i`, [[...options.schemas]])
|
|
42
|
+
: await q(`SELECT n.nspname AS name FROM pg_namespace n WHERE ${USER_SCHEMAS}
|
|
43
|
+
ORDER BY n.nspname <> 'public', n.nspname`);
|
|
44
|
+
const schemas = schemaRows.map((r) => r.name);
|
|
45
|
+
const missing = (options.schemas ?? []).filter((s) => !schemas.includes(s));
|
|
46
|
+
if (missing.length > 0)
|
|
47
|
+
throw new Error(`schema ${missing.map((s) => JSON.stringify(s)).join(", ")} does not exist`);
|
|
48
|
+
const types = new Map((await q(`SELECT t.oid::int8::text AS oid, t.typname AS name, n.nspname AS schema, t.typtype,
|
|
49
|
+
t.typbasetype::int8::text AS basetype, t.typelem::int8::text AS elem,
|
|
50
|
+
t.typarray::int8::text AS array, t.typnotnull AS notnull
|
|
51
|
+
FROM pg_type t JOIN pg_namespace n ON n.oid = t.typnamespace`)).map((t) => [t.oid, t]));
|
|
52
|
+
const resolve = resolver(types);
|
|
53
|
+
const excluded = (options.exclude ?? []).map(globToRegExp);
|
|
54
|
+
const relRows = (await q(`SELECT c.oid::int8::text AS oid, n.nspname AS schema, c.relname AS name, c.relkind,
|
|
55
|
+
obj_description(c.oid, 'pg_class') AS comment
|
|
56
|
+
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
57
|
+
WHERE c.relkind IN ('r', 'p', 'v', 'm', 'f') AND n.nspname = ANY($1::text[])
|
|
58
|
+
ORDER BY array_position($1::text[], n.nspname::text), c.relname`, [schemas])).filter((r) => !excluded.some((re) => re.test(r.name) || re.test(`${r.schema}.${r.name}`)));
|
|
59
|
+
const colRows = await q(`SELECT a.attrelid::int8::text AS relid, a.attname AS name, a.atttypid::int8::text AS typid,
|
|
60
|
+
format_type(a.atttypid, a.atttypmod) AS declared, a.attnotnull AS notnull,
|
|
61
|
+
a.attidentity AS identity, a.attgenerated AS generated,
|
|
62
|
+
pg_get_expr(d.adbin, d.adrelid) AS default, col_description(a.attrelid, a.attnum) AS comment
|
|
63
|
+
FROM pg_attribute a
|
|
64
|
+
LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
|
|
65
|
+
WHERE a.attrelid = ANY($1::oid[]) AND a.attnum > 0 AND NOT a.attisdropped
|
|
66
|
+
ORDER BY a.attrelid, a.attnum`, [relRows.map((r) => r.oid)]);
|
|
67
|
+
const colsByRel = new Map();
|
|
68
|
+
for (const c of colRows)
|
|
69
|
+
colsByRel.set(c.relid, [...(colsByRel.get(c.relid) ?? []), c]);
|
|
70
|
+
const views = new ViewNullability((text, values) => client.query(text, values), {
|
|
71
|
+
...(options.viewNotNull && { notNull: options.viewNotNull }),
|
|
72
|
+
});
|
|
73
|
+
const usedEnums = new Set();
|
|
74
|
+
const relations = [];
|
|
75
|
+
for (const rel of relRows) {
|
|
76
|
+
const kind = KINDS[rel.relkind];
|
|
77
|
+
const isView = kind === "view" || kind === "materialized view";
|
|
78
|
+
const viewNotNull = isView ? await views.notNull(rel.oid) : [];
|
|
79
|
+
const columns = (colsByRel.get(rel.oid) ?? []).map((c, i) => {
|
|
80
|
+
const t = resolve(c.typid);
|
|
81
|
+
if (t.enumOid)
|
|
82
|
+
usedEnums.add(t.enumOid);
|
|
83
|
+
const generated = c.generated !== "" ? c.default : null;
|
|
84
|
+
const identity = c.identity === "a" ? "always" : c.identity === "d" ? "by default" : null;
|
|
85
|
+
return {
|
|
86
|
+
name: c.name,
|
|
87
|
+
type: t.type,
|
|
88
|
+
declaredType: c.declared,
|
|
89
|
+
domain: t.domain,
|
|
90
|
+
nullable: isView ? !viewNotNull[i] : !(c.notnull || t.notnull),
|
|
91
|
+
hasDefault: !isView && (c.default !== null || identity !== null || generated !== null),
|
|
92
|
+
identity,
|
|
93
|
+
generated,
|
|
94
|
+
default: generated === null ? c.default : null,
|
|
95
|
+
comment: c.comment,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
relations.push({ schema: rel.schema, name: rel.name, kind, comment: rel.comment, columns });
|
|
99
|
+
}
|
|
100
|
+
const enumRows = await q(`SELECT t.oid::int8::text AS oid, n.nspname AS schema, t.typname AS name,
|
|
101
|
+
array_agg(e.enumlabel::text ORDER BY e.enumsortorder) AS values
|
|
102
|
+
FROM pg_type t JOIN pg_namespace n ON n.oid = t.typnamespace JOIN pg_enum e ON e.enumtypid = t.oid
|
|
103
|
+
WHERE n.nspname = ANY($1::text[]) OR t.oid = ANY($2::oid[])
|
|
104
|
+
GROUP BY t.oid, n.nspname, t.typname
|
|
105
|
+
ORDER BY t.typname, n.nspname`, [schemas, [...usedEnums]]);
|
|
106
|
+
const enums = enumRows.map(({ schema, name, values }) => ({ schema, name, values }));
|
|
107
|
+
return { version, schemas, relations, enums };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=introspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../src/introspect/introspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nullability of view columns, derived from the view's query tree.
|
|
3
|
+
*
|
|
4
|
+
* Postgres records no NOT NULL information for view (or materialized view) columns. Its rewrite
|
|
5
|
+
* rule (`pg_rewrite.ev_action`, the `_RETURN` rule) holds the parsed query, though, and from
|
|
6
|
+
* PostgreSQL 16 every column reference in it carries `varnullingrels`, the outer joins that can
|
|
7
|
+
* null it. A view column is NOT NULL here only when its expression provably cannot be NULL: a
|
|
8
|
+
* NOT NULL table column that no outer join nulls, a non-NULL constant, a cast or a strict
|
|
9
|
+
* operator over such values, a CASE whose every branch is NOT NULL, `count(*)`, ... Anything
|
|
10
|
+
* else (function calls outside a short list, scalar subqueries, set-returning function columns)
|
|
11
|
+
* is nullable. On PostgreSQL 15 and older every column reference counts as nullable.
|
|
12
|
+
*
|
|
13
|
+
* This module has no imports so that scripts/pg-catalog-from-pg.mjs can load it with Node's
|
|
14
|
+
* type stripping.
|
|
15
|
+
*/
|
|
16
|
+
/** Runs a query: node-postgres' `client.query(text, values)` fits. */
|
|
17
|
+
export type QueryFn = (text: string, values?: unknown[]) => Promise<{
|
|
18
|
+
readonly rows: readonly any[];
|
|
19
|
+
}>;
|
|
20
|
+
export interface NullabilityOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Columns known never to be NULL that the analysis cannot prove (typically columns of a
|
|
23
|
+
* set-returning function). Called with the view's name and the column's name.
|
|
24
|
+
*/
|
|
25
|
+
readonly notNull?: (view: string, column: string) => boolean;
|
|
26
|
+
}
|
|
27
|
+
/** A node of a parsed `pg_node_tree`: `{ _: "VAR", varno: "1", … }`. */
|
|
28
|
+
export interface Node {
|
|
29
|
+
readonly _: string;
|
|
30
|
+
readonly [field: string]: NodeValue;
|
|
31
|
+
}
|
|
32
|
+
export type NodeValue = Node | readonly NodeValue[] | string | null;
|
|
33
|
+
/** Parse a node tree into plain values: nodes as objects, lists as arrays, `<>` as null. */
|
|
34
|
+
export declare function parseNodeTree(text: string): NodeValue;
|
|
35
|
+
/** Per-column NOT NULL of views and materialized views; caches what it reads. */
|
|
36
|
+
export declare class ViewNullability {
|
|
37
|
+
private readonly query;
|
|
38
|
+
private readonly options;
|
|
39
|
+
private readonly views;
|
|
40
|
+
private readonly atts;
|
|
41
|
+
private procs;
|
|
42
|
+
private operators;
|
|
43
|
+
constructor(query: QueryFn, options?: NullabilityOptions);
|
|
44
|
+
/** NOT NULL flags of the view's columns, in column order. `relid` is the view's `pg_class.oid`. */
|
|
45
|
+
notNull(relid: string | number): Promise<boolean[]>;
|
|
46
|
+
private analyze;
|
|
47
|
+
private loadProcs;
|
|
48
|
+
private loadOperators;
|
|
49
|
+
/** A built-in operator that returns a value for non-NULL operands. */
|
|
50
|
+
private strictOperator;
|
|
51
|
+
private columns;
|
|
52
|
+
/** Is output column `attno` (1-based) of a (sub)query NOT NULL? */
|
|
53
|
+
private queryColumn;
|
|
54
|
+
private variable;
|
|
55
|
+
/** Column `attno` of a single set-returning function in FROM (`WITH ORDINALITY` adds a NOT NULL counter). */
|
|
56
|
+
private functionColumn;
|
|
57
|
+
private all;
|
|
58
|
+
private expr;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=nullability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullability.d.ts","sourceRoot":"","sources":["../../src/introspect/nullability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,sEAAsE;AACtE,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAA;CAAE,CAAC,CAAC;AAEvG,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9D;AAED,wEAAwE;AACxE,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AACD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,SAAS,SAAS,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;AA8BpE,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CA2BrD;AAwDD,iFAAiF;AACjF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;IAC/D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqC;IAC1D,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,SAAS,CAA2C;IAE5D,YAAY,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAuB,EAG3D;IAED,mGAAmG;IACnG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQlD;YAEa,OAAO;IAoBrB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,aAAa;IAQrB,sEAAsE;YACxD,cAAc;IAK5B,OAAO,CAAC,OAAO;IAsBf,mEAAmE;YACrD,WAAW;YAeX,QAAQ;IAgCtB,6GAA6G;YAC/F,cAAc;YAYd,GAAG;YAKH,IAAI;CAsDnB"}
|