@intelligo-dev/cli 1.0.0-beta.1 → 1.0.0-beta.2
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/bin.js +45 -19
- package/dist/bin.js.map +1 -1
- package/dist/commands/add.d.ts +1 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +2 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +75 -19
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/migrate.d.ts +97 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +124 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/upgrade-check.d.ts.map +1 -1
- package/dist/commands/upgrade-check.js +5 -2
- package/dist/commands/upgrade-check.js.map +1 -1
- package/dist/manifest.d.ts +8 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +4 -2
- package/dist/manifest.js.map +1 -1
- package/package.json +1 -1
- package/templates/app-scaffold/db-schema.ts.tpl +29 -0
- package/templates/app-scaffold/drizzle.config.ts.tpl +42 -0
- package/templates/app-scaffold/env.example.tpl +11 -0
- package/templates/app-scaffold/intelligo.ts.tpl +18 -3
- package/templates/app-scaffold/package.json.tpl +9 -1
- package/templates/app-scaffold/plans.ts.tpl +9 -1
- package/templates/app-scaffold/stripe-webhook-route.ts.tpl +24 -0
- package/templates/app-scaffold/theme-provider.tsx.tpl +6 -4
- package/templates/maintenance/maintenance-route.ts.tpl +110 -0
- package/templates/manifest.json +26 -4
- package/templates/registry-requires.json +139 -0
package/dist/bin.js
CHANGED
|
@@ -16,6 +16,7 @@ import { addFeature, formatAddResult, readCatalogue } from "./commands/add.js";
|
|
|
16
16
|
import { createApp, formatCreateResult } from "./commands/create.js";
|
|
17
17
|
import { exitCodeFor, formatResults, runChecks } from "./commands/doctor.js";
|
|
18
18
|
import { formatMigrateCheck, migrateCheck, migrateCheckExitCode, } from "./commands/migrate-check.js";
|
|
19
|
+
import { MIGRATIONS_TABLE_SQL, applyExitCode, applyMigrations, formatApplyResult, } from "./commands/migrate.js";
|
|
19
20
|
import { formatUpgradeReport, upgradeCheck, upgradeCheckExitCode, } from "./commands/upgrade-check.js";
|
|
20
21
|
import { MIGRATION_LOCATIONS, resolveMigrationsDir } from "./migrations-dir.js";
|
|
21
22
|
/** Templates ship with the CLI package. */
|
|
@@ -33,32 +34,63 @@ function usage() {
|
|
|
33
34
|
"",
|
|
34
35
|
" create <dir> Scaffold a new application",
|
|
35
36
|
" doctor Report configuration and migration-chain problems",
|
|
36
|
-
" migrate
|
|
37
|
+
" migrate Apply the framework's migration chain to DATABASE_URL",
|
|
38
|
+
" migrate --check Compare the framework's migrations to a database",
|
|
37
39
|
" add <feature> Generate consumer-owned source (--force to overwrite)",
|
|
38
40
|
" upgrade --check Show what a template upgrade would change",
|
|
39
41
|
"",
|
|
40
42
|
].join("\n");
|
|
41
43
|
}
|
|
42
|
-
async function
|
|
44
|
+
async function runMigrate(mode) {
|
|
43
45
|
const url = process.env.DATABASE_URL;
|
|
44
46
|
if (!url) {
|
|
45
|
-
console.error(
|
|
47
|
+
console.error(`DATABASE_URL is required for \`migrate${mode === "check" ? " --check" : ""}\`.`);
|
|
46
48
|
return 1;
|
|
47
49
|
}
|
|
48
|
-
// Imported lazily so `doctor` — the command you reach for when the
|
|
49
|
-
// app will not start — never needs a database driver to load.
|
|
50
|
-
const { Client } = await import("pg");
|
|
51
|
-
const client = new Client({ connectionString: url });
|
|
52
|
-
await client.connect();
|
|
53
50
|
const migrationsDir = resolveMigrationsDir(process.cwd());
|
|
54
51
|
if (!migrationsDir) {
|
|
55
52
|
console.error(`No migrations directory (looked in ${MIGRATION_LOCATIONS.join(", ")}) — run from the workspace root, with @intelligo-dev/core installed.`);
|
|
56
53
|
return 1;
|
|
57
54
|
}
|
|
55
|
+
// Imported lazily so `doctor` — the command you reach for when the
|
|
56
|
+
// app will not start — never needs a database driver to load.
|
|
57
|
+
const { Client } = await import("pg");
|
|
58
|
+
const client = new Client({ connectionString: url });
|
|
59
|
+
await client.connect();
|
|
58
60
|
try {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
if (mode === "check") {
|
|
62
|
+
const result = await migrateCheck(migrationsDir, async (sql) => (await client.query(sql)).rows);
|
|
63
|
+
console.log(formatMigrateCheck(result));
|
|
64
|
+
return migrateCheckExitCode(result);
|
|
65
|
+
}
|
|
66
|
+
// Applied here rather than by drizzle's migrator: the pending set is
|
|
67
|
+
// chosen by content hash — what `migrate --check` compares — and
|
|
68
|
+
// recorded in drizzle's own table, in one transaction, so a failure
|
|
69
|
+
// part-way leaves neither statements nor records behind.
|
|
70
|
+
const result = await applyMigrations({
|
|
71
|
+
migrationsDir,
|
|
72
|
+
query: async (sql) => (await client.query(sql)).rows,
|
|
73
|
+
run: async (pending) => {
|
|
74
|
+
await client.query("BEGIN");
|
|
75
|
+
try {
|
|
76
|
+
for (const ddl of MIGRATIONS_TABLE_SQL)
|
|
77
|
+
await client.query(ddl);
|
|
78
|
+
for (const migration of pending) {
|
|
79
|
+
for (const statement of migration.statements) {
|
|
80
|
+
await client.query(statement);
|
|
81
|
+
}
|
|
82
|
+
await client.query(`INSERT INTO "drizzle"."__drizzle_migrations" ("hash", "created_at") VALUES ($1, $2)`, [migration.hash, migration.createdAt]);
|
|
83
|
+
}
|
|
84
|
+
await client.query("COMMIT");
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
await client.query("ROLLBACK");
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
console.log(formatApplyResult(result));
|
|
93
|
+
return applyExitCode(result);
|
|
62
94
|
}
|
|
63
95
|
finally {
|
|
64
96
|
await client.end();
|
|
@@ -72,14 +104,8 @@ async function main() {
|
|
|
72
104
|
console.log(formatResults(results));
|
|
73
105
|
return exitCodeFor(results);
|
|
74
106
|
}
|
|
75
|
-
case "migrate":
|
|
76
|
-
|
|
77
|
-
console.error("Only `migrate --check` is implemented.");
|
|
78
|
-
console.error("Applying migrations stays with drizzle-kit for now.");
|
|
79
|
-
return 1;
|
|
80
|
-
}
|
|
81
|
-
return runMigrateCheck();
|
|
82
|
-
}
|
|
107
|
+
case "migrate":
|
|
108
|
+
return runMigrate(rest.includes("--check") ? "check" : "apply");
|
|
83
109
|
case "create": {
|
|
84
110
|
const target = rest.find((a) => !a.startsWith("--"));
|
|
85
111
|
if (!target) {
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,2CAA2C;AAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAChC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAC/C,IAAI,EACJ,WAAW,CACZ,CAAC;AAEF;;;;;GAKG;AACH,MAAM,iBAAiB,GAAW,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC9D,iBAAiB,CAClB,CAAC,OAAO,CAAC;AAEV,SAAS,KAAK;IACZ,OAAO;QACL,qBAAqB;QACrB,EAAE;QACF,gDAAgD;QAChD,uEAAuE;QACvE,sEAAsE;QACtE,2EAA2E;QAC3E,+DAA+D;QAC/D,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/add.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export type AddOptions = {
|
|
|
43
43
|
*/
|
|
44
44
|
variables?: Record<string, string>;
|
|
45
45
|
};
|
|
46
|
+
export declare function substitute(contents: string, variables: Record<string, string> | undefined): string;
|
|
46
47
|
export declare function addFeature(feature: string, options: AddOptions): AddResult;
|
|
47
48
|
export declare function formatAddResult(r: AddResult): string;
|
|
48
49
|
//# sourceMappingURL=add.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEhE,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAIrE;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kEAAkE;IAClE,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEhE,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAIrE;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kEAAkE;IAClE,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC5C,MAAM,CAMR;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,CAuE1E;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAWpD"}
|
package/dist/commands/add.js
CHANGED
|
@@ -13,7 +13,7 @@ import { emptyManifest, hashContents, readManifest, recordFeature, writeManifest
|
|
|
13
13
|
export function readCatalogue(templatesDir) {
|
|
14
14
|
return JSON.parse(readFileSync(path.join(templatesDir, "manifest.json"), "utf8"));
|
|
15
15
|
}
|
|
16
|
-
function substitute(contents, variables) {
|
|
16
|
+
export function substitute(contents, variables) {
|
|
17
17
|
if (!variables)
|
|
18
18
|
return contents;
|
|
19
19
|
return Object.entries(variables).reduce((out, [key, value]) => out.split(key).join(value), contents);
|
|
@@ -63,7 +63,7 @@ export function addFeature(feature, options) {
|
|
|
63
63
|
recorded.push({ path: file.target, hash: hashContents(contents) });
|
|
64
64
|
result.written.push(file.target);
|
|
65
65
|
}
|
|
66
|
-
writeManifest(options.appRoot, recordFeature(manifest, feature, spec.templateVersion, recorded));
|
|
66
|
+
writeManifest(options.appRoot, recordFeature(manifest, feature, spec.templateVersion, recorded, options.variables));
|
|
67
67
|
return result;
|
|
68
68
|
}
|
|
69
69
|
export function formatAddResult(r) {
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,GAEd,MAAM,gBAAgB,CAAC;AAYxB,MAAM,UAAU,aAAa,CAAC,YAAoB;IAChD,OAAO,IAAI,CAAC,KAAK,CACf,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAC1C,CAAC;AACzB,CAAC;AA2BD,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,22 @@ export type CheckResult = {
|
|
|
10
10
|
status: "ok" | "warn" | "error";
|
|
11
11
|
detail: string;
|
|
12
12
|
};
|
|
13
|
+
type ItemRequires = {
|
|
14
|
+
marker: string;
|
|
15
|
+
items?: string[];
|
|
16
|
+
files?: string[];
|
|
17
|
+
exports?: Record<string, string[]>;
|
|
18
|
+
features?: string[];
|
|
19
|
+
};
|
|
20
|
+
export type RegistryRequires = {
|
|
21
|
+
scaffold: string[];
|
|
22
|
+
items: Record<string, ItemRequires>;
|
|
23
|
+
};
|
|
13
24
|
export type DoctorOptions = {
|
|
14
25
|
/** Workspace root; defaults to the current working directory. */
|
|
15
26
|
root?: string;
|
|
27
|
+
/** Registry requirements; defaults to the copy bundled with the CLI. */
|
|
28
|
+
requires?: RegistryRequires | null;
|
|
16
29
|
/** Environment to validate; defaults to process.env. */
|
|
17
30
|
env?: NodeJS.ProcessEnv;
|
|
18
31
|
};
|
|
@@ -20,4 +33,5 @@ export declare function runChecks(options?: DoctorOptions): CheckResult[];
|
|
|
20
33
|
export declare function formatResults(results: CheckResult[]): string;
|
|
21
34
|
/** Process exit code: non-zero when any check errored. */
|
|
22
35
|
export declare function exitCodeFor(results: CheckResult[]): number;
|
|
36
|
+
export {};
|
|
23
37
|
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AASF,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrC,CAAC;AAoBF,MAAM,MAAM,aAAa,GAAG;IAC1B,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AASF,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,WAAW,EAAE,CA4KpE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAK5D;AAED,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAE1D"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -6,10 +6,22 @@
|
|
|
6
6
|
* actually went wrong that way, not because they sounded thorough.
|
|
7
7
|
*/
|
|
8
8
|
import path from "node:path";
|
|
9
|
-
import { existsSync } from "node:fs";
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
10
|
import { inspectMigrationChain, readMigrationChain } from "../migrations.js";
|
|
11
11
|
import { readManifest } from "../manifest.js";
|
|
12
12
|
import { MIGRATION_LOCATIONS, resolveMigrationsDir, } from "../migrations-dir.js";
|
|
13
|
+
/**
|
|
14
|
+
* The registry's requirements file ships with the CLI (a verified copy
|
|
15
|
+
* of registry/requires.json) so doctor can check an installed app
|
|
16
|
+
* without a registry checkout. `../../templates` resolves from src/
|
|
17
|
+
* and from dist/commands/ alike.
|
|
18
|
+
*/
|
|
19
|
+
function bundledRequires() {
|
|
20
|
+
const file = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..", "..", "templates", "registry-requires.json");
|
|
21
|
+
if (!existsSync(file))
|
|
22
|
+
return null;
|
|
23
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
24
|
+
}
|
|
13
25
|
/** Variables the app cannot boot without. */
|
|
14
26
|
const REQUIRED_ENV = [
|
|
15
27
|
"DATABASE_URL",
|
|
@@ -78,27 +90,71 @@ export function runChecks(options = {}) {
|
|
|
78
90
|
detail: "INTELLIGO_BILLING_PRODUCT unset — the composition root must call " +
|
|
79
91
|
"setDefaultProductSlug(), or plan lookups resolve to nothing",
|
|
80
92
|
});
|
|
81
|
-
// 4.
|
|
82
|
-
//
|
|
83
|
-
// composition root
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
// 4. Installed registry items against registry/requires.json: the
|
|
94
|
+
// sibling items they import from, the scaffold files they import,
|
|
95
|
+
// the exports the composition root must provide, and the feature
|
|
96
|
+
// keys they gate on — each a `next build` or a 403 that only shows
|
|
97
|
+
// up later. An item counts as installed when its marker file is.
|
|
98
|
+
const requires = options.requires === undefined ? bundledRequires() : options.requires;
|
|
99
|
+
if (requires) {
|
|
100
|
+
const exists = (rel) => [".ts", ".tsx", ".js", ".jsx", ".json", ""].some((ext) => existsSync(path.join(root, rel + ext)));
|
|
101
|
+
const plansSource = existsSync(path.join(root, "lib/plans.ts"))
|
|
102
|
+
? readFileSync(path.join(root, "lib/plans.ts"), "utf8")
|
|
103
|
+
: null;
|
|
104
|
+
for (const [name, item] of Object.entries(requires.items)) {
|
|
105
|
+
if (!existsSync(path.join(root, item.marker)))
|
|
106
|
+
continue;
|
|
107
|
+
const problems = [];
|
|
108
|
+
for (const dep of item.items ?? []) {
|
|
109
|
+
const marker = requires.items[dep]?.marker;
|
|
110
|
+
if (marker && !existsSync(path.join(root, marker))) {
|
|
111
|
+
problems.push(`install the ${dep} item first`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const file of item.files ?? []) {
|
|
115
|
+
if (!exists(file))
|
|
116
|
+
problems.push(`create ${file} (scaffold-provided)`);
|
|
95
117
|
}
|
|
118
|
+
for (const [file, names] of Object.entries(item.exports ?? {})) {
|
|
119
|
+
const abs = [".ts", ".tsx"]
|
|
120
|
+
.map((ext) => path.join(root, file + ext))
|
|
121
|
+
.find((p) => existsSync(p));
|
|
122
|
+
if (!abs)
|
|
123
|
+
continue; // reported above as a missing file
|
|
124
|
+
const source = readFileSync(abs, "utf8");
|
|
125
|
+
const missing = names.filter((n) => !new RegExp(`export\\s+(?:const|function|let|var)\\s+${n}\\b`).test(source) && !new RegExp(`export\\s*\\{[^}]*\\b${n}\\b`).test(source));
|
|
126
|
+
if (missing.length) {
|
|
127
|
+
problems.push(`${file} must export ${missing.join(", ")}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (const feature of item.features ?? []) {
|
|
131
|
+
if (plansSource !== null &&
|
|
132
|
+
!new RegExp(`\\b${feature}\\b\\s*:`).test(plansSource)) {
|
|
133
|
+
problems.push(`register the "${feature}" feature key in lib/plans.ts — an unregistered key is denied (403)`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
results.push(problems.length === 0
|
|
137
|
+
? { name: `item:${name}`, status: "ok", detail: "requirements met" }
|
|
138
|
+
: {
|
|
139
|
+
name: `item:${name}`,
|
|
140
|
+
status: "error",
|
|
141
|
+
detail: problems.join("; "),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// 4b. Maintenance route. It refuses to serve without a strong
|
|
146
|
+
// CRON_SECRET, and a scheduler hitting a 403 every five minutes
|
|
147
|
+
// is easy to miss.
|
|
148
|
+
if (existsSync(path.join(root, "app/api/cron/maintenance/route.ts"))) {
|
|
149
|
+
const cronSecret = env.CRON_SECRET ?? "";
|
|
150
|
+
results.push(cronSecret.length >= 32
|
|
151
|
+
? { name: "maintenance", status: "ok", detail: "CRON_SECRET set" }
|
|
96
152
|
: {
|
|
97
|
-
name: "
|
|
153
|
+
name: "maintenance",
|
|
98
154
|
status: "error",
|
|
99
|
-
detail:
|
|
100
|
-
|
|
101
|
-
"
|
|
155
|
+
detail: "app/api/cron/maintenance/route.ts exists but CRON_SECRET is " +
|
|
156
|
+
(cronSecret ? "shorter than 32 chars" : "unset") +
|
|
157
|
+
" — the route answers 403 until it is",
|
|
102
158
|
});
|
|
103
159
|
}
|
|
104
160
|
// 5. Generated source. A conflict — template and consumer both
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `intelligo migrate` — apply the framework's migration chain.
|
|
3
|
+
*
|
|
4
|
+
* A consumer application has two migration chains in one database:
|
|
5
|
+
* the framework's, shipped inside `@intelligo-dev/core` (its `.sql`
|
|
6
|
+
* files and journal are in the package's `files`), and its own, which
|
|
7
|
+
* drizzle-kit generates from the tables the application owns. They
|
|
8
|
+
* must not share a journal — drizzle-kit applies by timestamp, so a
|
|
9
|
+
* framework migration published after the consumer generated one of
|
|
10
|
+
* theirs would be silently skipped — and a consumer cannot write into
|
|
11
|
+
* `node_modules` anyway. So the framework chain is applied by this
|
|
12
|
+
* command, into drizzle's default `drizzle.__drizzle_migrations`
|
|
13
|
+
* table, and the consumer's chain by `drizzle-kit migrate` from their
|
|
14
|
+
* own `drizzle.config.ts`, into a table of its own (the scaffold sets
|
|
15
|
+
* `migrations.table` to `__app_migrations`).
|
|
16
|
+
*
|
|
17
|
+
* Migrations are selected by content hash (what `migrate --check`
|
|
18
|
+
* compares), not by drizzle's journal-timestamp rule, and are recorded
|
|
19
|
+
* in the same table drizzle's migrator writes — see
|
|
20
|
+
* `readPendingMigrations` for why.
|
|
21
|
+
*
|
|
22
|
+
* The one thing this refuses to do is guess. A database with the
|
|
23
|
+
* framework's tables but no migration records was provisioned with
|
|
24
|
+
* `db:push`; applying the whole chain to it would fail part-way (not
|
|
25
|
+
* every migration is `IF NOT EXISTS`-guarded) and leave the records
|
|
26
|
+
* half-written. Baselining is the fix, and it is deliberately a manual
|
|
27
|
+
* step — see `packages/core/src/db/migrations/README.md`.
|
|
28
|
+
*/
|
|
29
|
+
import { type MigrateCheckResult } from "./migrate-check.js";
|
|
30
|
+
export type ApplyDecision = {
|
|
31
|
+
action: "apply";
|
|
32
|
+
pending: string[];
|
|
33
|
+
} | {
|
|
34
|
+
action: "noop";
|
|
35
|
+
} | {
|
|
36
|
+
action: "refuse";
|
|
37
|
+
reason: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* What to do with a database, given the check result and whether the
|
|
41
|
+
* framework's schema already exists in it. Pure, so the three states
|
|
42
|
+
* that matter — empty, push-provisioned, behind — are unit-testable
|
|
43
|
+
* without a database.
|
|
44
|
+
*/
|
|
45
|
+
export declare function decideApply(check: MigrateCheckResult, schemaExists: boolean): ApplyDecision;
|
|
46
|
+
type QueryFn = (sql: string) => Promise<Array<Record<string, unknown>>>;
|
|
47
|
+
/**
|
|
48
|
+
* One migration ready to run: its statements and the journal entry it
|
|
49
|
+
* will be recorded under. `createdAt` is the journal's `when`, which is
|
|
50
|
+
* what drizzle-kit writes to `created_at` too, so records made here and
|
|
51
|
+
* records made by drizzle's own migrator are indistinguishable.
|
|
52
|
+
*/
|
|
53
|
+
export type PendingMigration = {
|
|
54
|
+
tag: string;
|
|
55
|
+
hash: string;
|
|
56
|
+
createdAt: number;
|
|
57
|
+
statements: string[];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Read the pending migrations off disk, in journal order.
|
|
61
|
+
*
|
|
62
|
+
* The chain is applied by content hash — the same key `migrate --check`
|
|
63
|
+
* compares — and not by drizzle's rule of "every entry whose journal
|
|
64
|
+
* timestamp is greater than the last applied row's". That rule depends
|
|
65
|
+
* on `when` values increasing monotonically, and this repository's do
|
|
66
|
+
* not (entries 12–41 were hand-numbered below entry 11), so drizzle's
|
|
67
|
+
* migrator silently skipped any later hand-numbered entry on a database
|
|
68
|
+
* that had already been migrated while this command reported it applied.
|
|
69
|
+
* Selecting by hash makes "pending" mean exactly what the check says.
|
|
70
|
+
*/
|
|
71
|
+
export declare function readPendingMigrations(migrationsDir: string, pendingTags: string[]): PendingMigration[];
|
|
72
|
+
/** The records table drizzle's migrator uses, created the way it creates it. */
|
|
73
|
+
export declare const MIGRATIONS_TABLE_SQL: string[];
|
|
74
|
+
export type ApplyMigrationsOptions = {
|
|
75
|
+
migrationsDir: string;
|
|
76
|
+
/** Runs a read-only query and returns its rows. */
|
|
77
|
+
query: QueryFn;
|
|
78
|
+
/**
|
|
79
|
+
* Applies the given migrations in order, all in one transaction,
|
|
80
|
+
* recording each in `drizzle.__drizzle_migrations` as it goes.
|
|
81
|
+
*/
|
|
82
|
+
run: (pending: PendingMigration[]) => Promise<void>;
|
|
83
|
+
};
|
|
84
|
+
export type ApplyMigrationsResult = ApplyDecision & {
|
|
85
|
+
/** After the run, for the summary line and for `noop` detection. */
|
|
86
|
+
chainLength: number;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* `users` is the first table the framework creates (auth), so its
|
|
90
|
+
* presence with no migration records is the push-provisioned signature.
|
|
91
|
+
*/
|
|
92
|
+
export declare const SCHEMA_PROBE_SQL = "SELECT to_regclass('public.users') AS rel";
|
|
93
|
+
export declare function applyMigrations(options: ApplyMigrationsOptions): Promise<ApplyMigrationsResult>;
|
|
94
|
+
export declare function formatApplyResult(r: ApplyMigrationsResult): string;
|
|
95
|
+
export declare function applyExitCode(r: ApplyMigrationsResult): number;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAKH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,kBAAkB,EACzB,YAAY,EAAE,OAAO,GACpB,aAAa,CAyBf;AAED,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAExE;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EAAE,GACpB,gBAAgB,EAAE,CAqBpB;AAED,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,UAGhC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,GAAG,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,8CAA8C,CAAC;AAE5E,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAiBhC;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAYlE;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAE9D"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `intelligo migrate` — apply the framework's migration chain.
|
|
3
|
+
*
|
|
4
|
+
* A consumer application has two migration chains in one database:
|
|
5
|
+
* the framework's, shipped inside `@intelligo-dev/core` (its `.sql`
|
|
6
|
+
* files and journal are in the package's `files`), and its own, which
|
|
7
|
+
* drizzle-kit generates from the tables the application owns. They
|
|
8
|
+
* must not share a journal — drizzle-kit applies by timestamp, so a
|
|
9
|
+
* framework migration published after the consumer generated one of
|
|
10
|
+
* theirs would be silently skipped — and a consumer cannot write into
|
|
11
|
+
* `node_modules` anyway. So the framework chain is applied by this
|
|
12
|
+
* command, into drizzle's default `drizzle.__drizzle_migrations`
|
|
13
|
+
* table, and the consumer's chain by `drizzle-kit migrate` from their
|
|
14
|
+
* own `drizzle.config.ts`, into a table of its own (the scaffold sets
|
|
15
|
+
* `migrations.table` to `__app_migrations`).
|
|
16
|
+
*
|
|
17
|
+
* Migrations are selected by content hash (what `migrate --check`
|
|
18
|
+
* compares), not by drizzle's journal-timestamp rule, and are recorded
|
|
19
|
+
* in the same table drizzle's migrator writes — see
|
|
20
|
+
* `readPendingMigrations` for why.
|
|
21
|
+
*
|
|
22
|
+
* The one thing this refuses to do is guess. A database with the
|
|
23
|
+
* framework's tables but no migration records was provisioned with
|
|
24
|
+
* `db:push`; applying the whole chain to it would fail part-way (not
|
|
25
|
+
* every migration is `IF NOT EXISTS`-guarded) and leave the records
|
|
26
|
+
* half-written. Baselining is the fix, and it is deliberately a manual
|
|
27
|
+
* step — see `packages/core/src/db/migrations/README.md`.
|
|
28
|
+
*/
|
|
29
|
+
import { readFileSync } from "node:fs";
|
|
30
|
+
import path from "node:path";
|
|
31
|
+
import { hashMigration, migrateCheck, } from "./migrate-check.js";
|
|
32
|
+
/**
|
|
33
|
+
* What to do with a database, given the check result and whether the
|
|
34
|
+
* framework's schema already exists in it. Pure, so the three states
|
|
35
|
+
* that matter — empty, push-provisioned, behind — are unit-testable
|
|
36
|
+
* without a database.
|
|
37
|
+
*/
|
|
38
|
+
export function decideApply(check, schemaExists) {
|
|
39
|
+
if (check.unknown.length > 0) {
|
|
40
|
+
return {
|
|
41
|
+
action: "refuse",
|
|
42
|
+
reason: `Database is ahead: ${check.unknown.length} applied migration(s) are ` +
|
|
43
|
+
`not in this checkout (${check.unknown.join(", ")}). Upgrade ` +
|
|
44
|
+
`@intelligo-dev/core before migrating, or restore the database.`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (check.unmanaged && schemaExists) {
|
|
48
|
+
return {
|
|
49
|
+
action: "refuse",
|
|
50
|
+
reason: `This database has the framework's tables but no migration records — ` +
|
|
51
|
+
`it was provisioned with db:push. Baseline it before running migrate, ` +
|
|
52
|
+
`otherwise all ${check.chain.length} migrations would be applied to ` +
|
|
53
|
+
`tables that already exist. See packages/core/src/db/migrations/README.md`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (check.pending.length === 0)
|
|
57
|
+
return { action: "noop" };
|
|
58
|
+
return { action: "apply", pending: check.pending };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read the pending migrations off disk, in journal order.
|
|
62
|
+
*
|
|
63
|
+
* The chain is applied by content hash — the same key `migrate --check`
|
|
64
|
+
* compares — and not by drizzle's rule of "every entry whose journal
|
|
65
|
+
* timestamp is greater than the last applied row's". That rule depends
|
|
66
|
+
* on `when` values increasing monotonically, and this repository's do
|
|
67
|
+
* not (entries 12–41 were hand-numbered below entry 11), so drizzle's
|
|
68
|
+
* migrator silently skipped any later hand-numbered entry on a database
|
|
69
|
+
* that had already been migrated while this command reported it applied.
|
|
70
|
+
* Selecting by hash makes "pending" mean exactly what the check says.
|
|
71
|
+
*/
|
|
72
|
+
export function readPendingMigrations(migrationsDir, pendingTags) {
|
|
73
|
+
const journal = JSON.parse(readFileSync(path.join(migrationsDir, "meta", "_journal.json"), "utf8"));
|
|
74
|
+
const byTag = new Map((journal.entries ?? []).map((e) => [e.tag, e]));
|
|
75
|
+
return pendingTags.map((tag) => {
|
|
76
|
+
const entry = byTag.get(tag);
|
|
77
|
+
if (!entry)
|
|
78
|
+
throw new Error(`${tag} is pending but not in the journal`);
|
|
79
|
+
const sql = readFileSync(path.join(migrationsDir, `${tag}.sql`), "utf8");
|
|
80
|
+
const statements = (entry.breakpoints === false
|
|
81
|
+
? [sql]
|
|
82
|
+
: sql.split("--> statement-breakpoint"))
|
|
83
|
+
.map((s) => s.trim())
|
|
84
|
+
.filter((s) => s.length > 0);
|
|
85
|
+
return { tag, hash: hashMigration(sql), createdAt: entry.when, statements };
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** The records table drizzle's migrator uses, created the way it creates it. */
|
|
89
|
+
export const MIGRATIONS_TABLE_SQL = [
|
|
90
|
+
`CREATE SCHEMA IF NOT EXISTS "drizzle"`,
|
|
91
|
+
`CREATE TABLE IF NOT EXISTS "drizzle"."__drizzle_migrations" (id SERIAL PRIMARY KEY, hash text NOT NULL, created_at bigint)`,
|
|
92
|
+
];
|
|
93
|
+
/**
|
|
94
|
+
* `users` is the first table the framework creates (auth), so its
|
|
95
|
+
* presence with no migration records is the push-provisioned signature.
|
|
96
|
+
*/
|
|
97
|
+
export const SCHEMA_PROBE_SQL = `SELECT to_regclass('public.users') AS rel`;
|
|
98
|
+
export async function applyMigrations(options) {
|
|
99
|
+
const check = await migrateCheck(options.migrationsDir, async (sql) => (await options.query(sql)));
|
|
100
|
+
const probe = await options.query(SCHEMA_PROBE_SQL);
|
|
101
|
+
const schemaExists = probe.length > 0 && probe[0].rel != null;
|
|
102
|
+
const decision = decideApply(check, schemaExists);
|
|
103
|
+
if (decision.action === "apply") {
|
|
104
|
+
await options.run(readPendingMigrations(options.migrationsDir, decision.pending));
|
|
105
|
+
}
|
|
106
|
+
return { ...decision, chainLength: check.chain.length };
|
|
107
|
+
}
|
|
108
|
+
export function formatApplyResult(r) {
|
|
109
|
+
switch (r.action) {
|
|
110
|
+
case "refuse":
|
|
111
|
+
return `✗ ${r.reason}`;
|
|
112
|
+
case "noop":
|
|
113
|
+
return `✓ Nothing to apply (${r.chainLength}/${r.chainLength} applied)`;
|
|
114
|
+
case "apply":
|
|
115
|
+
return [
|
|
116
|
+
`✓ Applied ${r.pending.length} migration(s):`,
|
|
117
|
+
...r.pending.map((tag) => ` ${tag}`),
|
|
118
|
+
].join("\n");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export function applyExitCode(r) {
|
|
122
|
+
return r.action === "refuse" ? 1 : 0;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade-check.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"upgrade-check.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa,CA8DxE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CA0B5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAE7D"}
|