@stacksjs/buddy 0.72.75 → 0.72.76

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.
@@ -73,11 +73,11 @@ ${unrebuildable.map((t)=>` ${t}`).join(`
73
73
  \u2022 ${removed.length} existing file(s) will be removed${protectedHistoryBlock}${outOfScopeBlock}${unrebuildableBlock}
74
74
  \u2022 These files are tracked in git, so review with \`git diff\` afterwards
75
75
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
76
- `);if(options.dryRun){await outro("Dry run. Nothing was written.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}if(!isCI&&hasTTY&&process.stdin.isTTY){await log.flush();if(!await confirm({message:`Replace ${removed.length} migration file(s) with ${files.length} generated for ${target}?`,initial:!1})){await outro("Cancelled. Nothing was written.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}}const result=await regenerateMigrationCorpus({dialect:target,replaceUnmarked:options.replaceUnmarked});if(resultFailed(result)){log.syncError(result.error.message);process.exit(ExitCode.FatalError)}log.success(`Wrote ${result.value.files.length} ${target} migration file(s) to database/migrations.`);if(applied>0){const{reconcileMigrationLedger}=await import("@stacksjs/database"),fixed=await reconcileMigrationLedger();if(fixed.remapped.length>0)log.info(`Repointed ${fixed.remapped.length} ledger row(s) at their renumbered file.`);if(fixed.recorded.length>0)log.info(`Recorded ${fixed.recorded.length} migration(s) already present in the schema.`);if(fixed.pruned.length)log.info(`Pruned ${fixed.pruned.length} duplicate ledger row(s).`);if(fixed.skipped.length>0)log.warn(`${fixed.skipped.length} ledger entr(ies) need a look - run \`./buddy migrate:status\`.`)}log.info("Review the change with `git diff`, then run `./buddy migrate`.");await outro("Regenerated.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("migrate:status","Compare database/migrations, the migrations ledger, and the live schema").option("--reconcile","Repair the ledger where the schema proves what happened",{default:!1}).option("--include-partial","With --reconcile, also record half-applied migrations",{default:!1}).option("--json","Emit the audit as JSON",{default:!1}).action(async(options)=>{const perf=options.json?void 0:await intro("buddy migrate:status"),{auditMigrationLedger,reconcileMigrationLedger}=await import("@stacksjs/database"),audit=await auditMigrationLedger();if(options.json){console.log(JSON.stringify(audit,(_k,v)=>v instanceof Set?[...v]:v,2));process.exit(audit.drift?ExitCode.FatalError:ExitCode.Success)}if(!audit.supported){log.info(`Dialect "${audit.dialect}" is not audited. Nothing to compare.`);await outro("Skipped.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}const{counts,entries,orphans}=audit,list=(status)=>entries.filter((e)=>e.status===status).map((e)=>e.file),report=[],section=(heading,files)=>{if(files.length===0)return;if(heading)report.push(` ${heading}`);for(const file of files.slice(0,8))report.push(` ${file}`);if(files.length>8)report.push(` \u2026 +${files.length-8} more`);report.push("")};report.push("");report.push(` Migration status: ${audit.dialect}`);report.push(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");report.push(` ${entries.length} file(s) on disk \xB7 ${audit.recordedCount} recorded in the ledger`);report.push("");if(counts.applied>0)report.push(` ${counts.applied} applied - recorded, and present in the schema.`,"");if(counts.unverifiable>0)report.push(` ${counts.unverifiable} unverifiable - data migrations with no schema trace to check.`,"");section(`${counts.pending} pending - not applied yet, will run on the next \`buddy migrate\`:`,list("pending"));if(counts.stranded>0){report.push(` ${counts.stranded} STRANDED - already applied to the schema, but missing from the ledger.`);report.push(" These re-run on the next `buddy migrate`, which is unsafe for anything not idempotent.");section("",list("stranded"))}section(`${counts.partial} PARTIAL - some effects present, some missing. Needs a human:`,list("partial"));section(`${counts.reverted} REVERTED - recorded as applied, but the effects are gone from the schema:`,list("reverted"));if(orphans.length>0)section(`${orphans.length} orphaned ledger row(s) - recorded, but no such file on disk:`,orphans.map((o)=>{if(o.renamedTo)return`${o.migration} -> renumbered to ${o.renamedTo}`;if(audit.remapPlan.superseded.includes(o.migration))return`${o.migration} (duplicate; already recorded under its current name)`;return`${o.migration} (no counterpart; migration deleted?)`}));console.log(report.join(`
76
+ `);if(options.dryRun){await outro("Dry run. Nothing was written.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}if(!isCI&&hasTTY&&process.stdin.isTTY){await log.flush();if(!await confirm({message:`Replace ${removed.length} migration file(s) with ${files.length} generated for ${target}?`,initial:!1})){await outro("Cancelled. Nothing was written.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}}const result=await regenerateMigrationCorpus({dialect:target,replaceUnmarked:options.replaceUnmarked});if(resultFailed(result)){log.syncError(result.error.message);process.exit(ExitCode.FatalError)}log.success(`Wrote ${result.value.files.length} ${target} migration file(s) to database/migrations.`);if(applied>0){const{reconcileMigrationLedger}=await import("@stacksjs/database"),fixed=await reconcileMigrationLedger();if(fixed.remapped.length>0)log.info(`Repointed ${fixed.remapped.length} ledger row(s) at their renumbered file.`);if(fixed.recorded.length>0)log.info(`Recorded ${fixed.recorded.length} migration(s) already present in the schema.`);if(fixed.pruned.length>0)log.info(`Pruned ${fixed.pruned.length} duplicate ledger row(s).`);if(fixed.skipped.length>0)log.warn(`${fixed.skipped.length} ledger entr(ies) need a look - run \`./buddy migrate:status\`.`)}log.info("Review the change with `git diff`, then run `./buddy migrate`.");await outro("Regenerated.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("migrate:status","Compare database/migrations, the migrations ledger, and the live schema").option("--reconcile","Repair the ledger where the schema proves what happened",{default:!1}).option("--include-partial","With --reconcile, also record half-applied migrations",{default:!1}).option("--json","Emit the audit as JSON",{default:!1}).action(async(options)=>{const perf=options.json?void 0:await intro("buddy migrate:status"),{auditMigrationLedger,reconcileMigrationLedger}=await import("@stacksjs/database"),audit=await auditMigrationLedger();if(options.json){console.log(JSON.stringify(audit,(_k,v)=>v instanceof Set?[...v]:v,2));process.exit(audit.drift?ExitCode.FatalError:ExitCode.Success)}if(!audit.supported){log.info(`Dialect "${audit.dialect}" is not audited. Nothing to compare.`);await outro("Skipped.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}const{counts,entries,orphans}=audit,list=(status)=>entries.filter((e)=>e.status===status).map((e)=>e.file),report=[],section=(heading,files)=>{if(files.length===0)return;if(heading)report.push(` ${heading}`);for(const file of files.slice(0,8))report.push(` ${file}`);if(files.length>8)report.push(` \u2026 +${files.length-8} more`);report.push("")};report.push("");report.push(` Migration status: ${audit.dialect}`);report.push(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");report.push(` ${entries.length} file(s) on disk \xB7 ${audit.recordedCount} recorded in the ledger`);report.push("");if(counts.applied>0)report.push(` ${counts.applied} applied - recorded, and present in the schema.`,"");if(counts.unverifiable>0)report.push(` ${counts.unverifiable} unverifiable - data migrations with no schema trace to check.`,"");section(`${counts.pending} pending - not applied yet, will run on the next \`buddy migrate\`:`,list("pending"));if(counts.stranded>0){report.push(` ${counts.stranded} STRANDED - already applied to the schema, but missing from the ledger.`);report.push(" These re-run on the next `buddy migrate`, which is unsafe for anything not idempotent.");section("",list("stranded"))}section(`${counts.partial} PARTIAL - some effects present, some missing. Needs a human:`,list("partial"));section(`${counts.reverted} REVERTED - recorded as applied, but the effects are gone from the schema:`,list("reverted"));if(orphans.length>0)section(`${orphans.length} orphaned ledger row(s) - recorded, but no such file on disk:`,orphans.map((o)=>{if(o.renamedTo)return`${o.migration} -> renumbered to ${o.renamedTo}`;if(audit.remapPlan.superseded.includes(o.migration))return`${o.migration} (duplicate; already recorded under its current name)`;return`${o.migration} (no counterpart; migration deleted?)`}));console.log(report.join(`
77
77
  `));if(!audit.drift){await outro("Ledger matches the corpus and the schema.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)}if(!options.reconcile){console.log(`
78
78
  Repair with: ./buddy migrate:status --reconcile
79
79
  That repoints renumbered ledger rows and records migrations the schema
80
80
  already proves. It never runs SQL from a migration file.
81
81
  `);await outro("Drift detected.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}const fixed=await reconcileMigrationLedger({includePartial:options.includePartial});if(fixed.remapped.length>0)log.success(`Repointed ${fixed.remapped.length} ledger row(s) at their renumbered file.`);if(fixed.recorded.length>0)log.success(`Recorded ${fixed.recorded.length} migration(s) the schema already reflects.`);if(fixed.pruned.length)log.success(`Pruned ${fixed.pruned.length} duplicate ledger row(s) left by a renumbering.`);if(fixed.skipped.length>0){log.warn(`Left ${fixed.skipped.length} entr(ies) alone:`);console.log(fixed.skipped.slice(0,8).map((s)=>` ${s.file} - ${s.reason}`).join(`
82
82
  `)+(fixed.skipped.length>8?`
83
- \u2026 +${fixed.skipped.length-8} more`:""))}if(fixed.remapped.length===0&&fixed.recorded.length===0)log.info("Nothing could be repaired automatically.");await outro("Reconciled.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"migrate")}
83
+ \u2026 +${fixed.skipped.length-8} more`:""))}if(fixed.remapped.length===0&&fixed.recorded.length===0&&fixed.pruned.length===0)log.info("Nothing could be repaired automatically.");await outro("Reconciled.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"migrate")}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/buddy",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.72.75",
5
+ "version": "0.72.76",
6
6
  "description": "Meet Buddy. The Stacks runtime.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -95,62 +95,62 @@
95
95
  "prepublishOnly": "bun run build"
96
96
  },
