@onreza/sqlx-js 0.0.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +496 -0
  3. package/ROADMAP.md +28 -0
  4. package/dist/bin/sqlx-js.d.ts +2 -0
  5. package/dist/bin/sqlx-js.js +180 -0
  6. package/dist/src/bun-runtime.d.ts +7 -0
  7. package/dist/src/bun-runtime.js +45 -0
  8. package/dist/src/bun.d.ts +22 -0
  9. package/dist/src/bun.js +9 -0
  10. package/dist/src/cache.d.ts +36 -0
  11. package/dist/src/cache.js +104 -0
  12. package/dist/src/codegen.d.ts +2 -0
  13. package/dist/src/codegen.js +74 -0
  14. package/dist/src/commands/migrate.d.ts +63 -0
  15. package/dist/src/commands/migrate.js +283 -0
  16. package/dist/src/commands/prepare.d.ts +23 -0
  17. package/dist/src/commands/prepare.js +314 -0
  18. package/dist/src/commands/schema.d.ts +14 -0
  19. package/dist/src/commands/schema.js +72 -0
  20. package/dist/src/commands/watch.d.ts +21 -0
  21. package/dist/src/commands/watch.js +94 -0
  22. package/dist/src/config.d.ts +6 -0
  23. package/dist/src/config.js +23 -0
  24. package/dist/src/index.d.ts +23 -0
  25. package/dist/src/index.js +10 -0
  26. package/dist/src/pg/analyze.d.ts +13 -0
  27. package/dist/src/pg/analyze.js +479 -0
  28. package/dist/src/pg/extensions.d.ts +2 -0
  29. package/dist/src/pg/extensions.js +15 -0
  30. package/dist/src/pg/narrow.d.ts +3 -0
  31. package/dist/src/pg/narrow.js +146 -0
  32. package/dist/src/pg/oids.d.ts +10 -0
  33. package/dist/src/pg/oids.js +137 -0
  34. package/dist/src/pg/param-map.d.ts +12 -0
  35. package/dist/src/pg/param-map.js +180 -0
  36. package/dist/src/pg/schema.d.ts +61 -0
  37. package/dist/src/pg/schema.js +225 -0
  38. package/dist/src/pg/wire.d.ts +134 -0
  39. package/dist/src/pg/wire.js +705 -0
  40. package/dist/src/postgres-runtime.d.ts +11 -0
  41. package/dist/src/postgres-runtime.js +150 -0
  42. package/dist/src/runtime.d.ts +69 -0
  43. package/dist/src/runtime.js +446 -0
  44. package/dist/src/scan/scanner.d.ts +12 -0
  45. package/dist/src/scan/scanner.js +283 -0
  46. package/dist/src/schema-snapshot.d.ts +104 -0
  47. package/dist/src/schema-snapshot.js +473 -0
  48. package/dist/src/typed.d.ts +25 -0
  49. package/dist/src/typed.js +1 -0
  50. package/package.json +78 -0
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { runPrepare } from "../src/commands/prepare.js";
6
+ import { runWatch } from "../src/commands/watch.js";
7
+ import { migrateRun, migrateInfo, migrateRevert, migrateAdd } from "../src/commands/migrate.js";
8
+ import { applyShadowMigrations, runSchemaCheck, runSchemaDump } from "../src/commands/schema.js";
9
+ function packageVersion() {
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+ for (const path of [join(here, "../package.json"), join(here, "../../package.json")]) {
12
+ if (!existsSync(path))
13
+ continue;
14
+ const pkg = JSON.parse(readFileSync(path, "utf8"));
15
+ if (typeof pkg.version === "string")
16
+ return pkg.version;
17
+ }
18
+ throw new Error("sqlx-js: cannot locate package.json for version");
19
+ }
20
+ const VERSION = packageVersion();
21
+ function help() {
22
+ console.error(`sqlx-js — compile-time-checked SQL for TypeScript + Postgres (v${VERSION})
23
+
24
+ usage:
25
+ sqlx-js prepare [--check | --watch] [--root <dir>] [--dts <path>] [--no-prune] [--shadow-url <url>]
26
+ sqlx-js migrate run [--lock-timeout <ms>] | info | revert [--lock-timeout <ms>] | add <name>
27
+ sqlx-js schema dump | check [--schema <path>] [--manifest <path>] [--no-manifest] [--shadow-url <url>]
28
+ sqlx-js --version
29
+
30
+ env:
31
+ DATABASE_URL=postgres://... (supports ?sslmode=require|verify-ca|verify-full)
32
+ SHADOW_DATABASE_URL=postgres://... (optional throwaway DB for prepare/schema checks)
33
+
34
+ flags:
35
+ --root <dir> scan root (default: cwd)
36
+ --dts <path> declarations output (default: <root>/sqlx-js-env.d.ts)
37
+ --check offline mode: validate cache vs sources, no DB
38
+ --watch re-prepare on file change (persistent PG connection)
39
+ --no-prune keep orphaned cache entries (default: remove)
40
+ --migrations <dir> migrations directory (default: <root>/migrations)
41
+ --lock-timeout <ms> advisory-lock acquisition timeout for migrate run/revert
42
+ --shadow-url <url> apply migrations to this DB, then prepare/introspect against it
43
+ --schema <path> schema snapshot path (default: <root>/.sqlx-js/schema/schema.json)
44
+ --manifest <path> LLM schema manifest path (default: <root>/.sqlx-js/schema/schema.md)
45
+ --no-manifest skip writing the LLM schema manifest during schema dump
46
+ `);
47
+ process.exit(2);
48
+ }
49
+ function arg(name, def) {
50
+ const argv = process.argv;
51
+ const eq = `${name}=`;
52
+ for (let i = 0; i < argv.length; i++) {
53
+ const a = argv[i];
54
+ if (a === name)
55
+ return argv[i + 1] ?? def;
56
+ if (a.startsWith(eq))
57
+ return a.slice(eq.length);
58
+ }
59
+ return def;
60
+ }
61
+ function flag(name) {
62
+ for (const a of process.argv) {
63
+ if (a === name)
64
+ return true;
65
+ }
66
+ return false;
67
+ }
68
+ const cmd = process.argv[2];
69
+ if (cmd === "--version" || cmd === "-v") {
70
+ console.log(VERSION);
71
+ process.exit(0);
72
+ }
73
+ if (cmd === "--help" || cmd === "-h" || !cmd) {
74
+ help();
75
+ }
76
+ const root = resolve(arg("--root", process.cwd()));
77
+ const databaseUrl = process.env.DATABASE_URL ?? "";
78
+ const shadowUrlArg = arg("--shadow-url");
79
+ const shadowUrl = shadowUrlArg ?? process.env.SHADOW_DATABASE_URL;
80
+ const cacheDir = join(root, ".sqlx-js");
81
+ const dtsArg = arg("--dts");
82
+ const dtsPath = dtsArg ? resolve(dtsArg) : join(root, "sqlx-js-env.d.ts");
83
+ const migrationsDir = join(root, arg("--migrations", "migrations"));
84
+ const schemaArg = arg("--schema");
85
+ const schemaPath = schemaArg ? resolve(schemaArg) : join(root, ".sqlx-js/schema/schema.json");
86
+ const manifestArg = arg("--manifest");
87
+ const manifestPath = manifestArg ? resolve(manifestArg) : join(root, ".sqlx-js/schema/schema.md");
88
+ if (cmd === "prepare") {
89
+ if (flag("--check") && shadowUrlArg) {
90
+ console.error("--shadow-url cannot be used with prepare --check; use live prepare or schema check --shadow-url");
91
+ process.exit(2);
92
+ }
93
+ const prepareShadowUrl = flag("--check") ? undefined : shadowUrl;
94
+ const prepareDatabaseUrl = prepareShadowUrl ?? databaseUrl;
95
+ if (!flag("--check") && !prepareDatabaseUrl) {
96
+ console.error("DATABASE_URL is required for prepare (use --check for offline)");
97
+ process.exit(2);
98
+ }
99
+ const opts = {
100
+ root,
101
+ databaseUrl: prepareDatabaseUrl,
102
+ cacheDir,
103
+ dtsPath,
104
+ check: flag("--check"),
105
+ prune: !flag("--no-prune"),
106
+ };
107
+ if (flag("--watch")) {
108
+ if (flag("--check")) {
109
+ console.error("--watch and --check are mutually exclusive");
110
+ process.exit(2);
111
+ }
112
+ await runWatch({
113
+ ...opts,
114
+ ...(prepareShadowUrl
115
+ ? {
116
+ beforePrepare: async () => {
117
+ const result = await applyShadowMigrations(prepareShadowUrl, migrationsDir);
118
+ return { resetSession: result.applied > 0 };
119
+ },
120
+ }
121
+ : {}),
122
+ });
123
+ }
124
+ else {
125
+ if (prepareShadowUrl)
126
+ await applyShadowMigrations(prepareShadowUrl, migrationsDir);
127
+ await runPrepare(opts);
128
+ }
129
+ }
130
+ else if (cmd === "schema") {
131
+ const sub = process.argv[3];
132
+ const schemaDatabaseUrl = shadowUrl ?? databaseUrl;
133
+ if (!schemaDatabaseUrl) {
134
+ console.error("DATABASE_URL is required for schema commands (or pass --shadow-url)");
135
+ process.exit(2);
136
+ }
137
+ const opts = {
138
+ databaseUrl,
139
+ snapshotPath: schemaPath,
140
+ manifestPath,
141
+ writeManifest: !flag("--no-manifest"),
142
+ shadowUrl,
143
+ migrationsDir,
144
+ };
145
+ if (sub === "dump")
146
+ await runSchemaDump(opts);
147
+ else if (sub === "check")
148
+ await runSchemaCheck(opts);
149
+ else
150
+ help();
151
+ }
152
+ else if (cmd === "migrate") {
153
+ const sub = process.argv[3];
154
+ if (!databaseUrl && sub !== "add") {
155
+ console.error("DATABASE_URL is required");
156
+ process.exit(2);
157
+ }
158
+ const tRaw = arg("--lock-timeout");
159
+ const lockTimeoutMs = tRaw ? Number(tRaw) : undefined;
160
+ if (sub === "run") {
161
+ await migrateRun({ databaseUrl, migrationsDir, lockTimeoutMs });
162
+ }
163
+ else if (sub === "info")
164
+ await migrateInfo({ databaseUrl, migrationsDir });
165
+ else if (sub === "revert")
166
+ await migrateRevert({ databaseUrl, migrationsDir, lockTimeoutMs });
167
+ else if (sub === "add") {
168
+ const name = process.argv[4];
169
+ if (!name) {
170
+ console.error("migrate add: name required");
171
+ process.exit(2);
172
+ }
173
+ migrateAdd({ databaseUrl, migrationsDir, name });
174
+ }
175
+ else
176
+ help();
177
+ }
178
+ else {
179
+ help();
180
+ }
@@ -0,0 +1,7 @@
1
+ import { SQL } from "bun";
2
+ export type BunClient = SQL;
3
+ export declare function getClient(): BunClient;
4
+ export declare function setClient(client: BunClient): void;
5
+ export declare function close(): Promise<void>;
6
+ export declare const sql: import("./runtime.js").SqlRoot;
7
+ export declare const unsafe: (query: string, ...params: unknown[]) => Promise<Record<string, unknown>[]>;
@@ -0,0 +1,45 @@
1
+ import { SQL } from "bun";
2
+ import { createSqlRuntime } from "./runtime.js";
3
+ class BunRuntimeClient {
4
+ client;
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ async query(query, params) {
9
+ return await this.client.unsafe(query, params);
10
+ }
11
+ async transaction(fn) {
12
+ return await this.client.begin(async (tx) => {
13
+ return await fn(new BunRuntimeClient(tx));
14
+ });
15
+ }
16
+ async close() {
17
+ await this.client.close();
18
+ }
19
+ }
20
+ let defaultClient = null;
21
+ function createDefaultClient() {
22
+ const url = process.env.DATABASE_URL;
23
+ if (!url)
24
+ throw new Error("sqlx-js: DATABASE_URL is not set");
25
+ return new BunRuntimeClient(new SQL({ url, bigint: true }));
26
+ }
27
+ function getRuntimeClient() {
28
+ defaultClient ??= createDefaultClient();
29
+ return defaultClient;
30
+ }
31
+ export function getClient() {
32
+ return getRuntimeClient().client;
33
+ }
34
+ export function setClient(client) {
35
+ defaultClient = new BunRuntimeClient(client);
36
+ }
37
+ export async function close() {
38
+ if (defaultClient) {
39
+ await defaultClient.close();
40
+ defaultClient = null;
41
+ }
42
+ }
43
+ const runtime = createSqlRuntime(getRuntimeClient);
44
+ export const sql = runtime.sql;
45
+ export const unsafe = runtime.unsafe;
@@ -0,0 +1,22 @@
1
+ import * as rt from "./bun-runtime.js";
2
+ import type { Typed as TypedFor, TypedFile as TypedFileFor, TypedSql as TypedSqlFor } from "./typed.js";
3
+ export interface KnownQueries {
4
+ }
5
+ export interface KnownFileQueries {
6
+ }
7
+ export type { SqlxJsConfig } from "./config.js";
8
+ export type { SslMode, ConnConfig } from "./pg/wire.js";
9
+ export { PgError, ConnectionLostError } from "./pg/wire.js";
10
+ export { NoRowsError, TooManyRowsError } from "./runtime.js";
11
+ export type { TransactionOptions, MigrateOptions } from "./runtime.js";
12
+ export type { BunClient } from "./bun-runtime.js";
13
+ export type TypedFile = TypedFileFor<KnownFileQueries>;
14
+ export type TypedSql = TypedSqlFor<KnownQueries, KnownFileQueries>;
15
+ export type Typed = TypedFor<KnownQueries, KnownFileQueries, import("./runtime.js").TransactionOptions>;
16
+ export declare const sql: Typed;
17
+ export type Unsafe = (query: string, ...params: unknown[]) => Promise<Record<string, unknown>[]>;
18
+ export declare const unsafe: Unsafe;
19
+ export declare const getClient: typeof rt.getClient;
20
+ export declare const setClient: typeof rt.setClient;
21
+ export declare const close: typeof rt.close;
22
+ export { migrate, clearSqlFileCache, encodePgArrayLiteral, id } from "./runtime.js";
@@ -0,0 +1,9 @@
1
+ import * as rt from "./bun-runtime.js";
2
+ export { PgError, ConnectionLostError } from "./pg/wire.js";
3
+ export { NoRowsError, TooManyRowsError } from "./runtime.js";
4
+ export const sql = rt.sql;
5
+ export const unsafe = rt.unsafe;
6
+ export const getClient = rt.getClient;
7
+ export const setClient = rt.setClient;
8
+ export const close = rt.close;
9
+ export { migrate, clearSqlFileCache, encodePgArrayLiteral, id } from "./runtime.js";
@@ -0,0 +1,36 @@
1
+ export type CacheColumn = {
2
+ name: string;
3
+ typeOid: number;
4
+ tsType: string;
5
+ nullable: boolean;
6
+ override?: "non-null" | "nullable";
7
+ };
8
+ export type CacheEntry = {
9
+ query: string;
10
+ paramOids: number[];
11
+ paramTsTypes: string[];
12
+ paramNullable?: boolean[];
13
+ columns: CacheColumn[];
14
+ hasResultSet: boolean;
15
+ hasInline?: boolean;
16
+ filePaths?: string[];
17
+ degraded?: {
18
+ reason: string;
19
+ };
20
+ };
21
+ export declare function fingerprint(query: string): string;
22
+ export declare function effectiveNullable(c: CacheColumn): boolean;
23
+ export declare class Cache {
24
+ private dir;
25
+ constructor(dir: string);
26
+ ensure(): void;
27
+ has(fp: string): boolean;
28
+ read(fp: string): CacheEntry | null;
29
+ write(fp: string, entry: CacheEntry): void;
30
+ list(): {
31
+ fp: string;
32
+ entry: CacheEntry;
33
+ }[];
34
+ remove(fp: string): void;
35
+ prune(keep: Iterable<string>): string[];
36
+ }
@@ -0,0 +1,104 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, unlinkSync, renameSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ export function fingerprint(query) {
5
+ const norm = query.replace(/\s+/g, " ").trim();
6
+ return createHash("sha256").update(norm).digest("hex").slice(0, 16);
7
+ }
8
+ export function effectiveNullable(c) {
9
+ if (c.override === "non-null")
10
+ return false;
11
+ if (c.override === "nullable")
12
+ return true;
13
+ return c.nullable;
14
+ }
15
+ function parseEntryJson(path) {
16
+ let text;
17
+ try {
18
+ text = readFileSync(path, "utf8");
19
+ }
20
+ catch (err) {
21
+ throw new Error(`sqlx-js: cannot read cache entry ${path}: ${err.message}`);
22
+ }
23
+ try {
24
+ return JSON.parse(text);
25
+ }
26
+ catch (err) {
27
+ throw new Error(`sqlx-js: cache entry ${path} is not valid JSON: ${err.message}`);
28
+ }
29
+ }
30
+ function assertEntryShape(fp, raw) {
31
+ if (!raw || typeof raw !== "object" || !Array.isArray(raw.columns)) {
32
+ throw new Error(`sqlx-js: cache entry ${fp}.json is malformed`);
33
+ }
34
+ const cols = raw.columns;
35
+ if (cols.length > 0) {
36
+ const c = cols[0];
37
+ if ("forceNonNull" in c || "forceNullable" in c) {
38
+ throw new Error(`sqlx-js: cache entry ${fp}.json uses an older schema ` +
39
+ `(columns.forceNonNull/forceNullable). Re-run \`sqlx-js prepare\` to regenerate.`);
40
+ }
41
+ }
42
+ return raw;
43
+ }
44
+ export class Cache {
45
+ dir;
46
+ constructor(dir) {
47
+ this.dir = dir;
48
+ }
49
+ ensure() {
50
+ if (!existsSync(this.dir))
51
+ mkdirSync(this.dir, { recursive: true });
52
+ }
53
+ has(fp) {
54
+ return existsSync(join(this.dir, `${fp}.json`));
55
+ }
56
+ read(fp) {
57
+ const p = join(this.dir, `${fp}.json`);
58
+ if (!existsSync(p))
59
+ return null;
60
+ return assertEntryShape(fp, parseEntryJson(p));
61
+ }
62
+ write(fp, entry) {
63
+ this.ensure();
64
+ const final = join(this.dir, `${fp}.json`);
65
+ const tmp = `${final}.tmp-${randomBytes(4).toString("hex")}`;
66
+ writeFileSync(tmp, JSON.stringify(entry, null, 2));
67
+ try {
68
+ renameSync(tmp, final);
69
+ }
70
+ catch (err) {
71
+ try {
72
+ unlinkSync(tmp);
73
+ }
74
+ catch { }
75
+ throw err;
76
+ }
77
+ }
78
+ list() {
79
+ if (!existsSync(this.dir))
80
+ return [];
81
+ return readdirSync(this.dir)
82
+ .filter((f) => f.endsWith(".json") && !f.includes(".tmp-"))
83
+ .map((f) => {
84
+ const fp = f.replace(/\.json$/, "");
85
+ return { fp, entry: assertEntryShape(fp, parseEntryJson(join(this.dir, f))) };
86
+ });
87
+ }
88
+ remove(fp) {
89
+ const p = join(this.dir, `${fp}.json`);
90
+ if (existsSync(p))
91
+ unlinkSync(p);
92
+ }
93
+ prune(keep) {
94
+ const keepSet = new Set(keep);
95
+ const removed = [];
96
+ for (const { fp } of this.list()) {
97
+ if (!keepSet.has(fp)) {
98
+ this.remove(fp);
99
+ removed.push(fp);
100
+ }
101
+ }
102
+ return removed;
103
+ }
104
+ }
@@ -0,0 +1,2 @@
1
+ import { type CacheEntry } from "./cache.js";
2
+ export declare function emitDts(outPath: string, entries: CacheEntry[]): void;
@@ -0,0 +1,74 @@
1
+ import { writeFileSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { effectiveNullable } from "./cache.js";
4
+ function entrySignature(e) {
5
+ const paramTypes = e.paramTsTypes.map((t, i) => {
6
+ const nullable = e.paramNullable?.[i] === true;
7
+ return nullable ? `${t} | null` : t;
8
+ });
9
+ const params = paramTypes.length === 0 ? "[]" : `[${paramTypes.join(", ")}]`;
10
+ if (!e.hasResultSet)
11
+ return { params, row: "never" };
12
+ const cols = e.columns.map((c) => {
13
+ const nullable = effectiveNullable(c);
14
+ const t = nullable ? `${c.tsType} | null` : c.tsType;
15
+ return `${JSON.stringify(c.name)}: ${t}`;
16
+ });
17
+ return { params, row: `{ ${cols.join("; ")} }` };
18
+ }
19
+ export function emitDts(outPath, entries) {
20
+ mkdirSync(dirname(outPath), { recursive: true });
21
+ const lines = [];
22
+ lines.push("// AUTO-GENERATED by sqlx-js. Do not edit.");
23
+ lines.push("// Run `sqlx-js prepare` to regenerate.");
24
+ lines.push("");
25
+ emitModule(lines, "@onreza/sqlx-js", entries);
26
+ lines.push("");
27
+ emitModule(lines, "@onreza/sqlx-js/bun", entries);
28
+ lines.push("");
29
+ lines.push("export {};");
30
+ writeFileSync(outPath, lines.join("\n") + "\n");
31
+ }
32
+ function emitModule(lines, moduleName, entries) {
33
+ lines.push(`declare module ${JSON.stringify(moduleName)} {`);
34
+ lines.push(" interface KnownQueries {");
35
+ const inlineSeen = new Set();
36
+ const inlineEntries = entries.filter((e) => {
37
+ if (e.hasInline === true)
38
+ return true;
39
+ if (e.hasInline === false)
40
+ return false;
41
+ return !e.filePaths || e.filePaths.length === 0;
42
+ });
43
+ for (const e of inlineEntries.slice().sort((a, b) => a.query.localeCompare(b.query))) {
44
+ if (inlineSeen.has(e.query))
45
+ continue;
46
+ inlineSeen.add(e.query);
47
+ const { params, row } = entrySignature(e);
48
+ if (e.degraded)
49
+ lines.push(` /** Nullability inference degraded: ${e.degraded.reason}. All result columns conservatively typed as nullable. */`);
50
+ lines.push(` ${JSON.stringify(e.query)}: { params: ${params}; row: ${row} };`);
51
+ }
52
+ lines.push(" }");
53
+ lines.push("");
54
+ lines.push(" interface KnownFileQueries {");
55
+ const filePairs = [];
56
+ for (const e of entries) {
57
+ if (!e.filePaths || e.filePaths.length === 0)
58
+ continue;
59
+ for (const p of e.filePaths)
60
+ filePairs.push({ path: p, entry: e });
61
+ }
62
+ const filePathsSeen = new Set();
63
+ for (const { path, entry } of filePairs.slice().sort((a, b) => a.path.localeCompare(b.path))) {
64
+ if (filePathsSeen.has(path))
65
+ continue;
66
+ filePathsSeen.add(path);
67
+ const { params, row } = entrySignature(entry);
68
+ if (entry.degraded)
69
+ lines.push(` /** Nullability inference degraded: ${entry.degraded.reason}. */`);
70
+ lines.push(` ${JSON.stringify(path)}: { params: ${params}; row: ${row} };`);
71
+ }
72
+ lines.push(" }");
73
+ lines.push("}");
74
+ }
@@ -0,0 +1,63 @@
1
+ import { PgClient } from "../pg/wire.js";
2
+ export type MigrateOptions = {
3
+ databaseUrl: string;
4
+ migrationsDir: string;
5
+ };
6
+ export declare const DEFAULT_MIGRATE_LOCK_KEY = 18750938867203960n;
7
+ export declare function ensureTable(c: PgClient): Promise<void>;
8
+ export declare function listApplied(c: PgClient): Promise<Map<number, {
9
+ name: string;
10
+ hash: string;
11
+ }>>;
12
+ export type ApplyOutcome = {
13
+ kind: "applied";
14
+ version: number;
15
+ name: string;
16
+ } | {
17
+ kind: "tampered";
18
+ version: number;
19
+ name: string;
20
+ applied: string;
21
+ current: string;
22
+ } | {
23
+ kind: "failed";
24
+ version: number;
25
+ name: string;
26
+ error: string;
27
+ };
28
+ export declare function applyPending(c: PgClient, migrationsDir: string, onEvent?: (e: ApplyOutcome) => void): Promise<{
29
+ applied: number;
30
+ tampered: number;
31
+ failed: number;
32
+ }>;
33
+ export declare function acquireMigrateLock(c: PgClient, lockKey?: number | bigint, timeoutMs?: number): Promise<void>;
34
+ export declare function releaseMigrateLock(c: PgClient, lockKey?: number | bigint): Promise<void>;
35
+ export declare function migrateRun(opts: MigrateOptions & {
36
+ lockKey?: number | bigint;
37
+ lockTimeoutMs?: number;
38
+ }): Promise<void>;
39
+ export declare function migrateInfo(opts: MigrateOptions): Promise<void>;
40
+ export type RevertOutcome = {
41
+ kind: "noop";
42
+ } | {
43
+ kind: "no-down";
44
+ version: number;
45
+ name: string;
46
+ } | {
47
+ kind: "reverted";
48
+ version: number;
49
+ name: string;
50
+ } | {
51
+ kind: "failed";
52
+ version: number;
53
+ name: string;
54
+ error: string;
55
+ };
56
+ export declare function revertLast(c: PgClient, migrationsDir: string): Promise<RevertOutcome>;
57
+ export declare function migrateRevert(opts: MigrateOptions & {
58
+ lockKey?: number | bigint;
59
+ lockTimeoutMs?: number;
60
+ }): Promise<void>;
61
+ export declare function migrateAdd(opts: MigrateOptions & {
62
+ name: string;
63
+ }): void;