@stacksjs/actions 0.75.244 → 0.75.246
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.
|
@@ -106,7 +106,7 @@ export declare interface DiscoveredModel {
|
|
|
106
106
|
dashboard?: DashboardModelOptions
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
|
-
* Manifest row written to `
|
|
109
|
+
* Manifest row written to `storage/framework/runtime/dashboard/discovered-models.json`
|
|
110
110
|
* for the web-side sidebar to consume. Includes the per-model `dashboard`
|
|
111
111
|
* config (stacksjs/stacks#1843) so both sidebar builders (the native one
|
|
112
112
|
* here and the HTML one in `defaults/resources/functions/dashboard/sidebar.ts`)
|
package/dist/dev/dashboard.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import process from"node:process";import{randomUUID}from"node:crypto";import{existsSync,renameSync,unlinkSync,writeFileSync}from"node:fs";import{connect}from"node:net";import{bold,cyan,dim,green}from"@stacksjs/cli";import{projectPath,publicPath,storagePath}from"@stacksjs/path";import{seedCsrfPageResponse,validateDevCsrfRequest}from"./csrf";import{resolveComponentsLibraryRoot}from"./defaults-resources";import{shouldDelegateDashboardRequest}from"./dashboard-request-routing";import{resolveDashboardCraftExecutable}from"./dashboard-native";import{resolveDashboardDomain,resolveDashboardProxyStrategy}from"./dashboard-proxy";import{buildManifest,discoverModels,findAvailablePort,waitForServer}from"./dashboard-utils";import{runDashboardSupervisor}from"./dashboard-supervisor";import{ensureDiscoveredPackages}from"../discover-packages";if(process.env.STACKS_DASHBOARD_WORKER!=="1"){const exitCode=await runDashboardSupervisor(import.meta.path,process.argv.slice(2));process.exit(exitCode)}const verboseIdx=process.argv.indexOf("--verbose"),verbose=verboseIdx!==-1&&process.argv[verboseIdx+1]!=="false",startTime=Bun.nanoseconds(),{log:originalConsoleLog,warn:originalConsoleWarn}=console,bufferedLogs=[];console.log=(...args)=>{bufferedLogs.push(args.map(String).join(" "))};console.warn=(...args)=>{bufferedLogs.push(args.map(String).join(" "))};const dashboardPath=storagePath("framework/defaults/views/dashboard"),userDashboardPath=projectPath("resources/views/dashboard"),preferredPort=Number(process.env.PORT_ADMIN)||3002,dashboardPort=await findAvailablePort(preferredPort),appUrl=process.env.APP_URL||"",dashboardDomain=resolveDashboardDomain(appUrl),sslBasePath=`${process.env.HOME}/.stacks/ssl`;function restoreConsole(){console.log=originalConsoleLog;console.warn=(...args)=>{const msg=args.map(String).join(" ");if(msg.includes("[STX] DOM API violation")||msg.includes("unsafe expression"))return;originalConsoleWarn(...args)}}async function startStxServer(){const{overridesReady}=await import("@stacksjs/config"),{autoImportsAreStale,generateAutoImportFiles,injectGlobalAutoImports}=await import("@stacksjs/server");await overridesReady;await ensureDiscoveredPackages();if(!existsSync(storagePath("framework/auto-imports/models.ts"))||autoImportsAreStale())await generateAutoImportFiles();await injectGlobalAutoImports();let serve;try{const localServe=process.env.BUN_PLUGIN_STX_SRC||`${process.env.HOME}/Code/Tools/stx/packages/bun-plugin/src/serve.ts`;if(!await Bun.file(localServe).exists())throw Error("local bun-plugin-stx source not found");serve=(await import(localServe)).serve}catch{try{serve=(await import("bun-plugin-stx/serve")).serve}catch{serve=(await import(projectPath("pantry/bun-plugin-stx/dist/serve.js"))).serve}}let stxModule;try{const localStx=process.env.STX_SRC;if(localStx&&await Bun.file(localStx).exists())stxModule=await import(localStx)}catch{}if(stxModule&&verbose)console.log("[Dashboard] Using local stx checkout");if(!stxModule)try{const vendoredStx=projectPath("pantry/@stacksjs/stx/dist/index.js");if(await Bun.file(vendoredStx).exists())stxModule=await import(vendoredStx)}catch{}const{listConfigFiles,readConfig,updateConfigKeys}=await import(storagePath("framework/defaults/resources/functions/dashboard/config-io.ts")),localTsChartsRoot=process.env.TS_CHARTS_SRC||`${process.env.HOME}/Code/Libraries/ts-charts`,dependencyBundles=new Map;function resolveTsChartsSource(packageName){return[`${localTsChartsRoot}/packages/${packageName}/src/index.ts`,projectPath(`node_modules/@ts-charts/${packageName}/src/index.ts`),projectPath(`pantry/@ts-charts/${packageName}/src/index.ts`)].find(existsSync)||null}const tsChartsEntry=[`${localTsChartsRoot}/packages/ts-charts/src/index.ts`,projectPath("node_modules/ts-charts/src/index.ts"),projectPath("pantry/ts-charts/src/index.ts")].find(existsSync);async function buildDashboardDependency(entrypoint){const cached=dependencyBundles.get(entrypoint);if(cached)return cached;const build=(async()=>{const result=await Bun.build({entrypoints:[entrypoint],target:"browser",format:"esm",minify:!0,plugins:[{name:"dashboard-ts-charts-source",setup(builder){builder.onResolve({filter:/^@ts-charts\/[a-z0-9-]+$/},(args)=>{const packageName=args.path.slice(11),source=resolveTsChartsSource(packageName);if(source)return{path:source};return null})}}]});if(!result.success){const errors=result.logs.filter((log)=>log.level==="error").map((log)=>log.message).join(`
|
|
1
|
+
import process from"node:process";import{randomUUID}from"node:crypto";import{existsSync,mkdirSync,renameSync,unlinkSync,writeFileSync}from"node:fs";import{dirname}from"node:path";import{connect}from"node:net";import{bold,cyan,dim,green}from"@stacksjs/cli";import{projectPath,publicPath,storagePath}from"@stacksjs/path";import{seedCsrfPageResponse,validateDevCsrfRequest}from"./csrf";import{resolveComponentsLibraryRoot}from"./defaults-resources";import{shouldDelegateDashboardRequest}from"./dashboard-request-routing";import{resolveDashboardCraftExecutable}from"./dashboard-native";import{resolveDashboardDomain,resolveDashboardProxyStrategy}from"./dashboard-proxy";import{buildManifest,discoverModels,findAvailablePort,waitForServer}from"./dashboard-utils";import{runDashboardSupervisor}from"./dashboard-supervisor";import{ensureDiscoveredPackages}from"../discover-packages";if(process.env.STACKS_DASHBOARD_WORKER!=="1"){const exitCode=await runDashboardSupervisor(import.meta.path,process.argv.slice(2));process.exit(exitCode)}const verboseIdx=process.argv.indexOf("--verbose"),verbose=verboseIdx!==-1&&process.argv[verboseIdx+1]!=="false",startTime=Bun.nanoseconds(),{log:originalConsoleLog,warn:originalConsoleWarn}=console,bufferedLogs=[];console.log=(...args)=>{bufferedLogs.push(args.map(String).join(" "))};console.warn=(...args)=>{bufferedLogs.push(args.map(String).join(" "))};const dashboardPath=storagePath("framework/defaults/views/dashboard"),userDashboardPath=projectPath("resources/views/dashboard"),preferredPort=Number(process.env.PORT_ADMIN)||3002,dashboardPort=await findAvailablePort(preferredPort),appUrl=process.env.APP_URL||"",dashboardDomain=resolveDashboardDomain(appUrl),sslBasePath=`${process.env.HOME}/.stacks/ssl`;function restoreConsole(){console.log=originalConsoleLog;console.warn=(...args)=>{const msg=args.map(String).join(" ");if(msg.includes("[STX] DOM API violation")||msg.includes("unsafe expression"))return;originalConsoleWarn(...args)}}async function startStxServer(){const{overridesReady}=await import("@stacksjs/config"),{autoImportsAreStale,generateAutoImportFiles,injectGlobalAutoImports}=await import("@stacksjs/server");await overridesReady;await ensureDiscoveredPackages();if(!existsSync(storagePath("framework/auto-imports/models.ts"))||autoImportsAreStale())await generateAutoImportFiles();await injectGlobalAutoImports();let serve;try{const localServe=process.env.BUN_PLUGIN_STX_SRC||`${process.env.HOME}/Code/Tools/stx/packages/bun-plugin/src/serve.ts`;if(!await Bun.file(localServe).exists())throw Error("local bun-plugin-stx source not found");serve=(await import(localServe)).serve}catch{try{serve=(await import("bun-plugin-stx/serve")).serve}catch{serve=(await import(projectPath("pantry/bun-plugin-stx/dist/serve.js"))).serve}}let stxModule;try{const localStx=process.env.STX_SRC;if(localStx&&await Bun.file(localStx).exists())stxModule=await import(localStx)}catch{}if(stxModule&&verbose)console.log("[Dashboard] Using local stx checkout");if(!stxModule)try{const vendoredStx=projectPath("pantry/@stacksjs/stx/dist/index.js");if(await Bun.file(vendoredStx).exists())stxModule=await import(vendoredStx)}catch{}const{listConfigFiles,readConfig,updateConfigKeys}=await import(storagePath("framework/defaults/resources/functions/dashboard/config-io.ts")),localTsChartsRoot=process.env.TS_CHARTS_SRC||`${process.env.HOME}/Code/Libraries/ts-charts`,dependencyBundles=new Map;function resolveTsChartsSource(packageName){return[`${localTsChartsRoot}/packages/${packageName}/src/index.ts`,projectPath(`node_modules/@ts-charts/${packageName}/src/index.ts`),projectPath(`pantry/@ts-charts/${packageName}/src/index.ts`)].find(existsSync)||null}const tsChartsEntry=[`${localTsChartsRoot}/packages/ts-charts/src/index.ts`,projectPath("node_modules/ts-charts/src/index.ts"),projectPath("pantry/ts-charts/src/index.ts")].find(existsSync);async function buildDashboardDependency(entrypoint){const cached=dependencyBundles.get(entrypoint);if(cached)return cached;const build=(async()=>{const result=await Bun.build({entrypoints:[entrypoint],target:"browser",format:"esm",minify:!0,plugins:[{name:"dashboard-ts-charts-source",setup(builder){builder.onResolve({filter:/^@ts-charts\/[a-z0-9-]+$/},(args)=>{const packageName=args.path.slice(11),source=resolveTsChartsSource(packageName);if(source)return{path:source};return null})}}]});if(!result.success){const errors=result.logs.filter((log)=>log.level==="error").map((log)=>log.message).join(`
|
|
2
2
|
`);throw Error(errors||`Failed to bundle ${entrypoint}`)}const output=result.outputs.find((file)=>file.path.endsWith(".js"));if(!output)throw Error(`No JavaScript output produced for ${entrypoint}`);return output.text()})();dependencyBundles.set(entrypoint,build);return build}function browserDependencyRoute(entrypoint){return async()=>{try{return new Response(await buildDashboardDependency(entrypoint),{headers:{"content-type":"text/javascript; charset=utf-8","cache-control":"no-cache"}})}catch(error){dependencyBundles.delete(entrypoint);return new Response(`throw new Error(${JSON.stringify(error.message)})`,{status:500,headers:{"content-type":"text/javascript; charset=utf-8"}})}}}let dashboardIconCss=null;async function buildDashboardIconCss(){const{generateCss}=await import("@stacksjs/stx"),dirs=[dashboardPath,userDashboardPath,storagePath("framework/defaults/resources/components/Dashboard")],icons=new Set;for(const dir of dirs){if(!existsSync(dir))continue;const glob=new Bun.Glob("**/*.{stx,ts}");for await(const file of glob.scan({cwd:dir,absolute:!0})){const text=await Bun.file(file).text();for(const match of text.matchAll(/\bi-[a-z][a-z0-9]*(?:-[a-z0-9]+)+/g))icons.add(match[0])}}if(icons.size===0)return"";return generateCss(`<div class="${[...icons].join(" ")}"></div>`,process.cwd())}const configRoutes={"/__deps/charts.js":browserDependencyRoute(storagePath("framework/core/charts/src/index.ts")),"/__deps/ts-charts.js":browserDependencyRoute(tsChartsEntry||`${localTsChartsRoot}/packages/ts-charts/src/index.ts`),"/__deps/dashboard-icons.css":async()=>{if(!dashboardIconCss)dashboardIconCss=buildDashboardIconCss();return new Response(await dashboardIconCss,{headers:{"content-type":"text/css; charset=utf-8","cache-control":"no-cache"}})},"/api/config/list":async()=>{try{return Response.json({ok:!0,files:listConfigFiles()})}catch(e){return Response.json({ok:!1,error:e?.message},{status:500})}},"/api/config/read":async(req)=>{try{const name=new URL(req.url).searchParams.get("name")||"";if(!/^[\w-]+$/.test(name))return Response.json({ok:!1,error:"Invalid config name"},{status:400});const result=await readConfig(name);if(!result)return Response.json({ok:!1,error:"Not found"},{status:404});return Response.json({ok:!0,name,fields:result.fields})}catch(e){return Response.json({ok:!1,error:e?.message},{status:500})}},"/api/config/source":async(req)=>{try{const name=new URL(req.url).searchParams.get("name")||"";if(!/^[\w-]+$/.test(name))return Response.json({ok:!1,error:"Invalid config name"},{status:400});const result=await readConfig(name);if(!result)return Response.json({ok:!1,error:"Not found"},{status:404});return new Response(result.source,{headers:{"content-type":"text/plain; charset=utf-8"}})}catch(e){return Response.json({ok:!1,error:e?.message},{status:500})}},"/api/config/update":async(req)=>{if(req.method!=="POST")return Response.json({ok:!1,error:"Method not allowed"},{status:405});try{await validateDevCsrfRequest(req);const body=await req.json(),file=body.file?.replace(/\.ts$/,"");if(!file||!/^[\w-]+$/.test(file))return Response.json({ok:!1,error:"Invalid file"},{status:400});const updates=[];if(Array.isArray(body.updates))for(const u of body.updates){const k=u.key??u.path;if(typeof k==="string")updates.push({key:k,value:u.value})}else if(body.key)updates.push({key:body.key,value:body.value});if(updates.length===0)return Response.json({ok:!1,error:"No updates supplied"},{status:400});const invalid=updates.find((update)=>!/^[A-Za-z_$][\w$]*$/.test(update.key)||typeof update.value!=="string"&&typeof update.value!=="number"&&typeof update.value!=="boolean"||typeof update.value==="number"&&!Number.isFinite(update.value));if(invalid)return Response.json({ok:!1,error:`Invalid value for configuration key "${invalid.key}"`},{status:400});const typedUpdates=updates;try{await updateConfigKeys(file,typedUpdates)}catch(err){const error=err?.message||"Configuration values could not be updated.",results=typedUpdates.map((update)=>({key:update.key,ok:!1,error}));return Response.json({ok:!1,file,results,error},{status:422})}const results=typedUpdates.map((update)=>({key:update.key,ok:!0,newValue:update.value}));return Response.json({ok:!0,file,results})}catch(e){if(e?.status===403)return Response.json({ok:!1,error:"Forbidden",message:"CSRF token mismatch"},{status:403});return Response.json({ok:!1,error:e?.message},{status:500})}}},router=await import("@stacksjs/router");await router.loadRoutes(await router.appRouteRegistry());const stacksRoute=router.route;serve({root:projectPath("resources"),patterns:[userDashboardPath,dashboardPath],port:dashboardPort,componentsDir:storagePath("framework/defaults/resources/components/Dashboard"),fallbackComponentsDir:resolveComponentsLibraryRoot(),layoutsDir:dashboardPath,partialsDir:dashboardPath,publicDir:publicPath(),renderCache:!0,renderCacheVary:"source",prewarmRenderCache:4,watchDirs:[projectPath("resources/functions"),storagePath("framework/defaults/resources/functions")],quiet:!0,routes:configRoutes,onRequest:async(req)=>{const pathname=new URL(req.url).pathname;if(shouldDelegateDashboardRequest(pathname,req.method))return stacksRoute.handleRequest(req);return null},onResponse:seedCsrfPageResponse,auth:!1,...stxModule&&{stxModule}}).catch((err)=>{restoreConsole();console.error(`
|
|
3
3
|
Failed to start dashboard server: ${err?.message||err}
|
|
4
|
-
`);process.exit(1)})}function portAnswers(port,timeoutMs=800){return new Promise((resolve)=>{const socket=connect({port,host:"127.0.0.1"}),finish=(answered)=>{try{socket.destroy()}catch{}resolve(answered)};socket.once("connect",()=>finish(!0));socket.once("error",()=>finish(!1));setTimeout(()=>finish(!1),timeoutMs).unref?.()})}async function registerWithRpxDaemon(domainToServe){const{writeEntry}=await import("@stacksjs/rpx");await writeEntry({id:`${domainToServe}-dashboard`,from:`localhost:${dashboardPort}`,to:domainToServe,cwd:process.cwd(),createdAt:new Date().toISOString(),pid:process.pid},void 0,verbose);return!0}async function startReverseProxy(){if(!dashboardDomain)return!1;try{let rpx;const loadRpx=async()=>rpx??=await import("@stacksjs/rpx"),strategy=await resolveDashboardProxyStrategy(dashboardDomain,{proxyManagedExternally:Boolean(process.env.STACKS_PROXY_MANAGED),isDaemonRunning:async()=>(await loadRpx()).isDaemonRunning(),httpsPortAnswers:()=>portAnswers(443)});if(strategy==="origin-only")return!1;if(strategy==="parent-managed")return!0;if(strategy==="daemon-route")return await registerWithRpxDaemon(dashboardDomain);await(await loadRpx()).startProxies({proxies:[{from:`localhost:${dashboardPort}`,to:dashboardDomain,cleanUrls:!1}],https:{basePath:sslBasePath,validityDays:825},regenerateUntrustedCerts:!1,verbose});return await portAnswers(443)}catch(error){if(verbose)originalConsoleLog(` ${dim(`Proxy: ${error}`)}`);return!1}}const[,discoveredModels]=await Promise.all([startStxServer(),discoverModels(projectPath("app/Models"),storagePath("framework/defaults/app/Models"))]),{loadDashboardConfig}=await import(storagePath("framework/defaults/resources/functions/dashboard/toggles.ts")),{feature:featureEnabled}=await import("@stacksjs/config"),{toggles:dashboardToggles,nav:dashboardNav}=await loadDashboardConfig(projectPath("config/dashboard.ts"),featureEnabled),manifestPath=storagePath("framework/
|
|
4
|
+
`);process.exit(1)})}function portAnswers(port,timeoutMs=800){return new Promise((resolve)=>{const socket=connect({port,host:"127.0.0.1"}),finish=(answered)=>{try{socket.destroy()}catch{}resolve(answered)};socket.once("connect",()=>finish(!0));socket.once("error",()=>finish(!1));setTimeout(()=>finish(!1),timeoutMs).unref?.()})}async function registerWithRpxDaemon(domainToServe){const{writeEntry}=await import("@stacksjs/rpx");await writeEntry({id:`${domainToServe}-dashboard`,from:`localhost:${dashboardPort}`,to:domainToServe,cwd:process.cwd(),createdAt:new Date().toISOString(),pid:process.pid},void 0,verbose);return!0}async function startReverseProxy(){if(!dashboardDomain)return!1;try{let rpx;const loadRpx=async()=>rpx??=await import("@stacksjs/rpx"),strategy=await resolveDashboardProxyStrategy(dashboardDomain,{proxyManagedExternally:Boolean(process.env.STACKS_PROXY_MANAGED),isDaemonRunning:async()=>(await loadRpx()).isDaemonRunning(),httpsPortAnswers:()=>portAnswers(443)});if(strategy==="origin-only")return!1;if(strategy==="parent-managed")return!0;if(strategy==="daemon-route")return await registerWithRpxDaemon(dashboardDomain);await(await loadRpx()).startProxies({proxies:[{from:`localhost:${dashboardPort}`,to:dashboardDomain,cleanUrls:!1}],https:{basePath:sslBasePath,validityDays:825},regenerateUntrustedCerts:!1,verbose});return await portAnswers(443)}catch(error){if(verbose)originalConsoleLog(` ${dim(`Proxy: ${error}`)}`);return!1}}const[,discoveredModels]=await Promise.all([startStxServer(),discoverModels(projectPath("app/Models"),storagePath("framework/defaults/app/Models"))]),{loadDashboardConfig}=await import(storagePath("framework/defaults/resources/functions/dashboard/toggles.ts")),{feature:featureEnabled}=await import("@stacksjs/config"),{toggles:dashboardToggles,nav:dashboardNav}=await loadDashboardConfig(projectPath("config/dashboard.ts"),featureEnabled),manifestPath=storagePath("framework/runtime/dashboard/discovered-models.json");mkdirSync(dirname(manifestPath),{recursive:!0});const manifestPayload={models:buildManifest(discoveredModels),sections:dashboardToggles,nav:dashboardNav},manifestTempPath=`${manifestPath}.${process.pid}.${randomUUID()}.tmp`;try{writeFileSync(manifestTempPath,JSON.stringify(manifestPayload,null,2),{flag:"wx"});renameSync(manifestTempPath,manifestPath)}finally{if(existsSync(manifestTempPath))unlinkSync(manifestTempPath)}const serverReady=await waitForServer(dashboardPort);restoreConsole();const proxyStarted=await startReverseProxy().catch((err)=>{if(verbose)console.warn("[Dashboard] Reverse proxy failed:",err);return!1}),dashboardHttpsUrl=dashboardDomain?`https://${dashboardDomain}`:null,dashboardLocalUrl=`http://localhost:${dashboardPort}`,initialUrl=dashboardHttpsUrl&&proxyStarted?`${dashboardHttpsUrl}/`:`${dashboardLocalUrl}/`,elapsedMs=(Bun.nanoseconds()-startTime)/1e6;console.log();console.log(` ${bold(cyan("stacks dashboard"))}`);console.log();if(dashboardHttpsUrl&&proxyStarted){console.log(` ${green("\u279C")} ${bold("Local")}: ${cyan(dashboardHttpsUrl)}`);console.log(` ${dim("\u279C")} ${dim("Origin")}: ${dim(dashboardLocalUrl)}`)}else{console.log(` ${green("\u279C")} ${bold("Local")}: ${cyan(dashboardLocalUrl)}`);if(dashboardHttpsUrl)console.log(` ${dim("\u279C")} ${dim("Pretty")}: ${dim(`${dashboardHttpsUrl} needs the rpx proxy - run \`buddy dev\``)}`)}console.log(` ${green("\u279C")} ${bold("Window")}: ${dim("Stacks Dashboard")} ${dim("1400\xD7900")}`);console.log(` ${green("\u279C")} ${bold("Models")}: ${dim(`${discoveredModels.length} discovered`)}`);if(dashboardPort!==preferredPort)console.log(` ${dim("\u279C")} ${dim(`Port ${preferredPort} in use, using ${dashboardPort}`)}`);if(!serverReady)console.log(` ${dim("\u26A0")} ${dim("Dev server may not be ready yet")}`);console.log();console.log(` ${dim(`ready in ${elapsedMs.toFixed(0)} ms`)}`);if(verbose){console.log();console.log(` ${dim("\u279C")} ${dim("URL")}: ${dim(initialUrl)}`);if(dashboardDomain){console.log(` ${dim("\u279C")} ${dim("SSL")}: ${dim(sslBasePath)}`);console.log(` ${dim("\u279C")} ${dim("Proxy")}: ${dim(`localhost:${dashboardPort} \u2192 ${dashboardDomain}`)}`)}if(bufferedLogs.length>0){console.log();for(const line of bufferedLogs)console.log(` ${dim(line)}`)}}console.log();let createApp,resolveCraftBinary;const nativeDisabled=process.env.STACKS_NO_NATIVE==="1",explicitCraftSdk=process.env.CRAFT_SDK_SRC;if(!nativeDisabled&&explicitCraftSdk){if(!existsSync(explicitCraftSdk))throw Error(`CRAFT_SDK_SRC not found: ${explicitCraftSdk}`);try{({createApp,resolveCraftBinary}=await import(explicitCraftSdk));if(!createApp||!resolveCraftBinary)throw Error("CRAFT_SDK_SRC must export createApp and resolveCraftBinary")}catch(error){throw Error(`Could not load CRAFT_SDK_SRC ${explicitCraftSdk}: ${error instanceof Error?error.message:String(error)}`)}}if(!nativeDisabled&&!explicitCraftSdk)try{({createApp,resolveCraftBinary}=await import("craft-native"))}catch{}const craftBinaryPath=createApp&&resolveCraftBinary?resolveDashboardCraftExecutable(resolveCraftBinary):void 0;if(createApp&&craftBinaryPath){const userIconPath=projectPath("resources/assets/images/app-icon.png"),defaultIconPath=storagePath("framework/defaults/resources/assets/images/app-icon.png"),appIconPath=await Bun.file(userIconPath).exists()?userIconPath:await Bun.file(defaultIconPath).exists()?defaultIconPath:void 0,app=createApp({url:dashboardLocalUrl,quiet:!verbose,craftPath:craftBinaryPath,window:{title:"Stacks Dashboard",width:1400,height:900,titlebarHidden:!0,webSidebarMaterial:!0,webSidebarWidth:250,...appIconPath&&{icon:appIconPath}}});process.on("SIGINT",()=>{app.close();process.exit(0)});process.on("SIGTERM",()=>{app.close();process.exit(0)});try{await app.show();process.exit(0)}catch(error){const fallbackUrl=dashboardHttpsUrl||dashboardLocalUrl;console.log(` ${dim("Native Craft window failed:")} ${dim(error instanceof Error?error.message:String(error))}`);console.log(` ${dim("Dashboard available at:")} ${cyan(fallbackUrl)}
|
|
5
5
|
`);await new Promise(()=>{})}}else{console.log(` ${dim(nativeDisabled?"Native window disabled by STACKS_NO_NATIVE=1. Open the URL above in a browser.":"Native window unavailable. Run pantry install craft, set CRAFT_BIN, or open the URL above in a browser.")}
|
|
6
6
|
`);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));await new Promise(()=>{})}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{frameworkPath,join,path,projectPath}from"@stacksjs/path";import{existsSync,globSync,mkdirSync,writeFileSync}from"@stacksjs/storage";import{readFileSync}from"node:fs";let parseMarkdownFn=null;async function getMarkdownParser(){if(parseMarkdownFn)return parseMarkdownFn;try{parseMarkdownFn=(await import("@stacksjs/ts-md")).parseMarkdown}catch{parseMarkdownFn=(s)=>s}return parseMarkdownFn}function renderDescription(raw){if(!raw)return"";return parseMarkdownFn?parseMarkdownFn(raw):raw}export async function generateComponentMeta(){await getMarkdownParser();const components=globSync(["components/*.stx","components/**/*.stx","resources/components/**/*.stx","
|
|
1
|
+
import{frameworkPath,join,path,projectPath}from"@stacksjs/path";import{existsSync,globSync,mkdirSync,writeFileSync}from"@stacksjs/storage";import{readFileSync}from"node:fs";let parseMarkdownFn=null;async function getMarkdownParser(){if(parseMarkdownFn)return parseMarkdownFn;try{parseMarkdownFn=(await import("@stacksjs/ts-md")).parseMarkdown}catch{parseMarkdownFn=(s)=>s}return parseMarkdownFn}function renderDescription(raw){if(!raw)return"";return parseMarkdownFn?parseMarkdownFn(raw):raw}export async function generateComponentMeta(){await getMarkdownParser();const components=[...globSync(["components/*.stx","components/**/*.stx","resources/components/**/*.stx"],{cwd:projectPath(),absolute:!0}),...globSync(["resources/components/**/*.stx"],{cwd:frameworkPath("defaults"),absolute:!0})],metaDirPath=frameworkPath("component-meta");if(!existsSync(metaDirPath))mkdirSync(metaDirPath,{recursive:!0});for(const componentPath of components){const componentExportName=path.parse(componentPath).name,meta=parseStxComponentMeta(componentPath),metaJsonFilePath=join(metaDirPath,`${componentExportName}.json`);writeFileSync(metaJsonFilePath,JSON.stringify(meta,null,2))}}export function parseStxComponentMeta(componentPath){const source=readFileSync(componentPath,"utf8"),scriptBlock=extractFirstScriptBlock(source),templateBlock=extractTemplate(source),props=scriptBlock?extractProps(scriptBlock):[],events=scriptBlock?extractEvents(scriptBlock):[],slots=extractSlots(templateBlock);return{props,events,slots}}function extractFirstScriptBlock(source){const serverMatch=/<script\b[^>]*\bserver\b[^>]*>([\s\S]*?)<\/script>/i.exec(source);if(serverMatch?.[1])return serverMatch[1];return/<script\b[^>]*>([\s\S]*?)<\/script>/i.exec(source)?.[1]??null}function extractTemplate(source){const templateMatch=/<template\b[^>]*>([\s\S]*?)<\/template>/i.exec(source);if(templateMatch?.[1])return templateMatch[1];return source.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi,"")}function extractProps(script){const interfaces=collectInterfaces(script),propsTypeBody=locatePropsType(script,interfaces);if(!propsTypeBody)return[];const fields=parseTypeBody(propsTypeBody,interfaces),defaults=extractDefaults(script);return fields.map((field)=>{return{name:field.required?field.name:`${field.name}?`,description:renderDescription(field.description),type:field.type,default:defaults[field.name]??field.default??"unknown",required:field.required}})}function collectInterfaces(script){const interfaces=new Map,ifaceRe=/(?:export\s+)?interface\s+([A-Z][\w$]*)\s*(?:extends\s+[\w$,\s]+)?\s*\{/g;let m;while((m=ifaceRe.exec(script))!==null){const name=m[1];if(!name)continue;const start=m.index+m[0].length,body=sliceBalanced(script,start-1,"{","}");if(body!==null)interfaces.set(name,body)}const typeAliasRe=/(?:export\s+)?type\s+([A-Z][\w$]*)\s*=\s*\{/g;while((m=typeAliasRe.exec(script))!==null){const name=m[1];if(!name)continue;const start=m.index+m[0].length,body=sliceBalanced(script,start-1,"{","}");if(body!==null)interfaces.set(name,body)}return interfaces}function locatePropsType(script,interfaces){const match=/defineProps\s*<\s*([\s\S]+?)\s*>\s*\(/.exec(script),generic=match?.[1]?.trim();if(!match||!generic)return null;if(generic.startsWith("{")){const braceStart=script.indexOf("{",match.index);return sliceBalanced(script,braceStart,"{","}")}const ref=generic.replace(/[<>(].*$/,"").split("&")[0]?.trim();if(!ref)return null;return interfaces.get(ref)??null}function parseTypeBody(body,interfaces){const fields=[],statements=splitTopLevel(body,[";",`
|
|
2
2
|
`]);let pendingDoc="";for(const raw of statements){const stmt=raw.trim();if(!stmt)continue;const docMatch=/^\/\*\*([\s\S]*?)\*\/\s*([\s\S]*)$/.exec(stmt);if(docMatch){pendingDoc=(docMatch[1]??"").split(`
|
|
3
3
|
`).map((l)=>l.replace(/^\s*\*\s?/,"")).join(`
|
|
4
4
|
`).trim();const remainder=(docMatch[2]??"").trim();if(!remainder)continue;const field=parseFieldLine(remainder,pendingDoc,interfaces);if(field)fields.push(field);pendingDoc="";continue}if(stmt.startsWith("//")){pendingDoc=stmt.replace(/^\/\/\s?/,"");continue}const field=parseFieldLine(stmt,pendingDoc,interfaces);if(field)fields.push(field);pendingDoc=""}return fields}function parseFieldLine(line,description,_interfaces){if(/^[a-zA-Z_$][\w$]*\s*\(/.test(line.trimStart()))return null;const m=/^([a-zA-Z_$][\w$]*)\s*(\??)\s*:\s*([\s\S]+?)\s*[;,]?\s*$/.exec(line);if(!m)return null;const name=m[1],optional=m[2]??"",type=m[3];if(!name||!type)return null;return{name,type:collapseWhitespace(type),required:optional!=="?",description}}function extractDefaults(script){const defaults={},destructRe=/const\s*\{\s*([\s\S]*?)\s*\}\s*=\s*(?:withDefaults\s*\(\s*)?defineProps/g;let m;while((m=destructRe.exec(script))!==null)if(m[1])parseDestructDefaults(m[1],defaults);const withDefaultsIdx=script.indexOf("withDefaults(");if(withDefaultsIdx>=0){const afterDefine=script.indexOf("defineProps",withDefaultsIdx);if(afterDefine>0){const generic=script.indexOf(">",afterDefine),closeParen=script.indexOf(")",generic>=0?generic:afterDefine);if(closeParen>0){const commaIdx=script.indexOf(",",closeParen),objStart=commaIdx>=0?script.indexOf("{",commaIdx):-1;if(objStart>0){const body=sliceBalanced(script,objStart,"{","}");if(body)parseObjectDefaults(body,defaults)}}}}return defaults}function parseDestructDefaults(destructBody,out){for(const part of splitTopLevel(destructBody,[","])){const m=/^\s*([a-zA-Z_$][\w$]*)\s*=\s*([\s\S]+?)\s*$/.exec(part),key=m?.[1],value=m?.[2];if(key&&value)out[key]=collapseWhitespace(value)}}function parseObjectDefaults(objectBody,out){for(const part of splitTopLevel(objectBody,[","])){const m=/^\s*([a-zA-Z_$][\w$]*)\s*:\s*([\s\S]+?)\s*$/.exec(part.trim()),key=m?.[1],value=m?.[2];if(key&&value)out[key]=collapseWhitespace(value)}}function extractEvents(script){const m=/defineEmits\s*<\s*\{([\s\S]*?)\}\s*>\s*\(/.exec(script);if(!m?.[1])return[];const events=[];for(const part of splitTopLevel(m[1],[";",`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{chmodSync,existsSync,lstatSync,mkdirSync,readFileSync,readdirSync,rmSync,statSync,writeFileSync}from"node:fs";import{dirname,join,relative}from"node:path";import{DEFAULTS_SYNC_MARKER,defaultsPackagePath}from"@stacksjs/path";const DEFAULTS_PACKAGE_IGNORES=new Set(["README.md","build.ts","node_modules","package.json","project","tests"]),LOCAL_DEFAULT_IGNORES=new Set([".DS_Store",".discovered-models.json",DEFAULTS_SYNC_MARKER,"dist","node_modules"]),LEGACY_PACKAGE_PROJECT_FILES=["pantry.lock"],SUPPORT_FILES=[{source:"project/buddy",target:"buddy",executable:!0},{source:"project/bootstrap",target:"bootstrap",executable:!0},{source:"project/storage/framework/tsconfig.app.json",target:"storage/framework/tsconfig.app.json"},{source:"project/storage/framework/tsconfig.base.json",target:"storage/framework/tsconfig.base.json"},{source:"project/storage/framework/server/tsconfig.docker.json",target:"storage/framework/server/tsconfig.docker.json"}];export const FRAMEWORK_TYPES_SUPPORT_DIRECTORY={source:"project/storage/framework/types",target:"storage/framework/types"},GENERATED_FRAMEWORK_TYPES=["server-auto-imports.d.ts","browser-auto-imports.d.ts"];function copyDirectoryIfChanged(source,target,projectRoot,changes,options,skip){for(const entry of readdirSync(source)){if(skip.has(entry)||LOCAL_DEFAULT_IGNORES.has(entry))continue;const sourcePath=join(source,entry),targetPath=join(target,entry);if(lstatSync(sourcePath).isDirectory())copyDirectoryIfChanged(sourcePath,targetPath,projectRoot,changes,options,skip);else copyFileIfChanged(sourcePath,targetPath,projectRoot,changes,options)}}function sameFile(left,right,shallow=!1){if(!existsSync(left)||!existsSync(right))return!1;const leftStat=statSync(left),rightStat=statSync(right);if(leftStat.size!==rightStat.size)return!1;if(shallow)return!0;return readFileSync(left).equals(readFileSync(right))}function copyFileIfChanged(source,target,projectRoot,changes,options,executable=!1){if(sameFile(source,target,options.shallow&&options.dryRun)){if(executable&&!options.dryRun)chmodSync(target,493);return}changes.push({path:relative(projectRoot,target),action:existsSync(target)?"update":"add"});if(options.dryRun)return;mkdirSync(dirname(target),{recursive:!0});writeFileSync(target,readFileSync(source));if(executable)chmodSync(target,493)}function syncDirectory(source,target,projectRoot,changes,options,isRoot=!1){if(!options.dryRun)mkdirSync(target,{recursive:!0});const sourceEntries=new Set;for(const entry of readdirSync(source)){if(isRoot&&DEFAULTS_PACKAGE_IGNORES.has(entry))continue;sourceEntries.add(entry);const sourcePath=join(source,entry),targetPath=join(target,entry);if(lstatSync(sourcePath).isDirectory()){syncDirectory(sourcePath,targetPath,projectRoot,changes,options);continue}copyFileIfChanged(sourcePath,targetPath,projectRoot,changes,options)}if(!existsSync(target))return;for(const entry of readdirSync(target)){if(LOCAL_DEFAULT_IGNORES.has(entry)||sourceEntries.has(entry))continue;const targetPath=join(target,entry);changes.push({path:relative(projectRoot,targetPath),action:"remove"});if(!options.dryRun)rmSync(targetPath,{recursive:!0,force:!0})}}export function syncPackageProjectFiles(projectRoot,defaultsPackageRoot,options={}){const changes=[],targetDefaults=join(projectRoot,"storage/framework/defaults");syncDirectory(defaultsPackageRoot,targetDefaults,projectRoot,changes,options,!0);for(const file of SUPPORT_FILES){const source=join(defaultsPackageRoot,file.source);if(!existsSync(source))continue;copyFileIfChanged(source,join(projectRoot,file.target),projectRoot,changes,options,file.executable)}const typesSource=join(defaultsPackageRoot,FRAMEWORK_TYPES_SUPPORT_DIRECTORY.source);if(existsSync(typesSource))copyDirectoryIfChanged(typesSource,join(projectRoot,FRAMEWORK_TYPES_SUPPORT_DIRECTORY.target),projectRoot,changes,options,new Set(GENERATED_FRAMEWORK_TYPES));const bunVersion=shippedBunVersion(defaultsPackageRoot);if(bunVersion)alignBunPins(projectRoot,bunVersion,changes,options);for(const legacyFile of LEGACY_PACKAGE_PROJECT_FILES){const target=join(projectRoot,legacyFile);if(!existsSync(target))continue;changes.push({path:legacyFile,action:"remove"});if(!options.dryRun)rmSync(target,{force:!0})}if(!options.dryRun)stampDefaultsSync(targetDefaults,defaultsPackageRoot);return changes}export const BUN_VERSION_FILE="project/bun-version";function shippedBunVersion(defaultsPackageRoot){try{const version=readFileSync(join(defaultsPackageRoot,BUN_VERSION_FILE),"utf8").trim();return/^\d+\.\d+\.\d+$/.test(version)?version:null}catch{return null}}function olderVersion(candidate,than){const left=candidate.split(".").map(Number),right=than.split(".").map(Number);for(let i=0;i<3;i++)if(left[i]!==right[i])return(left[i]??0)<(right[i]??0);return!1}const VERSION="(\\d+\\.\\d+\\.\\d+)",BUN_PINS=[new RegExp(`^(\\s*BUN_VERSION:\\s*['"]?)${VERSION}`,"gm"),new RegExp(`^(\\s*bun-version:\\s*['"]?)${VERSION}`,"gm"),new RegExp(`((?:^|[\\s'"])bun(?:\\.sh|\\.com)?@)${VERSION}`,"gm"),new RegExp(`(oven/bun:)${VERSION}`,"g"),new RegExp(`^(\\s*ARG\\s+BUN_VERSION=)${VERSION}`,"gm")];export function raiseBunPins(text,version){let next=text;for(const pattern of BUN_PINS)next=next.replace(pattern,(match,prefix,pinned)=>olderVersion(pinned,version)?`${prefix}${version}`:match);return next}function bunPinFiles(projectRoot){const files=[],workflows=join(projectRoot,".github/workflows");if(existsSync(workflows)){for(const entry of readdirSync(workflows))if(/\.ya?ml$/.test(entry))files.push(join(workflows,entry))}for(const entry of readdirSync(projectRoot))if(/^Dockerfile/.test(entry))files.push(join(projectRoot,entry));for(const path of["storage/framework/Dockerfile","storage/framework/server/Dockerfile"])if(existsSync(join(projectRoot,path)))files.push(join(projectRoot,path));return files}export function alignBunPins(projectRoot,version,changes=[],options={}){for(const file of bunPinFiles(projectRoot)){const text=readFileSync(file,"utf8"),next=raiseBunPins(text,version);if(next===text)continue;changes.push({path:relative(projectRoot,file),action:"update"});if(!options.dryRun)writeFileSync(file,next)}return changes}function stampDefaultsSync(targetDefaults,defaultsPackageRoot){const version=manifestVersion(defaultsPackageRoot);if(!version)return;const marker={version,syncedAt:new Date().toISOString()};mkdirSync(targetDefaults,{recursive:!0});writeFileSync(join(targetDefaults,DEFAULTS_SYNC_MARKER),`${JSON.stringify(marker,null,2)}
|
|
1
|
+
import{chmodSync,existsSync,lstatSync,mkdirSync,readFileSync,readdirSync,rmSync,statSync,writeFileSync}from"node:fs";import{dirname,join,relative}from"node:path";import{DEFAULTS_SYNC_MARKER,defaultsPackagePath,usesVendoredDefaults}from"@stacksjs/path";const DEFAULTS_PACKAGE_IGNORES=new Set(["README.md","build.ts","node_modules","package.json","project","tests"]),LOCAL_DEFAULT_IGNORES=new Set([".DS_Store",".discovered-models.json",DEFAULTS_SYNC_MARKER,"dist","node_modules"]),LEGACY_PACKAGE_PROJECT_FILES=["pantry.lock"],SUPPORT_FILES=[{source:"project/buddy",target:"buddy",executable:!0},{source:"project/bootstrap",target:"bootstrap",executable:!0},{source:"project/storage/framework/tsconfig.app.json",target:"storage/framework/tsconfig.app.json"},{source:"project/storage/framework/tsconfig.base.json",target:"storage/framework/tsconfig.base.json"},{source:"project/storage/framework/server/tsconfig.docker.json",target:"storage/framework/server/tsconfig.docker.json"}];export const FRAMEWORK_TYPES_SUPPORT_DIRECTORY={source:"project/storage/framework/types",target:"storage/framework/types"},GENERATED_FRAMEWORK_TYPES=["server-auto-imports.d.ts","browser-auto-imports.d.ts"];function copyDirectoryIfChanged(source,target,projectRoot,changes,options,skip){for(const entry of readdirSync(source)){if(skip.has(entry)||LOCAL_DEFAULT_IGNORES.has(entry))continue;const sourcePath=join(source,entry),targetPath=join(target,entry);if(lstatSync(sourcePath).isDirectory())copyDirectoryIfChanged(sourcePath,targetPath,projectRoot,changes,options,skip);else copyFileIfChanged(sourcePath,targetPath,projectRoot,changes,options)}}function sameFile(left,right,shallow=!1){if(!existsSync(left)||!existsSync(right))return!1;const leftStat=statSync(left),rightStat=statSync(right);if(leftStat.size!==rightStat.size)return!1;if(shallow)return!0;return readFileSync(left).equals(readFileSync(right))}function copyFileIfChanged(source,target,projectRoot,changes,options,executable=!1){if(sameFile(source,target,options.shallow&&options.dryRun)){if(executable&&!options.dryRun)chmodSync(target,493);return}changes.push({path:relative(projectRoot,target),action:existsSync(target)?"update":"add"});if(options.dryRun)return;mkdirSync(dirname(target),{recursive:!0});writeFileSync(target,readFileSync(source));if(executable)chmodSync(target,493)}function syncDirectory(source,target,projectRoot,changes,options,isRoot=!1){if(!options.dryRun)mkdirSync(target,{recursive:!0});const sourceEntries=new Set;for(const entry of readdirSync(source)){if(isRoot&&DEFAULTS_PACKAGE_IGNORES.has(entry))continue;sourceEntries.add(entry);const sourcePath=join(source,entry),targetPath=join(target,entry);if(lstatSync(sourcePath).isDirectory()){syncDirectory(sourcePath,targetPath,projectRoot,changes,options);continue}copyFileIfChanged(sourcePath,targetPath,projectRoot,changes,options)}if(!existsSync(target))return;for(const entry of readdirSync(target)){if(LOCAL_DEFAULT_IGNORES.has(entry)||sourceEntries.has(entry))continue;const targetPath=join(target,entry);changes.push({path:relative(projectRoot,targetPath),action:"remove"});if(!options.dryRun)rmSync(targetPath,{recursive:!0,force:!0})}}export function syncPackageProjectFiles(projectRoot,defaultsPackageRoot,options={}){const changes=[],targetDefaults=join(projectRoot,"storage/framework/defaults"),vendorDefaults=options.vendorDefaults??usesVendoredDefaults(projectRoot);if(vendorDefaults)syncDirectory(defaultsPackageRoot,targetDefaults,projectRoot,changes,options,!0);for(const file of SUPPORT_FILES){const source=join(defaultsPackageRoot,file.source);if(!existsSync(source))continue;copyFileIfChanged(source,join(projectRoot,file.target),projectRoot,changes,options,file.executable)}const typesSource=join(defaultsPackageRoot,FRAMEWORK_TYPES_SUPPORT_DIRECTORY.source);if(existsSync(typesSource))copyDirectoryIfChanged(typesSource,join(projectRoot,FRAMEWORK_TYPES_SUPPORT_DIRECTORY.target),projectRoot,changes,options,new Set(GENERATED_FRAMEWORK_TYPES));const bunVersion=shippedBunVersion(defaultsPackageRoot);if(bunVersion)alignBunPins(projectRoot,bunVersion,changes,options);for(const legacyFile of LEGACY_PACKAGE_PROJECT_FILES){const target=join(projectRoot,legacyFile);if(!existsSync(target))continue;changes.push({path:legacyFile,action:"remove"});if(!options.dryRun)rmSync(target,{force:!0})}if(!options.dryRun&&vendorDefaults)stampDefaultsSync(targetDefaults,defaultsPackageRoot);return changes}export const BUN_VERSION_FILE="project/bun-version";function shippedBunVersion(defaultsPackageRoot){try{const version=readFileSync(join(defaultsPackageRoot,BUN_VERSION_FILE),"utf8").trim();return/^\d+\.\d+\.\d+$/.test(version)?version:null}catch{return null}}function olderVersion(candidate,than){const left=candidate.split(".").map(Number),right=than.split(".").map(Number);for(let i=0;i<3;i++)if(left[i]!==right[i])return(left[i]??0)<(right[i]??0);return!1}const VERSION="(\\d+\\.\\d+\\.\\d+)",BUN_PINS=[new RegExp(`^(\\s*BUN_VERSION:\\s*['"]?)${VERSION}`,"gm"),new RegExp(`^(\\s*bun-version:\\s*['"]?)${VERSION}`,"gm"),new RegExp(`((?:^|[\\s'"])bun(?:\\.sh|\\.com)?@)${VERSION}`,"gm"),new RegExp(`(oven/bun:)${VERSION}`,"g"),new RegExp(`^(\\s*ARG\\s+BUN_VERSION=)${VERSION}`,"gm")];export function raiseBunPins(text,version){let next=text;for(const pattern of BUN_PINS)next=next.replace(pattern,(match,prefix,pinned)=>olderVersion(pinned,version)?`${prefix}${version}`:match);return next}function bunPinFiles(projectRoot){const files=[],workflows=join(projectRoot,".github/workflows");if(existsSync(workflows)){for(const entry of readdirSync(workflows))if(/\.ya?ml$/.test(entry))files.push(join(workflows,entry))}for(const entry of readdirSync(projectRoot))if(/^Dockerfile/.test(entry))files.push(join(projectRoot,entry));for(const path of["storage/framework/Dockerfile","storage/framework/server/Dockerfile"])if(existsSync(join(projectRoot,path)))files.push(join(projectRoot,path));return files}export function alignBunPins(projectRoot,version,changes=[],options={}){for(const file of bunPinFiles(projectRoot)){const text=readFileSync(file,"utf8"),next=raiseBunPins(text,version);if(next===text)continue;changes.push({path:relative(projectRoot,file),action:"update"});if(!options.dryRun)writeFileSync(file,next)}return changes}function stampDefaultsSync(targetDefaults,defaultsPackageRoot){const version=manifestVersion(defaultsPackageRoot);if(!version)return;const marker={version,syncedAt:new Date().toISOString()};mkdirSync(targetDefaults,{recursive:!0});writeFileSync(join(targetDefaults,DEFAULTS_SYNC_MARKER),`${JSON.stringify(marker,null,2)}
|
|
2
2
|
`)}function manifestVersion(packageRoot){try{const version=JSON.parse(readFileSync(join(packageRoot,"package.json"),"utf8"))?.version;return typeof version==="string"?version:null}catch{return null}}export function measureDefaultsDrift(projectRoot,options={}){const packageRoot=defaultsPackagePath(projectRoot);if(!existsSync(join(packageRoot,"package.json")))return null;return syncPackageProjectFiles(projectRoot,packageRoot,{dryRun:!0,shallow:options.shallow})}export function summarizeStructureChanges(changes){const added=changes.filter((change)=>change.action==="add").length,updated=changes.filter((change)=>change.action==="update").length,removed=changes.filter((change)=>change.action==="remove").length;return`+${added} ~${updated} -${removed}`}export function migratePackageProjectManifest(pkg){const changes=[],scripts=pkg.scripts??{},setScript=(name,value)=>{if(scripts[name]===value)return;scripts[name]=value;changes.push({path:`package.json#scripts.${name}`,action:"update"})};setScript("buddy","./buddy");setScript("typecheck","bun x --bun tsc --noEmit -p tsconfig.json --pretty false");setScript("typecheck:app","bun x --bun tsc --noEmit -p tsconfig.json --pretty false");setScript("types:check","bun x --bun tsc --noEmit -p tsconfig.json --pretty false");if(scripts["build:reset"]?.includes("storage/framework"))setScript("build:reset","rm -rf node_modules pantry.lock && bun install && ./buddy generate:types && ./buddy lint:fix");if(scripts["build:framework-types"]){delete scripts["build:framework-types"];changes.push({path:"package.json#scripts.build:framework-types",action:"remove"})}pkg.scripts=scripts;if(Array.isArray(pkg.workspaces)){const next=pkg.workspaces.filter((workspace)=>workspace!=="storage/framework/core"&&!workspace.startsWith("storage/framework/core/"));if(next.length!==pkg.workspaces.length){pkg.workspaces=next;changes.push({path:"package.json#workspaces",action:"update"})}}return changes}export function migratePackageProjectTsconfig(projectRoot,options={}){const path=join(projectRoot,"tsconfig.json");if(!existsSync(path))return[];const raw=readFileSync(path,"utf8"),next=raw.replace(/"extends"\s*:\s*"\.\/storage\/framework\/core\/tsconfig\.json"/,'"extends": "./storage/framework/tsconfig.app.json"');if(next===raw)return[];if(!options.dryRun)writeFileSync(path,next);return[{path:"tsconfig.json",action:"update"}]}export function detectProjectAiProviders(projectRoot){const providers=new Set(["codex"]);if(existsSync(join(projectRoot,"CLAUDE.md"))||existsSync(join(projectRoot,".claude")))providers.add("claude");if(existsSync(join(projectRoot,".cursor")))providers.add("cursor");if(existsSync(join(projectRoot,".github/copilot-instructions.md")))providers.add("copilot");if(existsSync(join(projectRoot,"GEMINI.md")))providers.add("gemini");return[...providers]}
|
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.
|
|
5
|
+
"version": "0.75.246",
|
|
6
6
|
"description": "The Stacks actions.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -66,55 +66,55 @@
|
|
|
66
66
|
"prepublishOnly": "bun run build"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@stacksjs/action-runner": "0.75.
|
|
70
|
-
"@stacksjs/ai": "0.75.
|
|
71
|
-
"@stacksjs/analytics": "0.75.
|
|
72
|
-
"@stacksjs/api": "0.75.
|
|
73
|
-
"@stacksjs/auth": "0.75.
|
|
74
|
-
"@stacksjs/build": "0.75.
|
|
69
|
+
"@stacksjs/action-runner": "0.75.246",
|
|
70
|
+
"@stacksjs/ai": "0.75.246",
|
|
71
|
+
"@stacksjs/analytics": "0.75.246",
|
|
72
|
+
"@stacksjs/api": "0.75.246",
|
|
73
|
+
"@stacksjs/auth": "0.75.246",
|
|
74
|
+
"@stacksjs/build": "0.75.246",
|
|
75
75
|
"@stacksjs/bumpx": "^0.2.25",
|
|
76
76
|
"@stacksjs/bunpress": "^0.2.15",
|
|
77
|
-
"@stacksjs/cli": "0.75.
|
|
78
|
-
"@stacksjs/cloud": "0.75.
|
|
79
|
-
"@stacksjs/cms": "0.75.
|
|
77
|
+
"@stacksjs/cli": "0.75.246",
|
|
78
|
+
"@stacksjs/cloud": "0.75.246",
|
|
79
|
+
"@stacksjs/cms": "0.75.246",
|
|
80
80
|
"@stacksjs/components": "^0.2.604",
|
|
81
|
-
"@stacksjs/config": "0.75.
|
|
82
|
-
"@stacksjs/database": "0.75.
|
|
83
|
-
"@stacksjs/desktop-build": "0.75.
|
|
84
|
-
"@stacksjs/dns": "0.75.
|
|
85
|
-
"@stacksjs/enums": "0.75.
|
|
86
|
-
"@stacksjs/env": "0.75.
|
|
87
|
-
"@stacksjs/error-handling": "0.75.
|
|
88
|
-
"@stacksjs/github": "0.75.
|
|
81
|
+
"@stacksjs/config": "0.75.246",
|
|
82
|
+
"@stacksjs/database": "0.75.246",
|
|
83
|
+
"@stacksjs/desktop-build": "0.75.246",
|
|
84
|
+
"@stacksjs/dns": "0.75.246",
|
|
85
|
+
"@stacksjs/enums": "0.75.246",
|
|
86
|
+
"@stacksjs/env": "0.75.246",
|
|
87
|
+
"@stacksjs/error-handling": "0.75.246",
|
|
88
|
+
"@stacksjs/github": "0.75.246",
|
|
89
89
|
"@stacksjs/gitit": "^0.2.5",
|
|
90
|
-
"@stacksjs/i18n": "0.75.
|
|
91
|
-
"@stacksjs/image": "0.75.
|
|
92
|
-
"@stacksjs/logging": "0.75.
|
|
90
|
+
"@stacksjs/i18n": "0.75.246",
|
|
91
|
+
"@stacksjs/image": "0.75.246",
|
|
92
|
+
"@stacksjs/logging": "0.75.246",
|
|
93
93
|
"@stacksjs/logsmith": "^0.2.11",
|
|
94
|
-
"@stacksjs/mobile": "0.75.
|
|
95
|
-
"@stacksjs/orm": "0.75.
|
|
96
|
-
"@stacksjs/path": "0.75.
|
|
97
|
-
"@stacksjs/payments": "0.75.
|
|
98
|
-
"@stacksjs/queue": "0.75.
|
|
99
|
-
"@stacksjs/registry": "0.75.
|
|
100
|
-
"@stacksjs/router": "0.75.
|
|
94
|
+
"@stacksjs/mobile": "0.75.246",
|
|
95
|
+
"@stacksjs/orm": "0.75.246",
|
|
96
|
+
"@stacksjs/path": "0.75.246",
|
|
97
|
+
"@stacksjs/payments": "0.75.246",
|
|
98
|
+
"@stacksjs/queue": "0.75.246",
|
|
99
|
+
"@stacksjs/registry": "0.75.246",
|
|
100
|
+
"@stacksjs/router": "0.75.246",
|
|
101
101
|
"@stacksjs/rpx": "^0.11.54",
|
|
102
|
-
"@stacksjs/scheduler": "0.75.
|
|
103
|
-
"@stacksjs/search-engine": "0.75.
|
|
104
|
-
"@stacksjs/security": "0.75.
|
|
105
|
-
"@stacksjs/server": "0.75.
|
|
106
|
-
"@stacksjs/sites": "0.75.
|
|
107
|
-
"@stacksjs/storage": "0.75.
|
|
108
|
-
"@stacksjs/strings": "0.75.
|
|
109
|
-
"@stacksjs/stx": "^0.2.
|
|
102
|
+
"@stacksjs/scheduler": "0.75.246",
|
|
103
|
+
"@stacksjs/search-engine": "0.75.246",
|
|
104
|
+
"@stacksjs/security": "0.75.246",
|
|
105
|
+
"@stacksjs/server": "0.75.246",
|
|
106
|
+
"@stacksjs/sites": "0.75.246",
|
|
107
|
+
"@stacksjs/storage": "0.75.246",
|
|
108
|
+
"@stacksjs/strings": "0.75.246",
|
|
109
|
+
"@stacksjs/stx": "^0.2.607",
|
|
110
110
|
"@stacksjs/tlsx": "^0.13.19",
|
|
111
111
|
"@stacksjs/ts-cloud": "^0.16.58",
|
|
112
112
|
"@stacksjs/ts-md": "^0.1.1",
|
|
113
|
-
"@stacksjs/tunnel": "0.75.
|
|
114
|
-
"@stacksjs/types": "0.75.
|
|
115
|
-
"@stacksjs/utils": "0.75.
|
|
116
|
-
"@stacksjs/whois": "0.75.
|
|
117
|
-
"bun-plugin-stx": "^0.2.
|
|
113
|
+
"@stacksjs/tunnel": "0.75.246",
|
|
114
|
+
"@stacksjs/types": "0.75.246",
|
|
115
|
+
"@stacksjs/utils": "0.75.246",
|
|
116
|
+
"@stacksjs/whois": "0.75.246",
|
|
117
|
+
"bun-plugin-stx": "^0.2.607"
|
|
118
118
|
},
|
|
119
119
|
"peerDependencies": {
|
|
120
120
|
"craft-native": ">=0.0.250",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
|
-
"@stacksjs/validation": "0.75.
|
|
132
|
+
"@stacksjs/validation": "0.75.246",
|
|
133
133
|
"better-dx": "^0.2.24"
|
|
134
134
|
}
|
|
135
135
|
}
|