@softure-ai/db 0.0.0-stage → 0.1.6
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 +16 -0
- package/LICENSE +21 -0
- package/README.md +383 -2
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +5 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/command.d.ts +8 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +38 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/run.d.ts +27 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +205 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/client.d.ts +73 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +90 -0
- package/dist/client.js.map +1 -0
- package/dist/configured.d.ts +31 -0
- package/dist/configured.d.ts.map +1 -0
- package/dist/configured.js +74 -0
- package/dist/configured.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/adopt.d.ts +33 -0
- package/dist/migrations/adopt.d.ts.map +1 -0
- package/dist/migrations/adopt.js +97 -0
- package/dist/migrations/adopt.js.map +1 -0
- package/dist/migrations/apply.d.ts +35 -0
- package/dist/migrations/apply.d.ts.map +1 -0
- package/dist/migrations/apply.js +115 -0
- package/dist/migrations/apply.js.map +1 -0
- package/dist/migrations/export.d.ts +10 -0
- package/dist/migrations/export.d.ts.map +1 -0
- package/dist/migrations/export.js +58 -0
- package/dist/migrations/export.js.map +1 -0
- package/dist/migrations/exported.d.ts +20 -0
- package/dist/migrations/exported.d.ts.map +1 -0
- package/dist/migrations/exported.js +61 -0
- package/dist/migrations/exported.js.map +1 -0
- package/dist/migrations/files.d.ts +21 -0
- package/dist/migrations/files.d.ts.map +1 -0
- package/dist/migrations/files.js +112 -0
- package/dist/migrations/files.js.map +1 -0
- package/dist/migrations/introspect.d.ts +6 -0
- package/dist/migrations/introspect.d.ts.map +1 -0
- package/dist/migrations/introspect.js +117 -0
- package/dist/migrations/introspect.js.map +1 -0
- package/dist/migrations/ledger.d.ts +27 -0
- package/dist/migrations/ledger.d.ts.map +1 -0
- package/dist/migrations/ledger.js +45 -0
- package/dist/migrations/ledger.js.map +1 -0
- package/dist/migrations/migrator.d.ts +97 -0
- package/dist/migrations/migrator.d.ts.map +1 -0
- package/dist/migrations/migrator.js +301 -0
- package/dist/migrations/migrator.js.map +1 -0
- package/dist/migrations/problems.d.ts +93 -0
- package/dist/migrations/problems.d.ts.map +1 -0
- package/dist/migrations/problems.js +62 -0
- package/dist/migrations/problems.js.map +1 -0
- package/dist/migrations/reference.d.ts +23 -0
- package/dist/migrations/reference.d.ts.map +1 -0
- package/dist/migrations/reference.js +64 -0
- package/dist/migrations/reference.js.map +1 -0
- package/dist/migrations/session.d.ts +15 -0
- package/dist/migrations/session.d.ts.map +1 -0
- package/dist/migrations/session.js +56 -0
- package/dist/migrations/session.js.map +1 -0
- package/dist/migrations/stubs.d.ts +23 -0
- package/dist/migrations/stubs.d.ts.map +1 -0
- package/dist/migrations/stubs.js +99 -0
- package/dist/migrations/stubs.js.map +1 -0
- package/dist/shared.d.ts +9 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +32 -0
- package/dist/shared.js.map +1 -0
- package/dist/testing.d.ts +23 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +62 -0
- package/dist/testing.js.map +1 -0
- package/package.json +73 -4
- package/src/cli/bin.ts +5 -0
- package/src/cli/command.ts +47 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/run.ts +250 -0
- package/src/client.ts +151 -0
- package/src/configured.ts +109 -0
- package/src/index.ts +46 -0
- package/src/migrations/adopt.ts +136 -0
- package/src/migrations/apply.ts +135 -0
- package/src/migrations/export.ts +66 -0
- package/src/migrations/exported.ts +82 -0
- package/src/migrations/files.ts +129 -0
- package/src/migrations/introspect.ts +165 -0
- package/src/migrations/ledger.ts +75 -0
- package/src/migrations/migrator.ts +403 -0
- package/src/migrations/problems.ts +99 -0
- package/src/migrations/reference.ts +78 -0
- package/src/migrations/session.ts +74 -0
- package/src/migrations/stubs.ts +139 -0
- package/src/shared.ts +36 -0
- package/src/testing.ts +80 -0
package/dist/cli/run.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// `softure migrate` (docs/02-module-standard.md §4). The app passes its validated config, so the
|
|
2
|
+
// same function serves the `softure` bin and an app script that esbuild bundles for a container:
|
|
3
|
+
//
|
|
4
|
+
// // scripts/migrate.ts
|
|
5
|
+
// import { runMigrateCli } from "@softure-ai/db/cli";
|
|
6
|
+
// import config from "../softure.config";
|
|
7
|
+
// process.exitCode = await runMigrateCli({ config, argv: process.argv.slice(2) });
|
|
8
|
+
//
|
|
9
|
+
// An app with its own migrations passes them as `app: { before, after }` (see MigrateOptions.app).
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
import { parseArgs } from "node:util";
|
|
12
|
+
import { pathToFileURL } from "node:url";
|
|
13
|
+
import { openCommandDatabase } from "../configured.js";
|
|
14
|
+
import { adoptModule } from "../migrations/adopt.js";
|
|
15
|
+
import { exportMigrations } from "../migrations/export.js";
|
|
16
|
+
import { migrate, planMigrations, runAppMigrations } from "../migrations/migrator.js";
|
|
17
|
+
import { describeProblem } from "../migrations/problems.js";
|
|
18
|
+
export const EXIT_OK = 0;
|
|
19
|
+
export const EXIT_FAILED = 1;
|
|
20
|
+
export const EXIT_USAGE = 2;
|
|
21
|
+
export const MIGRATE_USAGE = `Usage: softure migrate [options]
|
|
22
|
+
|
|
23
|
+
Applies the SQL migrations of every enabled module, each in its own schema.
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
--plan show what would be applied (or adopted) and change nothing
|
|
27
|
+
--adopt <module>@<version> record an existing schema as migrated, after comparing it;
|
|
28
|
+
applies the pending migrations of its dependencies first
|
|
29
|
+
--through <n> with --adopt: adopt files 1..n only, leave the rest to migrate
|
|
30
|
+
--migrations-dir <dir> read module files from <dir>/<module id>/ (bundled runners)
|
|
31
|
+
--export-migrations <dir> copy module files to <dir>/<module id>/ and exit (build stage)
|
|
32
|
+
--help show this help`;
|
|
33
|
+
const ADOPT_TARGET = /^([a-z][a-z0-9]*(?:-[a-z0-9]+)*)@(\d+\.\d+\.\d+)$/;
|
|
34
|
+
const consoleOutput = {
|
|
35
|
+
log: (line) => console.log(line),
|
|
36
|
+
error: (line) => console.error(line),
|
|
37
|
+
};
|
|
38
|
+
/** Runs the command and returns the process exit code: 0 done, 1 failed, 2 usage error. */
|
|
39
|
+
export async function runMigrateCli(options) {
|
|
40
|
+
const output = options.output ?? consoleOutput;
|
|
41
|
+
const cwd = options.cwd ?? process.cwd();
|
|
42
|
+
const command = parseCommand(options.argv);
|
|
43
|
+
if (typeof command === "string") {
|
|
44
|
+
output.error(`softure migrate: ${command}`);
|
|
45
|
+
output.error(MIGRATE_USAGE);
|
|
46
|
+
return EXIT_USAGE;
|
|
47
|
+
}
|
|
48
|
+
if (command.kind === "help") {
|
|
49
|
+
output.log(MIGRATE_USAGE);
|
|
50
|
+
return EXIT_OK;
|
|
51
|
+
}
|
|
52
|
+
if (command.kind === "export") {
|
|
53
|
+
const result = await exportMigrations(options.config.modules, resolve(cwd, command.targetDir));
|
|
54
|
+
if (!result.ok)
|
|
55
|
+
return reportFailure(output, result);
|
|
56
|
+
result.value.forEach((step) => output.log(`exported ${formatStep(step)}`));
|
|
57
|
+
return EXIT_OK;
|
|
58
|
+
}
|
|
59
|
+
const database = options.config.database;
|
|
60
|
+
if (database === null) {
|
|
61
|
+
output.error("softure migrate: the config has no database; set database.url in softure.config");
|
|
62
|
+
return EXIT_FAILED;
|
|
63
|
+
}
|
|
64
|
+
let opened;
|
|
65
|
+
try {
|
|
66
|
+
// The app's configured handle when it set one, so the app's hooks and the run share one instance.
|
|
67
|
+
opened = await openCommandDatabase(database);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
output.error(`softure migrate: ${describeError(error)}`);
|
|
71
|
+
return EXIT_FAILED;
|
|
72
|
+
}
|
|
73
|
+
const { handle } = opened;
|
|
74
|
+
try {
|
|
75
|
+
const migrationsDir = command.migrationsDir === undefined ? undefined : pathToFileURL(`${resolve(cwd, command.migrationsDir)}/`);
|
|
76
|
+
return await runDatabaseCommand(handle, { command, modules: options.config.modules, migrationsDir, output, app: options.app ?? {} });
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Connection and driver errors: the message only, never a stack or the database URL.
|
|
80
|
+
output.error(`softure migrate: ${describeError(error)}`);
|
|
81
|
+
return EXIT_FAILED;
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
await opened.close();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function runDatabaseCommand(handle, input) {
|
|
88
|
+
const { command, modules, output, app } = input;
|
|
89
|
+
const dirOption = input.migrationsDir === undefined ? {} : { migrationsDir: input.migrationsDir };
|
|
90
|
+
const hasAppMigrations = app.before !== undefined || app.after !== undefined;
|
|
91
|
+
if (command.plan && hasAppMigrations) {
|
|
92
|
+
output.log("app migrations: not planned; the app runs them itself on migrate");
|
|
93
|
+
}
|
|
94
|
+
if (command.kind === "adopt") {
|
|
95
|
+
if (!command.plan) {
|
|
96
|
+
const before = await runAppMigrations(handle, app, "before");
|
|
97
|
+
if (!before.ok)
|
|
98
|
+
return reportFailure(output, before);
|
|
99
|
+
if (before.value.ran)
|
|
100
|
+
output.log("applied app migrations (before)");
|
|
101
|
+
}
|
|
102
|
+
const result = await adoptModule(handle, {
|
|
103
|
+
modules,
|
|
104
|
+
module: command.module,
|
|
105
|
+
version: command.version,
|
|
106
|
+
dryRun: command.plan,
|
|
107
|
+
...(command.through === undefined ? {} : { through: command.through }),
|
|
108
|
+
...dirOption,
|
|
109
|
+
});
|
|
110
|
+
if (!result.ok)
|
|
111
|
+
return reportFailure(output, result);
|
|
112
|
+
const verb = command.plan ? "would" : "did";
|
|
113
|
+
[...result.value.ledger, ...result.value.dependencies].forEach((step) => output.log(`${verb} apply ${formatStep(step)}`));
|
|
114
|
+
result.value.adopted.forEach((step) => output.log(`${verb} adopt ${formatStep(step)}`));
|
|
115
|
+
const scope = command.through === undefined ? "" : ` through ${formatVersion(command.through)}`;
|
|
116
|
+
output.log(`${command.module}@${command.version}: the schema matches its migrations${scope}${command.plan ? " (plan only, nothing written)" : "; adopted"}`);
|
|
117
|
+
return EXIT_OK;
|
|
118
|
+
}
|
|
119
|
+
if (command.plan) {
|
|
120
|
+
const result = await planMigrations(handle, { modules, ...dirOption, app });
|
|
121
|
+
if (!result.ok)
|
|
122
|
+
return reportFailure(output, result);
|
|
123
|
+
const baseline = new Set(result.value.baseline);
|
|
124
|
+
result.value.pending.forEach((step) => output.log(`pending ${formatStep(step)}${baseline.has(step) ? " (adopted if its schema already holds objects)" : ""}`));
|
|
125
|
+
output.log(result.value.pending.length === 0 ? "nothing to apply" : `${result.value.pending.length} migration(s) to apply`);
|
|
126
|
+
return EXIT_OK;
|
|
127
|
+
}
|
|
128
|
+
const result = await migrate(handle, {
|
|
129
|
+
modules,
|
|
130
|
+
...dirOption,
|
|
131
|
+
app,
|
|
132
|
+
onApplied: (step) => output.log(`applied ${formatStep(step)}`),
|
|
133
|
+
onAdopted: (step) => output.log(`adopted ${formatStep(step)}`),
|
|
134
|
+
onAppMigrated: (phase) => output.log(`applied app migrations (${phase})`),
|
|
135
|
+
});
|
|
136
|
+
if (!result.ok)
|
|
137
|
+
return reportFailure(output, result);
|
|
138
|
+
output.log(formatSummary(result.value.applied.length, result.value.adopted.length));
|
|
139
|
+
return EXIT_OK;
|
|
140
|
+
}
|
|
141
|
+
function parseCommand(argv) {
|
|
142
|
+
let values;
|
|
143
|
+
try {
|
|
144
|
+
({ values } = parseArgs({
|
|
145
|
+
args: [...argv],
|
|
146
|
+
options: {
|
|
147
|
+
plan: { type: "boolean" },
|
|
148
|
+
adopt: { type: "string" },
|
|
149
|
+
through: { type: "string" },
|
|
150
|
+
"migrations-dir": { type: "string" },
|
|
151
|
+
"export-migrations": { type: "string" },
|
|
152
|
+
help: { type: "boolean" },
|
|
153
|
+
},
|
|
154
|
+
strict: true,
|
|
155
|
+
allowPositionals: false,
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return describeError(error);
|
|
160
|
+
}
|
|
161
|
+
if (values.help === true)
|
|
162
|
+
return { kind: "help" };
|
|
163
|
+
const exportDir = values["export-migrations"];
|
|
164
|
+
if (exportDir !== undefined) {
|
|
165
|
+
const others = ["plan", "adopt", "through", "migrations-dir"].filter((name) => values[name] !== undefined);
|
|
166
|
+
return others.length > 0 ? `--export-migrations cannot be combined with --${others.join(", --")}` : { kind: "export", targetDir: exportDir };
|
|
167
|
+
}
|
|
168
|
+
const plan = values.plan === true;
|
|
169
|
+
const migrationsDir = values["migrations-dir"];
|
|
170
|
+
if (values.adopt === undefined) {
|
|
171
|
+
return values.through === undefined ? { kind: "migrate", plan, migrationsDir } : "--through needs --adopt <module>@<version>";
|
|
172
|
+
}
|
|
173
|
+
const match = ADOPT_TARGET.exec(values.adopt);
|
|
174
|
+
if (match?.[1] === undefined || match[2] === undefined) {
|
|
175
|
+
return `--adopt expects <module>@<x.y.z>, e.g. auth@0.1.0, got "${values.adopt}"`;
|
|
176
|
+
}
|
|
177
|
+
const through = values.through === undefined ? undefined : parseThrough(values.through);
|
|
178
|
+
if (through === null) {
|
|
179
|
+
return `--through expects a positive whole number, got "${values.through ?? ""}"`;
|
|
180
|
+
}
|
|
181
|
+
return { kind: "adopt", plan, module: match[1], version: match[2], through, migrationsDir };
|
|
182
|
+
}
|
|
183
|
+
/** A positive whole number written in digits, or null. */
|
|
184
|
+
function parseThrough(text) {
|
|
185
|
+
return /^[1-9]\d*$/.test(text) ? Number(text) : null;
|
|
186
|
+
}
|
|
187
|
+
function reportFailure(output, failure) {
|
|
188
|
+
failure.problems.forEach((problem) => output.error(describeProblem(problem)));
|
|
189
|
+
return EXIT_FAILED;
|
|
190
|
+
}
|
|
191
|
+
function formatStep(step) {
|
|
192
|
+
return `${step.module} ${formatVersion(step.version)}_${step.name}.sql`;
|
|
193
|
+
}
|
|
194
|
+
function formatVersion(version) {
|
|
195
|
+
return String(version).padStart(4, "0");
|
|
196
|
+
}
|
|
197
|
+
function formatSummary(applied, adopted) {
|
|
198
|
+
if (applied === 0 && adopted === 0)
|
|
199
|
+
return "nothing to apply";
|
|
200
|
+
return adopted === 0 ? `${applied} migration(s) applied` : `${applied} migration(s) applied, ${adopted} adopted`;
|
|
201
|
+
}
|
|
202
|
+
function describeError(error) {
|
|
203
|
+
return error instanceof Error ? error.message : String(error);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { PGlite } from "@electric-sql/pglite";
|
|
2
|
+
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
3
|
+
import type { PgliteDatabase } from "drizzle-orm/pglite";
|
|
4
|
+
import type { Pool } from "pg";
|
|
5
|
+
/** The optional peer a URL scheme needs, named in the error when it is not installed. */
|
|
6
|
+
export interface DriverRequirement {
|
|
7
|
+
readonly packageName: string;
|
|
8
|
+
readonly scheme: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The drizzle schema a database is typed with. The default accepts any schema, so an app database made with
|
|
12
|
+
* `drizzle({ client, schema })` (and its transactions) can be passed wherever a module takes `Database` or
|
|
13
|
+
* `Queryable`; pass the app's schema to keep its relational `db.query` API typed.
|
|
14
|
+
*/
|
|
15
|
+
export type DatabaseSchema = Record<string, unknown>;
|
|
16
|
+
export type PostgresDatabase<TSchema extends DatabaseSchema = DatabaseSchema> = NodePgDatabase<TSchema> & {
|
|
17
|
+
$client: Pool;
|
|
18
|
+
};
|
|
19
|
+
export type PgliteClientDatabase<TSchema extends DatabaseSchema = DatabaseSchema> = PgliteDatabase<TSchema> & {
|
|
20
|
+
$client: PGlite;
|
|
21
|
+
};
|
|
22
|
+
/** The drizzle database modules and the app query through. */
|
|
23
|
+
export type Database<TSchema extends DatabaseSchema = DatabaseSchema> = PostgresDatabase<TSchema> | PgliteClientDatabase<TSchema>;
|
|
24
|
+
/**
|
|
25
|
+
* A connection *or* an open transaction. Query helpers take this, so one function serves a
|
|
26
|
+
* plain read and a step inside `db.transaction()`.
|
|
27
|
+
*/
|
|
28
|
+
export type Queryable<TSchema extends DatabaseSchema = DatabaseSchema> = Database<TSchema> | Parameters<Parameters<Database<TSchema>["transaction"]>[0]>[0];
|
|
29
|
+
export type DatabaseHandle = {
|
|
30
|
+
readonly kind: "postgres";
|
|
31
|
+
readonly db: PostgresDatabase;
|
|
32
|
+
readonly pool: Pool;
|
|
33
|
+
readonly close: () => Promise<void>;
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: "pglite";
|
|
36
|
+
readonly db: PgliteClientDatabase;
|
|
37
|
+
readonly client: PGlite;
|
|
38
|
+
readonly close: () => Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
export interface CreateDatabaseOptions {
|
|
41
|
+
/** Pool size for Postgres; ignored by PGlite, which has a single connection. Default 10. */
|
|
42
|
+
readonly max?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Opens the database a URL points at. Throws when the URL is empty or its scheme is not supported:
|
|
46
|
+
* that is a deployment bug. The message names the scheme only, never the URL, which holds a password.
|
|
47
|
+
* The config accepts an empty URL (a build has no DATABASE_URL), so this is where it is refused.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createDatabase(url: string, options?: CreateDatabaseOptions): Promise<DatabaseHandle>;
|
|
50
|
+
/**
|
|
51
|
+
* Wraps an open PGlite instance, e.g. the app's own, for `database.handle` in softure.config. `close` closes the
|
|
52
|
+
* instance, which writes a `pglite://<dir>` database back to its directory.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createPgliteHandle(client: PGlite): Promise<DatabaseHandle & {
|
|
55
|
+
kind: "pglite";
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* Wraps an open node-postgres pool, e.g. the app's own, for `database.handle` in softure.config. `close` ends
|
|
59
|
+
* the pool. The pool's `error` listener stays the app's: add one, or an idle client's lost connection crashes
|
|
60
|
+
* the process.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createPostgresHandle(pool: Pool): Promise<DatabaseHandle & {
|
|
63
|
+
kind: "postgres";
|
|
64
|
+
}>;
|
|
65
|
+
/** Whether `value` has the shape of a `DatabaseHandle` (what `database.handle` must return). */
|
|
66
|
+
export declare function isDatabaseHandle(value: unknown): value is DatabaseHandle;
|
|
67
|
+
/**
|
|
68
|
+
* Turns Node's "Cannot find package" for a driver (from the driver import or from drizzle's adapter, which imports
|
|
69
|
+
* it statically) into an error that says what to install. Anything else, including a missing package other than
|
|
70
|
+
* the driver, is returned unchanged.
|
|
71
|
+
*/
|
|
72
|
+
export declare function explainMissingDriver(error: unknown, driver: DriverRequirement): unknown;
|
|
73
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAM/B,yFAAyF;AACzF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAKD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD,MAAM,MAAM,gBAAgB,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC;AAC5H,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAElI,8DAA8D;AAC9D,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAElI;;;GAGG;AACH,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc,IACjE,QAAQ,CAAC,OAAO,CAAC,GACjB,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnE,MAAM,MAAM,cAAc,GACtB;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,oBAAoB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC,CAAC;AAEN,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAqB9G;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAGrG;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,cAAc,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAGrG;AAED,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAOxE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAWvF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const PGLITE_PREFIX = "pglite://";
|
|
2
|
+
const POSTGRES_PREFIXES = ["postgres://", "postgresql://"];
|
|
3
|
+
const MODULE_NOT_FOUND_CODES = new Set(["ERR_MODULE_NOT_FOUND", "MODULE_NOT_FOUND"]);
|
|
4
|
+
const POSTGRES_DRIVER = { packageName: "pg", scheme: "postgres://" };
|
|
5
|
+
const PGLITE_DRIVER = { packageName: "@electric-sql/pglite", scheme: "pglite://" };
|
|
6
|
+
/**
|
|
7
|
+
* Opens the database a URL points at. Throws when the URL is empty or its scheme is not supported:
|
|
8
|
+
* that is a deployment bug. The message names the scheme only, never the URL, which holds a password.
|
|
9
|
+
* The config accepts an empty URL (a build has no DATABASE_URL), so this is where it is refused.
|
|
10
|
+
*/
|
|
11
|
+
export async function createDatabase(url, options = {}) {
|
|
12
|
+
if (url === "") {
|
|
13
|
+
throw new Error("createDatabase: the database URL is empty; set database.url in softure.config (usually from DATABASE_URL)");
|
|
14
|
+
}
|
|
15
|
+
if (url.startsWith(PGLITE_PREFIX)) {
|
|
16
|
+
const dataDir = url.slice(PGLITE_PREFIX.length);
|
|
17
|
+
const { PGlite } = await importDriver(PGLITE_DRIVER, () => import("@electric-sql/pglite"));
|
|
18
|
+
const client = dataDir === "" ? new PGlite() : new PGlite(dataDir);
|
|
19
|
+
return createPgliteHandle(client);
|
|
20
|
+
}
|
|
21
|
+
if (POSTGRES_PREFIXES.some((prefix) => url.startsWith(prefix))) {
|
|
22
|
+
const { default: pg } = await importDriver(POSTGRES_DRIVER, () => import("pg"));
|
|
23
|
+
const pool = new pg.Pool({ connectionString: url, max: options.max ?? 10 });
|
|
24
|
+
// An idle client that loses its connection emits 'error' on the pool; unhandled, it would
|
|
25
|
+
// crash the process. The pool drops that client and the next query opens a new one.
|
|
26
|
+
pool.on("error", () => undefined);
|
|
27
|
+
return createPostgresHandle(pool);
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`createDatabase: unsupported database URL scheme ${describeScheme(url)}; use postgres://, postgresql:// or pglite://<dir>`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Wraps an open PGlite instance, e.g. the app's own, for `database.handle` in softure.config. `close` closes the
|
|
33
|
+
* instance, which writes a `pglite://<dir>` database back to its directory.
|
|
34
|
+
*/
|
|
35
|
+
export async function createPgliteHandle(client) {
|
|
36
|
+
const { drizzle } = await importDriver(PGLITE_DRIVER, () => import("drizzle-orm/pglite"));
|
|
37
|
+
return { kind: "pglite", db: drizzle({ client }), client, close: () => client.close() };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wraps an open node-postgres pool, e.g. the app's own, for `database.handle` in softure.config. `close` ends
|
|
41
|
+
* the pool. The pool's `error` listener stays the app's: add one, or an idle client's lost connection crashes
|
|
42
|
+
* the process.
|
|
43
|
+
*/
|
|
44
|
+
export async function createPostgresHandle(pool) {
|
|
45
|
+
const { drizzle } = await importDriver(POSTGRES_DRIVER, () => import("drizzle-orm/node-postgres"));
|
|
46
|
+
return { kind: "postgres", db: drizzle({ client: pool }), pool, close: () => pool.end() };
|
|
47
|
+
}
|
|
48
|
+
/** Whether `value` has the shape of a `DatabaseHandle` (what `database.handle` must return). */
|
|
49
|
+
export function isDatabaseHandle(value) {
|
|
50
|
+
if (typeof value !== "object" || value === null)
|
|
51
|
+
return false;
|
|
52
|
+
const candidate = value;
|
|
53
|
+
if (typeof candidate.db !== "object" || candidate.db === null || typeof candidate.close !== "function")
|
|
54
|
+
return false;
|
|
55
|
+
if (candidate.kind === "postgres")
|
|
56
|
+
return typeof candidate.pool === "object" && candidate.pool !== null;
|
|
57
|
+
if (candidate.kind === "pglite")
|
|
58
|
+
return typeof candidate.client === "object" && candidate.client !== null;
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Turns Node's "Cannot find package" for a driver (from the driver import or from drizzle's adapter, which imports
|
|
63
|
+
* it statically) into an error that says what to install. Anything else, including a missing package other than
|
|
64
|
+
* the driver, is returned unchanged.
|
|
65
|
+
*/
|
|
66
|
+
export function explainMissingDriver(error, driver) {
|
|
67
|
+
if (!(error instanceof Error))
|
|
68
|
+
return error;
|
|
69
|
+
const code = error.code;
|
|
70
|
+
if (typeof code !== "string" || !MODULE_NOT_FOUND_CODES.has(code))
|
|
71
|
+
return error;
|
|
72
|
+
if (!error.message.includes(`'${driver.packageName}'`))
|
|
73
|
+
return error;
|
|
74
|
+
return new Error(`createDatabase: ${driver.scheme} URLs need the "${driver.packageName}" package, which is not installed; run ` +
|
|
75
|
+
`\`npm install ${driver.packageName}\` and, in a Next.js app, list "@softure-ai/db" and "${driver.packageName}" ` +
|
|
76
|
+
"in serverExternalPackages (db README §2)", { cause: error });
|
|
77
|
+
}
|
|
78
|
+
async function importDriver(driver, load) {
|
|
79
|
+
try {
|
|
80
|
+
return await load();
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
throw explainMissingDriver(error, driver);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function describeScheme(url) {
|
|
87
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(url)?.[1];
|
|
88
|
+
return scheme === undefined ? "(none)" : `"${scheme}:"`;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAWA,MAAM,aAAa,GAAG,WAAW,CAAC;AAClC,MAAM,iBAAiB,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;AAC3D,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAQrF,MAAM,eAAe,GAAsB,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACxF,MAAM,aAAa,GAAsB,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AA0CtG;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,UAAiC,EAAE;IACnF,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2GAA2G,CAAC,CAAC;IAC/H,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5E,0FAA0F;QAC1F,oFAAoF;QACpF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mDAAmD,cAAc,CAAC,GAAG,CAAC,oDAAoD,CAC3H,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc;IACrD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC1F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;AAC1F,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAU;IACnD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACnG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAC5F,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,SAAS,GAAG,KAAgC,CAAC;IACnD,IAAI,OAAO,SAAS,CAAC,EAAE,KAAK,QAAQ,IAAI,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACrH,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;IACxG,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,SAAS,CAAC,MAAM,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC;IAC1G,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAAE,MAAyB;IAC5E,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,IAAI,GAAI,KAAoC,CAAC,IAAI,CAAC;IACxD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAChF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,WAAW,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,OAAO,IAAI,KAAK,CACd,mBAAmB,MAAM,CAAC,MAAM,mBAAmB,MAAM,CAAC,WAAW,yCAAyC;QAC5G,iBAAiB,MAAM,CAAC,WAAW,wDAAwD,MAAM,CAAC,WAAW,IAAI;QACjH,0CAA0C,EAC5C,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAI,MAAyB,EAAE,IAAsB;IAC9E,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SoftureDatabaseConfig } from "@softure-ai/core";
|
|
2
|
+
import { type CreateDatabaseOptions, type DatabaseHandle } from "./client.js";
|
|
3
|
+
declare module "@softure-ai/core" {
|
|
4
|
+
interface SoftureDatabaseHandleTypes {
|
|
5
|
+
readonly handle: DatabaseHandle;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The handle for the config's database: the app's `database.handle`, called once per function and checked, or
|
|
10
|
+
* else `getSharedDatabase(database.url)`. Never closes anything; for a server's whole life. A failed or invalid
|
|
11
|
+
* `handle` call is not kept, so the next call tries again.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getConfiguredDatabase(database: SoftureDatabaseConfig): Promise<DatabaseHandle>;
|
|
14
|
+
export interface CommandDatabase {
|
|
15
|
+
readonly handle: DatabaseHandle;
|
|
16
|
+
/** Closes what the command opened: its own handle, or the app's configured one (and forgets it). */
|
|
17
|
+
readonly close: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The database for a command's own process (`softure migrate`, a module CLI, an ops script): the app's
|
|
21
|
+
* configured handle when `database.handle` is set, so the app's hooks and the command share one instance,
|
|
22
|
+
* otherwise a new handle on `database.url` with `options`. `close` closes either one; a `pglite://` directory is
|
|
23
|
+
* written back only then. Not for a running server: closing would close the app's handle under it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function openCommandDatabase(database: SoftureDatabaseConfig, options?: CreateDatabaseOptions): Promise<CommandDatabase>;
|
|
26
|
+
/**
|
|
27
|
+
* Closes and forgets every configured handle this process resolved. For tests; at shutdown the app closes its own
|
|
28
|
+
* handle, which it owns (`closeSharedDatabases` leaves configured handles alone for that reason).
|
|
29
|
+
*/
|
|
30
|
+
export declare function closeConfiguredDatabases(): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=configured.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configured.d.ts","sourceRoot":"","sources":["../src/configured.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAoC,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGhH,OAAO,QAAQ,kBAAkB,CAAC;IAChC,UAAU,0BAA0B;QAClC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;KACjC;CACF;AAqBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiB9F;AAYD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,oGAAoG;IACpG,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,eAAe,CAAC,CAiBxI;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createDatabase, isDatabaseHandle } from "./client.js";
|
|
2
|
+
import { getSharedDatabase } from "./shared.js";
|
|
3
|
+
const CONFIGURED_KEY = Symbol.for("@softure-ai/db/configured-handles");
|
|
4
|
+
const host = globalThis;
|
|
5
|
+
function getConfiguredHandles() {
|
|
6
|
+
return (host[CONFIGURED_KEY] ??= { byFunction: new WeakMap(), open: new Set() });
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The handle for the config's database: the app's `database.handle`, called once per function and checked, or
|
|
10
|
+
* else `getSharedDatabase(database.url)`. Never closes anything; for a server's whole life. A failed or invalid
|
|
11
|
+
* `handle` call is not kept, so the next call tries again.
|
|
12
|
+
*/
|
|
13
|
+
export function getConfiguredDatabase(database) {
|
|
14
|
+
const source = database.handle;
|
|
15
|
+
if (source === undefined)
|
|
16
|
+
return getSharedDatabase(database.url);
|
|
17
|
+
const handles = getConfiguredHandles();
|
|
18
|
+
let handle = handles.byFunction.get(source);
|
|
19
|
+
if (handle === undefined) {
|
|
20
|
+
handle = resolveHandle(source);
|
|
21
|
+
const opened = handle;
|
|
22
|
+
handles.byFunction.set(source, opened);
|
|
23
|
+
handles.open.add(opened);
|
|
24
|
+
opened.catch(() => {
|
|
25
|
+
handles.byFunction.delete(source);
|
|
26
|
+
handles.open.delete(opened);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return handle;
|
|
30
|
+
}
|
|
31
|
+
async function resolveHandle(source) {
|
|
32
|
+
const value = await source();
|
|
33
|
+
if (!isDatabaseHandle(value)) {
|
|
34
|
+
throw new Error("database.handle: the function must return a database handle; wrap the app's client with createPostgresHandle(pool) or createPgliteHandle(client) from @softure-ai/db");
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The database for a command's own process (`softure migrate`, a module CLI, an ops script): the app's
|
|
40
|
+
* configured handle when `database.handle` is set, so the app's hooks and the command share one instance,
|
|
41
|
+
* otherwise a new handle on `database.url` with `options`. `close` closes either one; a `pglite://` directory is
|
|
42
|
+
* written back only then. Not for a running server: closing would close the app's handle under it.
|
|
43
|
+
*/
|
|
44
|
+
export async function openCommandDatabase(database, options = {}) {
|
|
45
|
+
const source = database.handle;
|
|
46
|
+
if (source === undefined) {
|
|
47
|
+
const handle = await createDatabase(database.url, options);
|
|
48
|
+
return { handle, close: handle.close };
|
|
49
|
+
}
|
|
50
|
+
const opened = getConfiguredDatabase(database);
|
|
51
|
+
const handle = await opened;
|
|
52
|
+
return {
|
|
53
|
+
handle,
|
|
54
|
+
close: async () => {
|
|
55
|
+
const handles = getConfiguredHandles();
|
|
56
|
+
handles.byFunction.delete(source);
|
|
57
|
+
handles.open.delete(opened);
|
|
58
|
+
await handle.close();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Closes and forgets every configured handle this process resolved. For tests; at shutdown the app closes its own
|
|
64
|
+
* handle, which it owns (`closeSharedDatabases` leaves configured handles alone for that reason).
|
|
65
|
+
*/
|
|
66
|
+
export async function closeConfiguredDatabases() {
|
|
67
|
+
const handles = host[CONFIGURED_KEY];
|
|
68
|
+
if (handles === undefined)
|
|
69
|
+
return;
|
|
70
|
+
host[CONFIGURED_KEY] = undefined;
|
|
71
|
+
const results = await Promise.allSettled([...handles.open]);
|
|
72
|
+
await Promise.all(results.flatMap((result) => (result.status === "fulfilled" ? [result.value.close()] : [])));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=configured.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configured.js","sourceRoot":"","sources":["../src/configured.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { createDatabase, createPgliteHandle, createPostgresHandle, isDatabaseHandle, type CreateDatabaseOptions, type Database, type DatabaseHandle, type DatabaseSchema, type PgliteClientDatabase, type PostgresDatabase, type Queryable, } from "./client.js";
|
|
2
|
+
export { closeSharedDatabases, getSharedDatabase } from "./shared.js";
|
|
3
|
+
export { closeConfiguredDatabases, getConfiguredDatabase, openCommandDatabase, type CommandDatabase } from "./configured.js";
|
|
4
|
+
export { computeChecksum, readMigrationFiles, type MigrationFile } from "./migrations/files.js";
|
|
5
|
+
export { describeProblem, type MigrationErrorCode, type MigrationFailure, type MigrationProblem, type MigrationResult, } from "./migrations/problems.js";
|
|
6
|
+
export { migrate, planMigrations, runAppMigrations, type AppMigrationHook, type AppMigrationPhase, type AppMigrations, type MigrateOptions, type MigrationPlan, type MigrationReport, type MigrationStep, } from "./migrations/migrator.js";
|
|
7
|
+
export { adoptModule, type AdoptionReport, type AdoptOptions } from "./migrations/adopt.js";
|
|
8
|
+
export { exportMigrations } from "./migrations/export.js";
|
|
9
|
+
export { checkExportedMigrations, type ExportedMigration, type ExportedMigrationsCheck, } from "./migrations/exported.js";
|
|
10
|
+
export { readJournal, type JournalRow, type MigrationMethod } from "./migrations/ledger.js";
|
|
11
|
+
export type { MigrationSession } from "./migrations/session.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7H,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC5F,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Public API of @softure-ai/db: the database client and the module migrator
|
|
2
|
+
// (docs/02-module-standard.md §4). Test databases: `@softure-ai/db/testing`; CLI: `@softure-ai/db/cli`.
|
|
3
|
+
export { createDatabase, createPgliteHandle, createPostgresHandle, isDatabaseHandle, } from "./client.js";
|
|
4
|
+
export { closeSharedDatabases, getSharedDatabase } from "./shared.js";
|
|
5
|
+
export { closeConfiguredDatabases, getConfiguredDatabase, openCommandDatabase } from "./configured.js";
|
|
6
|
+
export { computeChecksum, readMigrationFiles } from "./migrations/files.js";
|
|
7
|
+
export { describeProblem, } from "./migrations/problems.js";
|
|
8
|
+
export { migrate, planMigrations, runAppMigrations, } from "./migrations/migrator.js";
|
|
9
|
+
export { adoptModule } from "./migrations/adopt.js";
|
|
10
|
+
export { exportMigrations } from "./migrations/export.js";
|
|
11
|
+
export { checkExportedMigrations, } from "./migrations/exported.js";
|
|
12
|
+
export { readJournal } from "./migrations/ledger.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wGAAwG;AACxG,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GAQjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAC7H,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAsB,MAAM,uBAAuB,CAAC;AAChG,OAAO,EACL,eAAe,GAKhB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,OAAO,EACP,cAAc,EACd,gBAAgB,GAQjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAA0C,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,uBAAuB,GAGxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAyC,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type AnySoftureModule } from "@softure-ai/core";
|
|
2
|
+
import type { DatabaseHandle } from "../client.js";
|
|
3
|
+
import { type MigrationStep } from "./migrator.js";
|
|
4
|
+
import { type MigrationResult } from "./problems.js";
|
|
5
|
+
export interface AdoptOptions {
|
|
6
|
+
/** The enabled modules, as for `migrate`. */
|
|
7
|
+
readonly modules: readonly AnySoftureModule[];
|
|
8
|
+
/** The id of the module to adopt. */
|
|
9
|
+
readonly module: string;
|
|
10
|
+
/** Its version; must equal the enabled module's manifest version. */
|
|
11
|
+
readonly version: string;
|
|
12
|
+
/**
|
|
13
|
+
* The last file to adopt (1..n); default every file. The later files stay pending and the next
|
|
14
|
+
* `migrate` applies them.
|
|
15
|
+
*/
|
|
16
|
+
readonly through?: number;
|
|
17
|
+
/** Compare and report only; write nothing (also no ledger). */
|
|
18
|
+
readonly dryRun?: boolean;
|
|
19
|
+
readonly migrationsDir?: URL;
|
|
20
|
+
}
|
|
21
|
+
export interface AdoptionReport {
|
|
22
|
+
readonly module: string;
|
|
23
|
+
readonly version: string;
|
|
24
|
+
readonly dryRun: boolean;
|
|
25
|
+
/** Ledger migrations applied first (or that would be, on a dry run). */
|
|
26
|
+
readonly ledger: readonly MigrationStep[];
|
|
27
|
+
/** Pending files of the modules it depends on, applied before the comparison (or that would be). */
|
|
28
|
+
readonly dependencies: readonly MigrationStep[];
|
|
29
|
+
/** The module's migrations recorded as adopted (or that would be). */
|
|
30
|
+
readonly adopted: readonly MigrationStep[];
|
|
31
|
+
}
|
|
32
|
+
export declare function adoptModule(handle: DatabaseHandle, options: AdoptOptions): Promise<MigrationResult<AdoptionReport>>;
|
|
33
|
+
//# sourceMappingURL=adopt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../src/migrations/adopt.ts"],"names":[],"mappings":"AAMA,OAAO,EAAM,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,EAAsD,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAmC,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAKtF,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,oGAAoG;IACpG,QAAQ,CAAC,YAAY,EAAE,SAAS,aAAa,EAAE,CAAC;IAChD,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAkEzH"}
|