@stacksjs/buddy 0.75.408 → 0.75.409
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/commands/build.js +1 -1
- package/dist/commands/deploy.d.ts +12 -0
- package/dist/commands/deploy.js +1 -1
- package/package.json +57 -57
package/dist/commands/build.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import process from"node:process";import{intro,log,multiselect,onUnknownSubcommand,outro}from"@stacksjs/cli";import{Action}from"@stacksjs/enums";import{hasTTY,isCI}from"@stacksjs/env";import{projectPath}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";import{resultFailed}from"../result";let _runAction;async function runAction(...args){if(!_runAction)_runAction=(await import("@stacksjs/actions")).runAction;return _runAction(...args)}export function build(buddy){const descriptions={build:"Build any of your libraries (packages) for production use",components:"Build your component library",webComponents:"Build your framework agnostic web component library",elements:"An alias to the -w flag",buddy:"Build the Buddy binary",functions:"Build your function library",libs:"Build every package configured in config/library.ts",desktop:"Build the Desktop Application",mobile:"Build the native iOS and Android applications",android:"Build the native Android application",ios:"Build the native iOS application",dmg:"Package the desktop build as a macOS .app inside a .dmg",pages:"Build your frontend",docs:"Build your documentation",framework:"Build Stacks framework",cli:"Automagically build the CLI",server:"Build the Stacks cloud server (Docker image)",frontendStatic:"Build the prerendered marketing/public static site (storage/framework/frontend-dist)",select:"What are you trying to build?",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("build [type]",descriptions.build).option("-c, --components",descriptions.components).option("-w, --web-components",descriptions.webComponents).option("-e, --elements",descriptions.elements).option("-f, --functions",descriptions.functions).option("-l, --libs",descriptions.libs).option("-k, --desktop",descriptions.desktop).option("-m, --mobile",descriptions.mobile).option("--android",descriptions.android).option("--ios",descriptions.ios).option("-p, --views",descriptions.pages).option("--pages",descriptions.pages).option("-d, --docs",descriptions.docs).option("-b, --buddy",descriptions.buddy,{default:!1}).option("-s, --stacks",descriptions.framework,{default:!1}).option("--project [project]",descriptions.project,{default:!1}).option("--server",descriptions.server,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(server,options)=>{log.debug("Running `buddy build` ...",options);applyBuildTarget(server,options);if(options.mobile){options.android=!0;options.ios=!0}if(hasNoOptions(options)){if(!isCI&&hasTTY&&process.stdin.isTTY){const answers=await multiselect({message:descriptions.select,choices:[{label:"Frontend (views)",value:"views"},{label:"Components",value:"components"},{label:"Web Components",value:"webComponents"},{label:"Functions",value:"functions"},{label:"All library packages",value:"libs"},{label:"Desktop application",value:"desktop"},{label:"Mobile applications (iOS + Android)",value:"mobile"},{label:"Android application",value:"android"},{label:"iOS application",value:"ios"},{label:"Documentation",value:"docs"},{label:"Stacks framework",value:"stacks"},{label:"Buddy CLI",value:"buddy"},{label:"Server (Docker image)",value:"server"}]}),selected=new Set(answers);if(selected.has("views"))options.views=!0;if(selected.has("components"))options.components=!0;if(selected.has("webComponents"))options.webComponents=!0;if(selected.has("functions"))options.functions=!0;if(selected.has("libs"))options.libs=!0;if(selected.has("desktop"))options.desktop=!0;if(selected.has("mobile")){options.mobile=!0;options.android=!0;options.ios=!0}if(selected.has("android"))options.android=!0;if(selected.has("ios"))options.ios=!0;if(selected.has("docs"))options.docs=!0;if(selected.has("stacks"))options.stacks=!0;if(selected.has("buddy"))options.buddy=!0;if(selected.has("server"))options.server=!0}if(hasNoOptions(options)){options.views=!0;log.info("No build target specified, defaulting to the frontend (views). See `buddy build --help` for all targets.")}}let succeeded=!0;if(options.docs)succeeded=await runBuildAction(Action.BuildDocs,"documentation",options)&&succeeded;if(options.components)succeeded=await runBuildAction(Action.BuildComponentLibs,"component libraries",options)&&succeeded;if(options.webComponents)succeeded=await runBuildAction(Action.BuildWebComponentLib,"web component library",options)&&succeeded;if(options.functions)succeeded=await runBuildAction(Action.BuildFunctionLib,"function library",options)&&succeeded;if(options.libs)succeeded=await runBuildAction(Action.BuildLibs,"library packages",options)&&succeeded;if(options.desktop)succeeded=await runBuildAction(Action.BuildDesktop,"desktop application",options)&&succeeded;if(options.android)succeeded=await runBuildAction(Action.BuildAndroid,"Android application",options)&&succeeded;if(options.ios)succeeded=await runBuildAction(Action.BuildIos,"iOS application",options)&&succeeded;if(options.views)succeeded=await runBuildAction(Action.BuildViews,"frontend",options)&&succeeded;if(options.stacks)succeeded=await runBuildAction(Action.BuildStacks,"Stacks framework",options)&&succeeded;if(options.buddy)succeeded=await runBuildAction(Action.BuildCli,"Buddy CLI",options)&&succeeded;if(options.server)succeeded=await runBuildAction(Action.BuildServer,"server",options)&&succeeded;if(!succeeded)process.exit(ExitCode.FatalError);process.exit(ExitCode.Success)});buddy.command("build:components","Automagically build component libraries for production use & npm/CDN distribution").alias("prod:components").option("-c, --components",descriptions.components,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:components` ...",options);if(!await runBuildAction(Action.BuildComponentLibs,"component libraries",options))process.exit(ExitCode.FatalError)});buddy.command("build:cli",descriptions.cli).alias("prod:cli").option("-b, --buddy",descriptions.buddy,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:cli` ...",options);await runAction(Action.BuildCli,options)});buddy.command("build:server",descriptions.server).alias("prod:server").alias("build:docker").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:server` ...",options);await runAction(Action.BuildServer,options)});buddy.command("build:functions","Automagically build function library for npm/CDN distribution").option("-f, --functions",descriptions.functions,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:functions` ...",options);if(!await runBuildAction(Action.BuildFunctionLib,"function library",options))process.exit(ExitCode.FatalError)});buddy.command("build:libs",descriptions.libs).alias("build:libraries").alias("prod:libs").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:libs` ...",options);if(!await runBuildAction(Action.BuildLibs,"library packages",options))process.exit(ExitCode.FatalError)});buddy.command("build:web-components","Automagically build Web Component library for npm/CDN distribution").alias("build:wc").alias("prod:web-components").alias("prod:wc").option("-w, --web-components",descriptions.webComponents,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:web-components` ...",options);if(!await runBuildAction(Action.BuildWebComponentLib,"web component library",options))process.exit(ExitCode.FatalError)});buddy.command("build:frontend",descriptions.pages).alias("build:pages").alias("build:views").alias("prod:frontend").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend` ...",options);await runAction(Action.BuildViews,options)});buddy.command("build:docs","Automagically build your documentation site.").alias("prod:docs").alias("build:documentation").alias("prod:documentation").option("-d, --docs",descriptions.docs,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:docs` ...",options);await runAction(Action.BuildDocs,options)});buddy.command("build:frontend-static",descriptions.frontendStatic).alias("build:public").alias("prod:frontend-static").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend-static` ...",options);await runAction(Action.BuildFrontendStatic,options)});buddy.command("build:core","Automagically build the Stacks core.").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:core` ...",options);const startTime=await intro("buddy build:core"),result=await runAction(Action.BuildCore,options);if(resultFailed(result)){await log.error("Failed to build the Stacks core.",result.error);process.exit(ExitCode.FatalError)}await outro("Core packages built successfully",{startTime,useSeconds:!0})});buddy.command("build:desktop",descriptions.desktop).alias("prod:desktop").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:desktop` ...",options);const perf=await intro("buddy build:desktop"),{hasMacosDesktop}=await import("@stacksjs/desktop-build"),result=await runAction(await hasMacosDesktop(projectPath())?Action.BuildDesktopMacos:Action.BuildDesktop,options);if(resultFailed(result)){await outro("While running the build:desktop command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:mobile",descriptions.mobile).alias("prod:mobile").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:mobile` ...",options);const perf=await intro("buddy build:mobile"),androidSucceeded=await runBuildAction(Action.BuildAndroid,"Android application",options),iosSucceeded=await runBuildAction(Action.BuildIos,"iOS application",options);if(!androidSucceeded||!iosSucceeded){await outro("One or more mobile application builds failed",{startTime:perf,useSeconds:!0,type:"error"});process.exit(ExitCode.FatalError)}await outro("iOS and Android applications built",{startTime:perf,useSeconds:!0})});buddy.command("build:android",descriptions.android).alias("prod:android").option("-p, --project [project]",descriptions.project,{default:!1}).option("--bundle","Build a signed Android App Bundle (.aab) for Google Play (CRAFT_ANDROID_KEYSTORE and friends)",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:android` ...",options);if(options.bundle)process.env.STACKS_ANDROID_BUNDLE="1";const perf=await intro("buddy build:android"),result=await runAction(Action.BuildAndroid,options);if(resultFailed(result)){await outro("While building the Android application, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Android application built",{startTime:perf,useSeconds:!0})});buddy.command("build:ios",descriptions.ios).alias("prod:ios").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:ios` ...",options);const perf=await intro("buddy build:ios"),result=await runAction(Action.BuildIos,options);if(resultFailed(result)){await outro("While building the iOS application, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("iOS application built",{startTime:perf,useSeconds:!0})});buddy.command("build:dmg",descriptions.dmg).option("--app-name <name>","Bundle display name (or DESKTOP_APP_NAME / APP_NAME)").option("--app-version <version>","Bundle version (or DESKTOP_APP_VERSION; defaults to the project's package.json)").option("--bundle-id <id>","Reverse-DNS bundle identifier (or DESKTOP_BUNDLE_ID)").option("--signing-identity <identity>","Developer ID identity to sign with (or DESKTOP_SIGNING_IDENTITY)").option("--notary-profile <profile>","notarytool keychain profile to notarize and staple with (or DESKTOP_NOTARY_PROFILE)").option("--volume-name <name>","Name the mounted image shows (or DESKTOP_VOLUME_NAME)").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:dmg` ...",options);const perf=await intro("buddy build:dmg"),result=await runAction(Action.BuildDmg,options);if(resultFailed(result)){await outro("While running the build:dmg command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:stacks","Build the Stacks framework.").option("-s, --stacks",descriptions.framework,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:stacks` ...",options);const startTime=await intro("buddy build:stacks"),result=await runAction(Action.BuildStacks,options);if(resultFailed(result)){await log.error("Failed to build Stacks.",result.error);process.exit(ExitCode.FatalError)}await outro("Stacks built successfully",{startTime,useSeconds:!0})});onUnknownSubcommand(buddy,"build")}function hasNoOptions(options){return!options.components&&!options.webComponents&&!options.elements&&!options.functions&&!options.libs&&!options.desktop&&!options.mobile&&!options.android&&!options.ios&&!options.views&&!options.docs&&!options.stacks&&!options.buddy&&!options.server}export function applyBuildTarget(target,options){switch(target){case"components":options.components=!0;break;case"web-components":options.webComponents=!0;break;case"functions":options.functions=!0;break;case"libs":case"libraries":options.libs=!0;break;case"desktop":options.desktop=!0;break;case"mobile":options.mobile=!0;options.android=!0;options.ios=!0;break;case"android":options.android=!0;break;case"ios":options.ios=!0;break;case"views":options.views=!0;break;case"docs":options.docs=!0;break;case"buddy":case"cli":options.buddy=!0;break;case"stacks":options.stacks=!0;break;case"server":options.server=!0;break}}async function runBuildAction(action,target,options){const result=await runAction(action,options);if(resultFailed(result)){log.error(`Failed to build ${target}.`,result.error);return!1}return!0}
|
|
1
|
+
import process from"node:process";import{intro,log,multiselect,onUnknownSubcommand,outro}from"@stacksjs/cli";import{Action}from"@stacksjs/enums";import{hasTTY,isCI}from"@stacksjs/env";import{projectPath}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";import{resultFailed}from"../result";let _runAction;async function runAction(...args){if(!_runAction)_runAction=(await import("@stacksjs/actions")).runAction;return _runAction(...args)}export function build(buddy){const descriptions={build:"Build any of your libraries (packages) for production use",components:"Build your component library",webComponents:"Build your framework agnostic web component library",elements:"An alias to the -w flag",buddy:"Build the Buddy binary",functions:"Build your function library",libs:"Build every package configured in config/library.ts",desktop:"Build the Desktop Application",mobile:"Build the native iOS and Android applications",android:"Build the native Android application",ios:"Build the native iOS application",dmg:"Package the desktop build as a macOS .app inside a .dmg",pages:"Build your frontend",docs:"Build your documentation",framework:"Build Stacks framework",cli:"Automagically build the CLI",server:"Build the Stacks cloud server (Docker image)",frontendStatic:"Build the prerendered marketing/public static site (storage/framework/frontend-dist)",select:"What are you trying to build?",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("build [type]",descriptions.build).option("-c, --components",descriptions.components).option("-w, --web-components",descriptions.webComponents).option("-e, --elements",descriptions.elements).option("-f, --functions",descriptions.functions).option("-l, --libs",descriptions.libs).option("-k, --desktop",descriptions.desktop).option("-m, --mobile",descriptions.mobile).option("--android",descriptions.android).option("--ios",descriptions.ios).option("-p, --views",descriptions.pages).option("--pages",descriptions.pages).option("-d, --docs",descriptions.docs).option("-b, --buddy",descriptions.buddy,{default:!1}).option("-s, --stacks",descriptions.framework,{default:!1}).option("--project [project]",descriptions.project,{default:!1}).option("--server",descriptions.server,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(server,options)=>{log.debug("Running `buddy build` ...",options);applyBuildTarget(server,options);if(options.mobile){options.android=!0;options.ios=!0}if(hasNoOptions(options)){if(!isCI&&hasTTY&&process.stdin.isTTY){const answers=await multiselect({message:descriptions.select,choices:[{label:"Frontend (views)",value:"views"},{label:"Components",value:"components"},{label:"Web Components",value:"webComponents"},{label:"Functions",value:"functions"},{label:"All library packages",value:"libs"},{label:"Desktop application",value:"desktop"},{label:"Mobile applications (iOS + Android)",value:"mobile"},{label:"Android application",value:"android"},{label:"iOS application",value:"ios"},{label:"Documentation",value:"docs"},{label:"Stacks framework",value:"stacks"},{label:"Buddy CLI",value:"buddy"},{label:"Server (Docker image)",value:"server"}]}),selected=new Set(answers);if(selected.has("views"))options.views=!0;if(selected.has("components"))options.components=!0;if(selected.has("webComponents"))options.webComponents=!0;if(selected.has("functions"))options.functions=!0;if(selected.has("libs"))options.libs=!0;if(selected.has("desktop"))options.desktop=!0;if(selected.has("mobile")){options.mobile=!0;options.android=!0;options.ios=!0}if(selected.has("android"))options.android=!0;if(selected.has("ios"))options.ios=!0;if(selected.has("docs"))options.docs=!0;if(selected.has("stacks"))options.stacks=!0;if(selected.has("buddy"))options.buddy=!0;if(selected.has("server"))options.server=!0}if(hasNoOptions(options)){options.views=!0;log.info("No build target specified, defaulting to the frontend (views). See `buddy build --help` for all targets.")}}let succeeded=!0;if(options.docs)succeeded=await runBuildAction(Action.BuildDocs,"documentation",options)&&succeeded;if(options.components)succeeded=await runBuildAction(Action.BuildComponentLibs,"component libraries",options)&&succeeded;if(options.webComponents)succeeded=await runBuildAction(Action.BuildWebComponentLib,"web component library",options)&&succeeded;if(options.functions)succeeded=await runBuildAction(Action.BuildFunctionLib,"function library",options)&&succeeded;if(options.libs)succeeded=await runBuildAction(Action.BuildLibs,"library packages",options)&&succeeded;if(options.desktop)succeeded=await runBuildAction(Action.BuildDesktop,"desktop application",options)&&succeeded;if(options.android)succeeded=await runBuildAction(Action.BuildAndroid,"Android application",options)&&succeeded;if(options.ios)succeeded=await runBuildAction(Action.BuildIos,"iOS application",options)&&succeeded;if(options.views)succeeded=await runBuildAction(Action.BuildViews,"frontend",options)&&succeeded;if(options.stacks)succeeded=await runBuildAction(Action.BuildStacks,"Stacks framework",options)&&succeeded;if(options.buddy)succeeded=await runBuildAction(Action.BuildCli,"Buddy CLI",options)&&succeeded;if(options.server)succeeded=await runBuildAction(Action.BuildServer,"server",options)&&succeeded;if(!succeeded)process.exit(ExitCode.FatalError);process.exit(ExitCode.Success)});buddy.command("build:components","Automagically build component libraries for production use & npm/CDN distribution").alias("prod:components").option("-c, --components",descriptions.components,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:components` ...",options);if(!await runBuildAction(Action.BuildComponentLibs,"component libraries",options))process.exit(ExitCode.FatalError)});buddy.command("build:cli",descriptions.cli).alias("prod:cli").option("-b, --buddy",descriptions.buddy,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:cli` ...",options);await runAction(Action.BuildCli,options)});buddy.command("build:server",descriptions.server).alias("prod:server").alias("build:docker").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:server` ...",options);await runAction(Action.BuildServer,options)});buddy.command("build:functions","Automagically build function library for npm/CDN distribution").option("-f, --functions",descriptions.functions,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:functions` ...",options);if(!await runBuildAction(Action.BuildFunctionLib,"function library",options))process.exit(ExitCode.FatalError)});buddy.command("build:libs",descriptions.libs).alias("build:libraries").alias("prod:libs").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:libs` ...",options);if(!await runBuildAction(Action.BuildLibs,"library packages",options))process.exit(ExitCode.FatalError)});buddy.command("build:web-components","Automagically build Web Component library for npm/CDN distribution").alias("build:wc").alias("prod:web-components").alias("prod:wc").option("-w, --web-components",descriptions.webComponents,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:web-components` ...",options);if(!await runBuildAction(Action.BuildWebComponentLib,"web component library",options))process.exit(ExitCode.FatalError)});buddy.command("build:frontend",descriptions.pages).alias("build:pages").alias("build:views").alias("prod:frontend").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend` ...",options);await runAction(Action.BuildViews,options)});buddy.command("build:docs","Automagically build your documentation site.").alias("prod:docs").alias("build:documentation").alias("prod:documentation").option("-d, --docs",descriptions.docs,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:docs` ...",options);await runAction(Action.BuildDocs,options)});buddy.command("build:frontend-static",descriptions.frontendStatic).alias("build:public").alias("prod:frontend-static").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend-static` ...",options);await runAction(Action.BuildFrontendStatic,options)});buddy.command("build:core","Automagically build the Stacks core.").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:core` ...",options);const startTime=await intro("buddy build:core"),result=await runAction(Action.BuildCore,options);if(resultFailed(result)){await log.error("Failed to build the Stacks core.",result.error);process.exit(ExitCode.FatalError)}await outro("Core packages built successfully",{startTime,useSeconds:!0})});buddy.command("build:desktop",descriptions.desktop).alias("prod:desktop").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:desktop` ...",options);const perf=await intro("buddy build:desktop"),{hasMacosDesktop}=await import("@stacksjs/desktop-build"),result=await runAction(await hasMacosDesktop(projectPath())?Action.BuildDesktopMacos:Action.BuildDesktop,options);if(resultFailed(result)){await outro("While running the build:desktop command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:mobile",descriptions.mobile).alias("prod:mobile").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:mobile` ...",options);const perf=await intro("buddy build:mobile"),androidSucceeded=await runBuildAction(Action.BuildAndroid,"Android application",options),iosSucceeded=await runBuildAction(Action.BuildIos,"iOS application",options);if(!androidSucceeded||!iosSucceeded){await outro("One or more mobile application builds failed",{startTime:perf,useSeconds:!0,type:"error"});process.exit(ExitCode.FatalError)}await outro("iOS and Android applications built",{startTime:perf,useSeconds:!0})});buddy.command("build:android",descriptions.android).alias("prod:android").option("-p, --project [project]",descriptions.project,{default:!1}).option("--bundle","Build a signed Android App Bundle (.aab) for Google Play (CRAFT_ANDROID_KEYSTORE and friends)",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:android` ...",options);if(options.bundle)process.env.STACKS_ANDROID_BUNDLE="1";const perf=await intro("buddy build:android"),result=await runAction(Action.BuildAndroid,options);if(resultFailed(result)){await outro("While building the Android application, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Android application built",{startTime:perf,useSeconds:!0})});buddy.command("build:ios",descriptions.ios).alias("prod:ios").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:ios` ...",options);const perf=await intro("buddy build:ios"),result=await runAction(Action.BuildIos,options);if(resultFailed(result)){await outro("While building the iOS application, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("iOS application built",{startTime:perf,useSeconds:!0})});buddy.command("build:dmg",descriptions.dmg).option("--app-name <name>","Bundle display name (or DESKTOP_APP_NAME / APP_NAME)").option("--app-version <version>","Bundle version (or DESKTOP_APP_VERSION; defaults to the project's package.json)").option("--bundle-id <id>","Reverse-DNS bundle identifier (or DESKTOP_BUNDLE_ID)").option("--signing-identity <identity>","Developer ID identity to sign with (or DESKTOP_SIGNING_IDENTITY)").option("--notary-profile <profile>","notarytool keychain profile to notarize and staple with (or DESKTOP_NOTARY_PROFILE)").option("--notarize","Notarize and staple with an App Store Connect API key (or DESKTOP_NOTARIZE)").option("--api-key-id <id>","App Store Connect API key ID (or APP_STORE_CONNECT_API_KEY_ID)").option("--api-issuer-id <id>","App Store Connect API issuer ID (or APP_STORE_CONNECT_API_ISSUER_ID)").option("--api-key-path <path>","The AuthKey_*.p8 file (or APP_STORE_CONNECT_API_KEY_PATH, or its PEM in APP_STORE_CONNECT_API_KEY)").option("--volume-name <name>","Name the mounted image shows (or DESKTOP_VOLUME_NAME)").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:dmg` ...",options);const perf=await intro("buddy build:dmg"),result=await runAction(Action.BuildDmg,options);if(resultFailed(result)){await outro("While running the build:dmg command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:stacks","Build the Stacks framework.").option("-s, --stacks",descriptions.framework,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:stacks` ...",options);const startTime=await intro("buddy build:stacks"),result=await runAction(Action.BuildStacks,options);if(resultFailed(result)){await log.error("Failed to build Stacks.",result.error);process.exit(ExitCode.FatalError)}await outro("Stacks built successfully",{startTime,useSeconds:!0})});onUnknownSubcommand(buddy,"build")}function hasNoOptions(options){return!options.components&&!options.webComponents&&!options.elements&&!options.functions&&!options.libs&&!options.desktop&&!options.mobile&&!options.android&&!options.ios&&!options.views&&!options.docs&&!options.stacks&&!options.buddy&&!options.server}export function applyBuildTarget(target,options){switch(target){case"components":options.components=!0;break;case"web-components":options.webComponents=!0;break;case"functions":options.functions=!0;break;case"libs":case"libraries":options.libs=!0;break;case"desktop":options.desktop=!0;break;case"mobile":options.mobile=!0;options.android=!0;options.ios=!0;break;case"android":options.android=!0;break;case"ios":options.ios=!0;break;case"views":options.views=!0;break;case"docs":options.docs=!0;break;case"buddy":case"cli":options.buddy=!0;break;case"stacks":options.stacks=!0;break;case"server":options.server=!0;break}}async function runBuildAction(action,target,options){const result=await runAction(action,options);if(resultFailed(result)){log.error(`Failed to build ${target}.`,result.error);return!1}return!0}
|
|
@@ -166,6 +166,18 @@ export declare function assertFragmentIsOurs(where: string | SshTarget, tsCloudC
|
|
|
166
166
|
*/
|
|
167
167
|
export declare function assertPortsAreFree(where: string | SshTarget, tsCloudConfig: any, log: { error: (m: string) => void, info: (m: string) => void }): Promise<void>;
|
|
168
168
|
export declare function resolveDeployEnvValues(environment: 'production' | 'staging' | 'development', tsCloudConfig?: { project?: { slug?: string } }, fileOverride?: string): Promise<Record<string, string>>;
|
|
169
|
+
/**
|
|
170
|
+
* What a deploy that could not read its environment file should say beyond
|
|
171
|
+
* "restore its decryption key".
|
|
172
|
+
*
|
|
173
|
+
* Names only: the encrypted keys in the file and the private-key variable the
|
|
174
|
+
* env layer looked for, plus whether it was set. A lost key on 2026-10-31
|
|
175
|
+
* stopped a deploy with the generic message, and finding out that five keys
|
|
176
|
+
* were encrypted to a public key whose private half was nowhere took far
|
|
177
|
+
* longer than reading this would have. Values, ciphertext and key material
|
|
178
|
+
* are never included.
|
|
179
|
+
*/
|
|
180
|
+
export declare function deployEnvFailureDetail(filePath: string, fileName: string): string;
|
|
169
181
|
/**
|
|
170
182
|
* Merge the deploy-target's resolved env values underneath each site's own
|
|
171
183
|
* explicit `env` overrides, stripping a general `PORT` when the site
|
package/dist/commands/deploy.js
CHANGED
|
@@ -9,7 +9,7 @@ cloud-init may have failed: SSH in and check /var/log/cloud-init-output.log. Rai
|
|
|
9
9
|
unit=$(systemctl status "$pid" 2>/dev/null | head -1 | grep -oE '[a-zA-Z0-9_.@-]+\\.service' | head -1)
|
|
10
10
|
echo "$p \${unit:-unknown}"
|
|
11
11
|
done`,encoding:"utf8",stdio:["pipe","pipe","pipe"]})}catch{return}const clashes=[];for(const line of listing.split(`
|
|
12
|
-
`)){const[portText,unit="unknown"]=line.trim().split(/\s+/),port=Number(portText);if(!Number.isFinite(port)||!wanted.has(port))continue;if(unit.startsWith(`${slug}-`))continue;clashes.push(` ${port} (site '${wanted.get(port)}') is held by ${unit}`)}if(clashes.length===0)return;log.error("Another service on the box is already listening on a port this project wants:");for(const clash of clashes)log.error(clash);log.error("Two services on one port do not error: the kernel load-balances, and each domain serves the other's site about half the time.");log.info("Pick free ports in config/cloud.ts. `ss -lntp` on the box lists what is taken.");process.exit(ExitCode.FatalError)}export async function resolveDeployEnvValues(environment,tsCloudConfig,fileOverride){const fileName=fileOverride??(environment==="production"?".env.production":environment==="staging"?".env.staging":existsSync(p.projectPath(".env.development"))?".env.development":".env"),filePath=p.projectPath(fileName);if(!existsSync(filePath))return{};try{const{getEnv}=await import("@stacksjs/env"),result=getEnv(void 0,{file:fileName,format:"json"});if(!result.success||!result.output)throw Error("The environment could not be read completely");const parsed=JSON.parse(result.output),values={},undecrypted=[];for(const[key,value]of Object.entries(parsed)){if(/^DOTENV_(PUBLIC|PRIVATE)_KEY/.test(key))continue;values[key]=String(value);if(/^(?:encrypted|enc):/.test(values[key]))undecrypted.push(key)}if(undecrypted.length>0)throw Error("The environment still contains ciphertext");const{foreignTenantKeys,partitionTenantEnv}=await import("@stacksjs/env"),partition=partitionTenantEnv(values,{self:tsCloudConfig?.project?.slug,tenants:await resolveDeclaredTenants()});for(const{tenant,keys}of foreignTenantKeys(partition))log.warn(`[deploy] Skipping ${keys.length} '${tenant}' key(s) in ${fileName} - they belong to that tenant's own repository, and shipping them writes its secrets into this project's site .env files. Remove them with: buddy env:check --file ${fileName}. Keys: ${keys.join(", ")}`);return partition.own}catch{throw Error(`Cannot load deployment environment from ${fileName}; restore its decryption key and readable file before deploying
|
|
12
|
+
`)){const[portText,unit="unknown"]=line.trim().split(/\s+/),port=Number(portText);if(!Number.isFinite(port)||!wanted.has(port))continue;if(unit.startsWith(`${slug}-`))continue;clashes.push(` ${port} (site '${wanted.get(port)}') is held by ${unit}`)}if(clashes.length===0)return;log.error("Another service on the box is already listening on a port this project wants:");for(const clash of clashes)log.error(clash);log.error("Two services on one port do not error: the kernel load-balances, and each domain serves the other's site about half the time.");log.info("Pick free ports in config/cloud.ts. `ss -lntp` on the box lists what is taken.");process.exit(ExitCode.FatalError)}export async function resolveDeployEnvValues(environment,tsCloudConfig,fileOverride){const fileName=fileOverride??(environment==="production"?".env.production":environment==="staging"?".env.staging":existsSync(p.projectPath(".env.development"))?".env.development":".env"),filePath=p.projectPath(fileName);if(!existsSync(filePath))return{};try{const{getEnv}=await import("@stacksjs/env"),result=getEnv(void 0,{file:fileName,format:"json"});if(!result.success||!result.output)throw Error("The environment could not be read completely");const parsed=JSON.parse(result.output),values={},undecrypted=[];for(const[key,value]of Object.entries(parsed)){if(/^DOTENV_(PUBLIC|PRIVATE)_KEY/.test(key))continue;values[key]=String(value);if(/^(?:encrypted|enc):/.test(values[key]))undecrypted.push(key)}if(undecrypted.length>0)throw Error("The environment still contains ciphertext");const{foreignTenantKeys,partitionTenantEnv}=await import("@stacksjs/env"),partition=partitionTenantEnv(values,{self:tsCloudConfig?.project?.slug,tenants:await resolveDeclaredTenants()});for(const{tenant,keys}of foreignTenantKeys(partition))log.warn(`[deploy] Skipping ${keys.length} '${tenant}' key(s) in ${fileName} - they belong to that tenant's own repository, and shipping them writes its secrets into this project's site .env files. Remove them with: buddy env:check --file ${fileName}. Keys: ${keys.join(", ")}`);return partition.own}catch{throw Error(`Cannot load deployment environment from ${fileName}; restore its decryption key and readable file before deploying.${deployEnvFailureDetail(filePath,fileName)}`)}}export function deployEnvFailureDetail(filePath,fileName){let text;try{text=readFileSync(filePath,"utf8")}catch{return""}const encrypted=[];let publicKeyName="";for(const line of text.split(/\r?\n/)){const match=line.match(/^\s*(?:export\s+)?([A-Z0-9_]+)\s*=\s*['"]?(.*)$/i);if(!match)continue;const key=match[1]??"",value=match[2]??"";if(/^DOTENV_PUBLIC_KEY/.test(key)){publicKeyName=key;continue}if(/^(?:encrypted|enc):/.test(value))encrypted.push(key)}if(encrypted.length===0)return"";const privateKeyName=publicKeyName?publicKeyName.replace("DOTENV_PUBLIC_KEY","DOTENV_PRIVATE_KEY"):"DOTENV_PRIVATE_KEY",keysFile=join(dirname(filePath),".env.keys"),source=process.env[privateKeyName]?`${privateKeyName} is set but does not decrypt them; it must be the private half of ${publicKeyName||"the public key in the file"}`:existsSync(keysFile)?`${privateKeyName} is not set in the environment, and .env.keys did not supply a matching one`:`${privateKeyName} is not set in the environment and there is no .env.keys beside ${fileName}`;return` Encrypted in ${fileName}: ${encrypted.join(", ")}. ${source}.`}export function mergeSiteDeployEnv(sites,resolvedDeployEnv){return Object.fromEntries(Object.entries(sites).map(([siteName,site])=>{if(!site)return[siteName,site];const base=site.inheritEnv===!1?{}:{...resolvedDeployEnv};if(site.port!==void 0)delete base.PORT;return[siteName,{...site,env:{...base,...site.env||{}}}]}))}function looksLikeSqliteFile(value){return typeof value==="string"&&/\.(?:sqlite3?|db)$/i.test(value.trim())}export function siteSqlitePath(siteEnv={}){if(String(siteEnv.DB_CONNECTION??"sqlite").trim().toLowerCase()!=="sqlite")return null;const configured=typeof siteEnv.DB_DATABASE_PATH==="string"&&siteEnv.DB_DATABASE_PATH.trim()?siteEnv.DB_DATABASE_PATH:looksLikeSqliteFile(siteEnv.DB_DATABASE)?siteEnv.DB_DATABASE:"database/stacks.sqlite",path=String(configured).trim().replace(/^\.\//,"");if(!path||path.startsWith("/")||path.startsWith("~")||path.split("/").includes(".."))return null;return path}export function tsCloudPersistentStateSupport(buildSiteDeployScript){const missing=[];if(typeof buildSiteDeployScript!=="function")return{ok:!1,missing:["buildSiteDeployScript"]};const target="/var/www/probe-shared/database/probe.sqlite";let script="";try{script=buildSiteDeployScript({siteName:"probe",slug:"probe",appDir:"/var/www/probe-probe",artifactFetch:[],releaseId:"probe",execStart:"/bin/true",envEntries:{},port:3000,sharedPaths:[{path:"database/probe.sqlite",target,seed:!0}]}).join(`
|
|
13
13
|
`)}catch{return{ok:!1,missing:["shared paths with an explicit target"]}}if(!(script.includes("cp -a")&&script.includes("/current/")))missing.push("adoption of existing state into shared/");if(!script.includes(`ln -sfn ${target} `))missing.push("shared paths with an explicit target");return{ok:missing.length===0,missing}}export function projectDatabaseTarget(slug,relativePath){return`/var/www/${slug}-shared/${relativePath}`}function migrateIndex(site){if(!Array.isArray(site?.preStart))return-1;return site.preStart.findIndex((cmd)=>typeof cmd==="string"&&migratesDatabase(cmd))}function migratesDatabase(command){const withoutMessages=command.replace(/'[^']*'/g,"").replace(/"[^"]*"/g,"");if(/\bmigrate\b/.test(withoutMessages))return!0;return!/^\s*(?:echo|printf)\b/.test(command)&&/\bmigrate\b/.test(command)}export function applyAutomaticMigrations(sites){if(Object.values(sites).some((site)=>runsMigrations(site)))return sites;const isServerApp=(site)=>!!site&&typeof site.start==="string",owner=Object.entries(sites).filter(([,site])=>isServerApp(site)).find(([,site])=>site?.migrateOnDeploy!==!1)?.[0];if(!owner)return sites;const site=sites[owner],preStart=Array.isArray(site.preStart)?[...site.preStart]:[];preStart.push("./buddy migrate --no-generate");return{...sites,[owner]:{...site,preStart}}}function runsMigrations(site){return migrateIndex(site)!==-1}export function applyPersistentStatePaths(sites,slug){const isServerApp=(site)=>!!site&&typeof site.start==="string",appSites=Object.entries(sites).filter(([,site])=>isServerApp(site)),owners=new Map;for(const[name,site]of appSites){const sqlite=siteSqlitePath(site.env||{});if(!sqlite)continue;const migrates=runsMigrations(site),previous=owners.get(sqlite);if(!previous||!previous.migrates&&migrates)owners.set(sqlite,{name,migrates})}const out={};for(const[name,site]of Object.entries(sites)){if(!isServerApp(site)){out[name]=site;continue}const sqlite=siteSqlitePath(site.env||{}),framework=["storage/logs"];if(sqlite)framework.unshift({path:sqlite,target:projectDatabaseTarget(slug,sqlite),seed:name===owners.get(sqlite)?.name});const declared=Array.isArray(site.sharedPaths)?site.sharedPaths.filter(Boolean):[],byPath=new Map;for(const entry of[...declared,...framework])byPath.set(typeof entry==="string"?entry:entry.path,entry);out[name]={...site,sharedPaths:[...byPath.values()]}}return out}export function encryptedEnvFileNames(projectRoot){try{return readdirSync(projectRoot).filter((name)=>/^\.env\.[\w-]+$/.test(name)&&name!==".env.example")}catch{return[]}}export function declaresScheduledWork(schedulerFile){if(!existsSync(schedulerFile))return!1;const source=readFileSync(schedulerFile,"utf8").replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1");return/\bschedule\s*\.\s*(?:job|action|command|call|exec)\b/.test(source)}export function applyScheduledWork(sites,schedulerFile){if(Object.values(sites).some((site)=>site?.scheduler!==void 0))return sites;if(!declaresScheduledWork(schedulerFile))return sites;const appSites=Object.entries(sites).filter(([,site])=>typeof site?.start==="string"),owner=(appSites.find(([,site])=>runsMigrations(site))??appSites[0])?.[0];if(!owner)return sites;return{...sites,[owner]:{...sites[owner],scheduler:!0}}}const apiStartPattern=/\bserve:api\b|(?:^|[\s/"'])(?:serve|storage\/framework\/runtime\/production)\/api\.[cm]?[jt]s(?=$|[\s"';&|<>()])/;function servesApi(name,site){return name==="api"||typeof site?.start==="string"&&apiStartPattern.test(site.start)}function servesHttp(site){return Boolean(site?.port||site?.domain)}function describeSiteClassification(sites){const described=Object.entries(sites).filter(([,site])=>typeof site?.start==="string").map(([name,site])=>{if(servesApi(name,site))return`\`${name}\` (api)`;if(!servesHttp(site))return`\`${name}\` (headless, no HTTP surface)`;const env=site?.env??{},wiring=env.API_URL?"API_URL set":env.PORT_API?"PORT_API set":"no API_URL or PORT_API";return`\`${name}\` (page, ${wiring})`});return described.length>0?`Sites examined: ${described.join(", ")}.`:"No server-app sites were examined."}function isDashboardSite(name){return name==="dashboard"||name.startsWith("dashboard-")}export function apiDeploymentProblem(sites,hasApiRoutes){if(!hasApiRoutes)return;const entries=Object.entries(sites),appSites=entries.filter(([,site])=>typeof site?.start==="string");if(appSites.length===0)return;const api=entries.find(([name,site])=>servesApi(name,site)),pages=appSites.filter(([name,site])=>!servesApi(name,site)&&!isDashboardSite(name)&&servesHttp(site)),configured=(site)=>{const env=site?.env??{};return Boolean(env.API_URL||env.PORT_API)};if(!api){if(pages.every(([,site])=>configured(site)))return;return`This project declares API routes and no site serves them. \`/api/**\` will answer 502 on every request.
|
|
14
14
|
${describeSiteClassification(sites)}
|
|
15
15
|
Add an \`api\` site to config/cloud.ts running \`buddy serve:api\` on its own port, and set \`PORT_API\` on the site that serves the pages so its proxy can find it.
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/buddy",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.409",
|
|
6
6
|
"description": "Meet Buddy. The Stacks runtime.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -95,72 +95,72 @@
|
|
|
95
95
|
"prepublishOnly": "bun run build"
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@stacksjs/actions": "0.75.
|
|
99
|
-
"@stacksjs/ai": "0.75.
|
|
100
|
-
"@stacksjs/alias": "0.75.
|
|
101
|
-
"@stacksjs/analytics": "0.75.
|
|
102
|
-
"@stacksjs/api": "0.75.
|
|
103
|
-
"@stacksjs/arrays": "0.75.
|
|
104
|
-
"@stacksjs/auth": "0.75.
|
|
105
|
-
"@stacksjs/browser-extension": "0.75.
|
|
106
|
-
"@stacksjs/build": "0.75.
|
|
98
|
+
"@stacksjs/actions": "0.75.409",
|
|
99
|
+
"@stacksjs/ai": "0.75.409",
|
|
100
|
+
"@stacksjs/alias": "0.75.409",
|
|
101
|
+
"@stacksjs/analytics": "0.75.409",
|
|
102
|
+
"@stacksjs/api": "0.75.409",
|
|
103
|
+
"@stacksjs/arrays": "0.75.409",
|
|
104
|
+
"@stacksjs/auth": "0.75.409",
|
|
105
|
+
"@stacksjs/browser-extension": "0.75.409",
|
|
106
|
+
"@stacksjs/build": "0.75.409",
|
|
107
107
|
"@stacksjs/bumpx": "^0.2.26",
|
|
108
|
-
"@stacksjs/cache": "0.75.
|
|
109
|
-
"@stacksjs/chat": "0.75.
|
|
108
|
+
"@stacksjs/cache": "0.75.409",
|
|
109
|
+
"@stacksjs/chat": "0.75.409",
|
|
110
110
|
"@stacksjs/clapp": "^0.2.16",
|
|
111
|
-
"@stacksjs/cli": "0.75.
|
|
112
|
-
"@stacksjs/cloud": "0.75.
|
|
113
|
-
"@stacksjs/cms": "0.75.
|
|
114
|
-
"@stacksjs/collections": "0.75.
|
|
115
|
-
"@stacksjs/commerce": "0.75.
|
|
116
|
-
"@stacksjs/config": "0.75.
|
|
117
|
-
"@stacksjs/database": "0.75.
|
|
118
|
-
"@stacksjs/desktop-build": "0.75.
|
|
119
|
-
"@stacksjs/dns": "0.75.
|
|
111
|
+
"@stacksjs/cli": "0.75.409",
|
|
112
|
+
"@stacksjs/cloud": "0.75.409",
|
|
113
|
+
"@stacksjs/cms": "0.75.409",
|
|
114
|
+
"@stacksjs/collections": "0.75.409",
|
|
115
|
+
"@stacksjs/commerce": "0.75.409",
|
|
116
|
+
"@stacksjs/config": "0.75.409",
|
|
117
|
+
"@stacksjs/database": "0.75.409",
|
|
118
|
+
"@stacksjs/desktop-build": "0.75.409",
|
|
119
|
+
"@stacksjs/dns": "0.75.409",
|
|
120
120
|
"@stacksjs/dnsx": "^0.2.3",
|
|
121
|
-
"@stacksjs/email": "0.75.
|
|
122
|
-
"@stacksjs/enums": "0.75.
|
|
123
|
-
"@stacksjs/env": "0.75.
|
|
124
|
-
"@stacksjs/error-handling": "0.75.
|
|
125
|
-
"@stacksjs/events": "0.75.
|
|
126
|
-
"@stacksjs/features": "0.75.
|
|
127
|
-
"@stacksjs/git": "0.75.
|
|
121
|
+
"@stacksjs/email": "0.75.409",
|
|
122
|
+
"@stacksjs/enums": "0.75.409",
|
|
123
|
+
"@stacksjs/env": "0.75.409",
|
|
124
|
+
"@stacksjs/error-handling": "0.75.409",
|
|
125
|
+
"@stacksjs/events": "0.75.409",
|
|
126
|
+
"@stacksjs/features": "0.75.409",
|
|
127
|
+
"@stacksjs/git": "0.75.409",
|
|
128
128
|
"@stacksjs/gitit": "^0.2.5",
|
|
129
|
-
"@stacksjs/health": "0.75.
|
|
129
|
+
"@stacksjs/health": "0.75.409",
|
|
130
130
|
"@stacksjs/httx": "^0.1.10",
|
|
131
|
-
"@stacksjs/image": "0.75.
|
|
132
|
-
"@stacksjs/lint": "0.75.
|
|
133
|
-
"@stacksjs/logging": "0.75.
|
|
134
|
-
"@stacksjs/notifications": "0.75.
|
|
135
|
-
"@stacksjs/objects": "0.75.
|
|
136
|
-
"@stacksjs/orm": "0.75.
|
|
137
|
-
"@stacksjs/path": "0.75.
|
|
138
|
-
"@stacksjs/payments": "0.75.
|
|
139
|
-
"@stacksjs/realtime": "0.75.
|
|
140
|
-
"@stacksjs/router": "0.75.
|
|
131
|
+
"@stacksjs/image": "0.75.409",
|
|
132
|
+
"@stacksjs/lint": "0.75.409",
|
|
133
|
+
"@stacksjs/logging": "0.75.409",
|
|
134
|
+
"@stacksjs/notifications": "0.75.409",
|
|
135
|
+
"@stacksjs/objects": "0.75.409",
|
|
136
|
+
"@stacksjs/orm": "0.75.409",
|
|
137
|
+
"@stacksjs/path": "0.75.409",
|
|
138
|
+
"@stacksjs/payments": "0.75.409",
|
|
139
|
+
"@stacksjs/realtime": "0.75.409",
|
|
140
|
+
"@stacksjs/router": "0.75.409",
|
|
141
141
|
"@stacksjs/rpx": "^0.11.54",
|
|
142
|
-
"@stacksjs/scheduler": "0.75.
|
|
143
|
-
"@stacksjs/search-engine": "0.75.
|
|
144
|
-
"@stacksjs/security": "0.75.
|
|
145
|
-
"@stacksjs/server": "0.75.
|
|
146
|
-
"@stacksjs/sites": "0.75.
|
|
147
|
-
"@stacksjs/skills": "0.75.
|
|
148
|
-
"@stacksjs/socials": "0.75.
|
|
149
|
-
"@stacksjs/storage": "0.75.
|
|
150
|
-
"@stacksjs/strings": "0.75.
|
|
151
|
-
"@stacksjs/stx": "0.2.
|
|
152
|
-
"@stacksjs/testing": "0.75.
|
|
153
|
-
"@stacksjs/tinker": "0.75.
|
|
142
|
+
"@stacksjs/scheduler": "0.75.409",
|
|
143
|
+
"@stacksjs/search-engine": "0.75.409",
|
|
144
|
+
"@stacksjs/security": "0.75.409",
|
|
145
|
+
"@stacksjs/server": "0.75.409",
|
|
146
|
+
"@stacksjs/sites": "0.75.409",
|
|
147
|
+
"@stacksjs/skills": "0.75.409",
|
|
148
|
+
"@stacksjs/socials": "0.75.409",
|
|
149
|
+
"@stacksjs/storage": "0.75.409",
|
|
150
|
+
"@stacksjs/strings": "0.75.409",
|
|
151
|
+
"@stacksjs/stx": "0.2.780",
|
|
152
|
+
"@stacksjs/testing": "0.75.409",
|
|
153
|
+
"@stacksjs/tinker": "0.75.409",
|
|
154
154
|
"@stacksjs/tlsx": "^0.13.19",
|
|
155
155
|
"@stacksjs/ts-cloud": "^0.16.91",
|
|
156
|
-
"@stacksjs/tunnel": "0.75.
|
|
157
|
-
"@stacksjs/types": "0.75.
|
|
158
|
-
"@stacksjs/ui": "0.75.
|
|
159
|
-
"@stacksjs/utils": "0.75.
|
|
160
|
-
"@stacksjs/validation": "0.75.
|
|
156
|
+
"@stacksjs/tunnel": "0.75.409",
|
|
157
|
+
"@stacksjs/types": "0.75.409",
|
|
158
|
+
"@stacksjs/ui": "0.75.409",
|
|
159
|
+
"@stacksjs/utils": "0.75.409",
|
|
160
|
+
"@stacksjs/validation": "0.75.409",
|
|
161
161
|
"ajv": "^8.20.0",
|
|
162
162
|
"ajv-formats": "^3.0.1",
|
|
163
|
-
"bun-plugin-stx": "0.2.
|
|
163
|
+
"bun-plugin-stx": "0.2.780",
|
|
164
164
|
"ts-pantry": "^0.11.146"
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|