97
97
  "dependencies": {
98
- "@stacksjs/actions": "^0.72.75",
99
- "@stacksjs/ai": "^0.72.75",
100
- "@stacksjs/alias": "^0.72.75",
101
- "@stacksjs/analytics": "^0.72.75",
102
- "@stacksjs/arrays": "^0.72.75",
103
- "@stacksjs/auth": "^0.72.75",
104
- "@stacksjs/browser-extension": "^0.72.75",
105
- "@stacksjs/build": "^0.72.75",
106
- "@stacksjs/cache": "^0.72.75",
107
- "@stacksjs/chat": "^0.72.75",
98
+ "@stacksjs/actions": "^0.72.76",
99
+ "@stacksjs/ai": "^0.72.76",
100
+ "@stacksjs/alias": "^0.72.76",
101
+ "@stacksjs/analytics": "^0.72.76",
102
+ "@stacksjs/arrays": "^0.72.76",
103
+ "@stacksjs/auth": "^0.72.76",
104
+ "@stacksjs/browser-extension": "^0.72.76",
105
+ "@stacksjs/build": "^0.72.76",
106
+ "@stacksjs/cache": "^0.72.76",
107
+ "@stacksjs/chat": "^0.72.76",
108
108
  "@stacksjs/clapp": "^0.2.12",
109
- "@stacksjs/cli": "^0.72.75",
110
- "@stacksjs/cloud": "^0.72.75",
111
- "@stacksjs/cms": "^0.72.75",
112
- "@stacksjs/collections": "^0.72.75",
113
- "@stacksjs/config": "^0.72.75",
114
- "@stacksjs/database": "^0.72.75",
115
- "@stacksjs/desktop-build": "^0.72.75",
116
- "@stacksjs/dns": "^0.72.75",
109
+ "@stacksjs/cli": "^0.72.76",
110
+ "@stacksjs/cloud": "^0.72.76",
111
+ "@stacksjs/cms": "^0.72.76",
112
+ "@stacksjs/collections": "^0.72.76",
113
+ "@stacksjs/config": "^0.72.76",
114
+ "@stacksjs/database": "^0.72.76",
115
+ "@stacksjs/desktop-build": "^0.72.76",
116
+ "@stacksjs/dns": "^0.72.76",
117
117
  "@stacksjs/dnsx": "^0.2.3",
118
- "@stacksjs/email": "^0.72.75",
119
- "@stacksjs/enums": "^0.72.75",
120
- "@stacksjs/env": "^0.72.75",
121
- "@stacksjs/error-handling": "^0.72.75",
122
- "@stacksjs/events": "^0.72.75",
123
- "@stacksjs/git": "^0.72.75",
118
+ "@stacksjs/email": "^0.72.76",
119
+ "@stacksjs/enums": "^0.72.76",
120
+ "@stacksjs/env": "^0.72.76",
121
+ "@stacksjs/error-handling": "^0.72.76",
122
+ "@stacksjs/events": "^0.72.76",
123
+ "@stacksjs/git": "^0.72.76",
124
124
  "@stacksjs/gitit": "^0.2.5",
125
- "@stacksjs/health": "^0.72.75",
125
+ "@stacksjs/health": "^0.72.76",
126
126
  "@stacksjs/httx": "^0.1.10",
127
- "@stacksjs/image": "^0.72.75",
128
- "@stacksjs/lint": "^0.72.75",
129
- "@stacksjs/logging": "^0.72.75",
130
- "@stacksjs/notifications": "^0.72.75",
131
- "@stacksjs/objects": "^0.72.75",
132
- "@stacksjs/orm": "^0.72.75",
133
- "@stacksjs/path": "^0.72.75",
134
- "@stacksjs/payments": "^0.72.75",
135
- "@stacksjs/realtime": "^0.72.75",
136
- "@stacksjs/router": "^0.72.75",
127
+ "@stacksjs/image": "^0.72.76",
128
+ "@stacksjs/lint": "^0.72.76",
129
+ "@stacksjs/logging": "^0.72.76",
130
+ "@stacksjs/notifications": "^0.72.76",
131
+ "@stacksjs/objects": "^0.72.76",
132
+ "@stacksjs/orm": "^0.72.76",
133
+ "@stacksjs/path": "^0.72.76",
134
+ "@stacksjs/payments": "^0.72.76",
135
+ "@stacksjs/realtime": "^0.72.76",
136
+ "@stacksjs/router": "^0.72.76",
137
137
  "@stacksjs/rpx": "^0.11.42",
138
- "@stacksjs/scheduler": "^0.72.75",
139
- "@stacksjs/search-engine": "^0.72.75",
140
- "@stacksjs/security": "^0.72.75",
141
- "@stacksjs/server": "^0.72.75",
142
- "@stacksjs/sites": "^0.72.75",
143
- "@stacksjs/skills": "^0.72.75",
144
- "@stacksjs/storage": "^0.72.75",
145
- "@stacksjs/strings": "^0.72.75",
146
- "@stacksjs/testing": "^0.72.75",
147
- "@stacksjs/tinker": "^0.72.75",
138
+ "@stacksjs/scheduler": "^0.72.76",
139
+ "@stacksjs/search-engine": "^0.72.76",
140
+ "@stacksjs/security": "^0.72.76",
141
+ "@stacksjs/server": "^0.72.76",
142
+ "@stacksjs/sites": "^0.72.76",
143
+ "@stacksjs/skills": "^0.72.76",
144
+ "@stacksjs/storage": "^0.72.76",
145
+ "@stacksjs/strings": "^0.72.76",
146
+ "@stacksjs/testing": "^0.72.76",
147
+ "@stacksjs/tinker": "^0.72.76",
148
148
  "@stacksjs/ts-cloud": "^0.12.4",
149
- "@stacksjs/tunnel": "^0.72.75",
150
- "@stacksjs/types": "^0.72.75",
151
- "@stacksjs/ui": "^0.72.75",
152
- "@stacksjs/utils": "^0.72.75",
153
- "@stacksjs/validation": "^0.72.75",
149
+ "@stacksjs/tunnel": "^0.72.76",
150
+ "@stacksjs/types": "^0.72.76",
151
+ "@stacksjs/ui": "^0.72.76",
152
+ "@stacksjs/utils": "^0.72.76",
153
+ "@stacksjs/validation": "^0.72.76",
154
154
  "ajv": "^8.20.0",
155
155
  "ajv-formats": "^3.0.1",
156
156
  "ts-pantry": "^0.11.35"