@montytools/cli 0.2.4 → 0.2.5
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/bin/monty.mjs +39 -2
- package/package.json +1 -1
package/bin/monty.mjs
CHANGED
|
@@ -489,6 +489,27 @@ async function dev() {
|
|
|
489
489
|
let ended = false;
|
|
490
490
|
const buildFile = join(appDir, ".monty", "build");
|
|
491
491
|
const buildId = existsSync(buildFile) ? readFileSync(buildFile, "utf8").trim() : undefined;
|
|
492
|
+
// The DEV schema channel: heartbeats carry the compiled schema, and edits
|
|
493
|
+
// to monty.config.ts are re-compiled (softly) so schema changes reach the
|
|
494
|
+
// platform within one heartbeat. Publish owns the PROD schema.
|
|
495
|
+
let currentMeta = meta;
|
|
496
|
+
const configPath = join(appDir, "monty.config.ts");
|
|
497
|
+
let configMtime = statSync(configPath).mtimeMs;
|
|
498
|
+
|
|
499
|
+
async function refreshSchemaIfChanged() {
|
|
500
|
+
try {
|
|
501
|
+
const m = statSync(configPath).mtimeMs;
|
|
502
|
+
if (m === configMtime) return;
|
|
503
|
+
configMtime = m;
|
|
504
|
+
const fresh = await compileConfig(appDir, { soft: true });
|
|
505
|
+
if (fresh) {
|
|
506
|
+
currentMeta = fresh;
|
|
507
|
+
console.log(
|
|
508
|
+
`schema: monty.config.ts changed — dev schema updated (${Object.keys(fresh.schemaJson.tables).length} tables)`,
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
} catch { /* transient fs hiccup — next beat retries */ }
|
|
512
|
+
}
|
|
492
513
|
|
|
493
514
|
async function endSession() {
|
|
494
515
|
if (ended) return;
|
|
@@ -508,11 +529,19 @@ async function dev() {
|
|
|
508
529
|
}
|
|
509
530
|
|
|
510
531
|
async function heartbeat(originUrl) {
|
|
532
|
+
await refreshSchemaIfChanged();
|
|
511
533
|
try {
|
|
512
534
|
const r = await fetch(`${host}/api/dev-session`, {
|
|
513
535
|
method: "POST",
|
|
514
536
|
headers: { authorization: `Bearer ${cfg.key}`, "content-type": "application/json" },
|
|
515
|
-
body: JSON.stringify({
|
|
537
|
+
body: JSON.stringify({
|
|
538
|
+
slug: meta.slug,
|
|
539
|
+
tunnelUrl: originUrl,
|
|
540
|
+
name: currentMeta.name,
|
|
541
|
+
icon: currentMeta.icon,
|
|
542
|
+
buildId,
|
|
543
|
+
schemaJson: currentMeta.schemaJson,
|
|
544
|
+
}),
|
|
516
545
|
});
|
|
517
546
|
const data = await r.json().catch(() => null);
|
|
518
547
|
if (!r.ok) {
|
|
@@ -819,7 +848,7 @@ async function deploy() {
|
|
|
819
848
|
console.log(`deployed: ${body.url} (version ${body.version})`);
|
|
820
849
|
}
|
|
821
850
|
|
|
822
|
-
async function compileConfig(appDir) {
|
|
851
|
+
async function compileConfig(appDir, { soft = false } = {}) {
|
|
823
852
|
const { build } = await import("esbuild");
|
|
824
853
|
const tmpDir = join(appDir, ".monty");
|
|
825
854
|
mkdirSync(tmpDir, { recursive: true });
|
|
@@ -843,11 +872,19 @@ async function compileConfig(appDir) {
|
|
|
843
872
|
});
|
|
844
873
|
const result = spawnSync(process.execPath, [out], { encoding: "utf8" });
|
|
845
874
|
if (result.status !== 0) {
|
|
875
|
+
if (soft) {
|
|
876
|
+
console.log("schema: monty.config.ts doesn't compile right now — keeping the last good schema");
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
846
879
|
fail("CONFIG_COMPILE_FAILED", `monty.config.ts threw while loading:\n${result.stderr}\nFix the config (it must only call defineApp with zod tables).`);
|
|
847
880
|
}
|
|
848
881
|
return JSON.parse(result.stdout);
|
|
849
882
|
} catch (e) {
|
|
850
883
|
if (e?.errors) {
|
|
884
|
+
if (soft) {
|
|
885
|
+
console.log("schema: monty.config.ts doesn't compile right now — keeping the last good schema");
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
851
888
|
fail("CONFIG_COMPILE_FAILED", `esbuild could not bundle monty.config.ts: ${e.errors[0]?.text ?? e.message}`);
|
|
852
889
|
}
|
|
853
890
|
throw e;
|