@stacksjs/actions 0.75.144 → 0.75.146

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.
@@ -55,6 +55,23 @@ export declare function runPostSyncDependencyRefresh(options: PostSyncDependency
55
55
  * schema.
56
56
  */
57
57
  export declare function runPostSyncMigration(options: PostSyncMigrationOptions): Promise<void>;
58
+ /**
59
+ * Rewrite the app's `database/types.d.ts` against the models it now has.
60
+ *
61
+ * That file is generated from the app's models AND the framework's default
62
+ * ones, so it describes the framework version it was generated under. An
63
+ * upgrade that adds a column to a default model - `PersonalAccessToken`
64
+ * declaring `user_id` - left an app's committed copy one version behind, and a
65
+ * typed `insertInto('oauth_access_tokens').values({ user_id })` stopped
66
+ * compiling the moment the app upgraded, though nothing in the app changed.
67
+ *
68
+ * Only an app that already keeps the file gets it rewritten: one that never
69
+ * generated types has opted out, and an upgrade should not opt it in.
70
+ *
71
+ * Returns whether the file was regenerated. A nonzero exit throws; the caller
72
+ * treats that as non-fatal, since the next `buddy generate:db-types` repairs it.
73
+ */
74
+ export declare function runPostSyncDatabaseTypesRefresh(options: PostSyncDatabaseTypesOptions): Promise<boolean>;
58
75
  declare interface PostSyncSpawnOptions {
59
76
  cmd: string[]
60
77
  cwd: string
@@ -73,6 +90,12 @@ declare interface PostSyncDependencyOptions {
73
90
  projectRoot: string
74
91
  spawn: PostSyncSpawn
75
92
  }
93
+ declare interface PostSyncDatabaseTypesOptions {
94
+ cmd: string[]
95
+ projectRoot: string
96
+ spawn: PostSyncSpawn
97
+ exists: (path: string) => boolean
98
+ }
76
99
  declare type PostSyncSpawn = (options: PostSyncSpawnOptions) => { exited: Promise<number> }
77
100
  /**
78
101
  * Which installer owns the project's dependency graph.
@@ -1 +1 @@
1
- export function detectDependencyInstaller(hasPantryLock){return hasPantryLock?"pantry":"bun"}export function resolveDependencyRefreshCommand(options){return[options.installer==="pantry"?options.pantryExecutable:options.bunExecutable,"install","--force"]}export function resolvePantryExecutable(candidates,exists){for(const candidate of candidates)if(candidate&&exists(candidate))return candidate;return"pantry"}export function shouldRunPostSyncHooks(changeCount,alreadyRestarted){return changeCount>0||alreadyRestarted}export function shouldRefreshPostSyncDependencies(corePackageChanged,alreadyRestarted){return corePackageChanged||alreadyRestarted}export async function runPostSyncDependencyRefresh(options){const code=await options.spawn({cmd:options.cmd,cwd:options.projectRoot,stdin:"ignore",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`Post-upgrade dependency refresh exited with code ${code}.`)}export async function runPostSyncMigration(options){const code=await options.spawn({cmd:[options.bunExecutable,options.migrateScript,"migrate","--force"],cwd:options.projectRoot,stdin:"ignore",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`Post-upgrade migration exited with code ${code}.`)}
1
+ export function detectDependencyInstaller(hasPantryLock){return hasPantryLock?"pantry":"bun"}export function resolveDependencyRefreshCommand(options){return[options.installer==="pantry"?options.pantryExecutable:options.bunExecutable,"install","--force"]}export function resolvePantryExecutable(candidates,exists){for(const candidate of candidates)if(candidate&&exists(candidate))return candidate;return"pantry"}export function shouldRunPostSyncHooks(changeCount,alreadyRestarted){return changeCount>0||alreadyRestarted}export function shouldRefreshPostSyncDependencies(corePackageChanged,alreadyRestarted){return corePackageChanged||alreadyRestarted}export async function runPostSyncDependencyRefresh(options){const code=await options.spawn({cmd:options.cmd,cwd:options.projectRoot,stdin:"ignore",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`Post-upgrade dependency refresh exited with code ${code}.`)}export async function runPostSyncMigration(options){const code=await options.spawn({cmd:[options.bunExecutable,options.migrateScript,"migrate","--force"],cwd:options.projectRoot,stdin:"ignore",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`Post-upgrade migration exited with code ${code}.`)}export async function runPostSyncDatabaseTypesRefresh(options){if(!options.exists(`${options.projectRoot}/database/types.d.ts`))return!1;const code=await options.spawn({cmd:options.cmd,cwd:options.projectRoot,stdin:"ignore",stdout:"inherit",stderr:"inherit"}).exited;if(code!==0)throw Error(`\`buddy generate:db-types\` exited with code ${code}.`);return!0}
@@ -1,4 +1,4 @@
1
- import{chmodSync,copyFileSync,cpSync,existsSync,mkdirSync,mkdtempSync,readFileSync,rmSync,statSync,writeFileSync}from"node:fs";import{tmpdir}from"node:os";import{dirname,join}from"node:path";import process from"node:process";import{parseOptions}from"@stacksjs/cli";import{downloadTemplate}from"@stacksjs/gitit";import{path as p}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";import{buildTemplateString,detectLocalStacks,diffSnapshots,diffSnapshotsDetailed,MANAGED_PATHS,readChannel,readSyncedVersion,readVersion,resolveLatestStableTag,resolveSuccessMessage,resolveUpgradeContext,resolveUpgradeMessage,shouldAutoDetectLocalStacks,shouldCheckDirtyManagedPaths,shouldShortCircuit,snapshotTree,writeChannel,writeSyncedVersion}from"./framework-utils";import{detectDependencyInstaller,resolveDependencyRefreshCommand,resolvePantryExecutable,runPostSyncDependencyRefresh,runPostSyncMigration,shouldRefreshPostSyncDependencies,shouldRunPostSyncHooks}from"./framework-hooks";import{describeDanglingRouteActions,findDanglingRouteActions,pruneRetiredScaffoldRoutes}from"./route-actions";const options=parseOptions(),projectRoot=p.projectPath();if(!existsSync(p.projectPath("storage/framework/core"))){const{upgradeStacksPackages}=await import("./packages");await upgradeStacksPackages(projectRoot,{version:options.version,canary:options.canary,stable:options.stable,force:options.force,dryRun:options.dryRun,noPostinstall:options.noPostinstall??options.postinstall===!1})}const channelFile=join(projectRoot,".stacks-channel"),versionFile=join(projectRoot,".stacks-version"),currentChannel=readChannel(channelFile),corePkgPath=p.projectPath("storage/framework/core/buddy/package.json"),currentVersion=readVersion(corePkgPath),willResolveStable=!options.version&&!options.canary&&(!!options.stable||currentChannel!=="canary");let latestStableRef="";if(willResolveStable)latestStableRef=await resolveLatestStableTag()??(currentVersion?`v${currentVersion}`:"main");const ctx=resolveUpgradeContext(options,currentChannel,latestStableRef),explicitLocal=options.from?p.projectPath(options.from):null,detectedLocal=explicitLocal??(shouldAutoDetectLocalStacks(options)?detectLocalStacks(projectRoot):null),usingLocal=!!detectedLocal;console.log(resolveUpgradeMessage(ctx,currentChannel,!!options.stable));console.log(usingLocal?` source: local checkout at ${detectedLocal}`:` source: github:stacksjs/stacks#${ctx.ref}`);if(options.dryRun){await runDryRunPreview();process.exit(ExitCode.Success)}const alreadyRestarted=process.argv.includes("--__restarted");if(shouldCheckDirtyManagedPaths({force:!!options.force,alreadyRestarted})){const dirty=await detectDirtyManagedPaths(projectRoot);if(dirty.length>0){console.warn(`
1
+ import{chmodSync,copyFileSync,cpSync,existsSync,mkdirSync,mkdtempSync,readFileSync,rmSync,statSync,writeFileSync}from"node:fs";import{tmpdir}from"node:os";import{dirname,join}from"node:path";import process from"node:process";import{parseOptions}from"@stacksjs/cli";import{downloadTemplate}from"@stacksjs/gitit";import{path as p}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";import{buildTemplateString,detectLocalStacks,diffSnapshots,diffSnapshotsDetailed,MANAGED_PATHS,readChannel,readSyncedVersion,readVersion,resolveLatestStableTag,resolveSuccessMessage,resolveUpgradeContext,resolveUpgradeMessage,shouldAutoDetectLocalStacks,shouldCheckDirtyManagedPaths,shouldShortCircuit,snapshotTree,writeChannel,writeSyncedVersion}from"./framework-utils";import{detectDependencyInstaller,resolveDependencyRefreshCommand,resolvePantryExecutable,runPostSyncDatabaseTypesRefresh,runPostSyncDependencyRefresh,runPostSyncMigration,shouldRefreshPostSyncDependencies,shouldRunPostSyncHooks}from"./framework-hooks";import{describeDanglingRouteActions,findDanglingRouteActions,pruneRetiredScaffoldRoutes}from"./route-actions";const options=parseOptions(),projectRoot=p.projectPath();if(!existsSync(p.projectPath("storage/framework/core"))){const{upgradeStacksPackages}=await import("./packages");await upgradeStacksPackages(projectRoot,{version:options.version,canary:options.canary,stable:options.stable,force:options.force,dryRun:options.dryRun,noPostinstall:options.noPostinstall??options.postinstall===!1})}const channelFile=join(projectRoot,".stacks-channel"),versionFile=join(projectRoot,".stacks-version"),currentChannel=readChannel(channelFile),corePkgPath=p.projectPath("storage/framework/core/buddy/package.json"),currentVersion=readVersion(corePkgPath),willResolveStable=!options.version&&!options.canary&&(!!options.stable||currentChannel!=="canary");let latestStableRef="";if(willResolveStable)latestStableRef=await resolveLatestStableTag()??(currentVersion?`v${currentVersion}`:"main");const ctx=resolveUpgradeContext(options,currentChannel,latestStableRef),explicitLocal=options.from?p.projectPath(options.from):null,detectedLocal=explicitLocal??(shouldAutoDetectLocalStacks(options)?detectLocalStacks(projectRoot):null),usingLocal=!!detectedLocal;console.log(resolveUpgradeMessage(ctx,currentChannel,!!options.stable));console.log(usingLocal?` source: local checkout at ${detectedLocal}`:` source: github:stacksjs/stacks#${ctx.ref}`);if(options.dryRun){await runDryRunPreview();process.exit(ExitCode.Success)}const alreadyRestarted=process.argv.includes("--__restarted");if(shouldCheckDirtyManagedPaths({force:!!options.force,alreadyRestarted})){const dirty=await detectDirtyManagedPaths(projectRoot);if(dirty.length>0){console.warn(`
2
2
  \u26A0 The following framework-managed paths have uncommitted changes:`);for(const path of dirty)console.warn(` - ${path}`);console.warn(`
3
3
  Aborting to avoid clobbering your edits.`);console.warn(` Re-run with --force to overwrite, or commit / stash the changes first.
4
4
  `);process.exit(ExitCode.FatalError)}}let resolvedRemoteSha=null;if(!options.force&&!ctx.targetVersion){resolvedRemoteSha=await getRemoteSha(ctx,usingLocal,detectedLocal);const synced=readSyncedVersion(versionFile);if(shouldShortCircuit({force:!!options.force,targetVersion:ctx.targetVersion,remoteSha:resolvedRemoteSha,synced,channel:ctx.channel})){console.log(`\u2714 Already on the latest ${ctx.channel} (${resolvedRemoteSha.slice(0,7)}).`);process.exit(ExitCode.Success)}}const ownPath=p.frameworkPath("core/actions/src/upgrade/framework.ts"),ownHashBefore=await hashFileOrZero(ownPath),aggregate={added:0,changed:0,removed:0,unchanged:0},perPath=[];try{for(const managed of MANAGED_PATHS){const localTarget=join(projectRoot,managed.localPath),before=managed.isFile?await singleFileSnapshot(localTarget):await snapshotTree(localTarget,managed.skip);if(usingLocal&&detectedLocal)await syncFromLocal(detectedLocal,managed,localTarget);else{if(managed.isFile)continue;await syncFromGitHub(ctx.ref,managed,localTarget,!!options.force)}const after=managed.isFile?await singleFileSnapshot(localTarget):await snapshotTree(localTarget,managed.skip),summary=diffSnapshots(before,after);aggregate.added+=summary.added;aggregate.changed+=summary.changed;aggregate.removed+=summary.removed;aggregate.unchanged+=summary.unchanged;perPath.push({managed,summary})}if(!usingLocal)await syncRootFilesFromGitHub(ctx.ref)}catch(err){console.error("\u2718 Failed to upgrade Stacks framework:",err?.message||err);process.exit(ExitCode.FatalError)}const newVersion=readVersion(corePkgPath),ownHashAfter=await hashFileOrZero(ownPath);if(ownHashBefore!==0n&&ownHashAfter!==0n&&ownHashBefore!==ownHashAfter&&!alreadyRestarted){console.log(`Upgrade pulled a newer version of the upgrade action - re-running once to pick up new sync paths and hooks.
@@ -6,8 +6,8 @@ import{chmodSync,copyFileSync,cpSync,existsSync,mkdirSync,mkdtempSync,readFileSy
6
6
  `))console.warn(` ${line}`)}}const runHooks=!options.noPostinstall&&options.postinstall!==!1;if(runHooks)try{await runPostSyncHooks({aggregate,perPath,projectRoot,alreadyRestarted})}catch(err){console.error(`Post-sync hooks failed: ${err?.message||err}`);process.exit(ExitCode.FatalError)}if(ctx.channel==="canary"&&!ctx.targetVersion)console.warn("\u26A0 Canary builds may contain bugs or breaking changes. Not recommended for production.");process.exit(ExitCode.Success);async function runDryRunPreview(){console.log(`
7
7
  DRY RUN - preview only. No files will be written, nothing will be installed, no migrations will run.
8
8
  `);const dirty=await detectDirtyManagedPaths(projectRoot);if(dirty.length>0){console.warn(" Note: these framework-managed paths have uncommitted changes (a real run would abort without --force):");for(const path of dirty)console.warn(` - ${path}`);console.warn("")}let previewSha=null;if(!options.force&&!ctx.targetVersion){previewSha=await getRemoteSha(ctx,usingLocal,detectedLocal);const synced=readSyncedVersion(versionFile);if(shouldShortCircuit({force:!!options.force,targetVersion:ctx.targetVersion,remoteSha:previewSha,synced,channel:ctx.channel})){console.log(`\u2714 Already on the latest ${ctx.channel} (${previewSha.slice(0,7)}). A real run would change nothing.`);return}}const aggregate={added:0,changed:0,removed:0,unchanged:0},perPath=[];let sawRemoved=0,sourceVersion=null;const tmpBase=mkdtempSync(join(tmpdir(),"stacks-upgrade-dry-run-"));try{let repoTmp=null;for(const managed of MANAGED_PATHS){const localTarget=join(projectRoot,managed.localPath),before=managed.isFile?await singleFileSnapshot(localTarget):await snapshotTree(localTarget,managed.skip);let after;if(usingLocal&&detectedLocal){const src=join(detectedLocal,managed.subPath);if(!existsSync(src)){console.log(` ${managed.label.padEnd(10)} skip: source missing at ${src}`);continue}after=managed.isFile?await singleFileSnapshot(src):await snapshotTree(src,managed.skip)}else try{if(managed.isFile){if(!repoTmp){repoTmp=join(tmpBase,"repo");await downloadTemplate(`github:stacksjs/stacks#${ctx.ref}`,{dir:repoTmp,force:!0,forceClean:!0,preferOffline:!0,silent:!0})}after=await singleFileSnapshot(join(repoTmp,managed.subPath))}else{const dir=join(tmpBase,managed.label);await downloadTemplate(buildTemplateString(ctx.ref,managed.subPath),{dir,force:!0,forceClean:!0,preferOffline:!options.force,silent:!0});after=await snapshotTree(dir,managed.skip)}}catch(err){console.log(` ${managed.label.padEnd(10)} preview unavailable (${err?.message||err}); a real run would sync from github:stacksjs/stacks#${ctx.ref}`);continue}const summary=diffSnapshotsDetailed(before,after);aggregate.added+=summary.added;aggregate.changed+=summary.changed;aggregate.removed+=summary.removed;aggregate.unchanged+=summary.unchanged;perPath.push({managed,summary});sawRemoved+=summary.removed;if(managed.isFile){const moved=summary.added+summary.changed>0;console.log(` ${managed.label.padEnd(10)} ${moved?"would update":"unchanged"}`)}else if(summary.added+summary.changed+summary.removed===0)console.log(` ${managed.label.padEnd(10)} unchanged (${summary.unchanged} files)`);else{console.log(` ${managed.label.padEnd(10)} +${summary.added} ~${summary.changed} -${summary.removed} (${summary.unchanged} unchanged)`);const samples=[...summary.addedFiles.map((f)=>`+ ${f}`),...summary.changedFiles.map((f)=>`~ ${f}`)];for(const line of samples.slice(0,8))console.log(` ${line}`);if(samples.length>8)console.log(` ... and ${samples.length-8} more`)}}const sourcePkgPath=usingLocal&&detectedLocal?join(detectedLocal,"storage/framework/core/buddy/package.json"):repoTmp?join(repoTmp,"storage/framework/core/buddy/package.json"):join(tmpBase,"core","buddy","package.json");sourceVersion=readVersion(sourcePkgPath)}finally{rmSync(tmpBase,{recursive:!0,force:!0})}console.log("");if(currentVersion||sourceVersion)console.log(currentVersion===sourceVersion?` version: unchanged (v${currentVersion??"unknown"})`:` version: v${currentVersion??"unknown"} -> v${sourceVersion??"unknown"}`);console.log(`
9
- A real run would:`);console.log(" - sync the managed paths above into place");if(!ctx.targetVersion){console.log(` - write channel "${ctx.channel}" to .stacks-channel`);console.log(previewSha?` - record synced sha ${previewSha.slice(0,7)} in .stacks-version`:" - record the resolved commit sha in .stacks-version (unavailable in this preview)")}if(!(!options.noPostinstall&&options.postinstall!==!1))console.log(" - skip post-sync hooks (--no-postinstall)");else if(aggregate.added+aggregate.changed+aggregate.removed===0)console.log(" - skip post-sync hooks (nothing changed)");else{console.log(" - regenerate the auto-import manifest");if(perPath.some((entry)=>{const{managed,summary}=entry;if(managed.isFile)return!1;if(managed.label!=="core"&&managed.label!=="defaults")return!1;if(summary.added+summary.changed===0)return!1;return pkgJsonInTree(join(projectRoot,managed.localPath))}))console.log(" - run `bun install` to refresh dependencies");if(existsSync(join(projectRoot,"database","migrations")))console.log(" - run pending migrations")}if(sawRemoved>0)console.log(`
9
+ A real run would:`);console.log(" - sync the managed paths above into place");if(!ctx.targetVersion){console.log(` - write channel "${ctx.channel}" to .stacks-channel`);console.log(previewSha?` - record synced sha ${previewSha.slice(0,7)} in .stacks-version`:" - record the resolved commit sha in .stacks-version (unavailable in this preview)")}if(!(!options.noPostinstall&&options.postinstall!==!1))console.log(" - skip post-sync hooks (--no-postinstall)");else if(aggregate.added+aggregate.changed+aggregate.removed===0)console.log(" - skip post-sync hooks (nothing changed)");else{console.log(" - regenerate the auto-import manifest");if(perPath.some((entry)=>{const{managed,summary}=entry;if(managed.isFile)return!1;if(managed.label!=="core"&&managed.label!=="defaults")return!1;if(summary.added+summary.changed===0)return!1;return pkgJsonInTree(join(projectRoot,managed.localPath))}))console.log(" - run `bun install` to refresh dependencies");if(existsSync(join(projectRoot,"database","types.d.ts")))console.log(" - regenerate database/types.d.ts");if(existsSync(join(projectRoot,"database","migrations")))console.log(" - run pending migrations")}if(sawRemoved>0)console.log(`
10
10
  (-N counts files no longer shipped upstream; the sync leaves them in place.)`);console.log(`
11
11
  \u2714 Dry run complete. No changes were made.`)}async function detectDirtyManagedPaths(root){const gitDir=join(root,".git");if(!existsSync(gitDir))return[];try{const proc=Bun.spawn({cmd:["git","-C",root,"status","--porcelain","--",...MANAGED_PATHS.map((m)=>m.localPath)],stdout:"pipe",stderr:"pipe"}),output=await new Response(proc.stdout).text();await proc.exited;return output.split(`
12
12
  `).filter((line)=>line.length>0).map((line)=>line.slice(3))}catch{return[]}}async function getRemoteSha(context,fromLocal,stacksRoot){const SHA_RE=/^[0-9a-f]{40}$/i;try{if(fromLocal&&stacksRoot){const proc=Bun.spawn({cmd:["git","-C",stacksRoot,"rev-parse",context.ref],stdout:"pipe",stderr:"pipe"}),out=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&SHA_RE.test(out))return out.toLowerCase();const head=Bun.spawn({cmd:["git","-C",stacksRoot,"rev-parse","HEAD"],stdout:"pipe",stderr:"pipe"}),h=(await new Response(head.stdout).text()).trim();return await head.exited===0&&SHA_RE.test(h)?h.toLowerCase():null}const proc=Bun.spawn({cmd:["git","ls-remote","https://github.com/stacksjs/stacks.git",`refs/heads/${context.ref}`,`refs/tags/${context.ref}`,`refs/tags/${context.ref}^{}`],stdout:"pipe",stderr:"pipe"}),out=await new Response(proc.stdout).text();if(await proc.exited!==0)return null;const lines=out.split(`
13
- `).filter(Boolean),m=(lines.find((l)=>l.includes("^{}"))??lines[0])?.match(/^([0-9a-f]{40})\s/i);return m?.[1]?m[1].toLowerCase():null}catch{return null}}async function hashFileOrZero(absPath){try{if(!existsSync(absPath))return 0n;const buf=await Bun.file(absPath).arrayBuffer();return Bun.hash(buf)}catch{return 0n}}async function singleFileSnapshot(absPath){const out=new Map;if(!existsSync(absPath))return out;try{const file=Bun.file(absPath);if(file.size>0){const buf=await file.arrayBuffer();out.set("self",{size:file.size,hash:Bun.hash(buf)})}}catch{}return out}async function syncFromLocal(stacksRoot,managed,localTarget){const src=join(stacksRoot,managed.subPath);if(!existsSync(src)){console.warn(` skip ${managed.label}: source missing at ${src}`);return}if(managed.isFile){mkdirSync(dirname(localTarget),{recursive:!0});copyFileSync(src,localTarget);if(managed.executable)chmodSync(localTarget,493);return}mkdirSync(localTarget,{recursive:!0});cpSync(src,localTarget,{recursive:!0,force:!0,filter:(source)=>{if(!managed.skip)return!0;const name=source.split("/").pop()||"";return!managed.skip.includes(name)}})}async function syncFromGitHub(ref,managed,localTarget,force){const kept=new Map;for(const name of managed.skip??[]){const file=join(localTarget,name);try{if(existsSync(file)&&statSync(file).isFile())kept.set(file,readFileSync(file))}catch{}}const template=buildTemplateString(ref,managed.subPath);await downloadTemplate(template,{dir:localTarget,force:!0,forceClean:!1,preferOffline:!force});for(const[file,contents]of kept)writeFileSync(file,contents)}async function syncRootFilesFromGitHub(ref){const tmpDir=p.projectPath(".tmp-upgrade");try{await downloadTemplate(`github:stacksjs/stacks#${ref}`,{dir:tmpDir,force:!0,forceClean:!0,preferOffline:!0,silent:!0});for(const managed of MANAGED_PATHS){if(!managed.isFile)continue;const src=join(tmpDir,managed.subPath),dest=p.projectPath(managed.localPath);try{if(existsSync(src)&&existsSync(dest)){copyFileSync(src,dest);if(managed.executable)chmodSync(dest,493)}}catch{}}}catch{}finally{if(existsSync(tmpDir))rmSync(tmpDir,{recursive:!0,force:!0})}}async function runPostSyncHooks(args){const{aggregate,perPath,projectRoot,alreadyRestarted}=args,changeCount=aggregate.added+aggregate.changed+aggregate.removed;if(!shouldRunPostSyncHooks(changeCount,alreadyRestarted)){console.log("Nothing changed - skipping post-sync hooks.");return}console.log("Regenerating auto-import manifest...");try{const{generateAutoImportFiles}=await import("@stacksjs/server");await generateAutoImportFiles()}catch(err){console.warn(` auto-imports failed (non-fatal): ${err?.message||err}`)}if(shouldRefreshPostSyncDependencies(perPath.some((entry)=>{const{managed,summary}=entry;if(managed.isFile)return!1;if(managed.label!=="core"&&managed.label!=="defaults")return!1;if(summary.added+summary.changed===0)return!1;return pkgJsonInTree(join(projectRoot,managed.localPath))}),alreadyRestarted)){const installer=detectDependencyInstaller(existsSync(join(projectRoot,"pantry.lock"))),cmd=resolveDependencyRefreshCommand({installer,bunExecutable:process.argv[0]||"bun",pantryExecutable:resolvePantryExecutable(pantryExecutableCandidates(projectRoot),existsSync)});console.log(`Running \`${installer} install\` to refresh dependencies...`);try{await runPostSyncDependencyRefresh({cmd,projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions)})}catch(err){console.warn(` ${installer} install failed (non-fatal): ${err?.message||err}`)}}const migrationsDir=join(projectRoot,"database","migrations");if(existsSync(migrationsDir)){console.log("Running pending migrations...");const migrateScript=p.frameworkPath("core/buddy/src/cli.ts");await runPostSyncMigration({bunExecutable:process.argv[0]||"bun",migrateScript,projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions)})}}function pantryExecutableCandidates(projectRoot){const home=process.env.HOME??"";return[join(projectRoot,"pantry",".bin","pantry"),home?join(home,".local","bin","pantry"):"",home?join(home,".local","share","pantry","global","bin","pantry"):""].filter(Boolean)}function pkgJsonInTree(dir){try{if(!existsSync(dir))return!1;return readFileSync(join(dir,"package.json"),"utf-8").length>0}catch{return existsSync(dir)}}
13
+ `).filter(Boolean),m=(lines.find((l)=>l.includes("^{}"))??lines[0])?.match(/^([0-9a-f]{40})\s/i);return m?.[1]?m[1].toLowerCase():null}catch{return null}}async function hashFileOrZero(absPath){try{if(!existsSync(absPath))return 0n;const buf=await Bun.file(absPath).arrayBuffer();return Bun.hash(buf)}catch{return 0n}}async function singleFileSnapshot(absPath){const out=new Map;if(!existsSync(absPath))return out;try{const file=Bun.file(absPath);if(file.size>0){const buf=await file.arrayBuffer();out.set("self",{size:file.size,hash:Bun.hash(buf)})}}catch{}return out}async function syncFromLocal(stacksRoot,managed,localTarget){const src=join(stacksRoot,managed.subPath);if(!existsSync(src)){console.warn(` skip ${managed.label}: source missing at ${src}`);return}if(managed.isFile){mkdirSync(dirname(localTarget),{recursive:!0});copyFileSync(src,localTarget);if(managed.executable)chmodSync(localTarget,493);return}mkdirSync(localTarget,{recursive:!0});cpSync(src,localTarget,{recursive:!0,force:!0,filter:(source)=>{if(!managed.skip)return!0;const name=source.split("/").pop()||"";return!managed.skip.includes(name)}})}async function syncFromGitHub(ref,managed,localTarget,force){const kept=new Map;for(const name of managed.skip??[]){const file=join(localTarget,name);try{if(existsSync(file)&&statSync(file).isFile())kept.set(file,readFileSync(file))}catch{}}const template=buildTemplateString(ref,managed.subPath);await downloadTemplate(template,{dir:localTarget,force:!0,forceClean:!1,preferOffline:!force});for(const[file,contents]of kept)writeFileSync(file,contents)}async function syncRootFilesFromGitHub(ref){const tmpDir=p.projectPath(".tmp-upgrade");try{await downloadTemplate(`github:stacksjs/stacks#${ref}`,{dir:tmpDir,force:!0,forceClean:!0,preferOffline:!0,silent:!0});for(const managed of MANAGED_PATHS){if(!managed.isFile)continue;const src=join(tmpDir,managed.subPath),dest=p.projectPath(managed.localPath);try{if(existsSync(src)&&existsSync(dest)){copyFileSync(src,dest);if(managed.executable)chmodSync(dest,493)}}catch{}}}catch{}finally{if(existsSync(tmpDir))rmSync(tmpDir,{recursive:!0,force:!0})}}async function runPostSyncHooks(args){const{aggregate,perPath,projectRoot,alreadyRestarted}=args,changeCount=aggregate.added+aggregate.changed+aggregate.removed;if(!shouldRunPostSyncHooks(changeCount,alreadyRestarted)){console.log("Nothing changed - skipping post-sync hooks.");return}console.log("Regenerating auto-import manifest...");try{const{generateAutoImportFiles}=await import("@stacksjs/server");await generateAutoImportFiles()}catch(err){console.warn(` auto-imports failed (non-fatal): ${err?.message||err}`)}if(shouldRefreshPostSyncDependencies(perPath.some((entry)=>{const{managed,summary}=entry;if(managed.isFile)return!1;if(managed.label!=="core"&&managed.label!=="defaults")return!1;if(summary.added+summary.changed===0)return!1;return pkgJsonInTree(join(projectRoot,managed.localPath))}),alreadyRestarted)){const installer=detectDependencyInstaller(existsSync(join(projectRoot,"pantry.lock"))),cmd=resolveDependencyRefreshCommand({installer,bunExecutable:process.argv[0]||"bun",pantryExecutable:resolvePantryExecutable(pantryExecutableCandidates(projectRoot),existsSync)});console.log(`Running \`${installer} install\` to refresh dependencies...`);try{await runPostSyncDependencyRefresh({cmd,projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions)})}catch(err){console.warn(` ${installer} install failed (non-fatal): ${err?.message||err}`)}}try{if(await runPostSyncDatabaseTypesRefresh({cmd:[process.argv[0]||"bun",p.frameworkPath("core/buddy/src/cli.ts"),"generate:db-types"],projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions),exists:existsSync}))console.log("Regenerated database/types.d.ts")}catch(err){console.warn(` database/types.d.ts was not regenerated (non-fatal): ${err?.message||err}`)}const migrationsDir=join(projectRoot,"database","migrations");if(existsSync(migrationsDir)){console.log("Running pending migrations...");const migrateScript=p.frameworkPath("core/buddy/src/cli.ts");await runPostSyncMigration({bunExecutable:process.argv[0]||"bun",migrateScript,projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions)})}}function pantryExecutableCandidates(projectRoot){const home=process.env.HOME??"";return[join(projectRoot,"pantry",".bin","pantry"),home?join(home,".local","bin","pantry"):"",home?join(home,".local","share","pantry","global","bin","pantry"):""].filter(Boolean)}function pkgJsonInTree(dir){try{if(!existsSync(dir))return!1;return readFileSync(join(dir,"package.json"),"utf-8").length>0}catch{return existsSync(dir)}}
@@ -1,4 +1,4 @@
1
- import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";import{join,relative}from"node:path";import process from"node:process";import{runCommand}from"@stacksjs/cli";import{installedDefaultsVersion}from"@stacksjs/path";import{detectProjectAiProviders,measureDefaultsDrift,migratePackageProjectManifest,migratePackageProjectTsconfig,summarizeStructureChanges,syncPackageProjectFiles}from"./package-project";import{describeDanglingRouteActions,findDanglingRouteActions,pruneRetiredScaffoldRoutes}from"./route-actions";export function hasStacksDependency(pkg){return Boolean(pkg.dependencies?.stacks||pkg.devDependencies?.stacks)}export function standalonePackageUpdateCommand(){return"bun update"}export function frameworkPackageUpdateCommand(force=!1){return force?"bun update stacks --force":"bun update stacks"}export function installedStacksVersion(projectRoot){try{const manifest=JSON.parse(readFileSync(join(projectRoot,"node_modules/stacks/package.json"),"utf-8"));return typeof manifest.version==="string"?manifest.version:null}catch{return null}}export function needsFrameworkInstall(projectRoot,target){return installedStacksVersion(projectRoot)!==target}async function updateStandalonePackage(projectRoot,options){console.log(`
1
+ import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";import{join,relative}from"node:path";import process from"node:process";import{runCommand}from"@stacksjs/cli";import{installedDefaultsVersion}from"@stacksjs/path";import{runPostSyncDatabaseTypesRefresh}from"./framework-hooks";import{detectProjectAiProviders,measureDefaultsDrift,migratePackageProjectManifest,migratePackageProjectTsconfig,summarizeStructureChanges,syncPackageProjectFiles}from"./package-project";import{describeDanglingRouteActions,findDanglingRouteActions,pruneRetiredScaffoldRoutes}from"./route-actions";export function hasStacksDependency(pkg){return Boolean(pkg.dependencies?.stacks||pkg.devDependencies?.stacks)}export function standalonePackageUpdateCommand(){return"bun update"}export function frameworkPackageUpdateCommand(force=!1){return force?"bun update stacks --force":"bun update stacks"}export function installedStacksVersion(projectRoot){try{const manifest=JSON.parse(readFileSync(join(projectRoot,"node_modules/stacks/package.json"),"utf-8"));return typeof manifest.version==="string"?manifest.version:null}catch{return null}}export function needsFrameworkInstall(projectRoot,target){return installedStacksVersion(projectRoot)!==target}async function updateStandalonePackage(projectRoot,options){console.log(`
2
2
  Standalone package detected. No Stacks framework source is installed.`);if(options.dryRun){console.log(" --dry-run: would refresh the package dependencies with `bun update`. No files were changed.\n");process.exit(0)}if(options.noPostinstall){console.log(" --no-postinstall: skipping the dependency refresh. Run `bun update` when ready.\n");process.exit(0)}console.log(` Refreshing declared dependencies...
3
3
  `);if((await runCommand(standalonePackageUpdateCommand(),{cwd:projectRoot})).isErr){console.error("\n\u2717 The dependency refresh failed. Resolve the reported error and re-run `buddy update`.\n");process.exit(1)}console.log(`
4
4
  \u2714 Standalone package dependencies are up to date.
@@ -11,7 +11,7 @@ import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";
11
11
  `)?`
12
12
  `:"";writeFileSync(pkgPath,`${JSON.stringify(pkg,null,2)}${trailing}`);console.log("\u2714 Updated package.json")}if(options.noPostinstall){console.log(" --no-postinstall: skipping install. Run this to pull the new versions:");console.log(` ${frameworkPackageUpdateCommand()}
13
13
  `);process.exit(0)}const dependenciesNeedInstall=needsFrameworkInstall(projectRoot,target);if(changes.length>0||manifestChanges.length>0||projectManifestChanges.length>0||dependenciesNeedInstall||options.force){console.log(` Installing\u2026
14
- `);if((await runCommand(frameworkPackageUpdateCommand(options.force),{cwd:projectRoot})).isErr){console.error("\n\u2717 The install step failed. Your package.json was updated - resolve the error and re-run `bun update`.\n");process.exit(1)}}const defaultsPackageRoot=join(projectRoot,"node_modules/@stacksjs/defaults"),structureChanges=existsSync(join(defaultsPackageRoot,"package.json"))?syncPackageProjectFiles(projectRoot,defaultsPackageRoot):[],tsconfigChanges=migratePackageProjectTsconfig(projectRoot),prunedRoutes=reportRouteActions(projectRoot,!1);if(structureChanges.length>0||tsconfigChanges.length>0){const added=structureChanges.filter((change)=>change.action==="add").length,updated=structureChanges.filter((change)=>change.action==="update").length+tsconfigChanges.length,removed=structureChanges.filter((change)=>change.action==="remove").length;console.log(` Project structure: +${added} ~${updated} -${removed}`)}if(structureChanges.length>0)await regenerateAutoImports(projectRoot);for(const provider of detectProjectAiProviders(projectRoot))if((await runCommand(`./buddy setup:ai ${provider} --force`,{cwd:projectRoot})).isErr){console.error(`
14
+ `);if((await runCommand(frameworkPackageUpdateCommand(options.force),{cwd:projectRoot})).isErr){console.error("\n\u2717 The install step failed. Your package.json was updated - resolve the error and re-run `bun update`.\n");process.exit(1)}}const defaultsPackageRoot=join(projectRoot,"node_modules/@stacksjs/defaults"),structureChanges=existsSync(join(defaultsPackageRoot,"package.json"))?syncPackageProjectFiles(projectRoot,defaultsPackageRoot):[],tsconfigChanges=migratePackageProjectTsconfig(projectRoot),prunedRoutes=reportRouteActions(projectRoot,!1);if(structureChanges.length>0||tsconfigChanges.length>0){const added=structureChanges.filter((change)=>change.action==="add").length,updated=structureChanges.filter((change)=>change.action==="update").length+tsconfigChanges.length,removed=structureChanges.filter((change)=>change.action==="remove").length;console.log(` Project structure: +${added} ~${updated} -${removed}`)}if(structureChanges.length>0)await regenerateAutoImports(projectRoot);if(changes.length>0||dependenciesNeedInstall||structureChanges.length>0||options.force)await regenerateDatabaseTypes(projectRoot);for(const provider of detectProjectAiProviders(projectRoot))if((await runCommand(`./buddy setup:ai ${provider} --force`,{cwd:projectRoot})).isErr){console.error(`
15
15
  \u2717 AI setup refresh failed for ${provider}. Re-run \`buddy setup:ai ${provider} --force\`.
16
16
  `);process.exit(1)}if(!(changes.length>0||manifestChanges.length>0||projectManifestChanges.length>0||dependenciesNeedInstall||structureChanges.length>0||tsconfigChanges.length>0||prunedRoutes>0)&&!options.force)console.log(`
17
17
  \u2714 Already up to date - dependencies and managed project files match the target.
@@ -20,6 +20,6 @@ import{existsSync,readdirSync,readFileSync,statSync,writeFileSync}from"node:fs";
20
20
  `);process.exit(0)}function reportRouteActions(projectRoot,dryRun){const pruned=pruneRetiredScaffoldRoutes(projectRoot,{dryRun});for(const route of pruned)console.log(` ${dryRun?"Would remove":"Removed"} ${route.file}:${route.line}, the scaffold route to ${route.action}: removed in ${route.removedIn}, ${route.reason}`);const dangling=findDanglingRouteActions(projectRoot);if(dangling.length>0){console.warn(`
21
21
  ${dangling.length} route${dangling.length===1?"":"s"} name${dangling.length===1?"s":""} an action this version does not ship. Point ${dangling.length===1?"it":"them"} at an action that exists, or delete ${dangling.length===1?"it":"them"}:`);for(const line of describeDanglingRouteActions(dangling).split(`
22
22
  `))console.warn(` ${line}`);console.warn("")}return pruned.length}async function regenerateAutoImports(projectRoot){const proc=Bun.spawn({cmd:[process.execPath,"-e","await (await import('@stacksjs/server')).generateAutoImportFiles()"],cwd:projectRoot,stdout:"ignore",stderr:"pipe"});if(await proc.exited!==0){const stderr=(await new Response(proc.stderr).text()).trim();console.warn(` auto-imports were not regenerated (non-fatal): ${stderr.split(`
23
- `).pop()||`exit ${proc.exitCode}`}`);return}console.log(" Regenerated auto-imports")}export function resolveManifestSpec(name,spec,target,context,members){if(name!=="stacks"&&!name.startsWith("@stacksjs/"))return null;if(spec.startsWith("workspace:")&&members?.has(name))return null;if(context&&!context.lockstep.has(name)){const declared=context.metaDeps[name];if(!declared)return null;return baseVersion(declared)===baseVersion(spec)?null:declared}if(spec.startsWith("workspace:"))return`^${target}`;if(baseVersion(spec)===target)return null;if(!/^[\^~]?\d/.test(spec))return null;return`${/^[\^~]/.test(spec)?spec[0]:""}${target}`}export function workspaceMembers(projectRoot){const members=new Set;let patterns=[];try{const root=JSON.parse(readFileSync(join(projectRoot,"package.json"),"utf-8"));patterns=((Array.isArray(root.workspaces)?root.workspaces:root.workspaces?.packages)??[]).filter((one)=>typeof one==="string")}catch{return members}const manifestsFor=(pattern)=>{return[...new Bun.Glob(`${pattern.replace(/\/+$/,"")}/package.json`).scanSync({cwd:projectRoot,onlyFiles:!0})].filter((file)=>!file.split("/").includes("node_modules"))},excluded=new Set(patterns.filter((one)=>one.startsWith("!")).flatMap((one)=>manifestsFor(one.slice(1))));for(const pattern of patterns.filter((one)=>!one.startsWith("!")))for(const file of manifestsFor(pattern)){if(excluded.has(file))continue;try{const name=JSON.parse(readFileSync(join(projectRoot,file),"utf-8")).name;if(typeof name==="string"&&name)members.add(name)}catch{}}return members}export function reconcileVendoredManifests(projectRoot,target,options={}){const root=join(projectRoot,"storage/framework");if(!existsSync(root))return[];const changes=[],members=workspaceMembers(projectRoot),walk=(dir)=>{let entries;try{entries=readdirSync(dir)}catch{return}for(const entry of entries){if(entry==="node_modules"||entry==="dist"||entry===".git")continue;const full=join(dir,entry);let stat;try{stat=statSync(full)}catch{continue}if(stat.isDirectory()){walk(full);continue}if(entry!=="package.json")continue;let raw;try{raw=readFileSync(full,"utf-8")}catch{continue}let pkg;try{pkg=JSON.parse(raw)}catch{continue}let touched=!1;for(const field of["dependencies","devDependencies"]){const deps=pkg[field];if(!deps)continue;for(const[name,spec]of Object.entries(deps)){const next=resolveManifestSpec(name,spec,target,options.context,members);if(!next)continue;changes.push({file:relative(projectRoot,full),name,from:spec,to:next});deps[name]=next;touched=!0}}if(touched&&!options.dryRun){const suffix=raw.endsWith(`
23
+ `).pop()||`exit ${proc.exitCode}`}`);return}console.log(" Regenerated auto-imports")}async function regenerateDatabaseTypes(projectRoot){const buddy=join(projectRoot,"buddy");if(!existsSync(buddy))return;try{if(await runPostSyncDatabaseTypesRefresh({cmd:[buddy,"generate:db-types"],projectRoot,spawn:(spawnOptions)=>Bun.spawn(spawnOptions),exists:existsSync}))console.log(" Regenerated database/types.d.ts")}catch(err){console.warn(` database/types.d.ts was not regenerated (non-fatal): ${err.message} Run \`./buddy generate:db-types\`.`)}}export function resolveManifestSpec(name,spec,target,context,members){if(name!=="stacks"&&!name.startsWith("@stacksjs/"))return null;if(spec.startsWith("workspace:")&&members?.has(name))return null;if(context&&!context.lockstep.has(name)){const declared=context.metaDeps[name];if(!declared)return null;return baseVersion(declared)===baseVersion(spec)?null:declared}if(spec.startsWith("workspace:"))return`^${target}`;if(baseVersion(spec)===target)return null;if(!/^[\^~]?\d/.test(spec))return null;return`${/^[\^~]/.test(spec)?spec[0]:""}${target}`}export function workspaceMembers(projectRoot){const members=new Set;let patterns=[];try{const root=JSON.parse(readFileSync(join(projectRoot,"package.json"),"utf-8"));patterns=((Array.isArray(root.workspaces)?root.workspaces:root.workspaces?.packages)??[]).filter((one)=>typeof one==="string")}catch{return members}const manifestsFor=(pattern)=>{return[...new Bun.Glob(`${pattern.replace(/\/+$/,"")}/package.json`).scanSync({cwd:projectRoot,onlyFiles:!0})].filter((file)=>!file.split("/").includes("node_modules"))},excluded=new Set(patterns.filter((one)=>one.startsWith("!")).flatMap((one)=>manifestsFor(one.slice(1))));for(const pattern of patterns.filter((one)=>!one.startsWith("!")))for(const file of manifestsFor(pattern)){if(excluded.has(file))continue;try{const name=JSON.parse(readFileSync(join(projectRoot,file),"utf-8")).name;if(typeof name==="string"&&name)members.add(name)}catch{}}return members}export function reconcileVendoredManifests(projectRoot,target,options={}){const root=join(projectRoot,"storage/framework");if(!existsSync(root))return[];const changes=[],members=workspaceMembers(projectRoot),walk=(dir)=>{let entries;try{entries=readdirSync(dir)}catch{return}for(const entry of entries){if(entry==="node_modules"||entry==="dist"||entry===".git")continue;const full=join(dir,entry);let stat;try{stat=statSync(full)}catch{continue}if(stat.isDirectory()){walk(full);continue}if(entry!=="package.json")continue;let raw;try{raw=readFileSync(full,"utf-8")}catch{continue}let pkg;try{pkg=JSON.parse(raw)}catch{continue}let touched=!1;for(const field of["dependencies","devDependencies"]){const deps=pkg[field];if(!deps)continue;for(const[name,spec]of Object.entries(deps)){const next=resolveManifestSpec(name,spec,target,options.context,members);if(!next)continue;changes.push({file:relative(projectRoot,full),name,from:spec,to:next});deps[name]=next;touched=!0}}if(touched&&!options.dryRun){const suffix=raw.endsWith(`
24
24
  `)?`
25
25
  `:"";writeFileSync(full,`${JSON.stringify(pkg,null,2)}${suffix}`)}}};walk(root);return changes}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.144",
5
+ "version": "0.75.146",
6
6
  "description": "The Stacks actions.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -66,53 +66,53 @@
66
66
  "prepublishOnly": "bun run build"
67
67
  },
68
68
  "dependencies": {
69
- "@stacksjs/action-runner": "0.75.144",
70
- "@stacksjs/ai": "0.75.144",
71
- "@stacksjs/analytics": "0.75.144",
72
- "@stacksjs/api": "0.75.144",
73
- "@stacksjs/auth": "0.75.144",
74
- "@stacksjs/build": "0.75.144",
69
+ "@stacksjs/action-runner": "0.75.146",
70
+ "@stacksjs/ai": "0.75.146",
71
+ "@stacksjs/analytics": "0.75.146",
72
+ "@stacksjs/api": "0.75.146",
73
+ "@stacksjs/auth": "0.75.146",
74
+ "@stacksjs/build": "0.75.146",
75
75
  "@stacksjs/bumpx": "^0.2.21",
76
76
  "@stacksjs/bunpress": "^0.2.15",
77
- "@stacksjs/cli": "0.75.144",
78
- "@stacksjs/cloud": "0.75.144",
79
- "@stacksjs/cms": "0.75.144",
77
+ "@stacksjs/cli": "0.75.146",
78
+ "@stacksjs/cloud": "0.75.146",
79
+ "@stacksjs/cms": "0.75.146",
80
80
  "@stacksjs/components": "^0.2.445",
81
- "@stacksjs/config": "0.75.144",
82
- "@stacksjs/database": "0.75.144",
83
- "@stacksjs/desktop-build": "0.75.144",
84
- "@stacksjs/dns": "0.75.144",
85
- "@stacksjs/enums": "0.75.144",
86
- "@stacksjs/env": "0.75.144",
87
- "@stacksjs/error-handling": "0.75.144",
81
+ "@stacksjs/config": "0.75.146",
82
+ "@stacksjs/database": "0.75.146",
83
+ "@stacksjs/desktop-build": "0.75.146",
84
+ "@stacksjs/dns": "0.75.146",
85
+ "@stacksjs/enums": "0.75.146",
86
+ "@stacksjs/env": "0.75.146",
87
+ "@stacksjs/error-handling": "0.75.146",
88
88
  "@stacksjs/gitit": "^0.2.5",
89
- "@stacksjs/i18n": "0.75.144",
90
- "@stacksjs/image": "0.75.144",
91
- "@stacksjs/logging": "0.75.144",
89
+ "@stacksjs/i18n": "0.75.146",
90
+ "@stacksjs/image": "0.75.146",
91
+ "@stacksjs/logging": "0.75.146",
92
92
  "@stacksjs/logsmith": "^0.2.11",
93
- "@stacksjs/mobile": "0.75.144",
94
- "@stacksjs/orm": "0.75.144",
95
- "@stacksjs/path": "0.75.144",
96
- "@stacksjs/payments": "0.75.144",
97
- "@stacksjs/queue": "0.75.144",
98
- "@stacksjs/registry": "0.75.144",
99
- "@stacksjs/router": "0.75.144",
93
+ "@stacksjs/mobile": "0.75.146",
94
+ "@stacksjs/orm": "0.75.146",
95
+ "@stacksjs/path": "0.75.146",
96
+ "@stacksjs/payments": "0.75.146",
97
+ "@stacksjs/queue": "0.75.146",
98
+ "@stacksjs/registry": "0.75.146",
99
+ "@stacksjs/router": "0.75.146",
100
100
  "@stacksjs/rpx": "^0.11.54",
101
- "@stacksjs/scheduler": "0.75.144",
102
- "@stacksjs/search-engine": "0.75.144",
103
- "@stacksjs/security": "0.75.144",
104
- "@stacksjs/server": "0.75.144",
105
- "@stacksjs/sites": "0.75.144",
106
- "@stacksjs/storage": "0.75.144",
107
- "@stacksjs/strings": "0.75.144",
101
+ "@stacksjs/scheduler": "0.75.146",
102
+ "@stacksjs/search-engine": "0.75.146",
103
+ "@stacksjs/security": "0.75.146",
104
+ "@stacksjs/server": "0.75.146",
105
+ "@stacksjs/sites": "0.75.146",
106
+ "@stacksjs/storage": "0.75.146",
107
+ "@stacksjs/strings": "0.75.146",
108
108
  "@stacksjs/stx": "^0.2.445",
109
109
  "@stacksjs/tlsx": "^0.13.19",
110
110
  "@stacksjs/ts-cloud": "^0.16.52",
111
111
  "@stacksjs/ts-md": "^0.1.1",
112
- "@stacksjs/tunnel": "0.75.144",
113
- "@stacksjs/types": "0.75.144",
114
- "@stacksjs/utils": "0.75.144",
115
- "@stacksjs/whois": "0.75.144",
112
+ "@stacksjs/tunnel": "0.75.146",
113
+ "@stacksjs/types": "0.75.146",
114
+ "@stacksjs/utils": "0.75.146",
115
+ "@stacksjs/whois": "0.75.146",
116
116
  "bun-plugin-stx": "^0.2.445"
117
117
  },
118
118
  "peerDependencies": {
@@ -128,7 +128,7 @@
128
128
  }
129
129
  },
130
130
  "devDependencies": {
131
- "@stacksjs/validation": "0.75.144",
131
+ "@stacksjs/validation": "0.75.146",
132
132
  "better-dx": "^0.2.24"
133
133
  }
134
134
  }