@onreza/sqlx-js 0.1.0 → 0.3.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/README.md +128 -37
- package/ROADMAP.md +2 -3
- package/dist/bin/sqlx-js.js +97 -14
- package/dist/src/cache.d.ts +1 -0
- package/dist/src/cache.js +128 -1
- package/dist/src/codegen.js +16 -16
- package/dist/src/commands/init.d.ts +5 -0
- package/dist/src/commands/init.js +57 -0
- package/dist/src/commands/migrate.d.ts +190 -3
- package/dist/src/commands/migrate.js +1383 -46
- package/dist/src/commands/prepare.d.ts +16 -2
- package/dist/src/commands/prepare.js +116 -33
- package/dist/src/commands/schema.js +4 -0
- package/dist/src/commands/watch.js +1 -1
- package/dist/src/index.d.ts +14 -2
- package/dist/src/pg/narrow.js +8 -0
- package/dist/src/pg/oids.js +3 -2
- package/dist/src/pg/param-map.d.ts +2 -1
- package/dist/src/pg/param-map.js +181 -40
- package/dist/src/pg/schema.d.ts +17 -1
- package/dist/src/pg/schema.js +48 -2
- package/dist/src/pg/wire.d.ts +14 -1
- package/dist/src/pg/wire.js +81 -3
- package/dist/src/postgres-runtime.d.ts +9 -2
- package/dist/src/postgres-runtime.js +20 -5
- package/dist/src/runtime.d.ts +12 -0
- package/dist/src/runtime.js +83 -3
- package/dist/src/scan/scanner.js +1 -1
- package/package.json +5 -8
- package/dist/src/bun-runtime.d.ts +0 -7
- package/dist/src/bun-runtime.js +0 -45
- package/dist/src/bun.d.ts +0 -22
- package/dist/src/bun.js +0 -9
package/dist/src/cache.js
CHANGED
|
@@ -2,9 +2,136 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
2
2
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, unlinkSync, renameSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
export function fingerprint(query) {
|
|
5
|
-
const norm = query
|
|
5
|
+
const norm = normalizeForFingerprint(query);
|
|
6
6
|
return createHash("sha256").update(norm).digest("hex").slice(0, 16);
|
|
7
7
|
}
|
|
8
|
+
function normalizeForFingerprint(query) {
|
|
9
|
+
let out = "";
|
|
10
|
+
let pendingSpace = false;
|
|
11
|
+
let i = 0;
|
|
12
|
+
const emit = (text) => {
|
|
13
|
+
if (pendingSpace && out.length > 0)
|
|
14
|
+
out += " ";
|
|
15
|
+
out += text;
|
|
16
|
+
pendingSpace = false;
|
|
17
|
+
};
|
|
18
|
+
const markSpace = () => {
|
|
19
|
+
if (out.length > 0)
|
|
20
|
+
pendingSpace = true;
|
|
21
|
+
};
|
|
22
|
+
while (i < query.length) {
|
|
23
|
+
const ch = query[i];
|
|
24
|
+
if (/\s/.test(ch)) {
|
|
25
|
+
markSpace();
|
|
26
|
+
i++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (ch === "-" && query[i + 1] === "-") {
|
|
30
|
+
i = readLineComment(query, i);
|
|
31
|
+
markSpace();
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (ch === "/" && query[i + 1] === "*") {
|
|
35
|
+
i = readBlockComment(query, i);
|
|
36
|
+
markSpace();
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (ch === "'") {
|
|
40
|
+
const next = readSingleQuoted(query, i, isEscapeStringPrefix(query, i));
|
|
41
|
+
emit(query.slice(i, next));
|
|
42
|
+
i = next;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (ch === "\"") {
|
|
46
|
+
const next = readQuotedIdentifier(query, i);
|
|
47
|
+
emit(query.slice(i, next));
|
|
48
|
+
i = next;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (ch === "$") {
|
|
52
|
+
const next = readDollarQuoted(query, i);
|
|
53
|
+
if (next !== null) {
|
|
54
|
+
emit(query.slice(i, next));
|
|
55
|
+
i = next;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
emit(ch);
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
function readSingleQuoted(query, start, escapeBackslash) {
|
|
65
|
+
let i = start + 1;
|
|
66
|
+
while (i < query.length) {
|
|
67
|
+
const ch = query[i];
|
|
68
|
+
if (escapeBackslash && ch === "\\") {
|
|
69
|
+
i += 2;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (ch === "'") {
|
|
73
|
+
if (query[i + 1] === "'") {
|
|
74
|
+
i += 2;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
return i + 1;
|
|
78
|
+
}
|
|
79
|
+
i++;
|
|
80
|
+
}
|
|
81
|
+
return query.length;
|
|
82
|
+
}
|
|
83
|
+
function readQuotedIdentifier(query, start) {
|
|
84
|
+
let i = start + 1;
|
|
85
|
+
while (i < query.length) {
|
|
86
|
+
if (query[i] === "\"") {
|
|
87
|
+
if (query[i + 1] === "\"") {
|
|
88
|
+
i += 2;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
return i + 1;
|
|
92
|
+
}
|
|
93
|
+
i++;
|
|
94
|
+
}
|
|
95
|
+
return query.length;
|
|
96
|
+
}
|
|
97
|
+
function readDollarQuoted(query, start) {
|
|
98
|
+
let tagEnd = start + 1;
|
|
99
|
+
while (tagEnd < query.length && /[A-Za-z0-9_]/.test(query[tagEnd]))
|
|
100
|
+
tagEnd++;
|
|
101
|
+
if (query[tagEnd] !== "$")
|
|
102
|
+
return null;
|
|
103
|
+
const tag = query.slice(start, tagEnd + 1);
|
|
104
|
+
const end = query.indexOf(tag, tagEnd + 1);
|
|
105
|
+
return end === -1 ? query.length : end + tag.length;
|
|
106
|
+
}
|
|
107
|
+
function readLineComment(query, start) {
|
|
108
|
+
const end = query.indexOf("\n", start + 2);
|
|
109
|
+
return end === -1 ? query.length : end + 1;
|
|
110
|
+
}
|
|
111
|
+
function readBlockComment(query, start) {
|
|
112
|
+
let depth = 1;
|
|
113
|
+
let i = start + 2;
|
|
114
|
+
while (i < query.length && depth > 0) {
|
|
115
|
+
if (query[i] === "/" && query[i + 1] === "*") {
|
|
116
|
+
depth++;
|
|
117
|
+
i += 2;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (query[i] === "*" && query[i + 1] === "/") {
|
|
121
|
+
depth--;
|
|
122
|
+
i += 2;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
return i;
|
|
128
|
+
}
|
|
129
|
+
function isEscapeStringPrefix(query, quoteIndex) {
|
|
130
|
+
if (quoteIndex === 0 || query[quoteIndex - 1]?.toLowerCase() !== "e")
|
|
131
|
+
return false;
|
|
132
|
+
const beforePrefix = query[quoteIndex - 2];
|
|
133
|
+
return beforePrefix === undefined || !/[A-Za-z0-9_$]/.test(beforePrefix);
|
|
134
|
+
}
|
|
8
135
|
export function effectiveNullable(c) {
|
|
9
136
|
if (c.override === "non-null")
|
|
10
137
|
return false;
|
package/dist/src/codegen.js
CHANGED
|
@@ -24,8 +24,6 @@ export function emitDts(outPath, entries) {
|
|
|
24
24
|
lines.push("");
|
|
25
25
|
emitModule(lines, "@onreza/sqlx-js", entries);
|
|
26
26
|
lines.push("");
|
|
27
|
-
emitModule(lines, "@onreza/sqlx-js/bun", entries);
|
|
28
|
-
lines.push("");
|
|
29
27
|
lines.push("export {};");
|
|
30
28
|
writeFileSync(outPath, lines.join("\n") + "\n");
|
|
31
29
|
}
|
|
@@ -33,21 +31,23 @@ function emitModule(lines, moduleName, entries) {
|
|
|
33
31
|
lines.push(`declare module ${JSON.stringify(moduleName)} {`);
|
|
34
32
|
lines.push(" interface KnownQueries {");
|
|
35
33
|
const inlineSeen = new Set();
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
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))
|
|
34
|
+
const inlinePairs = [];
|
|
35
|
+
for (const e of entries) {
|
|
36
|
+
const emitInline = e.hasInline === true || (e.hasInline !== false && (!e.filePaths || e.filePaths.length === 0));
|
|
37
|
+
if (!emitInline)
|
|
45
38
|
continue;
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
const queries = e.inlineQueries && e.inlineQueries.length > 0 ? e.inlineQueries : [e.query];
|
|
40
|
+
for (const query of queries)
|
|
41
|
+
inlinePairs.push({ query, entry: e });
|
|
42
|
+
}
|
|
43
|
+
for (const { query, entry } of inlinePairs.slice().sort((a, b) => a.query.localeCompare(b.query))) {
|
|
44
|
+
if (inlineSeen.has(query))
|
|
45
|
+
continue;
|
|
46
|
+
inlineSeen.add(query);
|
|
47
|
+
const { params, row } = entrySignature(entry);
|
|
48
|
+
if (entry.degraded)
|
|
49
|
+
lines.push(` /** Nullability inference degraded: ${entry.degraded.reason}. All result columns conservatively typed as nullable. */`);
|
|
50
|
+
lines.push(` ${JSON.stringify(query)}: { params: ${params}; row: ${row} };`);
|
|
51
51
|
}
|
|
52
52
|
lines.push(" }");
|
|
53
53
|
lines.push("");
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
const CONFIG_TEMPLATE = `import type { SqlxJsConfig } from "@onreza/sqlx-js";
|
|
4
|
+
|
|
5
|
+
const config: SqlxJsConfig = {
|
|
6
|
+
// Map jsonb columns/params to TypeScript types declared in a .d.ts, e.g.
|
|
7
|
+
// "users.settings": "SqlxJsJson.UserSettings",
|
|
8
|
+
jsonbTypes: {},
|
|
9
|
+
// Map PostgreSQL type names to TypeScript types, e.g.
|
|
10
|
+
// geometry: "GeoJSON.Geometry",
|
|
11
|
+
customTypes: {},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default config;
|
|
15
|
+
`;
|
|
16
|
+
const ENV_TEMPLATE = `# Connection string used by sqlx-js prepare/migrate and the runtime.
|
|
17
|
+
DATABASE_URL=postgres://user:password@localhost:5432/your_db
|
|
18
|
+
# Managed Postgres with TLS:
|
|
19
|
+
# DATABASE_URL=postgres://user:password@db.example.com:5432/your_db?sslmode=verify-full
|
|
20
|
+
`;
|
|
21
|
+
export function runInit(opts) {
|
|
22
|
+
const log = opts.log ?? console.log;
|
|
23
|
+
const created = [];
|
|
24
|
+
const skipped = [];
|
|
25
|
+
const ensureFile = (rel, content) => {
|
|
26
|
+
const full = join(opts.root, rel);
|
|
27
|
+
if (existsSync(full)) {
|
|
28
|
+
skipped.push(rel);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
mkdirSync(dirname(full), { recursive: true });
|
|
32
|
+
writeFileSync(full, content);
|
|
33
|
+
created.push(rel);
|
|
34
|
+
};
|
|
35
|
+
const ensureDir = (rel) => {
|
|
36
|
+
const full = join(opts.root, rel);
|
|
37
|
+
if (existsSync(full)) {
|
|
38
|
+
skipped.push(`${rel}/`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
mkdirSync(full, { recursive: true });
|
|
42
|
+
created.push(`${rel}/`);
|
|
43
|
+
};
|
|
44
|
+
ensureFile("sqlx-js.config.ts", CONFIG_TEMPLATE);
|
|
45
|
+
ensureDir("migrations");
|
|
46
|
+
ensureFile(".env.example", ENV_TEMPLATE);
|
|
47
|
+
for (const f of created)
|
|
48
|
+
log(`created ${f}`);
|
|
49
|
+
for (const f of skipped)
|
|
50
|
+
log(`exists ${f} (left unchanged)`);
|
|
51
|
+
log("");
|
|
52
|
+
log("Next steps:");
|
|
53
|
+
log(" 1. Set DATABASE_URL (see .env.example).");
|
|
54
|
+
log(" 2. Add a migration: sqlx-js migrate add init");
|
|
55
|
+
log(" 3. Make sure tsconfig.json \"include\" covers sqlx-js-env.d.ts.");
|
|
56
|
+
log(" 4. Develop locally: sqlx-js migrate dev");
|
|
57
|
+
}
|
|
@@ -3,9 +3,22 @@ export type MigrateOptions = {
|
|
|
3
3
|
databaseUrl: string;
|
|
4
4
|
migrationsDir: string;
|
|
5
5
|
};
|
|
6
|
+
export type MigrationWorkflowOptions = MigrateOptions & {
|
|
7
|
+
root: string;
|
|
8
|
+
cacheDir: string;
|
|
9
|
+
dtsPath: string;
|
|
10
|
+
prune?: boolean;
|
|
11
|
+
shadowUrl?: string;
|
|
12
|
+
shadowAdminUrl?: string;
|
|
13
|
+
lockKey?: number | bigint;
|
|
14
|
+
lockTimeoutMs?: number;
|
|
15
|
+
};
|
|
16
|
+
export type MigrationStore = {
|
|
17
|
+
table: string;
|
|
18
|
+
};
|
|
6
19
|
export declare const DEFAULT_MIGRATE_LOCK_KEY = 18750938867203960n;
|
|
7
|
-
export declare function ensureTable(c: PgClient): Promise<
|
|
8
|
-
export declare function listApplied(c: PgClient): Promise<Map<number, {
|
|
20
|
+
export declare function ensureTable(c: PgClient): Promise<MigrationStore>;
|
|
21
|
+
export declare function listApplied(c: PgClient, store?: MigrationStore): Promise<Map<number, {
|
|
9
22
|
name: string;
|
|
10
23
|
hash: string;
|
|
11
24
|
}>>;
|
|
@@ -13,6 +26,11 @@ export type ApplyOutcome = {
|
|
|
13
26
|
kind: "applied";
|
|
14
27
|
version: number;
|
|
15
28
|
name: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: "adopted";
|
|
31
|
+
version: number;
|
|
32
|
+
name: string;
|
|
33
|
+
replaced: number;
|
|
16
34
|
} | {
|
|
17
35
|
kind: "tampered";
|
|
18
36
|
version: number;
|
|
@@ -25,6 +43,123 @@ export type ApplyOutcome = {
|
|
|
25
43
|
name: string;
|
|
26
44
|
error: string;
|
|
27
45
|
};
|
|
46
|
+
export type PlanOutcome = {
|
|
47
|
+
kind: "pending";
|
|
48
|
+
version: number;
|
|
49
|
+
name: string;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "adoptable";
|
|
52
|
+
version: number;
|
|
53
|
+
name: string;
|
|
54
|
+
replaced: number;
|
|
55
|
+
} | {
|
|
56
|
+
kind: "tampered";
|
|
57
|
+
version: number;
|
|
58
|
+
name: string;
|
|
59
|
+
applied: string;
|
|
60
|
+
current: string;
|
|
61
|
+
} | {
|
|
62
|
+
kind: "failed";
|
|
63
|
+
version: number;
|
|
64
|
+
name: string;
|
|
65
|
+
error: string;
|
|
66
|
+
};
|
|
67
|
+
export type MigrationPlanItem = {
|
|
68
|
+
kind: "apply";
|
|
69
|
+
version: number;
|
|
70
|
+
name: string;
|
|
71
|
+
} | {
|
|
72
|
+
kind: "adopt";
|
|
73
|
+
version: number;
|
|
74
|
+
name: string;
|
|
75
|
+
replaced: number;
|
|
76
|
+
};
|
|
77
|
+
export type MigrationPlanDiagnostic = Extract<PlanOutcome, {
|
|
78
|
+
kind: "tampered" | "failed";
|
|
79
|
+
}>;
|
|
80
|
+
export type MigrationPlanSnapshot = {
|
|
81
|
+
ok: boolean;
|
|
82
|
+
pending: number;
|
|
83
|
+
adoptable: number;
|
|
84
|
+
tampered: number;
|
|
85
|
+
failed: number;
|
|
86
|
+
steps: MigrationPlanItem[];
|
|
87
|
+
diagnostics: MigrationPlanDiagnostic[];
|
|
88
|
+
};
|
|
89
|
+
export type MigrationInfoStatus = "applied" | "pending" | "adoptable" | "superseded" | "tampered" | "failed";
|
|
90
|
+
export type MigrationInfoItem = {
|
|
91
|
+
version: number;
|
|
92
|
+
name: string;
|
|
93
|
+
status: MigrationInfoStatus;
|
|
94
|
+
detail?: string;
|
|
95
|
+
};
|
|
96
|
+
export type MigrationInfoSnapshot = {
|
|
97
|
+
historyTable: string | null;
|
|
98
|
+
summary: Record<MigrationInfoStatus, number>;
|
|
99
|
+
items: MigrationInfoItem[];
|
|
100
|
+
};
|
|
101
|
+
export type MigrationArchive = {
|
|
102
|
+
name: string;
|
|
103
|
+
path: string;
|
|
104
|
+
files: string[];
|
|
105
|
+
};
|
|
106
|
+
export type MigrationCheckIssue = {
|
|
107
|
+
severity: "error";
|
|
108
|
+
code: "invalid-file-name" | "invalid-version" | "duplicate-version" | "orphan-down" | "invalid-squash-metadata" | "invalid-squash-replacement" | "tampered-squash-replacement";
|
|
109
|
+
message: string;
|
|
110
|
+
file?: string;
|
|
111
|
+
version?: number;
|
|
112
|
+
name?: string;
|
|
113
|
+
};
|
|
114
|
+
export type MigrationCheckReport = {
|
|
115
|
+
ok: boolean;
|
|
116
|
+
migrations: number;
|
|
117
|
+
archives: number;
|
|
118
|
+
issues: MigrationCheckIssue[];
|
|
119
|
+
};
|
|
120
|
+
export type SchemaObjectDiff = {
|
|
121
|
+
added: string[];
|
|
122
|
+
removed: string[];
|
|
123
|
+
changed: string[];
|
|
124
|
+
};
|
|
125
|
+
export type SchemaDiffSummary = {
|
|
126
|
+
relations: SchemaObjectDiff;
|
|
127
|
+
types: SchemaObjectDiff;
|
|
128
|
+
functions: SchemaObjectDiff;
|
|
129
|
+
};
|
|
130
|
+
export type RevertDryRunPhase = "validate" | "begin" | "isolate" | "previous-up" | "snapshot-before" | "target-up" | "down" | "snapshot-after" | "rollback";
|
|
131
|
+
export type RevertDryRunOutcome = {
|
|
132
|
+
kind: "noop";
|
|
133
|
+
} | {
|
|
134
|
+
kind: "no-down";
|
|
135
|
+
version: number;
|
|
136
|
+
name: string;
|
|
137
|
+
} | {
|
|
138
|
+
kind: "passed";
|
|
139
|
+
version: number;
|
|
140
|
+
name: string;
|
|
141
|
+
} | {
|
|
142
|
+
kind: "schema-mismatch";
|
|
143
|
+
version: number;
|
|
144
|
+
name: string;
|
|
145
|
+
diff: SchemaDiffSummary;
|
|
146
|
+
} | {
|
|
147
|
+
kind: "failed";
|
|
148
|
+
version?: number;
|
|
149
|
+
name?: string;
|
|
150
|
+
phase: RevertDryRunPhase;
|
|
151
|
+
error: string;
|
|
152
|
+
};
|
|
153
|
+
export declare function checkMigrationFiles(migrationsDir: string): MigrationCheckReport;
|
|
154
|
+
export declare function planPending(c: PgClient, migrationsDir: string, onEvent?: (e: PlanOutcome) => void): Promise<{
|
|
155
|
+
pending: number;
|
|
156
|
+
adoptable: number;
|
|
157
|
+
tampered: number;
|
|
158
|
+
failed: number;
|
|
159
|
+
steps: MigrationPlanItem[];
|
|
160
|
+
}>;
|
|
161
|
+
export declare function inspectMigrationPlan(c: PgClient, migrationsDir: string): Promise<MigrationPlanSnapshot>;
|
|
162
|
+
export declare function inspectMigrations(c: PgClient, migrationsDir: string): Promise<MigrationInfoSnapshot>;
|
|
28
163
|
export declare function applyPending(c: PgClient, migrationsDir: string, onEvent?: (e: ApplyOutcome) => void): Promise<{
|
|
29
164
|
applied: number;
|
|
30
165
|
tampered: number;
|
|
@@ -32,11 +167,53 @@ export declare function applyPending(c: PgClient, migrationsDir: string, onEvent
|
|
|
32
167
|
}>;
|
|
33
168
|
export declare function acquireMigrateLock(c: PgClient, lockKey?: number | bigint, timeoutMs?: number): Promise<void>;
|
|
34
169
|
export declare function releaseMigrateLock(c: PgClient, lockKey?: number | bigint): Promise<void>;
|
|
170
|
+
export declare function sanitizePgDumpSchema(sql: string): string;
|
|
171
|
+
export declare function listMigrationArchives(migrationsDir: string): MigrationArchive[];
|
|
172
|
+
export declare function restoreMigrationArchive(migrationsDir: string, archiveName: string, opts?: {
|
|
173
|
+
force?: boolean;
|
|
174
|
+
}): {
|
|
175
|
+
archiveName: string;
|
|
176
|
+
restored: string[];
|
|
177
|
+
};
|
|
178
|
+
export declare function createSquashMigration(opts: {
|
|
179
|
+
migrationsDir: string;
|
|
180
|
+
name: string;
|
|
181
|
+
schemaSql: string;
|
|
182
|
+
replace?: boolean;
|
|
183
|
+
}): {
|
|
184
|
+
version: number;
|
|
185
|
+
name: string;
|
|
186
|
+
upPath: string;
|
|
187
|
+
replaced: number;
|
|
188
|
+
archiveDir?: string;
|
|
189
|
+
};
|
|
190
|
+
export declare function dumpSchema(databaseUrl: string, pgDumpPath?: string): string;
|
|
191
|
+
export declare function migrateSquash(opts: {
|
|
192
|
+
databaseUrl?: string;
|
|
193
|
+
migrationsDir: string;
|
|
194
|
+
name: string;
|
|
195
|
+
shadowUrl?: string;
|
|
196
|
+
shadowAdminUrl?: string;
|
|
197
|
+
replace?: boolean;
|
|
198
|
+
pgDumpPath?: string;
|
|
199
|
+
lockKey?: number | bigint;
|
|
200
|
+
lockTimeoutMs?: number;
|
|
201
|
+
}): Promise<void>;
|
|
35
202
|
export declare function migrateRun(opts: MigrateOptions & {
|
|
36
203
|
lockKey?: number | bigint;
|
|
37
204
|
lockTimeoutMs?: number;
|
|
205
|
+
dryRun?: boolean;
|
|
206
|
+
json?: boolean;
|
|
207
|
+
}): Promise<void>;
|
|
208
|
+
export declare function migrateInfo(opts: MigrateOptions & {
|
|
209
|
+
json?: boolean;
|
|
38
210
|
}): Promise<void>;
|
|
39
|
-
export declare function
|
|
211
|
+
export declare function migrateCheck(opts: {
|
|
212
|
+
migrationsDir: string;
|
|
213
|
+
json?: boolean;
|
|
214
|
+
}): void;
|
|
215
|
+
export declare function migrateDev(opts: MigrationWorkflowOptions): Promise<void>;
|
|
216
|
+
export declare function migrateVerify(opts: MigrationWorkflowOptions): Promise<void>;
|
|
40
217
|
export type RevertOutcome = {
|
|
41
218
|
kind: "noop";
|
|
42
219
|
} | {
|
|
@@ -54,10 +231,20 @@ export type RevertOutcome = {
|
|
|
54
231
|
error: string;
|
|
55
232
|
};
|
|
56
233
|
export declare function revertLast(c: PgClient, migrationsDir: string): Promise<RevertOutcome>;
|
|
234
|
+
export declare function checkLastDownMigration(c: PgClient, migrationsDir: string): Promise<RevertDryRunOutcome>;
|
|
57
235
|
export declare function migrateRevert(opts: MigrateOptions & {
|
|
58
236
|
lockKey?: number | bigint;
|
|
59
237
|
lockTimeoutMs?: number;
|
|
238
|
+
dryRun?: boolean;
|
|
239
|
+
shadowUrl?: string;
|
|
240
|
+
shadowAdminUrl?: string;
|
|
241
|
+
json?: boolean;
|
|
60
242
|
}): Promise<void>;
|
|
243
|
+
export declare function migrateArchiveList(opts: Pick<MigrateOptions, "migrationsDir">): void;
|
|
244
|
+
export declare function migrateArchiveRestore(opts: Pick<MigrateOptions, "migrationsDir"> & {
|
|
245
|
+
name: string;
|
|
246
|
+
force?: boolean;
|
|
247
|
+
}): void;
|
|
61
248
|
export declare function migrateAdd(opts: MigrateOptions & {
|
|
62
249
|
name: string;
|
|
63
250
|
}): void;
|