@stacksjs/buddy 0.70.59 → 0.70.61
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/cli.js +164 -4
- package/dist/commands/about.js +35 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +33 -0
- package/dist/commands/auth.js +68 -0
- package/dist/commands/build.js +153 -0
- package/dist/commands/cd.js +39 -0
- package/dist/commands/changelog.js +32 -0
- package/dist/commands/clean.js +37 -0
- package/dist/commands/cloud.js +503 -0
- package/dist/commands/commit.js +16 -0
- package/dist/commands/completion.js +143 -0
- package/dist/commands/config-migrate.js +94 -0
- package/dist/commands/configure.js +48 -0
- package/dist/commands/create.js +137 -0
- package/dist/commands/deploy.js +1404 -0
- package/dist/commands/dev.js +911 -0
- package/dist/commands/dns.js +62 -0
- package/dist/commands/doctor.js +280 -0
- package/dist/commands/domains.js +159 -0
- package/dist/commands/email.js +526 -0
- package/dist/commands/env.js +246 -0
- package/dist/commands/features.js +422 -0
- package/dist/commands/fresh.js +39 -0
- package/dist/commands/generate.js +104 -0
- package/dist/commands/http.js +30 -0
- package/dist/commands/index.js +53 -0
- package/dist/commands/install.js +23 -0
- package/dist/commands/key.js +23 -0
- package/dist/commands/lint.js +50 -0
- package/dist/commands/list.js +108 -0
- package/dist/commands/mail.js +693 -0
- package/dist/commands/maintenance.d.ts +2 -0
- package/dist/commands/maintenance.js +141 -0
- package/dist/commands/make.js +375 -0
- package/dist/commands/migrate-project.js +49 -0
- package/dist/commands/migrate.js +373 -0
- package/dist/commands/outdated.js +19 -0
- package/dist/commands/package.d.ts +2 -0
- package/dist/commands/package.js +17 -0
- package/dist/commands/phone.js +188 -0
- package/dist/commands/ports.js +118 -0
- package/dist/commands/prepublish.js +17 -0
- package/dist/commands/projects.js +29 -0
- package/dist/commands/publish.js +169 -0
- package/dist/commands/queue.js +249 -0
- package/dist/commands/release.js +30 -0
- package/dist/commands/route.js +21 -0
- package/dist/commands/saas.js +25 -0
- package/dist/commands/schedule.js +61 -0
- package/dist/commands/search.js +84 -0
- package/dist/commands/seed.js +71 -0
- package/dist/commands/serve.js +176 -0
- package/dist/commands/setup.js +215 -0
- package/dist/commands/share.d.ts +2 -0
- package/dist/commands/share.js +209 -0
- package/dist/commands/sms.js +328 -0
- package/dist/commands/stacks.d.ts +2 -0
- package/dist/commands/stacks.js +69 -0
- package/dist/commands/telemetry.js +74 -0
- package/dist/commands/test.js +130 -0
- package/dist/commands/tinker.js +37 -0
- package/dist/commands/types.js +18 -0
- package/dist/commands/upgrade.js +97 -0
- package/dist/commands/version.js +16 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +223 -0
- package/dist/custom-cli.d.ts +1 -0
- package/dist/custom-cli.js +23 -0
- package/dist/index.js +1 -3424
- package/dist/lazy-commands.d.ts +61 -0
- package/dist/lazy-commands.js +182 -0
- package/dist/migrators/index.js +62 -0
- package/dist/migrators/laravel/index.js +148 -0
- package/dist/migrators/laravel/migrations.js +231 -0
- package/dist/migrators/laravel/models.js +132 -0
- package/dist/migrators/rails/index.js +11 -0
- package/dist/migrators/types.js +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,164 @@
|
|
|
1
|
-
|
|
2
|
-
var JJ=Object.create;var{getPrototypeOf:QJ,defineProperty:P,getOwnPropertyNames:XJ}=Object;var ZJ=Object.prototype.hasOwnProperty;function $J(J){return this[J]}var WJ,BJ,rJ=(J,Q,Z)=>{var X=J!=null&&typeof J==="object";if(X){var $=Q?WJ??=new WeakMap:BJ??=new WeakMap,W=$.get(J);if(W)return W}Z=J!=null?JJ(QJ(J)):{};let B=Q||!J||!J.__esModule?P(Z,"default",{value:J,enumerable:!0}):Z;for(let G of XJ(J))if(!ZJ.call(B,G))P(B,G,{get:$J.bind(J,G),enumerable:!0});if(X)$.set(J,B);return B};var gJ=(J,Q)=>()=>(Q||J((Q={exports:{}}).exports,Q),Q.exports);var GJ=(J)=>J;function VJ(J,Q){this[J]=GJ.bind(null,Q)}var h=(J,Q)=>{for(var Z in Q)P(J,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:VJ.bind(Q,Z)})};var k=(J,Q)=>()=>(J&&(Q=J(J=0)),Q);var q=import.meta.require;var u={};h(u,{validateConfig:()=>f,loadPlugins:()=>YJ,loadBuddyConfig:()=>p,applyBuddyConfig:()=>HJ});import{existsSync as zJ}from"fs";import{log as L}from"@stacksjs/cli";import{path as I}from"@stacksjs/path";function f(J){let Q=[];if(typeof J!=="object"||J===null)return Q.push({path:"config",message:"Config must be an object",value:J}),Q;if(J.theme!==void 0){let X=["default","dracula","nord","solarized","monokai"];if(typeof J.theme!=="string"||!X.includes(J.theme))Q.push({path:"theme",message:`Theme must be one of: ${X.join(", ")}`,value:J.theme})}if(J.emoji!==void 0&&typeof J.emoji!=="boolean")Q.push({path:"emoji",message:"Emoji must be a boolean",value:J.emoji});if(J.commands!==void 0)if(!Array.isArray(J.commands))Q.push({path:"commands",message:"Commands must be an array",value:J.commands});else J.commands.forEach((X,$)=>{if(typeof X!=="function")Q.push({path:`commands[${$}]`,message:"Each command must be a function",value:X})});if(J.defaultFlags!==void 0)if(typeof J.defaultFlags!=="object"||J.defaultFlags===null)Q.push({path:"defaultFlags",message:"Default flags must be an object",value:J.defaultFlags});else{let X=["verbose","quiet","debug"];for(let $ of Object.keys(J.defaultFlags))if(!X.includes($))Q.push({path:`defaultFlags.${$}`,message:`Unknown flag. Valid flags are: ${X.join(", ")}`,value:J.defaultFlags[$]});else if(typeof J.defaultFlags[$]!=="boolean")Q.push({path:`defaultFlags.${$}`,message:"Flag value must be a boolean",value:J.defaultFlags[$]})}if(J.aliases!==void 0){if(typeof J.aliases!=="object"||J.aliases===null||Array.isArray(J.aliases))Q.push({path:"aliases",message:"Aliases must be an object mapping alias names to command names",value:J.aliases});else for(let[X,$]of Object.entries(J.aliases))if(typeof $!=="string")Q.push({path:`aliases.${X}`,message:"Alias target must be a string",value:$})}if(J.plugins!==void 0)if(!Array.isArray(J.plugins))Q.push({path:"plugins",message:"Plugins must be an array",value:J.plugins});else J.plugins.forEach((X,$)=>{if(typeof X==="string")return;if(typeof X!=="object"||X===null){Q.push({path:`plugins[${$}]`,message:"Each plugin must be an object or a string (module path)",value:X});return}if(!X.name||typeof X.name!=="string")Q.push({path:`plugins[${$}].name`,message:"Plugin must have a name property of type string",value:X.name});if(!X.setup||typeof X.setup!=="function")Q.push({path:`plugins[${$}].setup`,message:"Plugin must have a setup function",value:X.setup});if(X.hooks!==void 0){if(typeof X.hooks!=="object"||X.hooks===null)Q.push({path:`plugins[${$}].hooks`,message:"Plugin hooks must be an object",value:X.hooks})}});let Z=["theme","emoji","commands","defaultFlags","aliases","plugins"];for(let X of Object.keys(J))if(!Z.includes(X))Q.push({path:X,message:`Unknown configuration key. Valid keys are: ${Z.join(", ")}`,value:J[X]});return Q}async function p(){if(A)return A;let J=[I.projectPath("buddy.config.ts"),I.projectPath("buddy.config.js"),I.projectPath(".buddy.config.ts"),I.projectPath(".buddy.config.js")];for(let Q of J)if(zJ(Q))try{L.debug(`Loading buddy config from ${Q}`);let Z=await import(Q),X=Z.default||Z,$=f(X);if($.length>0){L.error("Invalid buddy.config.ts:");for(let W of $)L.error(` - ${W.path}: ${W.message}`);throw Error("Configuration validation failed")}return A=X,A}catch(Z){L.warn(`Failed to load buddy config from ${Q}:`,Z)}return A={},A}async function YJ(J,Q){if(!Q.plugins||Q.plugins.length===0)return;L.debug(`Loading ${Q.plugins.length} plugin(s)`);for(let Z of Q.plugins){let X;if(typeof Z==="string")try{let $=await import(Z);X=$.default||$}catch($){L.error(`Failed to load plugin from ${Z}:`,$);continue}else X=Z;try{if(L.debug(`Initializing plugin: ${X.name}${X.version?` v${X.version}`:""}`),await X.setup(J),X.hooks){if(X.hooks.beforeCommand)J.on("command:*",async($)=>{if(X.hooks?.beforeCommand)await X.hooks.beforeCommand({command:$})});if(X.hooks.afterCommand)J.on("command:*",async($)=>{if(X.hooks?.afterCommand)await X.hooks.afterCommand({command:$})})}L.debug(`Plugin ${X.name} initialized successfully`)}catch($){L.error(`Failed to initialize plugin ${X.name}:`,$)}}}async function HJ(J){let Q=await p();if(Q.emoji!==void 0&&J.options.noEmoji===void 0)J.useEmoji=Q.emoji;if(Q.defaultFlags){if(Q.defaultFlags.verbose&&!J.isVerbose)J.isVerbose=!0;if(Q.defaultFlags.quiet&&!J.isQuiet)J.isQuiet=!0;if(Q.defaultFlags.debug&&!J.isDebug)J.isDebug=!0}if(Q.commands&&Array.isArray(Q.commands)){for(let Z of Q.commands)if(typeof Z==="function")Z(J)}if(Q.aliases)for(let[Z,X]of Object.entries(Q.aliases)){let $=J.commands.find((W)=>W.name===X);if($&&!$.aliasNames.includes(Z))$.aliasNames.push(Z)}}var A=null;var m=()=>{};var b={};h(b,{markLoaded:()=>UJ,loadCommands:()=>C,loadCommandGroup:()=>OJ,loadCommand:()=>t,loadAllCommands:()=>KJ,getCommandsToLoad:()=>AJ,getCommandNames:()=>qJ});function l(J){return`${J.path}#${J.exportName}`}function UJ(J,Q){let Z=Y[Q];if(!Z)return;let X=T.get(J);if(!X)X=new Set,T.set(J,X);X.add(l(Z))}async function t(J,Q){let Z=Y[J];if(!Z)return!1;let X=T.get(Q);if(!X)X=new Set,T.set(Q,X);let $=l(Z);if(X.has($))return!0;X.add($);try{let B=(await import(Z.path))[Z.exportName];if(typeof B==="function")return B(Q),!0;else return!1}catch{return!1}}async function C(J,Q){let Z=(W)=>new Promise((B,G)=>setTimeout(()=>G(Error("timeout")),W)),X=new Set,$=[];for(let W of J){let B=Y[W],G=B?`${B.path}#${B.exportName}`:`name:${W}`;if(X.has(G))continue;X.add(G),$.push(W)}await Promise.all($.map(async(W)=>{try{await Promise.race([t(W,Q),Z(5000)])}catch{}}))}async function OJ(J,Q){let Z=LJ[J];if(Z)await C(Z,Q)}async function KJ(J){let Q=Object.keys(Y);await C(Q,J)}function qJ(){return Object.keys(Y)}function AJ(J){let Q=J[0],Z=Q==="--version"||Q==="-v",X=Q==="--help"||Q==="-h",$=Q==="help";if(Z)return["version"];if(!Q||X||$)return Object.keys(Y);let W=Q.split(":")[0];if(W==="list")return["list",...Object.keys(Y).filter((B)=>B!=="list")];if(Y[W])return[W];if(Q.includes(":")){let B=W;if(Y[B])return[B]}return Object.keys(Y)}var Y,LJ,T;var y=k(()=>{Y={about:{path:"./commands/about.ts",exportName:"about"},add:{path:"./commands/add.ts",exportName:"add"},auth:{path:"./commands/auth.ts",exportName:"auth"},build:{path:"./commands/build.ts",exportName:"build"},cd:{path:"./commands/cd.ts",exportName:"cd"},changelog:{path:"./commands/changelog.ts",exportName:"changelog"},clean:{path:"./commands/clean.ts",exportName:"clean"},cloud:{path:"./commands/cloud.ts",exportName:"cloud"},commit:{path:"./commands/commit.ts",exportName:"commit"},completion:{path:"./commands/completion.ts",exportName:"completion"},"config:migrate":{path:"./commands/config-migrate.ts",exportName:"configMigrate"},configure:{path:"./commands/configure.ts",exportName:"configure"},create:{path:"./commands/create.ts",exportName:"create"},deploy:{path:"./commands/deploy.ts",exportName:"deploy"},dev:{path:"./commands/dev.ts",exportName:"dev"},dns:{path:"./commands/dns.ts",exportName:"dns"},doctor:{path:"./commands/doctor.ts",exportName:"doctor"},domains:{path:"./commands/domains.ts",exportName:"domains"},email:{path:"./commands/email.ts",exportName:"email"},env:{path:"./commands/env.ts",exportName:"env"},"dashboard:install":{path:"./commands/features.ts",exportName:"features"},"dashboard:uninstall":{path:"./commands/features.ts",exportName:"features"},"commerce:install":{path:"./commands/features.ts",exportName:"features"},"commerce:uninstall":{path:"./commands/features.ts",exportName:"features"},"cms:install":{path:"./commands/features.ts",exportName:"features"},"cms:uninstall":{path:"./commands/features.ts",exportName:"features"},"marketing:install":{path:"./commands/features.ts",exportName:"features"},"marketing:uninstall":{path:"./commands/features.ts",exportName:"features"},"monitoring:install":{path:"./commands/features.ts",exportName:"features"},"monitoring:uninstall":{path:"./commands/features.ts",exportName:"features"},"realtime:install":{path:"./commands/features.ts",exportName:"features"},"realtime:uninstall":{path:"./commands/features.ts",exportName:"features"},"queue:install":{path:"./commands/features.ts",exportName:"features"},"queue:uninstall":{path:"./commands/features.ts",exportName:"features"},fresh:{path:"./commands/fresh.ts",exportName:"fresh"},generate:{path:"./commands/generate.ts",exportName:"generate"},http:{path:"./commands/http.ts",exportName:"http"},install:{path:"./commands/install.ts",exportName:"install"},key:{path:"./commands/key.ts",exportName:"key"},lint:{path:"./commands/lint.ts",exportName:"lint"},list:{path:"./commands/list.ts",exportName:"list"},mail:{path:"./commands/mail.ts",exportName:"mailCommands"},"mail:preview":{path:"./commands/mail.ts",exportName:"mailCommands"},maintenance:{path:"./commands/maintenance.ts",exportName:"maintenance"},down:{path:"./commands/maintenance.ts",exportName:"maintenance"},up:{path:"./commands/maintenance.ts",exportName:"maintenance"},status:{path:"./commands/maintenance.ts",exportName:"maintenance"},make:{path:"./commands/make.ts",exportName:"make"},migrate:{path:"./commands/migrate.ts",exportName:"migrate"},"migrate:fresh":{path:"./commands/migrate.ts",exportName:"migrate"},"migrate:switch":{path:"./commands/migrate.ts",exportName:"migrate"},"migrate:dns":{path:"./commands/migrate.ts",exportName:"migrate"},"migrate:project":{path:"./commands/migrate-project.ts",exportName:"migrateProject"},outdated:{path:"./commands/outdated.ts",exportName:"outdated"},package:{path:"./commands/package.ts",exportName:"packageCommands"},phone:{path:"./commands/phone.ts",exportName:"phone"},ports:{path:"./commands/ports.ts",exportName:"ports"},prepublish:{path:"./commands/prepublish.ts",exportName:"prepublish"},projects:{path:"./commands/projects.ts",exportName:"projects"},publish:{path:"./commands/publish.ts",exportName:"publish"},"publish:model":{path:"./commands/publish.ts",exportName:"publish"},"publish:controller":{path:"./commands/publish.ts",exportName:"publish"},"publish:middleware":{path:"./commands/publish.ts",exportName:"publish"},"publish:action":{path:"./commands/publish.ts",exportName:"publish"},"publish:core":{path:"./commands/publish.ts",exportName:"publish"},queue:{path:"./commands/queue.ts",exportName:"queue"},release:{path:"./commands/release.ts",exportName:"release"},route:{path:"./commands/route.ts",exportName:"route"},saas:{path:"./commands/saas.ts",exportName:"saas"},schedule:{path:"./commands/schedule.ts",exportName:"schedule"},search:{path:"./commands/search.ts",exportName:"search"},seed:{path:"./commands/seed.ts",exportName:"seed"},"seed:roles":{path:"./commands/seed.ts",exportName:"seed"},"roles:seed":{path:"./commands/seed.ts",exportName:"seed"},serve:{path:"./commands/serve.ts",exportName:"serve"},"serve:api":{path:"./commands/serve.ts",exportName:"serveApi"},setup:{path:"./commands/setup.ts",exportName:"setup"},share:{path:"./commands/share.ts",exportName:"share"},stack:{path:"./commands/stacks.ts",exportName:"stacks"},sms:{path:"./commands/sms.ts",exportName:"sms"},telemetry:{path:"./commands/telemetry.ts",exportName:"telemetryCommand"},test:{path:"./commands/test.ts",exportName:"test"},tinker:{path:"./commands/tinker.ts",exportName:"tinker"},types:{path:"./commands/types.ts",exportName:"types"},undeploy:{path:"./commands/cloud.ts",exportName:"cloud"},upgrade:{path:"./commands/upgrade.ts",exportName:"upgrade"},version:{path:"./commands/version.ts",exportName:"version"}},LJ={minimal:["version","help"],development:["dev","build","test","lint"],database:["migrate","seed","fresh"],scaffolding:["make","generate"],deployment:["deploy","release","cloud"],info:["about","doctor","list"]},T=new WeakMap});var d={};h(d,{setup:()=>wJ,optimizePantryDeps:()=>s,ensurePantryInstalled:()=>g,ensurePantryDependencies:()=>a,ensureEnvIsSet:()=>i,ensureAppKey:()=>c});import{existsSync as j,readFileSync as r,writeFileSync as DJ}from"fs";import{join as N}from"path";import O from"process";import{runAction as FJ,setupSSL as _J}from"@stacksjs/actions";import{log as V,onUnknownSubcommand as NJ,runCommand as R}from"@stacksjs/cli";import{Action as RJ}from"@stacksjs/enums";import{handleError as M}from"@stacksjs/error-handling";import{path as v}from"@stacksjs/path";import{copyFile as MJ,storage as SJ}from"@stacksjs/storage";import{ExitCode as D}from"@stacksjs/types";function S(J,Q){let Z=Number(O.env[J]);if(Number.isFinite(Z)&&Z>0)return Z;return Q}function wJ(J){let Q={setup:"This command ensures your project is setup correctly",ssl:"Setup SSL certificates and hosts file for HTTPS development",ohMyZsh:"Enable Oh My Zsh",aws:"Ensures AWS is connected to the project",project:"Target a specific project",verbose:"Enable verbose output",domain:"Custom domain to setup (defaults to APP_URL)",skipHosts:"Skip adding domain to hosts file",skipTrust:"Skip trusting the certificate",skipAws:"Skip AWS configuration during setup",skipKeygen:"Skip generating an application key during setup"};J.command("setup",Q.setup).alias("ensure").option("-p, --project [project]",Q.project,{default:!1}).option("--skip-aws",Q.skipAws,{default:!1}).option("--skip-keygen",Q.skipKeygen,{default:!1}).option("--verbose",Q.verbose,{default:!1}).action(async(Z)=>{V.debug("Running `buddy setup` ...",Z),await g(),await s(),await kJ(Z)}),J.command("setup:ssl",Q.ssl).alias("ssl:setup").option("-d, --domain [domain]",Q.domain).option("--skip-hosts",Q.skipHosts,{default:!1}).option("--skip-trust",Q.skipTrust,{default:!1}).option("--verbose",Q.verbose,{default:!1}).action(async(Z)=>{if(V.debug("Running `buddy setup:ssl` ...",Z),!await _J({domain:Z.domain,skipHosts:Z.skipHosts,skipTrust:Z.skipTrust,verbose:Z.verbose}))V.warn("SSL setup completed with warnings"),V.info("You may need to manually trust certificates or update hosts file")}),J.command("setup:oh-my-zsh",Q.ohMyZsh).alias("upgrade:oh-my-zsh").option("--verbose",Q.verbose,{default:!1}).action(async(Z)=>{V.debug("Running `buddy setup:oh-my-zsh` ...",Z);let X=await FJ(RJ.UpgradeShell);if(X.isErr)V.error(X.error),O.exit(D.FatalError)}),NJ(J,"setup")}async function EJ(){if((await R("pantry --version",{silent:!0,timeoutMs:xJ})).isOk)return!0;return!1}async function PJ(){let J=await R(v.frameworkPath("scripts/pantry-install"),{timeoutMs:IJ});if(J.isOk)return;M(J.error),O.exit(D.FatalError)}async function g(){if(!await EJ())await PJ()}async function a(J){V.info("Installing Pantry dependencies...");let Q=await R("pantry install",{cwd:J,timeoutMs:TJ});if(Q.isOk){V.success("Installed Pantry dependencies");return}M(Q.error),O.exit(D.FatalError)}function hJ(J){let Q=N(J,".env");if(!j(Q))return!1;return/^APP_KEY=.+$/m.test(r(Q,"utf-8"))}async function c(J){if(hJ(J)){V.success("APP_KEY existed");return}let Q=await R("./buddy key:generate",{cwd:J,timeoutMs:jJ});if(Q.isErr)M(Q.error),O.exit(D.FatalError);V.success("Generated application key")}async function kJ(J){let Q=J.cwd||v.projectPath();if(await a(Q),await i(J),!J.skipKeygen)await c(Q);if(!J.skipAws){V.info("Ensuring AWS is connected...");let Z=await R("./buddy configure:aws",{cwd:Q,timeoutMs:vJ});if(Z.isErr)M(Z.error),O.exit(D.FatalError);V.success("Configured AWS")}V.success("Project is setup"),V.info("Happy coding! \uD83D\uDC99")}function bJ(J){let Q=N(J,".env"),Z=N(J,".env.example"),X=j(Q)?Q:j(Z)?Z:void 0;if(!X)return;let W=r(X,"utf-8").match(/^DB_CONNECTION=(.+)$/m);if(!W)return;let B=W[1].trim().replace(/['"]/g,"");return CJ[B]}async function s(){let J=v.projectPath(),Q=N(J,"config","deps.ts");if(!j(Q)){V.debug("No config/deps.ts found, skipping dependency optimization");return}let Z={};try{let B=await import(Q),G=B.config||B.default;if(G?.dependencies)Z={...G.dependencies}}catch(B){V.debug("Could not load config/deps.ts, skipping dependency optimization");return}let X=bJ(J);if(X){if(!Object.keys(Z).some((G)=>G===X||G.startsWith(`${X}/`)))V.info(`Detected DB_CONNECTION requires ${X}, adding to dependencies`),Z[X]="*"}let $=["# Auto-generated from config/deps.ts and .env sniffing.","# This file is regenerated on each `buddy setup` run.","#","# To learn more, please visit:","# https://stacksjs.com/docs/dependency-management","","dependencies:"];for(let[B,G]of Object.entries(Z))$.push(` ${B}: ${G}`);let W=N(J,"deps.yaml");DJ(W,`${$.join(`
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { cli, log } from "@stacksjs/cli";
|
|
3
|
+
import { path as p } from "@stacksjs/path";
|
|
4
|
+
const args = process.argv.slice(2), requestedCommand = args[0] || "help", isHelpFlag = args.includes("--help") || args.includes("-h"), isVersionOnly = ["--version", "-v", "version"].includes(requestedCommand), isHelpMode = requestedCommand === "help" || isHelpFlag && args.length <= 2, skipAppKeyCheck = [
|
|
5
|
+
"build",
|
|
6
|
+
"lint",
|
|
7
|
+
"lint:fix",
|
|
8
|
+
"test",
|
|
9
|
+
"test:types",
|
|
10
|
+
"test:unit",
|
|
11
|
+
"test:feature",
|
|
12
|
+
"typecheck",
|
|
13
|
+
"types:fix",
|
|
14
|
+
"types:generate",
|
|
15
|
+
"clean",
|
|
16
|
+
"fresh",
|
|
17
|
+
"about",
|
|
18
|
+
"doctor",
|
|
19
|
+
"setup",
|
|
20
|
+
"setup:ssl",
|
|
21
|
+
"setup:oh-my-zsh",
|
|
22
|
+
"deploy",
|
|
23
|
+
"serve",
|
|
24
|
+
"new",
|
|
25
|
+
"create",
|
|
26
|
+
"migrate",
|
|
27
|
+
"seed",
|
|
28
|
+
"generate",
|
|
29
|
+
"make",
|
|
30
|
+
"key:generate",
|
|
31
|
+
"scaffold:crud"
|
|
32
|
+
].some((cmd) => requestedCommand === cmd || requestedCommand.startsWith(`${cmd}:`)) || isHelpFlag || isHelpMode, needsFullSetup = !isVersionOnly;
|
|
33
|
+
if (needsFullSetup) {
|
|
34
|
+
const reportFatal = (label, error) => {
|
|
35
|
+
log.debug(`Buddy ${label}`);
|
|
36
|
+
try {
|
|
37
|
+
process.stderr.write(`
|
|
38
|
+
[buddy] ${label}: ${error?.stack ?? String(error)}
|
|
39
|
+
`);
|
|
40
|
+
} catch {}
|
|
41
|
+
log.error(error);
|
|
42
|
+
return process.exit(1);
|
|
43
|
+
};
|
|
44
|
+
process.on("uncaughtException", (error) => reportFatal("uncaughtException", error));
|
|
45
|
+
process.on("unhandledRejection", (error) => reportFatal("unhandledRejection", error));
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const buddy = cli("buddy"), configPath = "./buddy.config.js";
|
|
49
|
+
try {
|
|
50
|
+
await Bun.file(configPath).text();
|
|
51
|
+
const { applyBuddyConfig } = await import("./config.js");
|
|
52
|
+
await applyBuddyConfig(buddy);
|
|
53
|
+
} catch {}
|
|
54
|
+
if (needsFullSetup) {
|
|
55
|
+
const { loadCommands, getCommandsToLoad, markLoaded } = await import("./lazy-commands.js"), { setup } = await import("./commands/setup.js");
|
|
56
|
+
setup(buddy);
|
|
57
|
+
markLoaded(buddy, "setup");
|
|
58
|
+
if (!skipAppKeyCheck) {
|
|
59
|
+
const { runAction } = await import("@stacksjs/actions"), { Action } = await import("@stacksjs/enums"), { ensureProjectIsInitialized } = await import("@stacksjs/utils");
|
|
60
|
+
if (!await ensureProjectIsInitialized()) {
|
|
61
|
+
log.info("Your `APP_KEY` is not yet set");
|
|
62
|
+
log.info("Generating application key...");
|
|
63
|
+
const result = await runAction(Action.KeyGenerate);
|
|
64
|
+
if (result.isErr) {
|
|
65
|
+
log.error("Failed to set random application key.", result.error);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const commandsToLoad = getCommandsToLoad(args);
|
|
71
|
+
await loadCommands(commandsToLoad, buddy);
|
|
72
|
+
await dynamicImports(buddy);
|
|
73
|
+
} else {
|
|
74
|
+
const { loadCommand } = await import("./lazy-commands.js");
|
|
75
|
+
await loadCommand("version", buddy);
|
|
76
|
+
}
|
|
77
|
+
buddy.help();
|
|
78
|
+
if (args.length === 0 && process.stdin.isTTY && !buddy.isNoInteraction)
|
|
79
|
+
await showInteractiveMenu(buddy);
|
|
80
|
+
else
|
|
81
|
+
buddy.parse();
|
|
82
|
+
}
|
|
83
|
+
async function showInteractiveMenu(buddy) {
|
|
84
|
+
const { bold, green, intro } = await import("@stacksjs/cli"), { select } = await import("@stacksjs/cli");
|
|
85
|
+
await intro("buddy");
|
|
86
|
+
console.log(bold(green("What would you like to do?")));
|
|
87
|
+
console.log("");
|
|
88
|
+
const choice = await select({
|
|
89
|
+
message: "Select a command:",
|
|
90
|
+
choices: [
|
|
91
|
+
{ value: "dev", label: "Start development server" },
|
|
92
|
+
{ value: "build", label: "Build for production" },
|
|
93
|
+
{ value: "test", label: "Run tests" },
|
|
94
|
+
{ value: "list", label: "List all commands" },
|
|
95
|
+
{ value: "doctor", label: "Run health checks" },
|
|
96
|
+
{ value: "about", label: "Show system information" },
|
|
97
|
+
{ value: "help", label: "Show help" },
|
|
98
|
+
{ value: "exit", label: "Exit" }
|
|
99
|
+
],
|
|
100
|
+
initial: 0
|
|
101
|
+
});
|
|
102
|
+
console.log("");
|
|
103
|
+
if (choice === "exit")
|
|
104
|
+
process.exit(0);
|
|
105
|
+
else if (choice === "help")
|
|
106
|
+
buddy.outputHelp();
|
|
107
|
+
else {
|
|
108
|
+
process.argv = ["bun", "buddy", choice];
|
|
109
|
+
buddy.parse();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
await main();
|
|
113
|
+
async function dynamicImports(buddy) {
|
|
114
|
+
const { fs } = await import("@stacksjs/storage"), commandsDir = p.appPath("Commands");
|
|
115
|
+
try {
|
|
116
|
+
const registry = (await import(p.appPath("Commands.ts"))).default || {};
|
|
117
|
+
for (const [signature, config] of Object.entries(registry)) {
|
|
118
|
+
const commandConfig = typeof config === "string" ? { file: config, enabled: !0 } : config;
|
|
119
|
+
if (commandConfig.enabled === !1)
|
|
120
|
+
continue;
|
|
121
|
+
const commandPath = `${commandsDir}/${commandConfig.file}.ts`;
|
|
122
|
+
if (!fs.existsSync(commandPath)) {
|
|
123
|
+
log.debug(`Command file not found: ${commandPath} (registered as '${signature}')`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const dynamicImport = await import(commandPath);
|
|
128
|
+
if (typeof dynamicImport.default === "function") {
|
|
129
|
+
dynamicImport.default(buddy);
|
|
130
|
+
if (commandConfig.aliases && Array.isArray(commandConfig.aliases))
|
|
131
|
+
for (const alias of commandConfig.aliases)
|
|
132
|
+
buddy.alias(signature, alias);
|
|
133
|
+
} else
|
|
134
|
+
log.error(`Expected a default export function in ${commandConfig.file}.ts, but got:`, dynamicImport.default);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
log.error(`Failed to load command ${commandConfig.file}:`, error);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
if (!fs.existsSync(commandsDir)) {
|
|
141
|
+
log.debug("app/Commands directory not found, skipping user commands");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
log.debug("Commands.ts not found, using auto-discovery");
|
|
145
|
+
const commandFiles = fs.readdirSync(commandsDir).filter((file) => file.endsWith(".ts"));
|
|
146
|
+
for (const file of commandFiles) {
|
|
147
|
+
const commandPath = `${commandsDir}/${file}`;
|
|
148
|
+
try {
|
|
149
|
+
const dynamicImport = await import(commandPath);
|
|
150
|
+
if (typeof dynamicImport.default === "function")
|
|
151
|
+
dynamicImport.default(buddy);
|
|
152
|
+
else
|
|
153
|
+
log.debug(`Skipping ${file} \u2014 no default export function`);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
log.error(`Failed to load command ${file}:`, error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const listenerImport = await import(p.listenersPath("Console.ts"));
|
|
161
|
+
if (typeof listenerImport.default === "function")
|
|
162
|
+
listenerImport.default(buddy);
|
|
163
|
+
} catch {}
|
|
164
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { bold, dim, green, intro, log, onUnknownSubcommand } from "@stacksjs/cli";
|
|
3
|
+
import { storage } from "@stacksjs/storage";
|
|
4
|
+
export function about(buddy) {
|
|
5
|
+
buddy.command("about", "Display diagnostic information about Stacks").action(async () => {
|
|
6
|
+
log.debug("Running `buddy about` ...");
|
|
7
|
+
await intro("buddy about");
|
|
8
|
+
try {
|
|
9
|
+
const stacksVersion = (await storage.readPackageJson("./package.json")).version || "unknown", bunVersion = process.versions.bun || "N/A", nodeVersion = process.versions.node || "N/A", os = process.platform, arch = process.arch, osVersion = process.version, env = process.env.NODE_ENV || process.env.APP_ENV || "development";
|
|
10
|
+
log.info("");
|
|
11
|
+
log.info(green(bold("Stacks Framework")));
|
|
12
|
+
log.info(dim("\u2500".repeat(50)));
|
|
13
|
+
log.info("");
|
|
14
|
+
log.info(bold("Version Information:"));
|
|
15
|
+
log.info(` Stacks: ${dim(stacksVersion)}`);
|
|
16
|
+
log.info(` Bun: ${dim(bunVersion)}`);
|
|
17
|
+
if (nodeVersion !== "N/A")
|
|
18
|
+
log.info(` Node: ${dim(nodeVersion)}`);
|
|
19
|
+
log.info("");
|
|
20
|
+
log.info(bold("Environment:"));
|
|
21
|
+
log.info(` Mode: ${dim(env)}`);
|
|
22
|
+
log.info(` OS: ${dim(`${os} ${arch}`)}`);
|
|
23
|
+
log.info(` Runtime: ${dim(osVersion)}`);
|
|
24
|
+
log.info("");
|
|
25
|
+
log.info(bold("Configuration:"));
|
|
26
|
+
log.info(` Cache: ${dim("file")}`);
|
|
27
|
+
log.info(` Debug: ${dim(process.env.DEBUG ? "enabled" : "disabled")}`);
|
|
28
|
+
log.info("");
|
|
29
|
+
} catch (error) {
|
|
30
|
+
log.error("Failed to retrieve system information:", error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
onUnknownSubcommand(buddy, "about");
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAdd } from "@stacksjs/actions";
|
|
3
|
+
import { log } from "@stacksjs/logging";
|
|
4
|
+
import { ExitCode } from "@stacksjs/types";
|
|
5
|
+
import { onUnknownSubcommand } from "@stacksjs/cli";
|
|
6
|
+
export function add(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
add: "Add a stack to your project (coming soon)",
|
|
9
|
+
table: "Add the Table Stack to your project",
|
|
10
|
+
calendar: "Add the Calendar Stack to your project",
|
|
11
|
+
all: "Add all stacks",
|
|
12
|
+
select: "Which stack/s are you trying to add?",
|
|
13
|
+
project: "Target a specific project",
|
|
14
|
+
verbose: "Enable verbose output"
|
|
15
|
+
};
|
|
16
|
+
buddy.command("add", descriptions.add).option("-t, --table", descriptions.table, { default: !1 }).option("-c, --calendar", descriptions.calendar, { default: !1 }).option("-a, --all", descriptions.all, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
17
|
+
log.debug("Running `buddy add`...", options);
|
|
18
|
+
if (hasNoOptions(options))
|
|
19
|
+
;
|
|
20
|
+
await runAdd(options);
|
|
21
|
+
process.exit(ExitCode.Success);
|
|
22
|
+
});
|
|
23
|
+
buddy.command("add:table", descriptions.table).option("-t, --table", descriptions.table, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
24
|
+
await runAdd(options);
|
|
25
|
+
});
|
|
26
|
+
buddy.command("add:calendar", descriptions.calendar).option("-t, --calendar", descriptions.calendar, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
27
|
+
await runAdd(options);
|
|
28
|
+
});
|
|
29
|
+
onUnknownSubcommand(buddy, "add");
|
|
30
|
+
}
|
|
31
|
+
function hasNoOptions(options) {
|
|
32
|
+
return !options.all && !options.table && !options.calendar;
|
|
33
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
export function auth(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
setup: "Set up authentication (migrations + personal access client)",
|
|
9
|
+
token: "Create a personal access client token",
|
|
10
|
+
client: "Create a new OAuth client",
|
|
11
|
+
prune: "Prune expired and revoked tokens",
|
|
12
|
+
project: "Target a specific project",
|
|
13
|
+
verbose: "Enable verbose output"
|
|
14
|
+
};
|
|
15
|
+
buddy.command("auth:setup", descriptions.setup).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
16
|
+
log.debug("Running `buddy auth:setup` ...", options);
|
|
17
|
+
const perf = await intro("buddy auth:setup"), result = await runAction(Action.AuthSetup, options);
|
|
18
|
+
if (result.isErr) {
|
|
19
|
+
await outro("While setting up authentication, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
20
|
+
process.exit(ExitCode.FatalError);
|
|
21
|
+
}
|
|
22
|
+
await outro("Authentication setup completed successfully.", {
|
|
23
|
+
startTime: perf,
|
|
24
|
+
useSeconds: !0
|
|
25
|
+
});
|
|
26
|
+
process.exit(ExitCode.Success);
|
|
27
|
+
});
|
|
28
|
+
buddy.command("auth:token", descriptions.token).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
29
|
+
log.debug("Running `buddy auth:token` ...", options);
|
|
30
|
+
const perf = await intro("buddy auth:token"), result = await runAction(Action.CreatePersonalAccessClient, options);
|
|
31
|
+
if (result.isErr) {
|
|
32
|
+
await outro("While creating the personal access client token, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
33
|
+
process.exit(ExitCode.FatalError);
|
|
34
|
+
}
|
|
35
|
+
await outro("Personal access client token created successfully.", {
|
|
36
|
+
startTime: perf,
|
|
37
|
+
useSeconds: !0
|
|
38
|
+
});
|
|
39
|
+
process.exit(ExitCode.Success);
|
|
40
|
+
});
|
|
41
|
+
buddy.command("auth:client", descriptions.client).option("-n, --name [name]", "Client name", { default: "OAuth Client" }).option("-r, --redirect [redirect]", "Redirect URI", { default: "http://localhost" }).option("--personal", "Create a personal access client", { default: !1 }).option("--password", "Create a password grant client", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
42
|
+
log.debug("Running `buddy auth:client` ...", options);
|
|
43
|
+
const perf = await intro("buddy auth:client"), result = await runAction(Action.AuthClient, options);
|
|
44
|
+
if (result.isErr) {
|
|
45
|
+
await outro("While creating the OAuth client, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
46
|
+
process.exit(ExitCode.FatalError);
|
|
47
|
+
}
|
|
48
|
+
await outro("OAuth client created successfully.", {
|
|
49
|
+
startTime: perf,
|
|
50
|
+
useSeconds: !0
|
|
51
|
+
});
|
|
52
|
+
process.exit(ExitCode.Success);
|
|
53
|
+
});
|
|
54
|
+
buddy.command("auth:prune", descriptions.prune).option("--expired", "Prune expired tokens (default: true)", { default: !0 }).option("--revoked", "Prune revoked tokens (default: true)", { default: !0 }).option("-d, --days [days]", "Prune revoked tokens older than N days", { default: 7 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
55
|
+
log.debug("Running `buddy auth:prune` ...", options);
|
|
56
|
+
const perf = await intro("buddy auth:prune"), result = await runAction(Action.AuthPrune, options);
|
|
57
|
+
if (result.isErr) {
|
|
58
|
+
await outro("While pruning tokens, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
59
|
+
process.exit(ExitCode.FatalError);
|
|
60
|
+
}
|
|
61
|
+
await outro("Token pruning completed successfully.", {
|
|
62
|
+
startTime: perf,
|
|
63
|
+
useSeconds: !0
|
|
64
|
+
});
|
|
65
|
+
process.exit(ExitCode.Success);
|
|
66
|
+
});
|
|
67
|
+
onUnknownSubcommand(buddy, "auth");
|
|
68
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
3
|
+
import { Action } from "@stacksjs/enums";
|
|
4
|
+
import { ExitCode } from "@stacksjs/types";
|
|
5
|
+
let _runAction;
|
|
6
|
+
async function runAction(...args) {
|
|
7
|
+
if (!_runAction)
|
|
8
|
+
_runAction = (await import("@stacksjs/actions")).runAction;
|
|
9
|
+
return _runAction(...args);
|
|
10
|
+
}
|
|
11
|
+
export function build(buddy) {
|
|
12
|
+
const descriptions = {
|
|
13
|
+
build: "Build any of your libraries (packages) for production use",
|
|
14
|
+
components: "Build your component library",
|
|
15
|
+
webComponents: "Build your framework agnostic web component library",
|
|
16
|
+
elements: "An alias to the -w flag",
|
|
17
|
+
buddy: "Build the Buddy binary",
|
|
18
|
+
functions: "Build your function library",
|
|
19
|
+
desktop: "Build the Desktop Application",
|
|
20
|
+
pages: "Build your frontend",
|
|
21
|
+
docs: "Build your documentation",
|
|
22
|
+
framework: "Build Stacks framework",
|
|
23
|
+
cli: "Automagically build the CLI",
|
|
24
|
+
server: "Build the Stacks cloud server (Docker image)",
|
|
25
|
+
frontendStatic: "Build the prerendered marketing/public static site (storage/framework/frontend-dist)",
|
|
26
|
+
select: "What are you trying to build?",
|
|
27
|
+
project: "Target a specific project",
|
|
28
|
+
verbose: "Enable verbose output"
|
|
29
|
+
};
|
|
30
|
+
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("-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) => {
|
|
31
|
+
log.debug("Running `buddy build` ...", options);
|
|
32
|
+
switch (server) {
|
|
33
|
+
case "components":
|
|
34
|
+
options.components = !0;
|
|
35
|
+
break;
|
|
36
|
+
case "web-components":
|
|
37
|
+
options.webComponents = !0;
|
|
38
|
+
break;
|
|
39
|
+
case "functions":
|
|
40
|
+
options.functions = !0;
|
|
41
|
+
break;
|
|
42
|
+
case "views":
|
|
43
|
+
options.views = !0;
|
|
44
|
+
break;
|
|
45
|
+
case "docs":
|
|
46
|
+
options.docs = !0;
|
|
47
|
+
break;
|
|
48
|
+
case "buddy":
|
|
49
|
+
options.buddy = !0;
|
|
50
|
+
break;
|
|
51
|
+
case "cli":
|
|
52
|
+
options.buddy = !0;
|
|
53
|
+
break;
|
|
54
|
+
case "stacks":
|
|
55
|
+
options.stacks = !0;
|
|
56
|
+
break;
|
|
57
|
+
case "server":
|
|
58
|
+
options.server = !0;
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (hasNoOptions(options))
|
|
64
|
+
options.stacks = !0;
|
|
65
|
+
if (options.docs)
|
|
66
|
+
await runAction(Action.BuildDocs);
|
|
67
|
+
if (options.components)
|
|
68
|
+
await runAction(Action.BuildComponentLibs);
|
|
69
|
+
if (options.webComponents)
|
|
70
|
+
await runAction(Action.BuildWebComponentLib);
|
|
71
|
+
if (options.functions)
|
|
72
|
+
await runAction(Action.BuildFunctionLib);
|
|
73
|
+
if (options.views)
|
|
74
|
+
await runAction(Action.BuildViews);
|
|
75
|
+
if (options.stacks)
|
|
76
|
+
await runAction(Action.BuildStacks);
|
|
77
|
+
if (options.buddy)
|
|
78
|
+
await runAction(Action.BuildCli);
|
|
79
|
+
if (options.server)
|
|
80
|
+
await runAction(Action.BuildServer);
|
|
81
|
+
process.exit(ExitCode.Success);
|
|
82
|
+
});
|
|
83
|
+
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) => {
|
|
84
|
+
log.debug("Running `buddy build:components` ...", options);
|
|
85
|
+
await runAction(Action.BuildComponentLibs, options);
|
|
86
|
+
});
|
|
87
|
+
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) => {
|
|
88
|
+
log.debug("Running `buddy build:cli` ...", options);
|
|
89
|
+
await runAction(Action.BuildCli, options);
|
|
90
|
+
});
|
|
91
|
+
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) => {
|
|
92
|
+
log.debug("Running `buddy build:server` ...", options);
|
|
93
|
+
await runAction(Action.BuildServer, options);
|
|
94
|
+
});
|
|
95
|
+
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) => {
|
|
96
|
+
log.debug("Running `buddy build:functions` ...", options);
|
|
97
|
+
await runAction(Action.BuildFunctionLib, options);
|
|
98
|
+
});
|
|
99
|
+
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, {
|
|
100
|
+
default: !0
|
|
101
|
+
}).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
102
|
+
log.debug("Running `buddy build:web-components` ...", options);
|
|
103
|
+
await runAction(Action.BuildWebComponentLib, options);
|
|
104
|
+
});
|
|
105
|
+
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) => {
|
|
106
|
+
log.debug("Running `buddy build:frontend` ...", options);
|
|
107
|
+
await runAction(Action.BuildViews, options);
|
|
108
|
+
});
|
|
109
|
+
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) => {
|
|
110
|
+
log.debug("Running `buddy build:docs` ...", options);
|
|
111
|
+
await runAction(Action.BuildDocs, options);
|
|
112
|
+
});
|
|
113
|
+
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) => {
|
|
114
|
+
log.debug("Running `buddy build:frontend-static` ...", options);
|
|
115
|
+
await runAction(Action.BuildFrontendStatic, options);
|
|
116
|
+
});
|
|
117
|
+
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) => {
|
|
118
|
+
log.debug("Running `buddy build:core` ...", options);
|
|
119
|
+
const startTime = await intro("buddy build:core"), result = await runAction(Action.BuildCore, options);
|
|
120
|
+
if (result.isErr) {
|
|
121
|
+
log.error("Failed to build the Stacks core.", result.error);
|
|
122
|
+
process.exit(ExitCode.FatalError);
|
|
123
|
+
}
|
|
124
|
+
await outro("Core packages built successfully", {
|
|
125
|
+
startTime,
|
|
126
|
+
useSeconds: !0
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
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) => {
|
|
130
|
+
log.debug("Running `buddy build:desktop` ...", options);
|
|
131
|
+
const perf = await intro("buddy build:desktop"), result = await runAction(Action.BuildDesktop, options);
|
|
132
|
+
if (result.isErr) {
|
|
133
|
+
await outro("While running the build:desktop command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
134
|
+
process.exit(ExitCode.FatalError);
|
|
135
|
+
}
|
|
136
|
+
console.log("");
|
|
137
|
+
await outro("Exited", { startTime: perf, useSeconds: !0 });
|
|
138
|
+
process.exit(ExitCode.Success);
|
|
139
|
+
});
|
|
140
|
+
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) => {
|
|
141
|
+
log.debug("Running `buddy build:stacks` ...", options);
|
|
142
|
+
const startTime = await intro("buddy build:stacks"), result = await runAction(Action.BuildStacks, options);
|
|
143
|
+
if (result.isErr) {
|
|
144
|
+
log.error("Failed to build Stacks.", result.error);
|
|
145
|
+
process.exit(ExitCode.FatalError);
|
|
146
|
+
}
|
|
147
|
+
await outro("Stacks built successfully", { startTime, useSeconds: !0 });
|
|
148
|
+
});
|
|
149
|
+
onUnknownSubcommand(buddy, "build");
|
|
150
|
+
}
|
|
151
|
+
function hasNoOptions(options) {
|
|
152
|
+
return !options.components && !options.webComponents && !options.elements && !options.functions && !options.views && !options.docs && !options.stacks && !options.buddy && !options.server;
|
|
153
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { ExitCode } from "@stacksjs/types";
|
|
4
|
+
import { findStacksProjects } from "@stacksjs/utils";
|
|
5
|
+
export function cd(buddy) {
|
|
6
|
+
buddy.command("cd [name]", "Print the absolute path of a Stacks project by name").option("--eval", 'Emit `cd "path"` instead of just the path \u2014 pair with `eval "$(buddy cd <name> --eval)"` for real shell-cd', { default: !1 }).option("--root <dir>", "Search root for the project scan (overrides STACKS_PROJECTS_ROOT and the home-dir default)").option("--verbose", "Enable verbose output", { default: !1 }).action(async (name, options) => {
|
|
7
|
+
if (!name) {
|
|
8
|
+
process.stderr.write(`Usage: buddy cd <project-name> [--eval] [--root <dir>]
|
|
9
|
+
`);
|
|
10
|
+
process.stderr.write('Tip: add `bcd() { eval "$(buddy cd "$1" --eval)"; }` to your shell rc to make this act like a real `cd`.\n');
|
|
11
|
+
process.exit(ExitCode.FatalError);
|
|
12
|
+
}
|
|
13
|
+
const root = options.root ?? process.env.STACKS_PROJECTS_ROOT ?? void 0, projects = await findStacksProjects(root, { quiet: !0 }), needle = name.toLowerCase(), exact = projects.filter((p) => basename(p).toLowerCase() === needle), matches = exact.length > 0 ? exact : projects.filter((p) => basename(p).toLowerCase().includes(needle));
|
|
14
|
+
if (matches.length === 0) {
|
|
15
|
+
process.stderr.write(`No Stacks project matched: ${name}
|
|
16
|
+
`);
|
|
17
|
+
if (!root)
|
|
18
|
+
process.stderr.write(`(Scanned home dir, excluding ~/Documents, ~/Library, ~/Pictures, ~/.Trash. Set STACKS_PROJECTS_ROOT or pass --root <dir> to scan elsewhere.)
|
|
19
|
+
`);
|
|
20
|
+
process.exit(ExitCode.FatalError);
|
|
21
|
+
}
|
|
22
|
+
if (matches.length > 1) {
|
|
23
|
+
process.stderr.write(`Ambiguous project name "${name}". Matches:
|
|
24
|
+
`);
|
|
25
|
+
for (const m of matches)
|
|
26
|
+
process.stderr.write(` - ${basename(m)} \u2192 ${m}
|
|
27
|
+
`);
|
|
28
|
+
process.exit(ExitCode.FatalError);
|
|
29
|
+
}
|
|
30
|
+
const dest = matches[0];
|
|
31
|
+
if (options.eval)
|
|
32
|
+
process.stdout.write(`cd ${JSON.stringify(dest)}
|
|
33
|
+
`);
|
|
34
|
+
else
|
|
35
|
+
process.stdout.write(`${dest}
|
|
36
|
+
`);
|
|
37
|
+
process.exit(ExitCode.Success);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
export function changelog(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
changelog: "Create a CHANGELOG.md file",
|
|
9
|
+
quiet: "Minimal output",
|
|
10
|
+
dryRun: "Do not write the file, just output the changes",
|
|
11
|
+
from: "Start git revision for generated changelog",
|
|
12
|
+
project: "Target a specific project",
|
|
13
|
+
to: "End git revision for generated changelog",
|
|
14
|
+
verbose: "Enable verbose output",
|
|
15
|
+
version: "Version heading to use for the generated changelog entry"
|
|
16
|
+
};
|
|
17
|
+
buddy.command("changelog", descriptions.changelog).option("-q, --quiet", descriptions.quiet, { default: !1 }).option("-d, --dry-run", descriptions.dryRun, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--from <revision>", descriptions.from).option("--to <revision>", descriptions.to).option("--version <version>", descriptions.version).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
18
|
+
log.debug("Running `buddy changelog` ...", options);
|
|
19
|
+
const perf = await intro("buddy changelog"), result = await runAction(Action.Changelog, options);
|
|
20
|
+
if (result.isErr) {
|
|
21
|
+
await outro("While running the changelog command, there was an issue", { ...options, startTime: perf, useSeconds: !0 }, result.error);
|
|
22
|
+
process.exit(ExitCode.FatalError);
|
|
23
|
+
}
|
|
24
|
+
await outro("Generated CHANGELOG.md", {
|
|
25
|
+
...options,
|
|
26
|
+
startTime: perf,
|
|
27
|
+
useSeconds: !0,
|
|
28
|
+
type: "success"
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
onUnknownSubcommand(buddy, "changelog");
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { runAction } from "@stacksjs/actions";
|
|
3
|
+
import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
|
|
4
|
+
import { Action } from "@stacksjs/enums";
|
|
5
|
+
import { ExitCode } from "@stacksjs/types";
|
|
6
|
+
export function clean(buddy) {
|
|
7
|
+
const descriptions = {
|
|
8
|
+
clean: "Removes all node_modules & lock files",
|
|
9
|
+
project: "Target a specific project",
|
|
10
|
+
verbose: "Enable verbose output"
|
|
11
|
+
};
|
|
12
|
+
buddy.command("clean", descriptions.clean).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
|
|
13
|
+
log.debug("Running `buddy clean` ...", options);
|
|
14
|
+
if (!buddy.isForce && !buddy.isNoInteraction) {
|
|
15
|
+
const { confirm } = await import("@stacksjs/cli");
|
|
16
|
+
if (!await confirm({
|
|
17
|
+
message: "This will remove all node_modules and lock files. Continue?",
|
|
18
|
+
initial: !1
|
|
19
|
+
})) {
|
|
20
|
+
log.info("Clean cancelled");
|
|
21
|
+
process.exit(ExitCode.Success);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const perf = await intro("buddy clean"), result = await runAction(Action.Clean, options);
|
|
25
|
+
if (result.isErr) {
|
|
26
|
+
await outro("While running the clean command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
|
|
27
|
+
process.exit(ExitCode.FatalError);
|
|
28
|
+
}
|
|
29
|
+
await outro("Cleaned up", {
|
|
30
|
+
startTime: perf,
|
|
31
|
+
useSeconds: !0,
|
|
32
|
+
message: "Cleaned up"
|
|
33
|
+
});
|
|
34
|
+
process.exit(ExitCode.Success);
|
|
35
|
+
});
|
|
36
|
+
onUnknownSubcommand(buddy, "clean");
|
|
37
|
+
}
|