@metaobjectsdev/cli 1.0.9-rc.6 → 1.0.10
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/dist/src/commands/deps.d.ts.map +1 -1
- package/dist/src/commands/deps.js +9 -8
- package/dist/src/commands/deps.js.map +1 -1
- package/dist/src/commands/docs.d.ts.map +1 -1
- package/dist/src/commands/docs.js +19 -12
- package/dist/src/commands/docs.js.map +1 -1
- package/dist/src/commands/eject.d.ts.map +1 -1
- package/dist/src/commands/eject.js +3 -2
- package/dist/src/commands/eject.js.map +1 -1
- package/dist/src/commands/export.d.ts.map +1 -1
- package/dist/src/commands/export.js +3 -2
- package/dist/src/commands/export.js.map +1 -1
- package/dist/src/commands/gen.d.ts.map +1 -1
- package/dist/src/commands/gen.js +8 -7
- package/dist/src/commands/gen.js.map +1 -1
- package/dist/src/commands/generator.d.ts.map +1 -1
- package/dist/src/commands/generator.js +3 -2
- package/dist/src/commands/generator.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +5 -2
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/migrate.d.ts.map +1 -1
- package/dist/src/commands/migrate.js +30 -23
- package/dist/src/commands/migrate.js.map +1 -1
- package/dist/src/commands/prompt-snapshot.d.ts.map +1 -1
- package/dist/src/commands/prompt-snapshot.js +5 -4
- package/dist/src/commands/prompt-snapshot.js.map +1 -1
- package/dist/src/commands/types.d.ts.map +1 -1
- package/dist/src/commands/types.js +7 -1
- package/dist/src/commands/types.js.map +1 -1
- package/dist/src/commands/upgrade.d.ts.map +1 -1
- package/dist/src/commands/upgrade.js +4 -3
- package/dist/src/commands/upgrade.js.map +1 -1
- package/dist/src/commands/verify.d.ts.map +1 -1
- package/dist/src/commands/verify.js +35 -23
- package/dist/src/commands/verify.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/args.d.ts.map +1 -1
- package/dist/src/lib/args.js +17 -6
- package/dist/src/lib/args.js.map +1 -1
- package/dist/src/lib/catalog-listing.d.ts.map +1 -1
- package/dist/src/lib/catalog-listing.js +5 -1
- package/dist/src/lib/catalog-listing.js.map +1 -1
- package/dist/src/lib/dependency-sync.d.ts.map +1 -1
- package/dist/src/lib/dependency-sync.js +4 -3
- package/dist/src/lib/dependency-sync.js.map +1 -1
- package/dist/src/lib/error-text.d.ts +2 -0
- package/dist/src/lib/error-text.d.ts.map +1 -0
- package/dist/src/lib/error-text.js +15 -0
- package/dist/src/lib/error-text.js.map +1 -0
- package/dist/src/lib/gen-migrate-advice.d.ts +1 -1
- package/dist/src/lib/gen-migrate-advice.d.ts.map +1 -1
- package/dist/src/lib/gen-migrate-advice.js +24 -0
- package/dist/src/lib/gen-migrate-advice.js.map +1 -1
- package/dist/src/lib/git-ignore.d.ts.map +1 -1
- package/dist/src/lib/git-ignore.js +2 -1
- package/dist/src/lib/git-ignore.js.map +1 -1
- package/dist/src/lib/output.d.ts +3 -2
- package/dist/src/lib/output.d.ts.map +1 -1
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/requirement-check.d.ts.map +1 -1
- package/dist/src/lib/requirement-check.js +43 -2
- package/dist/src/lib/requirement-check.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/deps.ts +9 -8
- package/src/commands/docs.ts +19 -12
- package/src/commands/eject.ts +3 -2
- package/src/commands/export.ts +3 -2
- package/src/commands/gen.ts +8 -7
- package/src/commands/generator.ts +3 -2
- package/src/commands/init.ts +5 -2
- package/src/commands/migrate.ts +32 -23
- package/src/commands/prompt-snapshot.ts +5 -4
- package/src/commands/types.ts +6 -1
- package/src/commands/upgrade.ts +4 -3
- package/src/commands/verify.ts +37 -23
- package/src/index.ts +3 -2
- package/src/lib/args.ts +19 -6
- package/src/lib/catalog-listing.ts +5 -1
- package/src/lib/dependency-sync.ts +4 -3
- package/src/lib/error-text.ts +13 -0
- package/src/lib/gen-migrate-advice.ts +24 -1
- package/src/lib/git-ignore.ts +2 -1
- package/src/lib/output.ts +3 -2
- package/src/lib/requirement-check.ts +46 -2
|
@@ -40,7 +40,7 @@ const VIEW_CHANGE_KINDS: ReadonlySet<Change["kind"]> = new Set(["create-view", "
|
|
|
40
40
|
export interface GenMigrateAdviceInput {
|
|
41
41
|
metadata: MetaRoot;
|
|
42
42
|
/** `metaobjects.config.ts` `dialect` — undefined when no DB code is generated. */
|
|
43
|
-
dialect: "sqlite" | "postgres" | undefined;
|
|
43
|
+
dialect: "sqlite" | "postgres" | "mysql" | undefined;
|
|
44
44
|
/** `.metaobjects/config.json` `migrate.dialect`, when set (may say `d1`). */
|
|
45
45
|
migrateDialect: "sqlite" | "postgres" | "d1" | undefined;
|
|
46
46
|
columnNamingStrategy: "snake_case" | "literal" | "kebab-case" | undefined;
|
|
@@ -55,6 +55,8 @@ export interface GenMigrateAdviceInput {
|
|
|
55
55
|
export async function genMigrateAdvice(input: GenMigrateAdviceInput): Promise<string | undefined> {
|
|
56
56
|
if (input.dialect === undefined || input.changedFiles.length === 0) return undefined;
|
|
57
57
|
|
|
58
|
+
if (input.dialect === "mysql") return mysqlAdvice(input);
|
|
59
|
+
|
|
58
60
|
const d1 = d1BindingFor(input);
|
|
59
61
|
const schemaDialect = d1 !== undefined ? "d1" : input.dialect;
|
|
60
62
|
let built;
|
|
@@ -94,6 +96,27 @@ export async function genMigrateAdvice(input: GenMigrateAdviceInput): Promise<st
|
|
|
94
96
|
: `migrate the schema change with \`meta migrate --db <url> --dialect ${input.dialect} --slug <name> --apply\``;
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
/**
|
|
100
|
+
* MySQL: `meta migrate` does not own the schema, so there is no migration to write. When the
|
|
101
|
+
* run touched a table-backed object, say that the adopter's DDL has to follow. The provenance
|
|
102
|
+
* (which generated file belongs to which table-backed object) does not depend on the dialect,
|
|
103
|
+
* so it is read through the Postgres expected-schema builder.
|
|
104
|
+
*/
|
|
105
|
+
function mysqlAdvice(input: GenMigrateAdviceInput): string | undefined {
|
|
106
|
+
let provenance: ReadonlyMap<string, string>;
|
|
107
|
+
try {
|
|
108
|
+
provenance = buildExpectedSchemaWithProvenance(input.metadata, {
|
|
109
|
+
dialect: "postgres",
|
|
110
|
+
...(input.columnNamingStrategy !== undefined ? { columnNamingStrategy: input.columnNamingStrategy } : {}),
|
|
111
|
+
}).provenance;
|
|
112
|
+
} catch {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
if (!touchesTableBackedObject(input.changedFiles, provenance)) return undefined;
|
|
116
|
+
return "MetaObjects does not manage a MySQL schema: apply the matching change to your MySQL DDL " +
|
|
117
|
+
"(the generated Drizzle tables describe the columns it must have)";
|
|
118
|
+
}
|
|
119
|
+
|
|
97
120
|
/** The project's D1 binding when it migrates through D1, else undefined. */
|
|
98
121
|
function d1BindingFor(input: GenMigrateAdviceInput): D1Binding | undefined {
|
|
99
122
|
if (input.dialect !== "sqlite" && input.migrateDialect !== "d1") return undefined;
|
package/src/lib/git-ignore.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import { spawnSync } from "node:child_process";
|
|
19
19
|
import { toPosix } from "./rel-posix.js";
|
|
20
|
+
import { describeError } from "./error-text.js";
|
|
20
21
|
|
|
21
22
|
/** Ignored paths, or the reason the question could not be asked. */
|
|
22
23
|
export type GitIgnoreResult =
|
|
@@ -75,7 +76,7 @@ export function gitIgnored(
|
|
|
75
76
|
try {
|
|
76
77
|
res = spawnSync(gitBin, args, { encoding: "utf-8", input });
|
|
77
78
|
} catch (err) {
|
|
78
|
-
return { unavailable: `git could not be run (${(err
|
|
79
|
+
return { unavailable: `git could not be run (${describeError(err)})` };
|
|
79
80
|
}
|
|
80
81
|
if (res.error !== undefined) {
|
|
81
82
|
return { unavailable: "git is not on PATH" };
|
package/src/lib/output.ts
CHANGED
|
@@ -47,8 +47,9 @@ export interface GenFileEntry {
|
|
|
47
47
|
export interface GenResultShape {
|
|
48
48
|
files: GenFileEntry[];
|
|
49
49
|
outDir: string;
|
|
50
|
-
/** Absent for a value-object-only project (no DB code generated → no dialect used).
|
|
51
|
-
dialect
|
|
50
|
+
/** Absent for a value-object-only project (no DB code generated → no dialect used). The
|
|
51
|
+
* CODEGEN dialect, which may be `mysql` (a dialect `meta migrate` does not speak). */
|
|
52
|
+
dialect: Dialect | "mysql" | undefined;
|
|
52
53
|
dryRun: boolean;
|
|
53
54
|
warnings: string[];
|
|
54
55
|
/**
|
|
@@ -675,14 +675,58 @@ export function summariseRequirements(
|
|
|
675
675
|
// `exactOptionalPropertyTypes`, so the keys are absent rather than undefined.
|
|
676
676
|
};
|
|
677
677
|
|
|
678
|
-
|
|
678
|
+
// `undecided` counts only the requirements a `@disposition` could actually
|
|
679
|
+
// SETTLE. A parent is `partial` because a descendant is, so a disposition on it
|
|
680
|
+
// would have to mean "we accept that memory is incomplete" — which settles
|
|
681
|
+
// nothing, names no work, and cannot be acted on.
|
|
682
|
+
//
|
|
683
|
+
// Measured on a real ledger before this was written: one adopter's tree printed
|
|
684
|
+
// "19 recorded gap(s) with no @disposition", and SIXTEEN of the nineteen were
|
|
685
|
+
// roll-up parents (`assistant`, `memory`, `security`, `understanding`,
|
|
686
|
+
// `conversation`, `growth`, `action`). Three were leaves anyone could rule on.
|
|
687
|
+
// Overstating by 6x is not cosmetic: a count nobody can action is a count
|
|
688
|
+
// everybody learns to skip, and the real gaps then ride along inside it
|
|
689
|
+
// invisibly — the opposite of what the line exists to do.
|
|
690
|
+
//
|
|
691
|
+
// Ancestry comes from the scan's own dotted PATHS rather than a second
|
|
692
|
+
// traversal, so this cannot disagree with how every other check addresses a
|
|
693
|
+
// node. `::` carries no dot, so splitting on "." keeps a package-qualified root
|
|
694
|
+
// segment intact. EVERY ancestor is excluded, not only the immediate parent:
|
|
695
|
+
// real ledgers are five deep, and an L1 node three levels above the work is no
|
|
696
|
+
// more actionable than the L2 one.
|
|
697
|
+
//
|
|
698
|
+
// A descendant marks its ancestors whether or not it is itself DISPOSED, and
|
|
699
|
+
// that asymmetry is the point. Once the only outstanding leaf under a parent has
|
|
700
|
+
// been ruled on, nothing beneath that parent is owed — so the parent must not be
|
|
701
|
+
// resurrected as a fresh decision by the roll-up status the ruled-on child gave
|
|
702
|
+
// it. Skipping disposed descendants here would do exactly that: it was the first
|
|
703
|
+
// implementation, and the test for the disposed-child tree caught it.
|
|
704
|
+
const rollUpAncestors = new Set<string>();
|
|
705
|
+
for (const { node, path } of scan.addressed) {
|
|
706
|
+
if (!node.hasOutstandingWork()) continue;
|
|
707
|
+
const segments = path.split(".");
|
|
708
|
+
for (let i = 1; i < segments.length; i++) {
|
|
709
|
+
rollUpAncestors.add(segments.slice(0, i).join("."));
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
for (const { node: req, path } of scan.addressed) {
|
|
679
714
|
if (req.subType === REQUIREMENT_SUBTYPE_ARCHITECTURAL) summary.architectural++;
|
|
680
715
|
else summary.functional++;
|
|
681
716
|
|
|
682
717
|
const status = req.status();
|
|
718
|
+
// byStatus is UNCHANGED on purpose: a roll-up parent is still genuinely
|
|
719
|
+
// `partial`, and the status breakdown is where that belongs. Only the
|
|
720
|
+
// "decisions owed" line narrows.
|
|
683
721
|
if (status !== undefined) summary.byStatus[status] = (summary.byStatus[status] ?? 0) + 1;
|
|
684
722
|
|
|
685
|
-
if (
|
|
723
|
+
if (
|
|
724
|
+
req.hasOutstandingWork() &&
|
|
725
|
+
req.disposition() === undefined &&
|
|
726
|
+
!rollUpAncestors.has(path)
|
|
727
|
+
) {
|
|
728
|
+
summary.undecided++;
|
|
729
|
+
}
|
|
686
730
|
if (req.disposition() === REQUIREMENT_DISPOSITION_DEFERRED && req.trackedBy().length === 0) {
|
|
687
731
|
summary.deferredUntracked++;
|
|
688
732
|
}
|