@stacksjs/actions 0.74.27 → 0.74.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bump.js +3 -3
- package/dist/dev/api.js +1 -1
- package/dist/dev/views.js +1 -1
- package/dist/discover-packages.d.ts +20 -0
- package/dist/discover-packages.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/serve/api.js +1 -1
- package/package.json +40 -40
package/dist/bump.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{execSync,log,parseOptions}from"@stacksjs/cli";import{path as p}from"@stacksjs/path";import{versionBump}from"@stacksjs/bumpx";import{generateChangelog,loadLogsmithConfig}from"@stacksjs/logsmith";import{existsSync,readdirSync,readFileSync,unlinkSync,writeFileSync}from"node:fs";import{join,relative}from"node:path";const options=parseOptions(),allowedBumps=new Set(["patch","minor","major","prepatch","preminor","premajor","prerelease"]),rawBump=options?.bump?.toString(),bumpArg=rawBump?allowedBumps.has(rawBump)||/^\d+\.\d+\.\d+(?:-[\w.]+)?$/.test(rawBump)?rawBump:null:null;if(rawBump&&!bumpArg)log.warn(`Ignoring invalid --bump "${rawBump}"; expected one of patch|minor|major or x.y.z`);const isDryRun=options?.dryRun===!0,isVerbose=options?.verbose===!0;async function readPackage(file){if(!existsSync(file))return;return await Bun.file(file).json()}const rootManifest=p.projectPath("package.json"),rootPkg=await readPackage(rootManifest),isFrameworkRelease=rootPkg?.name==="stacks"&&existsSync(p.frameworkPath("core/package.json")),bumpCwd=isFrameworkRelease?p.frameworkPath("core"):p.projectPath(),primaryManifest=isFrameworkRelease?p.frameworkPath("core/package.json"):rootManifest;async function resolveBumpArg(bump){if(!bump||/^\d+\.\d+\.\d+(?:-[\w.]+)?$/.test(bump))return bump;if(!["patch","minor","major"].includes(bump))return bump;const match=(await readPackage(primaryManifest))?.version?.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!match)return bump;const major=Number(match[1]),minor=Number(match[2]),patch=Number(match[3]);if(bump==="major")return`${major+1}.0.0`;if(bump==="minor")return`${major}.${minor+1}.0`;return`${major}.${minor}.${patch+1}`}const resolvedBumpArg=await resolveBumpArg(bumpArg);async function git(args,cwd=p.projectPath(),options={}){return await execSync(["git",...args],{cwd,stdin:"inherit",stderr:"pipe",throwOnError:options.throwOnError??!0})}async function readVersion(file){const pkg=await readPackage(file);if(!pkg?.version||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(pkg.version))throw Error(`Invalid version in ${file}: ${pkg?.version??"<missing>"}`);return pkg.version}function lockfileVersion(contents){const match=contents.match(/"lockfileVersion"\s*:\s*(\d+)/);return match?Number(match[1]):null}async function packageFilesFor(pattern,cwd){const glob=new Bun.Glob(pattern),files=[];for await(const file of glob.scan({cwd,absolute:!0,onlyFiles:!0})){if(file.includes("/node_modules/")||file.includes("/dist/")||file.includes("/pantry/"))continue;files.push(`./${relative(bumpCwd,file)}`)}return files}async function existingPackageFiles(files){const existing=[];for(const file of files){const absolutePath=join(bumpCwd,file);if(await Bun.file(absolutePath).exists())existing.push(file)}return existing}async function frameworkBumpFiles(){return Array.from(new Set([...await packageFilesFor("package.json",bumpCwd),...await packageFilesFor("*/package.json",bumpCwd),...await packageFilesFor("*/*/package.json",bumpCwd),...await existingPackageFiles(["../package.json","../defaults/ide/vscode/package.json","../api/package.json","../cloud/package.json","../docs/package.json","../orm/package.json","../server/package.json"]),...await packageFilesFor("../libs/**/package.json",bumpCwd)]))}const bumpFiles=isFrameworkRelease?await frameworkBumpFiles():["./package.json"];log.debug(`Release mode: ${isFrameworkRelease?"framework monorepo":"consumer app"} (${rootPkg?.name??"unknown"})`);log.debug(`Bumping ${bumpFiles.length} package manifest(s) in ${bumpCwd}`);await versionBump({release:resolvedBumpArg??void 0,files:bumpFiles,cwd:bumpCwd,recursive:!1,commit:!1,tag:!1,push:!1,changelog:!1,noGitCheck:!0,dryRun:isDryRun,yes:Boolean(resolvedBumpArg),verbose:isVerbose});const nextVersion=isDryRun&&resolvedBumpArg&&/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(resolvedBumpArg)?resolvedBumpArg:await readVersion(primaryManifest),latestTag=(await git(["describe","--abbrev=0","--tags"],p.projectPath(),{throwOnError:!1}).catch(()=>"")).trim();async function writeChangelog(){const config=await loadLogsmithConfig({dir:p.projectPath(),from:latestTag||void 0,to:"HEAD",output:isDryRun?!1:"CHANGELOG.md",theme:"github",verbose:isVerbose}),result=await generateChangelog(config);if(isDryRun){log.info(result.content);return}const changelogPath=p.projectPath("CHANGELOG.md");if(!existsSync(changelogPath))return;let content=readFileSync(changelogPath,"utf-8");const versionSeen=new RegExp(`\\bv?${nextVersion.replace(/\./g,"\\.")}\\b`);if(/\/compare\/[^)\s]+\.\.\.HEAD\)/.test(content))content=content.replace(/(\/compare\/[^)\s]+\.\.\.)HEAD(\))/,`$1v${nextVersion}$2`);else if(!versionSeen.test(content.split(`
|
|
1
|
+
import{execSync,log,parseOptions}from"@stacksjs/cli";import{path as p}from"@stacksjs/path";import{versionBump}from"@stacksjs/bumpx";import{generateChangelog,loadLogsmithConfig}from"@stacksjs/logsmith";import{existsSync,readdirSync,readFileSync,unlinkSync,writeFileSync}from"node:fs";import{join,relative}from"node:path";const options=parseOptions(),allowedBumps=new Set(["patch","minor","major","prepatch","preminor","premajor","prerelease"]),rawBump=options?.bump?.toString(),bumpArg=rawBump?allowedBumps.has(rawBump)||/^\d+\.\d+\.\d+(?:-[\w.]+)?$/.test(rawBump)?rawBump:null:null;if(rawBump&&!bumpArg)log.warn(`Ignoring invalid --bump "${rawBump}"; expected one of patch|minor|major or x.y.z`);const isDryRun=options?.dryRun===!0,isVerbose=options?.verbose===!0;async function readPackage(file){if(!existsSync(file))return;return await Bun.file(file).json()}const rootManifest=p.projectPath("package.json"),rootPkg=await readPackage(rootManifest),isFrameworkRelease=rootPkg?.name==="stacks"&&existsSync(p.frameworkPath("core/package.json")),bumpCwd=isFrameworkRelease?p.frameworkPath("core"):p.projectPath(),primaryManifest=isFrameworkRelease?p.frameworkPath("core/package.json"):rootManifest;async function resolveBumpArg(bump){if(!bump||/^\d+\.\d+\.\d+(?:-[\w.]+)?$/.test(bump))return bump;if(!["patch","minor","major"].includes(bump))return bump;const match=(await readPackage(primaryManifest))?.version?.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!match)return bump;const major=Number(match[1]),minor=Number(match[2]),patch=Number(match[3]);if(bump==="major")return`${major+1}.0.0`;if(bump==="minor")return`${major}.${minor+1}.0`;return`${major}.${minor}.${patch+1}`}const resolvedBumpArg=await resolveBumpArg(bumpArg);async function git(args,cwd=p.projectPath(),options={}){return await execSync(["git",...args],{cwd,stdin:"inherit",stderr:"pipe",throwOnError:options.throwOnError??!0})}async function isGitIgnored(file){return(await git(["check-ignore","--",file],p.projectPath(),{throwOnError:!1})).trim().length>0}async function readVersion(file){const pkg=await readPackage(file);if(!pkg?.version||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(pkg.version))throw Error(`Invalid version in ${file}: ${pkg?.version??"<missing>"}`);return pkg.version}function lockfileVersion(contents){const match=contents.match(/"lockfileVersion"\s*:\s*(\d+)/);return match?Number(match[1]):null}async function packageFilesFor(pattern,cwd){const glob=new Bun.Glob(pattern),files=[];for await(const file of glob.scan({cwd,absolute:!0,onlyFiles:!0})){if(file.includes("/node_modules/")||file.includes("/dist/")||file.includes("/pantry/"))continue;files.push(`./${relative(bumpCwd,file)}`)}return files}async function existingPackageFiles(files){const existing=[];for(const file of files){const absolutePath=join(bumpCwd,file);if(await Bun.file(absolutePath).exists())existing.push(file)}return existing}async function frameworkBumpFiles(){return Array.from(new Set([...await packageFilesFor("package.json",bumpCwd),...await packageFilesFor("*/package.json",bumpCwd),...await packageFilesFor("*/*/package.json",bumpCwd),...await existingPackageFiles(["../package.json","../defaults/ide/vscode/package.json","../api/package.json","../cloud/package.json","../docs/package.json","../orm/package.json","../server/package.json"]),...await packageFilesFor("../libs/**/package.json",bumpCwd)]))}const bumpFiles=isFrameworkRelease?await frameworkBumpFiles():["./package.json"];log.debug(`Release mode: ${isFrameworkRelease?"framework monorepo":"consumer app"} (${rootPkg?.name??"unknown"})`);log.debug(`Bumping ${bumpFiles.length} package manifest(s) in ${bumpCwd}`);await versionBump({release:resolvedBumpArg??void 0,files:bumpFiles,cwd:bumpCwd,recursive:!1,commit:!1,tag:!1,push:!1,changelog:!1,noGitCheck:!0,dryRun:isDryRun,yes:Boolean(resolvedBumpArg),verbose:isVerbose});const nextVersion=isDryRun&&resolvedBumpArg&&/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(resolvedBumpArg)?resolvedBumpArg:await readVersion(primaryManifest),latestTag=(await git(["describe","--abbrev=0","--tags"],p.projectPath(),{throwOnError:!1}).catch(()=>"")).trim();async function writeChangelog(){const config=await loadLogsmithConfig({dir:p.projectPath(),from:latestTag||void 0,to:"HEAD",output:isDryRun?!1:"CHANGELOG.md",theme:"github",verbose:isVerbose}),result=await generateChangelog(config);if(isDryRun){log.info(result.content);return}const changelogPath=p.projectPath("CHANGELOG.md");if(!existsSync(changelogPath))return;let content=readFileSync(changelogPath,"utf-8");const versionSeen=new RegExp(`\\bv?${nextVersion.replace(/\./g,"\\.")}\\b`);if(/\/compare\/[^)\s]+\.\.\.HEAD\)/.test(content))content=content.replace(/(\/compare\/[^)\s]+\.\.\.)HEAD(\))/,`$1v${nextVersion}$2`);else if(!versionSeen.test(content.split(`
|
|
2
2
|
`).slice(0,4).join(`
|
|
3
3
|
`)))content=content.replace(/^(#\s.*\n+)?/,(match)=>`${match??""}## v${nextVersion}
|
|
4
4
|
|
|
5
|
-
`);writeFileSync(changelogPath,content)}await writeChangelog();if(!isDryRun&&isFrameworkRelease)pinLockstepDeps(nextVersion);async function refreshPantryLock(){const lockPath=p.projectPath("pantry.lock");if(!existsSync(lockPath))return;const previousLock=readFileSync(lockPath);try{await execSync(["pantry","install","--ignore-scripts","--quiet"],{cwd:p.projectPath(),stdin:"inherit"});if(!existsSync(lockPath))throw Error("Pantry completed without writing pantry.lock")}catch(error){writeFileSync(lockPath,previousLock);throw Error("Release aborted: Pantry could not refresh pantry.lock without lifecycle scripts. The previous lockfile was restored.",{cause:error})}}if(!isDryRun)await refreshPantryLock();if(!isDryRun&&existsSync(p.projectPath("bun.lock"))){const lockPath=p.projectPath("bun.lock"),previousLock=readFileSync(lockPath);unlinkSync(lockPath);try{await execSync(["bun","install","--lockfile-only"],{cwd:p.projectPath(),stdin:"inherit"})}catch(error){writeFileSync(lockPath,previousLock);throw error}if(!existsSync(lockPath)){writeFileSync(lockPath,previousLock);throw Error("Release aborted: `bun install --lockfile-only` wrote no lockfile, so the previous one has been restored. This usually means a dependency range this bump just raised names a version that is not published yet - release that package first, then re-run.")}const expectedLockfileVersion=lockfileVersion(previousLock.toString("utf8")),regeneratedLock=readFileSync(lockPath,"utf8"),producedVersion=lockfileVersion(regeneratedLock);if(expectedLockfileVersion==null||producedVersion!==expectedLockfileVersion){writeFileSync(lockPath,previousLock);
|
|
6
|
-
`)}if(pinned>0)log.debug(`Pinned ${pinned} lockstep core dep(s) to ^${version}`)}async function stageReleaseArtifacts(){const pathspecs=isFrameworkRelease?[":(glob)storage/framework/**/package.json","package.json"]:["package.json"];for(const file of["CHANGELOG.md","bun.lock","pantry.lock"])if(existsSync(p.projectPath(file)))pathspecs.push(file)
|
|
5
|
+
`);writeFileSync(changelogPath,content)}await writeChangelog();if(!isDryRun&&isFrameworkRelease)pinLockstepDeps(nextVersion);async function refreshPantryLock(){const lockPath=p.projectPath("pantry.lock");if(!existsSync(lockPath))return;const previousLock=readFileSync(lockPath);try{await execSync(["pantry","install","--ignore-scripts","--quiet"],{cwd:p.projectPath(),stdin:"inherit"});if(!existsSync(lockPath))throw Error("Pantry completed without writing pantry.lock")}catch(error){writeFileSync(lockPath,previousLock);throw Error("Release aborted: Pantry could not refresh pantry.lock without lifecycle scripts. The previous lockfile was restored.",{cause:error})}}if(!isDryRun)await refreshPantryLock();if(!isDryRun&&existsSync(p.projectPath("bun.lock"))){const lockPath=p.projectPath("bun.lock"),previousLock=readFileSync(lockPath);unlinkSync(lockPath);try{await execSync(["bun","install","--lockfile-only"],{cwd:p.projectPath(),stdin:"inherit"})}catch(error){writeFileSync(lockPath,previousLock);throw error}if(!existsSync(lockPath)){writeFileSync(lockPath,previousLock);throw Error("Release aborted: `bun install --lockfile-only` wrote no lockfile, so the previous one has been restored. This usually means a dependency range this bump just raised names a version that is not published yet - release that package first, then re-run.")}const expectedLockfileVersion=lockfileVersion(previousLock.toString("utf8")),regeneratedLock=readFileSync(lockPath,"utf8"),producedVersion=lockfileVersion(regeneratedLock);if(expectedLockfileVersion==null||producedVersion!==expectedLockfileVersion){writeFileSync(lockPath,previousLock);const remedy=producedVersion!=null&&expectedLockfileVersion!=null&&producedVersion>expectedLockfileVersion?"the committed lockfile predates the Bun this repository declares. Regenerate it once with that toolchain (`bun install --lockfile-only`) and commit the result as its own change, then re-run the release.":"this machine's Bun is older than the one that wrote the committed lockfile. Re-run the release with the repository's declared Bun toolchain through `pantry install`.";throw Error(`Release aborted: regenerating bun.lock produced lockfileVersion ${producedVersion??"unknown"}, but the committed one is v${expectedLockfileVersion??"unknown"} \u2014 ${remedy}`)}}function lockstepPackages(version){const names=new Set;for(const entry of readdirSync(p.frameworkPath("core"),{withFileTypes:!0})){if(!entry.isDirectory())continue;const manifest=p.frameworkPath(`core/${entry.name}/package.json`);if(!existsSync(manifest))continue;const pkg=JSON.parse(readFileSync(manifest,"utf-8"));if(pkg.name?.startsWith("@stacksjs/")&&pkg.version===version)names.add(pkg.name)}return names}function pinLockstepDeps(version){const lockstep=lockstepPackages(version),next=`^${version}`,manifests=[p.frameworkPath("core/package.json"),...readdirSync(p.frameworkPath("core"),{withFileTypes:!0}).filter((entry)=>entry.isDirectory()).map((entry)=>p.frameworkPath(`core/${entry.name}/package.json`)).filter((path)=>existsSync(path))];let pinned=0;for(const manifestPath of manifests){const manifest=JSON.parse(readFileSync(manifestPath,"utf-8"));let changed=!1;for(const field of["dependencies","devDependencies"]){const deps=manifest[field];if(!deps)continue;for(const name of Object.keys(deps)){if(!lockstep.has(name)||deps[name].startsWith("workspace:")||deps[name]===next)continue;deps[name]=next;changed=!0;pinned++}}if(changed)writeFileSync(manifestPath,`${JSON.stringify(manifest,null,2)}
|
|
6
|
+
`)}if(pinned>0)log.debug(`Pinned ${pinned} lockstep core dep(s) to ^${version}`)}async function stageReleaseArtifacts(){const pathspecs=isFrameworkRelease?[":(glob)storage/framework/**/package.json","package.json"]:["package.json"];for(const file of["CHANGELOG.md","bun.lock","pantry.lock"]){if(!existsSync(p.projectPath(file)))continue;if(await isGitIgnored(file))continue;pathspecs.push(file)}await git(["add","--",...pathspecs]);const leftover=(await git(["status","--porcelain"])).split(`
|
|
7
7
|
`).map((line)=>line.trimEnd()).filter((line)=>line&&!line.startsWith("A ")&&!line.startsWith("M "));if(leftover.length)log.warn(`Kept ${leftover.length} change(s) out of the release commit:
|
|
8
8
|
${leftover.slice(0,20).join(`
|
|
9
9
|
`)}${leftover.length>20?`
|
package/dist/dev/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync}from"node:fs";import process from"node:process";import{parseOptions}from"@stacksjs/cli";import{config,overridesReady}from"@stacksjs/config";import{path}from"@stacksjs/path";import{disableViewRouting,route}from"@stacksjs/router";import{autoImportsAreStale,generateAutoImportFiles,generateServerAutoImportTypes,injectGlobalAutoImports}from"@stacksjs/server";import{resolveApiHost}from"../helpers/api-host";import{exitWithParent}from"./exit-with-parent";const _options=parseOptions();exitWithParent();await generateServerAutoImportTypes();await overridesReady;const port=Number(process.env.PORT_API)||config.ports?.api||3008,hostname=resolveApiHost()
|
|
1
|
+
import{existsSync}from"node:fs";import process from"node:process";import{parseOptions}from"@stacksjs/cli";import{config,overridesReady}from"@stacksjs/config";import{path}from"@stacksjs/path";import{disableViewRouting,route}from"@stacksjs/router";import{autoImportsAreStale,generateAutoImportFiles,generateServerAutoImportTypes,injectGlobalAutoImports}from"@stacksjs/server";import{resolveApiHost}from"../helpers/api-host";import{exitWithParent}from"./exit-with-parent";const _options=parseOptions();exitWithParent();await generateServerAutoImportTypes();await overridesReady;const port=Number(process.env.PORT_API)||config.ports?.api||3008,hostname=resolveApiHost();try{const{discoverPackages}=await import("../discover-packages");await discoverPackages()}catch{}const modelsIndex=path.storagePath("framework/auto-imports/models.ts");if(!existsSync(modelsIndex)||autoImportsAreStale())await generateAutoImportFiles();await injectGlobalAutoImports();try{const typesenseDev=path.appPath("Lib/typesense-dev.ts");if(existsSync(typesenseDev)){const mod=await import(typesenseDev);if(typeof mod.ensureTypesenseRunning==="function")await mod.ensureTypesenseRunning()}}catch(err){const{log}=await import("@stacksjs/cli");log.warn(`[api:dev] search engine bootstrap skipped: ${err.message}`)}try{const listenerPath=path.appPath("Listener.ts");if(existsSync(listenerPath)){const listener=await import(listenerPath);if(typeof listener.handleEvents==="function")await listener.handleEvents()}}catch(err){const{log}=await import("@stacksjs/cli");log.warn(`[api:dev] failed to bootstrap event listeners - dispatched events will be ignored: ${err.message}`)}try{const{startModelMigrationWatcher}=await import("./migrate-watcher");startModelMigrationWatcher()}catch(err){const{log}=await import("@stacksjs/cli");log.debug(`[api:dev] auto-migrate watcher not started: ${err.message}`)}function resolveDefaultsCorsPath(){const published=path.appPath("Middleware/Cors.ts");if(existsSync(published))return published;const vendored=path.frameworkPath("defaults/app/Middleware/Cors.ts");if(existsSync(vendored))return vendored;try{return`${Bun.resolveSync("@stacksjs/defaults/package.json",process.cwd()).replace(/package\.json$/,"")}app/Middleware/Cors.ts`}catch{return vendored}}const corsMod=await import(resolveDefaultsCorsPath()),corsMiddleware=corsMod.default;route.use(corsMiddleware.toRouterHandler());const SAFE_REQUEST_ID=/^[a-zA-Z0-9._-]{8,128}$/;route.use(async(request,next)=>{const inbound=request?.headers?.get?.("x-request-id")||request?.headers?.get?.("X-Request-ID")||"",id=typeof inbound==="string"&&SAFE_REQUEST_ID.test(inbound)?inbound:crypto.randomUUID();request._requestId=id;request._startNs=process.hrtime.bigint();const response=await next();if(response&&response.status===404&&(response.headers.get("content-type")||"").includes("json"))try{const body=await response.clone().json();if(body&&(body.message==="Not Found"||body.error==="Not Found")){const url=new URL(request.url),enriched={...body,path:url.pathname,method:request.method,request_id:id},headers=new Headers(response.headers);headers.set("X-Request-ID",id);return new Response(JSON.stringify(enriched),{status:404,headers})}}catch{}return response});await route.importRoutes();disableViewRouting(route.bunRouter);try{await route.serve({port,hostname});console.log(`
|
|
2
2
|
\u279C API server ready: http://${hostname}:${port}
|
|
3
3
|
`)}catch(err){if((err?.code||err?.errno)==="EADDRINUSE"||String(err?.message||"").includes("EADDRINUSE")){console.error(`
|
|
4
4
|
[dev/api] Port ${port} is already in use. Kill the other process and re-run \`./buddy dev\`, or set PORT_API to another port.
|
package/dist/dev/views.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AsyncLocalStorage}from"node:async_hooks";import{existsSync}from"node:fs";import{join}from"node:path";import{config,installRequestContext,overridesReady,parseCookieHeader,resolveViewPatterns}from"@stacksjs/config";import{log}from"@stacksjs/logging";import{projectPath,siteConfigPath}from"@stacksjs/path";import{seedCsrfPageResponse}from"./csrf";import{resolveDefaultsResources}from"./defaults-resources";import{exitWithParent}from"./exit-with-parent";const requestStore=new AsyncLocalStorage;function currentRequestContext(){return requestStore.getStore()??globalThis.__stxServeContext}installRequestContext(currentRequestContext);exitWithParent();const projectServe=projectPath("serve.ts");try{if(await Bun.file(projectServe).exists())await import(projectServe);else await startDefaultServer()}catch{await startDefaultServer()}function parseCookies(req){return parseCookieHeader(req.headers.get("cookie"))}async function startDefaultServer(){await overridesReady;const{applyViewSecurityHeaders,describeApiProxyRules,describeRedirectRules,injectGlobalAutoImports,isApiBoundRequest,proxyToBackend,resolveApiProxyRules,resolveEmbeddableRules,resolveRedirect,resolveRedirectRules}=await import("@stacksjs/server"),{applyRequestLocale}=await import("@stacksjs/i18n");await injectGlobalAutoImports();const{serve}=await import("bun-plugin-stx/serve"),{site:siteConfig,i18n:i18nConfig}=await loadStxSiteConfig(),defaultsResources=resolveDefaultsResources(),userViewsPath="resources/views",defaultViewsPath=join(defaultsResources,"views"),userComponentsPath=await firstExistingPath(["resources/components","components"])??"resources/components",userLayoutsPath=await firstExistingPath(["resources/views/layouts","resources/layouts"])??"resources/views/layouts",defaultLayoutsPath=join(defaultsResources,"layouts"),userPartialsPath=await firstExistingPath(["resources/partials","resources/views/partials","partials","resources/components"]),preferredPort=Number(process.env.PORT)||3000,apiPort=Number(process.env.PORT_API)||3008,docsPort=Number(process.env.PORT_DOCS)||config.ports?.docs||3006,apiBase=`http://127.0.0.1:${apiPort}`,docsBase=`http://127.0.0.1:${docsPort}`,apiProxyRules=resolveApiProxyRules(config.server?.proxy),redirectRules=resolveRedirectRules(config.server?.redirects),embeddableRules=resolveEmbeddableRules(config.server?.security?.embeddable);if(apiProxyRules.paths.length>0||apiProxyRules.prefixes.length>1)console.log(` API proxy: ${describeApiProxyRules(apiProxyRules)}`);if(embeddableRules.paths.length>0||embeddableRules.prefixes.length>0)console.log(` Frameable by other origins: ${[...embeddableRules.paths,...embeddableRules.prefixes].join(" ")}`);if(redirectRules.size>0)console.log(` Redirects: ${describeRedirectRules(redirectRules)}`);const hasUserDocsView=["docs.stx","docs/index.stx"].some((rel)=>existsSync(projectPath(`${userViewsPath}/${rel}`))),hasDocsSite=existsSync(projectPath("docs")),docsProxyEnabled=!hasUserDocsView&&hasDocsSite,{authCookieName,stxPageAuthMiddleware}=await import("@stacksjs/auth"),authCookie=authCookieName(),viewPatterns=resolveViewPatterns(userViewsPath,defaultViewsPath,config?.ui?.defaultViews,(path)=>existsSync(projectPath(path)));for(const name of viewPatterns.missing)log.warn(`ui.defaultViews lists "${name}", which does not exist under ${defaultViewsPath} - ignoring.`);await serve({patterns:viewPatterns.patterns,port:preferredPort,componentsDir:userComponentsPath,fallbackComponentsDir:join(defaultsResources,"components"),layoutsDir:userLayoutsPath,...userPartialsPath&&{partialsDir:userPartialsPath},fallbackLayoutsDir:defaultLayoutsPath,fallbackPartialsDir:defaultViewsPath,quiet:!0,openPath:process.env.STACKS_DEV_ENTRY_PATH||"/",...i18nConfig&&{i18n:i18nConfig},...siteConfig?.url&&{site:siteConfig},auth:{cookieName:authCookie,redirectTo:"/login"},middleware:stxPageAuthMiddleware({cookieName:authCookie,redirectTo:"/login"}),onRequest:async(req)=>{const url=new URL(req.url),{maintenanceGate}=await import("@stacksjs/server"),gated=await maintenanceGate(req);if(gated)return gated;const redirected=resolveRedirect(url,redirectRules);if(redirected)return redirected;if(existsSync(projectPath("resources/views/blog.stx"))){const{renderBlogFeed}=await import("../blog"),feed=await renderBlogFeed(req);if(feed)return feed}else{const{renderBlog}=await import("../blog"),blogResponse=await renderBlog(req);if(blogResponse)return blogResponse}if(docsProxyEnabled&&(url.pathname==="/docs"||url.pathname.startsWith("/docs/")))return proxyToBackend(req,docsBase,"/docs");if(isApiBoundRequest(req,url.pathname,apiProxyRules))return proxyToBackend(req,apiBase);if(i18nConfig&&req.method==="GET"){const localeSwitch=url.pathname.match(/^\/locale\/([a-z]{2}(?:-[a-z]{2})?)\/?$/i);if(localeSwitch){const{createLocaleSwitchResponse}=await import("@stacksjs/i18n");return createLocaleSwitchResponse(req,localeSwitch[1],i18nConfig)}}const locale=await applyRequestLocale(req);let site=null;if(config.sites?.enabled){const sites=await import("@stacksjs/sites"),resolved=await sites.resolveSiteByHost(sites.requestHost(req.headers,sites.sitesOptions()));sites.setCurrentSite(resolved);site=sites.toSiteSnapshot(resolved)}const ctx={cookies:parseCookies(req),url:req.url,path:url.pathname,search:url.search,host:url.host,locale,site};globalThis.__stxServeSearch=url.search;globalThis.__stxServeContext=ctx;if(config.analytics?.capturePageviews)import("@stacksjs/analytics").then(({recordPageview})=>recordPageview(req)).catch(()=>{});requestStore.enterWith(ctx);return null},onResponse:async(req,response)=>{const secured=applyViewSecurityHeaders(req,response,embeddableRules),baseline=secured??response;let current=baseline;if(current.status===404&&config.sites?.enabled)try{const{cmsNotFoundFallback}=await import("@stacksjs/cms"),cmsResponse=await cmsNotFoundFallback(req);if(cmsResponse)current=cmsResponse}catch(error){log.debug(`CMS fallback skipped: ${error.message}`)}return await seedCsrfPageResponse(req,current)??(current===baseline?secured:current)}})}async function firstExistingPath(candidates){const existing=candidates.filter((candidate)=>existsSync(projectPath(candidate)));if(existing.length===0)return null;for(const candidate of existing)if(containsTemplates(projectPath(candidate)))return candidate;return existing[0]}function containsTemplates(dir){try{return[...new Bun.Glob("**/*.stx").scanSync({cwd:dir,onlyFiles:!0})].length>0}catch{return!1}}function fallbackI18nFromSite(site){const locales=site.i18n.locales,defaultLocale=site.i18n.defaultLocale??locales[0];return{locales,defaultLocale,labels:site.i18n.labels??Object.fromEntries(locales.map((c)=>[c,c.toUpperCase()])),translations:{},pickerSelector:site.i18n.pickerSelector??"#lang-picker"}}async function resolveSiteI18n(site){try{const{resolveI18n}=await import("@stacksjs/stx");if(typeof resolveI18n==="function"){const i18n=resolveI18n(site,projectPath());if(i18n)return i18n}}catch{}return fallbackI18nFromSite(site)}async function loadStxSiteConfig(){const sitePath=siteConfigPath();if(!existsSync(sitePath))return{};try{const mod=await import(sitePath),site=mod.default??mod.site??mod.config;if(!site)return{};if(!site.i18n)return{site};const i18n=await resolveSiteI18n(site);return{site,i18n}}catch{}return{}}
|
|
1
|
+
import{AsyncLocalStorage}from"node:async_hooks";import{existsSync}from"node:fs";import{join}from"node:path";import{config,installRequestContext,overridesReady,parseCookieHeader,resolveViewPatterns}from"@stacksjs/config";import{log}from"@stacksjs/logging";import{projectPath,siteConfigPath}from"@stacksjs/path";import{seedCsrfPageResponse}from"./csrf";import{resolveDefaultsResources}from"./defaults-resources";import{exitWithParent}from"./exit-with-parent";const requestStore=new AsyncLocalStorage;function currentRequestContext(){return requestStore.getStore()??globalThis.__stxServeContext}installRequestContext(currentRequestContext);exitWithParent();const projectServe=projectPath("serve.ts");try{if(await Bun.file(projectServe).exists())await import(projectServe);else await startDefaultServer()}catch{await startDefaultServer()}function parseCookies(req){return parseCookieHeader(req.headers.get("cookie"))}async function startDefaultServer(){await overridesReady;const{applyViewSecurityHeaders,describeApiProxyRules,describeRedirectRules,injectGlobalAutoImports,isApiBoundRequest,proxyToBackend,resolveApiProxyRules,resolveEmbeddableRules,resolveRedirect,resolveRedirectRules}=await import("@stacksjs/server"),{applyRequestLocale}=await import("@stacksjs/i18n");await injectGlobalAutoImports();const{serve}=await import("bun-plugin-stx/serve"),{site:siteConfig,i18n:i18nConfig}=await loadStxSiteConfig(),defaultsResources=resolveDefaultsResources(),userViewsPath="resources/views",defaultViewsPath=join(defaultsResources,"views"),userComponentsPath=await firstExistingPath(["resources/components","components"])??"resources/components",userLayoutsPath=await firstExistingPath(["resources/views/layouts","resources/layouts"])??"resources/views/layouts",defaultLayoutsPath=join(defaultsResources,"layouts"),userPartialsPath=await firstExistingPath(["resources/partials","resources/views/partials","partials","resources/components"]),preferredPort=Number(process.env.PORT)||3000,apiPort=Number(process.env.PORT_API)||3008,docsPort=Number(process.env.PORT_DOCS)||config.ports?.docs||3006,apiBase=`http://127.0.0.1:${apiPort}`,docsBase=`http://127.0.0.1:${docsPort}`,apiProxyRules=resolveApiProxyRules(config.server?.proxy),redirectRules=resolveRedirectRules(config.server?.redirects),embeddableRules=resolveEmbeddableRules(config.server?.security?.embeddable);if(apiProxyRules.paths.length>0||apiProxyRules.prefixes.length>1)console.log(` API proxy: ${describeApiProxyRules(apiProxyRules)}`);if(embeddableRules.paths.length>0||embeddableRules.prefixes.length>0)console.log(` Frameable by other origins: ${[...embeddableRules.paths,...embeddableRules.prefixes].join(" ")}`);if(redirectRules.size>0)console.log(` Redirects: ${describeRedirectRules(redirectRules)}`);const hasUserDocsView=["docs.stx","docs/index.stx"].some((rel)=>existsSync(projectPath(`${userViewsPath}/${rel}`))),hasDocsSite=existsSync(projectPath("docs")),docsProxyEnabled=!hasUserDocsView&&hasDocsSite,{authCookieName,stxPageAuthMiddleware}=await import("@stacksjs/auth"),{enhanceRequest,loadMiddlewareHandlers}=await import("@stacksjs/router"),authCookie=authCookieName(),pageMiddleware=await loadMiddlewareHandlers(),viewPatterns=resolveViewPatterns(userViewsPath,defaultViewsPath,config?.ui?.defaultViews,(path)=>existsSync(projectPath(path)));for(const name of viewPatterns.missing)log.warn(`ui.defaultViews lists "${name}", which does not exist under ${defaultViewsPath} - ignoring.`);await serve({patterns:viewPatterns.patterns,port:preferredPort,componentsDir:userComponentsPath,fallbackComponentsDir:join(defaultsResources,"components"),layoutsDir:userLayoutsPath,...userPartialsPath&&{partialsDir:userPartialsPath},fallbackLayoutsDir:defaultLayoutsPath,fallbackPartialsDir:defaultViewsPath,quiet:!0,openPath:process.env.STACKS_DEV_ENTRY_PATH||"/",...i18nConfig&&{i18n:i18nConfig},...siteConfig?.url&&{site:siteConfig},auth:{cookieName:authCookie,redirectTo:"/login"},middleware:{...pageMiddleware,...stxPageAuthMiddleware({cookieName:authCookie,redirectTo:"/login"})},prepareMiddlewareRequest:(request)=>enhanceRequest(request),onRequest:async(req)=>{const url=new URL(req.url),{maintenanceGate}=await import("@stacksjs/server"),gated=await maintenanceGate(req);if(gated)return gated;const redirected=resolveRedirect(url,redirectRules);if(redirected)return redirected;if(existsSync(projectPath("resources/views/blog.stx"))){const{renderBlogFeed}=await import("../blog"),feed=await renderBlogFeed(req);if(feed)return feed}else{const{renderBlog}=await import("../blog"),blogResponse=await renderBlog(req);if(blogResponse)return blogResponse}if(docsProxyEnabled&&(url.pathname==="/docs"||url.pathname.startsWith("/docs/")))return proxyToBackend(req,docsBase,"/docs");if(isApiBoundRequest(req,url.pathname,apiProxyRules))return proxyToBackend(req,apiBase);if(i18nConfig&&req.method==="GET"){const localeSwitch=url.pathname.match(/^\/locale\/([a-z]{2}(?:-[a-z]{2})?)\/?$/i);if(localeSwitch){const{createLocaleSwitchResponse}=await import("@stacksjs/i18n");return createLocaleSwitchResponse(req,localeSwitch[1],i18nConfig)}}const locale=await applyRequestLocale(req);let site=null;if(config.sites?.enabled){const sites=await import("@stacksjs/sites"),resolved=await sites.resolveSiteByHost(sites.requestHost(req.headers,sites.sitesOptions()));sites.setCurrentSite(resolved);site=sites.toSiteSnapshot(resolved)}const ctx={cookies:parseCookies(req),url:req.url,path:url.pathname,search:url.search,host:url.host,locale,site};globalThis.__stxServeSearch=url.search;globalThis.__stxServeContext=ctx;if(config.analytics?.capturePageviews)import("@stacksjs/analytics").then(({recordPageview})=>recordPageview(req)).catch(()=>{});requestStore.enterWith(ctx);return null},onResponse:async(req,response)=>{const secured=applyViewSecurityHeaders(req,response,embeddableRules),baseline=secured??response;let current=baseline;if(current.status===404&&config.sites?.enabled)try{const{cmsNotFoundFallback}=await import("@stacksjs/cms"),cmsResponse=await cmsNotFoundFallback(req);if(cmsResponse)current=cmsResponse}catch(error){log.debug(`CMS fallback skipped: ${error.message}`)}return await seedCsrfPageResponse(req,current)??(current===baseline?secured:current)}})}async function firstExistingPath(candidates){const existing=candidates.filter((candidate)=>existsSync(projectPath(candidate)));if(existing.length===0)return null;for(const candidate of existing)if(containsTemplates(projectPath(candidate)))return candidate;return existing[0]}function containsTemplates(dir){try{return[...new Bun.Glob("**/*.stx").scanSync({cwd:dir,onlyFiles:!0})].length>0}catch{return!1}}function fallbackI18nFromSite(site){const locales=site.i18n.locales,defaultLocale=site.i18n.defaultLocale??locales[0];return{locales,defaultLocale,labels:site.i18n.labels??Object.fromEntries(locales.map((c)=>[c,c.toUpperCase()])),translations:{},pickerSelector:site.i18n.pickerSelector??"#lang-picker"}}async function resolveSiteI18n(site){try{const{resolveI18n}=await import("@stacksjs/stx");if(typeof resolveI18n==="function"){const i18n=resolveI18n(site,projectPath());if(i18n)return i18n}}catch{}return fallbackI18nFromSite(site)}async function loadStxSiteConfig(){const sitePath=siteConfigPath();if(!existsSync(sitePath))return{};try{const mod=await import(sitePath),site=mod.default??mod.site??mod.config;if(!site)return{};if(!site.i18n)return{site};const i18n=await resolveSiteI18n(site);return{site,i18n}}catch{}return{}}
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import type { StackDirectory } from '@stacksjs/types';
|
|
2
2
|
export declare function discoverPackages(options?: DiscoverPackagesOptions): Promise<DiscoveredPackagesManifest>;
|
|
3
|
+
/**
|
|
4
|
+
* Discover packages, and never fail a boot for it.
|
|
5
|
+
*
|
|
6
|
+
* The production entries call this; `buddy dev` and `buddy package:discover`
|
|
7
|
+
* call `discoverPackages` directly because they want the result or the error.
|
|
8
|
+
*
|
|
9
|
+
* Discovery used to run in exactly two places, `dev/api.ts` and the
|
|
10
|
+
* `package:discover` command, and the manifest it writes is gitignored. A
|
|
11
|
+
* deployed application therefore ran whatever manifest happened to ride along
|
|
12
|
+
* in the tarball from a developer's machine, or none at all - so a package's
|
|
13
|
+
* routes, models and migrations worked in `buddy dev` and silently did not in
|
|
14
|
+
* production. Worse than absent: a manifest naming a package that is no longer
|
|
15
|
+
* installed makes `assertRouteMiddlewareResolvable()` throw during router boot.
|
|
16
|
+
*
|
|
17
|
+
* Swallowing the error is deliberate. An application's own routes and models do
|
|
18
|
+
* not depend on discovery having succeeded, and a server that refuses to start
|
|
19
|
+
* because one dependency shipped an unreadable directory is worse than one that
|
|
20
|
+
* starts without that dependency's routes.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ensureDiscoveredPackages(): Promise<void>;
|
|
3
23
|
/**
|
|
4
24
|
* Find the installed packages that extend this application.
|
|
5
25
|
*
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{existsSync}from"node:fs";import{isAbsolute,join,relative}from"node:path";import{projectPath,storagePath}from"@stacksjs/path";async function readManifest(file){try{return await Bun.file(file).json()}catch{return null}}async function directDependencies(projectRoot){const pkg=await readManifest(join(projectRoot,"package.json"));if(!pkg)return[];const names=new Set;for(const field of["dependencies","devDependencies","peerDependencies"]){const block=pkg[field];if(block&&typeof block==="object")for(const name of Object.keys(block))names.add(name)}return[...names].sort()}async function fromNodeModules(projectRoot){const root=join(projectRoot,"node_modules");if(!existsSync(root))return[];const out=[];for(const name of await directDependencies(projectRoot)){const dir=join(root,name),pkg=await readManifest(join(dir,"package.json"));if(!pkg?.name||!pkg.stacks||typeof pkg.stacks!=="object")continue;out.push({name:pkg.name,meta:pkg.stacks,dir})}return out}async function fromPantry(projectRoot){const root=join(projectRoot,"pantry");if(!existsSync(root))return[];const out=[];for(const pattern of["*/package.json","@*/*/package.json"]){const glob=new Bun.Glob(pattern);for await(const file of glob.scan({cwd:root,absolute:!0,onlyFiles:!0})){const pkg=await readManifest(file);if(!pkg?.name||!pkg.stacks||typeof pkg.stacks!=="object")continue;out.push({name:pkg.name,meta:pkg.stacks,dir:join(file,"..")})}}return out.sort((a,b)=>a.name.localeCompare(b.name))}async function dontDiscover(projectRoot){const list=(await readManifest(join(projectRoot,"package.json")))?.stacks?.["dont-discover"];return new Set(Array.isArray(list)?list:[])}export async function discoverPackages(options={}){const projectRoot=options.projectRoot??projectPath(),manifestPath=options.manifestPath??storagePath("framework/discovered-packages.json"),excluded=await dontDiscover(projectRoot),found=[...await fromNodeModules(projectRoot),...await fromPantry(projectRoot)],packages={},shadowed=[],chosen=new Map;for(const candidate of found){if(excluded.has(candidate.name))continue;const root=toRelative(projectRoot,candidate.dir),already=chosen.get(candidate.name);if(already!==void 0){shadowed.push({name:candidate.name,used:already,ignored:root});continue}chosen.set(candidate.name,root);packages[candidate.name]={...candidate.meta,root}}const manifest={generated_at:new Date().toISOString(),packages,...shadowed.length>0?{shadowed}:{}};if(options.dryRun)return manifest;try{const current=await Bun.file(manifestPath).json();if(JSON.stringify(current.packages??{})===JSON.stringify(manifest.packages)&&JSON.stringify(current.shadowed??[])===JSON.stringify(shadowed))return current}catch{}await Bun.write(
|
|
2
|
-
`);return manifest}function toRelative(projectRoot,dir){const rel=relative(projectRoot,dir);return rel&&!rel.startsWith("..")&&!isAbsolute(rel)?rel:dir}
|
|
1
|
+
import{existsSync,renameSync,unlinkSync}from"node:fs";import process from"node:process";import{isAbsolute,join,relative}from"node:path";import{projectPath,storagePath}from"@stacksjs/path";async function readManifest(file){try{return await Bun.file(file).json()}catch{return null}}async function directDependencies(projectRoot){const pkg=await readManifest(join(projectRoot,"package.json"));if(!pkg)return[];const names=new Set;for(const field of["dependencies","devDependencies","peerDependencies"]){const block=pkg[field];if(block&&typeof block==="object")for(const name of Object.keys(block))names.add(name)}return[...names].sort()}async function fromNodeModules(projectRoot){const root=join(projectRoot,"node_modules");if(!existsSync(root))return[];const out=[];for(const name of await directDependencies(projectRoot)){const dir=join(root,name),pkg=await readManifest(join(dir,"package.json"));if(!pkg?.name||!pkg.stacks||typeof pkg.stacks!=="object")continue;out.push({name:pkg.name,meta:pkg.stacks,dir})}return out}async function fromPantry(projectRoot){const root=join(projectRoot,"pantry");if(!existsSync(root))return[];const out=[];for(const pattern of["*/package.json","@*/*/package.json"]){const glob=new Bun.Glob(pattern);for await(const file of glob.scan({cwd:root,absolute:!0,onlyFiles:!0})){const pkg=await readManifest(file);if(!pkg?.name||!pkg.stacks||typeof pkg.stacks!=="object")continue;out.push({name:pkg.name,meta:pkg.stacks,dir:join(file,"..")})}}return out.sort((a,b)=>a.name.localeCompare(b.name))}async function dontDiscover(projectRoot){const list=(await readManifest(join(projectRoot,"package.json")))?.stacks?.["dont-discover"];return new Set(Array.isArray(list)?list:[])}export async function discoverPackages(options={}){const projectRoot=options.projectRoot??projectPath(),manifestPath=options.manifestPath??storagePath("framework/discovered-packages.json"),excluded=await dontDiscover(projectRoot),found=[...await fromNodeModules(projectRoot),...await fromPantry(projectRoot)],packages={},shadowed=[],chosen=new Map;for(const candidate of found){if(excluded.has(candidate.name))continue;const root=toRelative(projectRoot,candidate.dir),already=chosen.get(candidate.name);if(already!==void 0){shadowed.push({name:candidate.name,used:already,ignored:root});continue}chosen.set(candidate.name,root);packages[candidate.name]={...candidate.meta,root}}const manifest={generated_at:new Date().toISOString(),packages,...shadowed.length>0?{shadowed}:{}};if(options.dryRun)return manifest;try{const current=await Bun.file(manifestPath).json();if(JSON.stringify(current.packages??{})===JSON.stringify(manifest.packages)&&JSON.stringify(current.shadowed??[])===JSON.stringify(shadowed))return current}catch{}const temp=`${manifestPath}.${process.pid}.tmp`;try{await Bun.write(temp,`${JSON.stringify(manifest,null,2)}
|
|
2
|
+
`);renameSync(temp,manifestPath)}catch(error){try{unlinkSync(temp)}catch{}throw error}return manifest}export async function ensureDiscoveredPackages(){try{await discoverPackages()}catch(error){const{log}=await import("@stacksjs/logging");log.warn(`[discovery] Could not refresh the package manifest: ${error instanceof Error?error.message:String(error)}`)}}function toRelative(projectRoot,dir){const rel=relative(projectRoot,dir);return rel&&!rel.startsWith("..")&&!isAbsolute(rel)?rel:dir}
|
package/dist/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export {
|
|
|
68
68
|
make as runMake,
|
|
69
69
|
setDryRun,
|
|
70
70
|
} from './make';
|
|
71
|
-
export { discoverPackages } from './discover-packages';
|
|
71
|
+
export { discoverPackages, ensureDiscoveredPackages } from './discover-packages';
|
|
72
72
|
export { parseFields, scaffoldCrud } from './scaffold-crud';
|
|
73
73
|
export { installStack, uninstallStack, listStacks } from './stacks';
|
|
74
74
|
export { makeJob } from './make-job';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setActionRunner}from"@stacksjs/action-runner";import{runAction}from"./helpers";setActionRunner((action,options)=>runAction(action,options));export*from"./action";export{add as runAdd}from"./add";export{BlogAdminError,deleteBlogPost,getBlogPost,listBlogPosts,saveBlogPost,slugify as blogSlugify}from"./blog-admin";export{commit as runCommit}from"./commit";export*from"./dev";export*from"./generate";export*from"./helpers";export*from"./library";export{formatProject,lintFix,lintProject}from"./lint/lint";export{DEFAULT_STX_LINT_CONFIG,loadStxLintConfig,runStxLint}from"./lint/stx-gate";export{measureDefaultsDrift,summarizeStructureChanges}from"./upgrade/package-project";export*from"./setup";export{createComponent,createDatabase,createFactory,createFunction,createLanguage,createMiddleware,createMigration,createModel,createMail,createNotification,createPage,isDryRunActive,makeAction,makeCertificate,makeComponent,makeDatabase,makeFunction,makeLanguage,makeMail,makeNotification,makePage,makeQueueTable,makeStack,make as runMake,setDryRun}from"./make";export{discoverPackages}from"./discover-packages";export{parseFields,scaffoldCrud}from"./scaffold-crud";export{installStack,uninstallStack,listStacks}from"./stacks";export{makeJob}from"./make-job";export{makeCommand}from"./make-command";export{makePolicy}from"./make-policy";export{makeResource}from"./make-resource";
|
|
1
|
+
import{setActionRunner}from"@stacksjs/action-runner";import{runAction}from"./helpers";setActionRunner((action,options)=>runAction(action,options));export*from"./action";export{add as runAdd}from"./add";export{BlogAdminError,deleteBlogPost,getBlogPost,listBlogPosts,saveBlogPost,slugify as blogSlugify}from"./blog-admin";export{commit as runCommit}from"./commit";export*from"./dev";export*from"./generate";export*from"./helpers";export*from"./library";export{formatProject,lintFix,lintProject}from"./lint/lint";export{DEFAULT_STX_LINT_CONFIG,loadStxLintConfig,runStxLint}from"./lint/stx-gate";export{measureDefaultsDrift,summarizeStructureChanges}from"./upgrade/package-project";export*from"./setup";export{createComponent,createDatabase,createFactory,createFunction,createLanguage,createMiddleware,createMigration,createModel,createMail,createNotification,createPage,isDryRunActive,makeAction,makeCertificate,makeComponent,makeDatabase,makeFunction,makeLanguage,makeMail,makeNotification,makePage,makeQueueTable,makeStack,make as runMake,setDryRun}from"./make";export{discoverPackages,ensureDiscoveredPackages}from"./discover-packages";export{parseFields,scaffoldCrud}from"./scaffold-crud";export{installStack,uninstallStack,listStacks}from"./stacks";export{makeJob}from"./make-job";export{makeCommand}from"./make-command";export{makePolicy}from"./make-policy";export{makeResource}from"./make-resource";
|
package/dist/serve/api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync}from"node:fs";import{dirname,join}from"node:path";import process from"node:process";import{config,overridesReady}from"@stacksjs/config";import{log}from"@stacksjs/logging";import{appPath,frameworkPath}from"@stacksjs/path";import{disableViewRouting,route}from"@stacksjs/router";import{resolveApiHost}from"../helpers/api-host";function resolveDefaultsFile(rel){if(rel.startsWith("app/")){const published=appPath(rel.slice(4));if(existsSync(published))return published}const vendored=frameworkPath(`defaults/${rel}`);if(existsSync(vendored))return vendored;try{const pkgJson=Bun.resolveSync("@stacksjs/defaults/package.json",process.cwd());return join(dirname(pkgJson),rel)}catch{return vendored}}await overridesReady;const port=Number(process.env.PORT)||config.ports?.api||3008,hostname=resolveApiHost();log.info("[Stacks API] Starting server...");log.info(`[Stacks API] Environment: ${process.env.APP_ENV||"development"}`);const corsMod=await import(resolveDefaultsFile("app/Middleware/Cors.ts")),corsMiddleware=corsMod.default;route.use(corsMiddleware.toRouterHandler());await route.importRoutes();try{const{describeUnforwardableRoutes,resolveApiProxyRules,unforwardableRoutes}=await import("@stacksjs/server"),{listRootMountedAppRoutes}=await import("@stacksjs/router"),unreachable=unforwardableRoutes(listRootMountedAppRoutes().filter((entry)=>entry.method==="GET"||entry.method==="HEAD"),resolveApiProxyRules(config.server?.proxy));if(unreachable.length>0)log.warn(describeUnforwardableRoutes(unreachable))}catch(error){log.debug(`[Stacks API] Route reachability check skipped: ${error instanceof Error?error.message:String(error)}`)}disableViewRouting(route.bunRouter);const isDeployed=["production","staging","development"].includes((process.env.APP_ENV||"").toLowerCase()),server=await route.serve({port,hostname,reusePort:isDeployed});process.on("SIGTERM",()=>{const graceMs=Number(process.env.SHUTDOWN_GRACE_MS)||15000;setTimeout(()=>process.exit(0),graceMs).unref();Promise.resolve(server?.stop()).then(()=>process.exit(0))});log.info(`[Stacks API] Server running at http://${hostname}:${port}`);
|
|
1
|
+
import{existsSync}from"node:fs";import{dirname,join}from"node:path";import process from"node:process";import{config,overridesReady}from"@stacksjs/config";import{log}from"@stacksjs/logging";import{appPath,frameworkPath}from"@stacksjs/path";import{disableViewRouting,route}from"@stacksjs/router";import{ensureDiscoveredPackages}from"../discover-packages";import{resolveApiHost}from"../helpers/api-host";function resolveDefaultsFile(rel){if(rel.startsWith("app/")){const published=appPath(rel.slice(4));if(existsSync(published))return published}const vendored=frameworkPath(`defaults/${rel}`);if(existsSync(vendored))return vendored;try{const pkgJson=Bun.resolveSync("@stacksjs/defaults/package.json",process.cwd());return join(dirname(pkgJson),rel)}catch{return vendored}}await overridesReady;const port=Number(process.env.PORT)||config.ports?.api||3008,hostname=resolveApiHost();log.info("[Stacks API] Starting server...");log.info(`[Stacks API] Environment: ${process.env.APP_ENV||"development"}`);const corsMod=await import(resolveDefaultsFile("app/Middleware/Cors.ts")),corsMiddleware=corsMod.default;route.use(corsMiddleware.toRouterHandler());await ensureDiscoveredPackages();const{injectGlobalAutoImports}=await import("@stacksjs/server");await injectGlobalAutoImports();await route.importRoutes();try{const{describeUnforwardableRoutes,resolveApiProxyRules,unforwardableRoutes}=await import("@stacksjs/server"),{listRootMountedAppRoutes}=await import("@stacksjs/router"),unreachable=unforwardableRoutes(listRootMountedAppRoutes().filter((entry)=>entry.method==="GET"||entry.method==="HEAD"),resolveApiProxyRules(config.server?.proxy));if(unreachable.length>0)log.warn(describeUnforwardableRoutes(unreachable))}catch(error){log.debug(`[Stacks API] Route reachability check skipped: ${error instanceof Error?error.message:String(error)}`)}disableViewRouting(route.bunRouter);const isDeployed=["production","staging","development"].includes((process.env.APP_ENV||"").toLowerCase()),server=await route.serve({port,hostname,reusePort:isDeployed});process.on("SIGTERM",()=>{const graceMs=Number(process.env.SHUTDOWN_GRACE_MS)||15000;setTimeout(()=>process.exit(0),graceMs).unref();Promise.resolve(server?.stop()).then(()=>process.exit(0))});log.info(`[Stacks API] Server running at http://${hostname}:${port}`);
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/actions",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.74.
|
|
5
|
+
"version": "0.74.29",
|
|
6
6
|
"description": "The Stacks actions.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -60,52 +60,52 @@
|
|
|
60
60
|
"prepublishOnly": "bun run build"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@stacksjs/action-runner": "0.74.
|
|
64
|
-
"@stacksjs/ai": "0.74.
|
|
65
|
-
"@stacksjs/analytics": "0.74.
|
|
66
|
-
"@stacksjs/api": "0.74.
|
|
67
|
-
"@stacksjs/auth": "0.74.
|
|
68
|
-
"@stacksjs/build": "0.74.
|
|
63
|
+
"@stacksjs/action-runner": "0.74.29",
|
|
64
|
+
"@stacksjs/ai": "0.74.29",
|
|
65
|
+
"@stacksjs/analytics": "0.74.29",
|
|
66
|
+
"@stacksjs/api": "0.74.29",
|
|
67
|
+
"@stacksjs/auth": "0.74.29",
|
|
68
|
+
"@stacksjs/build": "0.74.29",
|
|
69
69
|
"@stacksjs/bumpx": "^0.2.6",
|
|
70
70
|
"@stacksjs/bunpress": "^0.2.8",
|
|
71
|
-
"@stacksjs/cli": "0.74.
|
|
72
|
-
"@stacksjs/cloud": "0.74.
|
|
73
|
-
"@stacksjs/cms": "0.74.
|
|
74
|
-
"@stacksjs/config": "0.74.
|
|
75
|
-
"@stacksjs/database": "0.74.
|
|
76
|
-
"@stacksjs/desktop-build": "0.74.
|
|
77
|
-
"@stacksjs/dns": "0.74.
|
|
78
|
-
"@stacksjs/enums": "0.74.
|
|
79
|
-
"@stacksjs/env": "0.74.
|
|
80
|
-
"@stacksjs/error-handling": "0.74.
|
|
71
|
+
"@stacksjs/cli": "0.74.29",
|
|
72
|
+
"@stacksjs/cloud": "0.74.29",
|
|
73
|
+
"@stacksjs/cms": "0.74.29",
|
|
74
|
+
"@stacksjs/config": "0.74.29",
|
|
75
|
+
"@stacksjs/database": "0.74.29",
|
|
76
|
+
"@stacksjs/desktop-build": "0.74.29",
|
|
77
|
+
"@stacksjs/dns": "0.74.29",
|
|
78
|
+
"@stacksjs/enums": "0.74.29",
|
|
79
|
+
"@stacksjs/env": "0.74.29",
|
|
80
|
+
"@stacksjs/error-handling": "0.74.29",
|
|
81
81
|
"@stacksjs/gitit": "^0.2.5",
|
|
82
|
-
"@stacksjs/i18n": "0.74.
|
|
83
|
-
"@stacksjs/image": "0.74.
|
|
84
|
-
"@stacksjs/logging": "0.74.
|
|
82
|
+
"@stacksjs/i18n": "0.74.29",
|
|
83
|
+
"@stacksjs/image": "0.74.29",
|
|
84
|
+
"@stacksjs/logging": "0.74.29",
|
|
85
85
|
"@stacksjs/logsmith": "^0.2.3",
|
|
86
|
-
"@stacksjs/orm": "0.74.
|
|
87
|
-
"@stacksjs/path": "0.74.
|
|
88
|
-
"@stacksjs/payments": "0.74.
|
|
89
|
-
"@stacksjs/queue": "0.74.
|
|
90
|
-
"@stacksjs/registry": "0.74.
|
|
91
|
-
"@stacksjs/router": "0.74.
|
|
86
|
+
"@stacksjs/orm": "0.74.29",
|
|
87
|
+
"@stacksjs/path": "0.74.29",
|
|
88
|
+
"@stacksjs/payments": "0.74.29",
|
|
89
|
+
"@stacksjs/queue": "0.74.29",
|
|
90
|
+
"@stacksjs/registry": "0.74.29",
|
|
91
|
+
"@stacksjs/router": "0.74.29",
|
|
92
92
|
"@stacksjs/rpx": "^0.11.42",
|
|
93
|
-
"@stacksjs/scheduler": "0.74.
|
|
94
|
-
"@stacksjs/search-engine": "0.74.
|
|
95
|
-
"@stacksjs/security": "0.74.
|
|
96
|
-
"@stacksjs/server": "0.74.
|
|
97
|
-
"@stacksjs/sites": "0.74.
|
|
98
|
-
"@stacksjs/storage": "0.74.
|
|
99
|
-
"@stacksjs/strings": "0.74.
|
|
93
|
+
"@stacksjs/scheduler": "0.74.29",
|
|
94
|
+
"@stacksjs/search-engine": "0.74.29",
|
|
95
|
+
"@stacksjs/security": "0.74.29",
|
|
96
|
+
"@stacksjs/server": "0.74.29",
|
|
97
|
+
"@stacksjs/sites": "0.74.29",
|
|
98
|
+
"@stacksjs/storage": "0.74.29",
|
|
99
|
+
"@stacksjs/strings": "0.74.29",
|
|
100
100
|
"@stacksjs/stx": "^0.2.274",
|
|
101
101
|
"@stacksjs/tlsx": "^0.13.19",
|
|
102
|
-
"@stacksjs/ts-cloud": "^0.12.
|
|
102
|
+
"@stacksjs/ts-cloud": "^0.12.15",
|
|
103
103
|
"@stacksjs/ts-md": "^0.1.1",
|
|
104
|
-
"@stacksjs/tunnel": "0.74.
|
|
105
|
-
"@stacksjs/types": "0.74.
|
|
106
|
-
"@stacksjs/utils": "0.74.
|
|
107
|
-
"@stacksjs/whois": "0.74.
|
|
108
|
-
"bun-plugin-stx": "^0.2.
|
|
104
|
+
"@stacksjs/tunnel": "0.74.29",
|
|
105
|
+
"@stacksjs/types": "0.74.29",
|
|
106
|
+
"@stacksjs/utils": "0.74.29",
|
|
107
|
+
"@stacksjs/whois": "0.74.29",
|
|
108
|
+
"bun-plugin-stx": "^0.2.279"
|
|
109
109
|
},
|
|
110
110
|
"peerDependencies": {
|
|
111
111
|
"craft-native": ">=0.0.72",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
}
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
123
|
-
"@stacksjs/validation": "0.74.
|
|
123
|
+
"@stacksjs/validation": "0.74.29",
|
|
124
124
|
"better-dx": "^0.2.24"
|
|
125
125
|
}
|
|
126
126
|
}
|