@metaobjectsdev/cli 1.0.5-rc.9 → 1.0.7-rc.1
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 +1 -0
- package/dist/src/commands/export.d.ts.map +1 -1
- package/dist/src/commands/export.js +18 -3
- package/dist/src/commands/export.js.map +1 -1
- package/dist/src/commands/migrate.d.ts +1 -1
- package/dist/src/commands/migrate.d.ts.map +1 -1
- package/dist/src/commands/migrate.js +72 -17
- package/dist/src/commands/migrate.js.map +1 -1
- package/dist/src/commands/verify.js +1 -1
- package/dist/src/commands/verify.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/args.d.ts +11 -0
- package/dist/src/lib/args.d.ts.map +1 -1
- package/dist/src/lib/args.js +35 -0
- package/dist/src/lib/args.js.map +1 -1
- package/dist/src/lib/catalog-listing.d.ts +5 -0
- package/dist/src/lib/catalog-listing.d.ts.map +1 -1
- package/dist/src/lib/catalog-listing.js +10 -0
- package/dist/src/lib/catalog-listing.js.map +1 -1
- package/dist/src/lib/config.d.ts +3 -0
- package/dist/src/lib/config.d.ts.map +1 -1
- package/dist/src/lib/config.js +1 -0
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/kysely.d.ts +12 -0
- package/dist/src/lib/kysely.d.ts.map +1 -1
- package/dist/src/lib/kysely.js +33 -4
- package/dist/src/lib/kysely.js.map +1 -1
- package/dist/src/lib/output.d.ts +7 -0
- package/dist/src/lib/output.d.ts.map +1 -1
- package/dist/src/lib/output.js +6 -1
- package/dist/src/lib/output.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/export.ts +18 -5
- package/src/commands/migrate.ts +76 -18
- package/src/commands/verify.ts +1 -1
- package/src/index.ts +2 -0
- package/src/lib/args.ts +43 -0
- package/src/lib/catalog-listing.ts +11 -0
- package/src/lib/config.ts +4 -0
- package/src/lib/kysely.ts +38 -8
- package/src/lib/output.ts +13 -1
package/src/lib/kysely.ts
CHANGED
|
@@ -1,7 +1,43 @@
|
|
|
1
1
|
import { Kysely } from "kysely";
|
|
2
2
|
import { BunSqliteDialect, isBun } from "./bun-sqlite-dialect.js";
|
|
3
|
+
import { sep } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
3
5
|
import { installCommand } from "./pm-detect.js";
|
|
4
6
|
|
|
7
|
+
/**
|
|
8
|
+
* The directory a dynamic `import()` of a DB driver resolves from: the project whose
|
|
9
|
+
* `node_modules` holds `@metaobjectsdev/cli`. `undefined` when the CLI is not running from
|
|
10
|
+
* an installed package (a source checkout), where there is no one place to name.
|
|
11
|
+
*/
|
|
12
|
+
export function cliInstallRoot(moduleUrl: string): string | undefined {
|
|
13
|
+
const path = moduleUrl.startsWith("file:") ? fileURLToPath(moduleUrl) : moduleUrl;
|
|
14
|
+
const marker = `${sep}node_modules${sep}@metaobjectsdev${sep}`;
|
|
15
|
+
const i = path.lastIndexOf(marker);
|
|
16
|
+
return i === -1 ? undefined : path.slice(0, i);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A missing driver says WHERE it must be installed. In a monorepo the package that
|
|
21
|
+
* depends on the CLI need not be the one that runs the app, and installing the driver in
|
|
22
|
+
* the wrong one changes nothing.
|
|
23
|
+
*/
|
|
24
|
+
export function missingDriverMessage(
|
|
25
|
+
dialect: string, pkg: string, root: string | undefined, cmd: string,
|
|
26
|
+
): string {
|
|
27
|
+
const where = root === undefined
|
|
28
|
+
? "where @metaobjectsdev/cli is installed"
|
|
29
|
+
: `where @metaobjectsdev/cli is installed (${root})`;
|
|
30
|
+
return `dialect '${dialect}' requires '${pkg}', resolvable from ${where} — in a monorepo, ` +
|
|
31
|
+
`the package that depends on the CLI, not necessarily the one that runs your app. ` +
|
|
32
|
+
`Install it there: '${cmd}'`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function missingDriver(dialect: string, pkg: string): Promise<Error> {
|
|
36
|
+
const root = cliInstallRoot(import.meta.url);
|
|
37
|
+
const cmd = await installCommand(pkg, root ?? process.cwd());
|
|
38
|
+
return new Error(missingDriverMessage(dialect, pkg, root, cmd));
|
|
39
|
+
}
|
|
40
|
+
|
|
5
41
|
export type Dialect = "sqlite" | "postgres" | "d1";
|
|
6
42
|
|
|
7
43
|
export interface KyselyHandle {
|
|
@@ -81,10 +117,7 @@ export async function buildKyselyFromUrl(
|
|
|
81
117
|
const mod = await import("@libsql/kysely-libsql");
|
|
82
118
|
LibsqlDialect = mod.LibsqlDialect as unknown as LibsqlDialectCtor;
|
|
83
119
|
} catch {
|
|
84
|
-
|
|
85
|
-
throw new Error(
|
|
86
|
-
`dialect 'sqlite' requires '@libsql/kysely-libsql'; install it: '${cmd}'`,
|
|
87
|
-
);
|
|
120
|
+
throw await missingDriver("sqlite", "@libsql/kysely-libsql");
|
|
88
121
|
}
|
|
89
122
|
sqliteDialect = new LibsqlDialect({ url });
|
|
90
123
|
}
|
|
@@ -110,10 +143,7 @@ export async function buildKyselyFromUrl(
|
|
|
110
143
|
pg = await import("pg") as unknown as PgPoolModule;
|
|
111
144
|
({ PostgresDialect } = await import("kysely"));
|
|
112
145
|
} catch {
|
|
113
|
-
|
|
114
|
-
throw new Error(
|
|
115
|
-
`dialect 'postgres' requires 'pg'; install it: '${cmd}'`,
|
|
116
|
-
);
|
|
146
|
+
throw await missingDriver("postgres", "pg");
|
|
117
147
|
}
|
|
118
148
|
const PoolCtor = pg.Pool ?? pg.default?.Pool;
|
|
119
149
|
if (PoolCtor === undefined) {
|
package/src/lib/output.ts
CHANGED
|
@@ -181,6 +181,12 @@ export interface MigrateResultShape {
|
|
|
181
181
|
* that cannot work.
|
|
182
182
|
*/
|
|
183
183
|
format?: "default" | "flyway";
|
|
184
|
+
/**
|
|
185
|
+
* Data-hazard warnings: changes that apply to an empty table and fail on a populated one.
|
|
186
|
+
* Text output already carries them on stderr; JSON/toon carry them here so a programmatic
|
|
187
|
+
* caller sees the risk before applying.
|
|
188
|
+
*/
|
|
189
|
+
warnings?: string[];
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
export function formatMigrateResult(result: MigrateResultShape, _opts: FormatOptions): string {
|
|
@@ -298,6 +304,7 @@ export function migrateResultToData(result: MigrateResultShape): {
|
|
|
298
304
|
written: string[];
|
|
299
305
|
summary: string;
|
|
300
306
|
help: string[];
|
|
307
|
+
warnings?: string[];
|
|
301
308
|
} {
|
|
302
309
|
const changeEntries = Object.entries(result.changeCounts).filter(([, v]) => v > 0);
|
|
303
310
|
const changes = changeEntries.map(([kind, count]) => ({ kind, count }));
|
|
@@ -352,7 +359,12 @@ export function migrateResultToData(result: MigrateResultShape): {
|
|
|
352
359
|
help = ["re-run with --slug <name> to write the migration"];
|
|
353
360
|
}
|
|
354
361
|
|
|
355
|
-
|
|
362
|
+
const warnings = result.warnings ?? [];
|
|
363
|
+
return {
|
|
364
|
+
changes, written: result.writtenPaths, summary, help,
|
|
365
|
+
// Only when present, so a run with no hazard keeps its existing shape.
|
|
366
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
367
|
+
};
|
|
356
368
|
}
|
|
357
369
|
|
|
358
370
|
export function formatMigrateResultToon(result: MigrateResultShape): string {
|