@stacksjs/buddy 0.70.258 → 0.70.260
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.d.ts +11 -1
- package/dist/cli.js +5 -164
- package/dist/commands/about.js +1 -35
- package/dist/commands/add.js +1 -25
- package/dist/commands/ai-context.js +4 -27
- package/dist/commands/auth.js +1 -68
- package/dist/commands/build.js +1 -221
- package/dist/commands/cd.js +8 -39
- package/dist/commands/changelog.js +1 -32
- package/dist/commands/clean.js +1 -44
- package/dist/commands/cloud.js +2 -519
- package/dist/commands/commit.js +1 -16
- package/dist/commands/completion.js +6 -42
- package/dist/commands/config-migrate.js +6 -94
- package/dist/commands/configure.js +2 -45
- package/dist/commands/create.js +1 -162
- package/dist/commands/deploy.js +13 -1676
- package/dist/commands/desktop-apple.js +12 -399
- package/dist/commands/dev.js +6 -1083
- package/dist/commands/dns.js +3 -103
- package/dist/commands/docs/buddy-commands.js +10 -132
- package/dist/commands/docs/buddy-commands.test.js +1 -38
- package/dist/commands/docs/framework-repo.js +1 -14
- package/dist/commands/docs/framework-repo.test.js +1 -68
- package/dist/commands/docs/generated-artifacts.js +3 -70
- package/dist/commands/docs/generated-artifacts.test.js +1 -19
- package/dist/commands/docs/links.js +2 -85
- package/dist/commands/docs/links.test.js +4 -66
- package/dist/commands/docs.js +1 -24
- package/dist/commands/doctor.js +2 -478
- package/dist/commands/domains.js +2 -152
- package/dist/commands/email.js +31 -503
- package/dist/commands/env.js +1 -312
- package/dist/commands/extension.js +1 -239
- package/dist/commands/features.js +9 -345
- package/dist/commands/fresh.js +1 -46
- package/dist/commands/generate.js +2 -152
- package/dist/commands/http.js +1 -33
- package/dist/commands/index.js +1 -57
- package/dist/commands/install.js +1 -22
- package/dist/commands/key.js +1 -23
- package/dist/commands/link.js +2 -147
- package/dist/commands/lint.js +2 -84
- package/dist/commands/list.js +1 -140
- package/dist/commands/mail.js +15 -1477
- package/dist/commands/maintenance.js +1 -141
- package/dist/commands/make.js +1 -392
- package/dist/commands/migrate-project.js +1 -49
- package/dist/commands/migrate.js +27 -625
- package/dist/commands/outdated.js +1 -19
- package/dist/commands/package.js +1 -17
- package/dist/commands/phone.js +17 -181
- package/dist/commands/ports.js +2 -118
- package/dist/commands/prepublish.js +1 -17
- package/dist/commands/projects.js +1 -29
- package/dist/commands/protocol/craft-evidence.js +4 -98
- package/dist/commands/protocol/craft-evidence.test.js +1 -20
- package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
- package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
- package/dist/commands/protocol/desktop-support.js +2 -32
- package/dist/commands/protocol/desktop-workflow.test.js +3 -35
- package/dist/commands/protocol/driver-registry.js +2 -71
- package/dist/commands/protocol/pantry-evidence.js +4 -144
- package/dist/commands/protocol/pantry-evidence.test.js +1 -29
- package/dist/commands/protocol/release-manifest.js +3 -102
- package/dist/commands/protocol/release-manifest.test.js +2 -34
- package/dist/commands/protocol/run-conformance.js +4 -346
- package/dist/commands/protocol/run-conformance.test.js +1 -52
- package/dist/commands/protocol/run-driver-contracts.js +4 -83
- package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
- package/dist/commands/protocol/source-manifest.js +3 -113
- package/dist/commands/protocol/sync-suite.js +3 -136
- package/dist/commands/protocol/sync-suite.test.js +1 -44
- package/dist/commands/protocol.js +1 -60
- package/dist/commands/publish.js +8 -500
- package/dist/commands/queue.js +1 -248
- package/dist/commands/release.js +1 -42
- package/dist/commands/route.js +1 -21
- package/dist/commands/run-tool.js +1 -9
- package/dist/commands/saas.js +1 -25
- package/dist/commands/schedule.js +1 -61
- package/dist/commands/search.js +1 -84
- package/dist/commands/seed.js +1 -47
- package/dist/commands/serve.js +1 -55
- package/dist/commands/setup-ai.js +2 -121
- package/dist/commands/setup.js +2 -305
- package/dist/commands/share.js +1 -214
- package/dist/commands/sms.js +32 -319
- package/dist/commands/stacks.js +1 -72
- package/dist/commands/telemetry.js +1 -74
- package/dist/commands/test.js +1 -130
- package/dist/commands/tinker.js +1 -37
- package/dist/commands/types.js +1 -18
- package/dist/commands/upgrade.js +1 -98
- package/dist/commands/user.js +3 -84
- package/dist/commands/version.js +1 -14
- package/dist/config.js +1 -231
- package/dist/custom-cli.js +1 -23
- package/dist/database-preflight.js +1 -88
- package/dist/global-options.js +1 -4
- package/dist/index.js +1 -1
- package/dist/lazy-commands.js +1 -241
- package/dist/migrators/index.js +2 -62
- package/dist/migrators/laravel/index.js +1 -148
- package/dist/migrators/laravel/migrations.js +4 -231
- package/dist/migrators/laravel/models.js +8 -111
- package/dist/migrators/rails/index.js +1 -11
- package/dist/production-server.js +1 -257
- package/dist/project-setup.js +1 -36
- package/dist/serve-entry.js +1 -5
- package/dist/version-info.js +1 -5
- package/package.json +53 -46
package/dist/config.js
CHANGED
|
@@ -1,231 +1 @@
|
|
|
1
|
-
import { existsSync } from "
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
|
-
import { log } from "@stacksjs/cli";
|
|
4
|
-
import { path as p } from "@stacksjs/path";
|
|
5
|
-
export async function loadProjectDnsConfig(fallback) {
|
|
6
|
-
const configPath = p.projectConfigPath("dns.ts");
|
|
7
|
-
if (!existsSync(configPath))
|
|
8
|
-
return fallback;
|
|
9
|
-
const loaded = await import(`${pathToFileURL(configPath).href}?updated=${Date.now()}`);
|
|
10
|
-
return loaded.default ?? loaded.dns ?? fallback;
|
|
11
|
-
}
|
|
12
|
-
export function validateConfig(config) {
|
|
13
|
-
const errors = [];
|
|
14
|
-
if (typeof config !== "object" || config === null) {
|
|
15
|
-
errors.push({
|
|
16
|
-
path: "config",
|
|
17
|
-
message: "Config must be an object",
|
|
18
|
-
value: config
|
|
19
|
-
});
|
|
20
|
-
return errors;
|
|
21
|
-
}
|
|
22
|
-
if (config.theme !== void 0) {
|
|
23
|
-
const validThemes = ["default", "dracula", "nord", "solarized", "monokai"];
|
|
24
|
-
if (typeof config.theme !== "string" || !validThemes.includes(config.theme))
|
|
25
|
-
errors.push({
|
|
26
|
-
path: "theme",
|
|
27
|
-
message: `Theme must be one of: ${validThemes.join(", ")}`,
|
|
28
|
-
value: config.theme
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (config.emoji !== void 0 && typeof config.emoji !== "boolean")
|
|
32
|
-
errors.push({
|
|
33
|
-
path: "emoji",
|
|
34
|
-
message: "Emoji must be a boolean",
|
|
35
|
-
value: config.emoji
|
|
36
|
-
});
|
|
37
|
-
if (config.commands !== void 0)
|
|
38
|
-
if (!Array.isArray(config.commands))
|
|
39
|
-
errors.push({
|
|
40
|
-
path: "commands",
|
|
41
|
-
message: "Commands must be an array",
|
|
42
|
-
value: config.commands
|
|
43
|
-
});
|
|
44
|
-
else
|
|
45
|
-
config.commands.forEach((cmd, index) => {
|
|
46
|
-
if (typeof cmd !== "function")
|
|
47
|
-
errors.push({
|
|
48
|
-
path: `commands[${index}]`,
|
|
49
|
-
message: "Each command must be a function",
|
|
50
|
-
value: cmd
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
if (config.defaultFlags !== void 0)
|
|
54
|
-
if (typeof config.defaultFlags !== "object" || config.defaultFlags === null)
|
|
55
|
-
errors.push({
|
|
56
|
-
path: "defaultFlags",
|
|
57
|
-
message: "Default flags must be an object",
|
|
58
|
-
value: config.defaultFlags
|
|
59
|
-
});
|
|
60
|
-
else {
|
|
61
|
-
const flagKeys = ["verbose", "quiet", "debug"];
|
|
62
|
-
for (const key of Object.keys(config.defaultFlags))
|
|
63
|
-
if (!flagKeys.includes(key))
|
|
64
|
-
errors.push({
|
|
65
|
-
path: `defaultFlags.${key}`,
|
|
66
|
-
message: `Unknown flag. Valid flags are: ${flagKeys.join(", ")}`,
|
|
67
|
-
value: config.defaultFlags[key]
|
|
68
|
-
});
|
|
69
|
-
else if (typeof config.defaultFlags[key] !== "boolean")
|
|
70
|
-
errors.push({
|
|
71
|
-
path: `defaultFlags.${key}`,
|
|
72
|
-
message: "Flag value must be a boolean",
|
|
73
|
-
value: config.defaultFlags[key]
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
if (config.aliases !== void 0) {
|
|
77
|
-
if (typeof config.aliases !== "object" || config.aliases === null || Array.isArray(config.aliases))
|
|
78
|
-
errors.push({
|
|
79
|
-
path: "aliases",
|
|
80
|
-
message: "Aliases must be an object mapping alias names to command names",
|
|
81
|
-
value: config.aliases
|
|
82
|
-
});
|
|
83
|
-
else
|
|
84
|
-
for (const [alias, command] of Object.entries(config.aliases))
|
|
85
|
-
if (typeof command !== "string")
|
|
86
|
-
errors.push({
|
|
87
|
-
path: `aliases.${alias}`,
|
|
88
|
-
message: "Alias target must be a string",
|
|
89
|
-
value: command
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
if (config.plugins !== void 0)
|
|
93
|
-
if (!Array.isArray(config.plugins))
|
|
94
|
-
errors.push({
|
|
95
|
-
path: "plugins",
|
|
96
|
-
message: "Plugins must be an array",
|
|
97
|
-
value: config.plugins
|
|
98
|
-
});
|
|
99
|
-
else
|
|
100
|
-
config.plugins.forEach((plugin, index) => {
|
|
101
|
-
if (typeof plugin === "string")
|
|
102
|
-
return;
|
|
103
|
-
if (typeof plugin !== "object" || plugin === null) {
|
|
104
|
-
errors.push({
|
|
105
|
-
path: `plugins[${index}]`,
|
|
106
|
-
message: "Each plugin must be an object or a string (module path)",
|
|
107
|
-
value: plugin
|
|
108
|
-
});
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (!plugin.name || typeof plugin.name !== "string")
|
|
112
|
-
errors.push({
|
|
113
|
-
path: `plugins[${index}].name`,
|
|
114
|
-
message: "Plugin must have a name property of type string",
|
|
115
|
-
value: plugin.name
|
|
116
|
-
});
|
|
117
|
-
if (!plugin.setup || typeof plugin.setup !== "function")
|
|
118
|
-
errors.push({
|
|
119
|
-
path: `plugins[${index}].setup`,
|
|
120
|
-
message: "Plugin must have a setup function",
|
|
121
|
-
value: plugin.setup
|
|
122
|
-
});
|
|
123
|
-
if (plugin.hooks !== void 0) {
|
|
124
|
-
if (typeof plugin.hooks !== "object" || plugin.hooks === null)
|
|
125
|
-
errors.push({
|
|
126
|
-
path: `plugins[${index}].hooks`,
|
|
127
|
-
message: "Plugin hooks must be an object",
|
|
128
|
-
value: plugin.hooks
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
const validKeys = ["theme", "emoji", "commands", "defaultFlags", "aliases", "plugins"];
|
|
133
|
-
for (const key of Object.keys(config))
|
|
134
|
-
if (!validKeys.includes(key))
|
|
135
|
-
errors.push({
|
|
136
|
-
path: key,
|
|
137
|
-
message: `Unknown configuration key. Valid keys are: ${validKeys.join(", ")}`,
|
|
138
|
-
value: config[key]
|
|
139
|
-
});
|
|
140
|
-
return errors;
|
|
141
|
-
}
|
|
142
|
-
let cachedConfig = null;
|
|
143
|
-
export async function loadBuddyConfig() {
|
|
144
|
-
if (cachedConfig)
|
|
145
|
-
return cachedConfig;
|
|
146
|
-
const configPaths = [
|
|
147
|
-
p.projectPath("buddy.config.ts"),
|
|
148
|
-
p.projectPath("buddy.config.js"),
|
|
149
|
-
p.projectPath(".buddy.config.ts"),
|
|
150
|
-
p.projectPath(".buddy.config.js")
|
|
151
|
-
];
|
|
152
|
-
for (const configPath of configPaths)
|
|
153
|
-
if (existsSync(configPath))
|
|
154
|
-
try {
|
|
155
|
-
log.debug(`Loading buddy config from ${configPath}`);
|
|
156
|
-
const configModule = await import(configPath), config = configModule.default || configModule, validationErrors = validateConfig(config);
|
|
157
|
-
if (validationErrors.length > 0) {
|
|
158
|
-
log.error("Invalid buddy.config.ts:");
|
|
159
|
-
for (const error of validationErrors)
|
|
160
|
-
log.error(` - ${error.path}: ${error.message}`);
|
|
161
|
-
throw Error("Configuration validation failed");
|
|
162
|
-
}
|
|
163
|
-
cachedConfig = config;
|
|
164
|
-
return config;
|
|
165
|
-
} catch (error) {
|
|
166
|
-
log.warn(`Failed to load buddy config from ${configPath}:`, error);
|
|
167
|
-
}
|
|
168
|
-
cachedConfig = {};
|
|
169
|
-
return cachedConfig;
|
|
170
|
-
}
|
|
171
|
-
export async function loadPlugins(cli, config) {
|
|
172
|
-
if (!config.plugins || config.plugins.length === 0)
|
|
173
|
-
return;
|
|
174
|
-
log.debug(`Loading ${config.plugins.length} plugin(s)`);
|
|
175
|
-
for (const pluginConfig of config.plugins) {
|
|
176
|
-
let plugin;
|
|
177
|
-
if (typeof pluginConfig === "string")
|
|
178
|
-
try {
|
|
179
|
-
const pluginModule = await import(pluginConfig);
|
|
180
|
-
plugin = pluginModule.default || pluginModule;
|
|
181
|
-
} catch (error) {
|
|
182
|
-
log.error(`Failed to load plugin from ${pluginConfig}:`, error);
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
else
|
|
186
|
-
plugin = pluginConfig;
|
|
187
|
-
try {
|
|
188
|
-
log.debug(`Initializing plugin: ${plugin.name}${plugin.version ? ` v${plugin.version}` : ""}`);
|
|
189
|
-
await plugin.setup(cli);
|
|
190
|
-
if (plugin.hooks) {
|
|
191
|
-
if (plugin.hooks.beforeCommand)
|
|
192
|
-
cli.on("command:*", async (command) => {
|
|
193
|
-
if (plugin.hooks?.beforeCommand)
|
|
194
|
-
await plugin.hooks.beforeCommand({ command });
|
|
195
|
-
});
|
|
196
|
-
if (plugin.hooks.afterCommand)
|
|
197
|
-
cli.on("command:*", async (command) => {
|
|
198
|
-
if (plugin.hooks?.afterCommand)
|
|
199
|
-
await plugin.hooks.afterCommand({ command });
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
log.debug(`Plugin ${plugin.name} initialized successfully`);
|
|
203
|
-
} catch (error) {
|
|
204
|
-
log.error(`Failed to initialize plugin ${plugin.name}:`, error);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
export async function applyBuddyConfig(buddy) {
|
|
209
|
-
const config = await loadBuddyConfig();
|
|
210
|
-
if (config.emoji !== void 0 && buddy.options.noEmoji === void 0)
|
|
211
|
-
buddy.useEmoji = config.emoji;
|
|
212
|
-
if (config.defaultFlags) {
|
|
213
|
-
if (config.defaultFlags.verbose && !buddy.isVerbose)
|
|
214
|
-
buddy.isVerbose = !0;
|
|
215
|
-
if (config.defaultFlags.quiet && !buddy.isQuiet)
|
|
216
|
-
buddy.isQuiet = !0;
|
|
217
|
-
if (config.defaultFlags.debug && !buddy.isDebug)
|
|
218
|
-
buddy.isDebug = !0;
|
|
219
|
-
}
|
|
220
|
-
if (config.commands && Array.isArray(config.commands)) {
|
|
221
|
-
for (const registerCommand of config.commands)
|
|
222
|
-
if (typeof registerCommand === "function")
|
|
223
|
-
registerCommand(buddy);
|
|
224
|
-
}
|
|
225
|
-
if (config.aliases)
|
|
226
|
-
for (const [alias, command] of Object.entries(config.aliases)) {
|
|
227
|
-
const targetCommand = buddy.commands.find((cmd) => cmd.name === command);
|
|
228
|
-
if (targetCommand && !targetCommand.aliasNames.includes(alias))
|
|
229
|
-
targetCommand.aliasNames.push(alias);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
1
|
+
import{existsSync}from"node:fs";import{pathToFileURL}from"node:url";import{log}from"@stacksjs/cli";import{path as p}from"@stacksjs/path";export async function loadProjectDnsConfig(fallback){const configPath=p.projectConfigPath("dns.ts");if(!existsSync(configPath))return fallback;const loaded=await import(`${pathToFileURL(configPath).href}?updated=${Date.now()}`);return loaded.default??loaded.dns??fallback}export function validateConfig(config){const errors=[];if(typeof config!=="object"||config===null){errors.push({path:"config",message:"Config must be an object",value:config});return errors}if(config.theme!==void 0){const validThemes=["default","dracula","nord","solarized","monokai"];if(typeof config.theme!=="string"||!validThemes.includes(config.theme))errors.push({path:"theme",message:`Theme must be one of: ${validThemes.join(", ")}`,value:config.theme})}if(config.emoji!==void 0&&typeof config.emoji!=="boolean")errors.push({path:"emoji",message:"Emoji must be a boolean",value:config.emoji});if(config.commands!==void 0)if(!Array.isArray(config.commands))errors.push({path:"commands",message:"Commands must be an array",value:config.commands});else config.commands.forEach((cmd,index)=>{if(typeof cmd!=="function")errors.push({path:`commands[${index}]`,message:"Each command must be a function",value:cmd})});if(config.defaultFlags!==void 0)if(typeof config.defaultFlags!=="object"||config.defaultFlags===null)errors.push({path:"defaultFlags",message:"Default flags must be an object",value:config.defaultFlags});else{const flagKeys=["verbose","quiet","debug"];for(const key of Object.keys(config.defaultFlags))if(!flagKeys.includes(key))errors.push({path:`defaultFlags.${key}`,message:`Unknown flag. Valid flags are: ${flagKeys.join(", ")}`,value:config.defaultFlags[key]});else if(typeof config.defaultFlags[key]!=="boolean")errors.push({path:`defaultFlags.${key}`,message:"Flag value must be a boolean",value:config.defaultFlags[key]})}if(config.aliases!==void 0){if(typeof config.aliases!=="object"||config.aliases===null||Array.isArray(config.aliases))errors.push({path:"aliases",message:"Aliases must be an object mapping alias names to command names",value:config.aliases});else for(const[alias,command]of Object.entries(config.aliases))if(typeof command!=="string")errors.push({path:`aliases.${alias}`,message:"Alias target must be a string",value:command})}if(config.plugins!==void 0)if(!Array.isArray(config.plugins))errors.push({path:"plugins",message:"Plugins must be an array",value:config.plugins});else config.plugins.forEach((plugin,index)=>{if(typeof plugin==="string")return;if(typeof plugin!=="object"||plugin===null){errors.push({path:`plugins[${index}]`,message:"Each plugin must be an object or a string (module path)",value:plugin});return}if(!plugin.name||typeof plugin.name!=="string")errors.push({path:`plugins[${index}].name`,message:"Plugin must have a name property of type string",value:plugin.name});if(!plugin.setup||typeof plugin.setup!=="function")errors.push({path:`plugins[${index}].setup`,message:"Plugin must have a setup function",value:plugin.setup});if(plugin.hooks!==void 0){if(typeof plugin.hooks!=="object"||plugin.hooks===null)errors.push({path:`plugins[${index}].hooks`,message:"Plugin hooks must be an object",value:plugin.hooks})}});const validKeys=["theme","emoji","commands","defaultFlags","aliases","plugins"];for(const key of Object.keys(config))if(!validKeys.includes(key))errors.push({path:key,message:`Unknown configuration key. Valid keys are: ${validKeys.join(", ")}`,value:config[key]});return errors}let cachedConfig=null;export async function loadBuddyConfig(){if(cachedConfig)return cachedConfig;const configPaths=[p.projectPath("buddy.config.ts"),p.projectPath("buddy.config.js"),p.projectPath(".buddy.config.ts"),p.projectPath(".buddy.config.js")];for(const configPath of configPaths)if(existsSync(configPath))try{log.debug(`Loading buddy config from ${configPath}`);const configModule=await import(configPath),config=configModule.default||configModule,validationErrors=validateConfig(config);if(validationErrors.length>0){log.error("Invalid buddy.config.ts:");for(const error of validationErrors)log.error(` - ${error.path}: ${error.message}`);throw Error("Configuration validation failed")}cachedConfig=config;return config}catch(error){log.warn(`Failed to load buddy config from ${configPath}:`,error)}cachedConfig={};return cachedConfig}export async function loadPlugins(cli,config){if(!config.plugins||config.plugins.length===0)return;log.debug(`Loading ${config.plugins.length} plugin(s)`);for(const pluginConfig of config.plugins){let plugin;if(typeof pluginConfig==="string")try{const pluginModule=await import(pluginConfig);plugin=pluginModule.default||pluginModule}catch(error){log.error(`Failed to load plugin from ${pluginConfig}:`,error);continue}else plugin=pluginConfig;try{log.debug(`Initializing plugin: ${plugin.name}${plugin.version?` v${plugin.version}`:""}`);await plugin.setup(cli);if(plugin.hooks){if(plugin.hooks.beforeCommand)cli.on("command:*",async(command)=>{if(plugin.hooks?.beforeCommand)await plugin.hooks.beforeCommand({command})});if(plugin.hooks.afterCommand)cli.on("command:*",async(command)=>{if(plugin.hooks?.afterCommand)await plugin.hooks.afterCommand({command})})}log.debug(`Plugin ${plugin.name} initialized successfully`)}catch(error){log.error(`Failed to initialize plugin ${plugin.name}:`,error)}}}export async function applyBuddyConfig(buddy){const config=await loadBuddyConfig();if(config.emoji!==void 0&&buddy.options.noEmoji===void 0)buddy.useEmoji=config.emoji;if(config.defaultFlags){if(config.defaultFlags.verbose&&!buddy.isVerbose)buddy.isVerbose=!0;if(config.defaultFlags.quiet&&!buddy.isQuiet)buddy.isQuiet=!0;if(config.defaultFlags.debug&&!buddy.isDebug)buddy.isDebug=!0}if(config.commands&&Array.isArray(config.commands)){for(const registerCommand of config.commands)if(typeof registerCommand==="function")registerCommand(buddy)}if(config.aliases)for(const[alias,command]of Object.entries(config.aliases)){const targetCommand=buddy.commands.find((cmd)=>cmd.name===command);if(targetCommand&&!targetCommand.aliasNames.includes(alias))targetCommand.aliasNames.push(alias)}}
|
package/dist/custom-cli.js
CHANGED
|
@@ -1,23 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { cli } from "@stacksjs/cli";
|
|
3
|
-
import { config } from "@stacksjs/config";
|
|
4
|
-
import { handleError } from "@stacksjs/error-handling";
|
|
5
|
-
import { path as p } from "@stacksjs/path";
|
|
6
|
-
import { fs } from "@stacksjs/storage";
|
|
7
|
-
process.on("uncaughtException", handleError);
|
|
8
|
-
process.on("unhandledRejection", handleError);
|
|
9
|
-
async function main() {
|
|
10
|
-
const buddy = cli(config.cli.name);
|
|
11
|
-
if (!fs.existsSync(p.projectPath(config.cli.command)))
|
|
12
|
-
fs.writeFileSync(p.projectPath(config.cli.command), "import('./storage/framework/core/buddy/src/custom-cli')");
|
|
13
|
-
const commandsDir = p.appPath("Commands"), commandFiles = fs.readdirSync(commandsDir).filter((file) => file.endsWith(".ts"));
|
|
14
|
-
for (const file of commandFiles) {
|
|
15
|
-
const dynamicImport = await import(`${commandsDir}/${file}`);
|
|
16
|
-
if (typeof dynamicImport.default === "function")
|
|
17
|
-
dynamicImport.default(buddy);
|
|
18
|
-
else
|
|
19
|
-
console.error(`Expected a default export function in ${file}, but got:`, dynamicImport.default);
|
|
20
|
-
}
|
|
21
|
-
buddy.parse();
|
|
22
|
-
}
|
|
23
|
-
await main();
|
|
1
|
+
import process from"node:process";import{cli}from"@stacksjs/cli";import{config}from"@stacksjs/config";import{handleError}from"@stacksjs/error-handling";import{path as p}from"@stacksjs/path";import{fs}from"@stacksjs/storage";process.on("uncaughtException",handleError);process.on("unhandledRejection",handleError);async function main(){const buddy=cli(config.cli.name);if(!fs.existsSync(p.projectPath(config.cli.command)))fs.writeFileSync(p.projectPath(config.cli.command),"import('./storage/framework/core/buddy/src/custom-cli')");const commandsDir=p.appPath("Commands"),commandFiles=fs.readdirSync(commandsDir).filter((file)=>file.endsWith(".ts"));for(const file of commandFiles){const dynamicImport=await import(`${commandsDir}/${file}`);if(typeof dynamicImport.default==="function")dynamicImport.default(buddy);else console.error(`Expected a default export function in ${file}, but got:`,dynamicImport.default)}buddy.parse()}await main();
|
|
@@ -1,88 +1 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { confirmOrNull, log } from "@stacksjs/cli";
|
|
3
|
-
import { ExitCode } from "@stacksjs/types";
|
|
4
|
-
export function canPromptInteractively() {
|
|
5
|
-
if (process.env.CI || process.env.CONTINUOUS_INTEGRATION || process.env.BUILD_NUMBER || process.env.RUN_ID)
|
|
6
|
-
return !1;
|
|
7
|
-
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8
|
-
}
|
|
9
|
-
export function resolveCreatePolicy() {
|
|
10
|
-
const value = String(process.env.DB_CREATE_DATABASE || "").toLowerCase();
|
|
11
|
-
if (value === "always" || value === "true" || value === "1")
|
|
12
|
-
return "always";
|
|
13
|
-
if (value === "never" || value === "false" || value === "0")
|
|
14
|
-
return "never";
|
|
15
|
-
return "prompt";
|
|
16
|
-
}
|
|
17
|
-
function decide(create) {
|
|
18
|
-
process.env.STACKS_CREATE_DATABASE = create ? "1" : "0";
|
|
19
|
-
}
|
|
20
|
-
const UNANSWERED = Symbol("unanswered");
|
|
21
|
-
async function confirmWithTimeout(message, timeoutMs) {
|
|
22
|
-
let timer;
|
|
23
|
-
try {
|
|
24
|
-
return await Promise.race([
|
|
25
|
-
confirmOrNull({ message, initial: !0 }).then((v) => v === null ? UNANSWERED : v),
|
|
26
|
-
new Promise((resolve) => {
|
|
27
|
-
timer = setTimeout(() => resolve(UNANSWERED), timeoutMs);
|
|
28
|
-
})
|
|
29
|
-
]);
|
|
30
|
-
} finally {
|
|
31
|
-
if (timer)
|
|
32
|
-
clearTimeout(timer);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
export async function preflightDatabase(options = {}) {
|
|
36
|
-
const commandName = options.command || "migrate", {
|
|
37
|
-
canCreateDatabases,
|
|
38
|
-
describeTarget,
|
|
39
|
-
manualCreateHint,
|
|
40
|
-
probeTargetDatabase,
|
|
41
|
-
resolveConnectionTarget
|
|
42
|
-
} = await import("@stacksjs/database"), target = resolveConnectionTarget();
|
|
43
|
-
if (!target)
|
|
44
|
-
return;
|
|
45
|
-
const probe = await probeTargetDatabase(target);
|
|
46
|
-
if (probe.ok || probe.kind !== "missing-database")
|
|
47
|
-
return;
|
|
48
|
-
const where = describeTarget(target), standing = resolveCreatePolicy();
|
|
49
|
-
if (standing === "never") {
|
|
50
|
-
decide(!1);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (options.createDatabase || standing === "always") {
|
|
54
|
-
decide(!0);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
if (!canPromptInteractively()) {
|
|
58
|
-
log.syncError(`The database "${target.database}" does not exist on ${where}.`);
|
|
59
|
-
log.syncError("Refusing to create it in a non-interactive shell.");
|
|
60
|
-
log.syncError(" Create it ahead of time, re-run with --create-database, or set DB_CREATE_DATABASE=always.");
|
|
61
|
-
log.syncError(` ${manualCreateHint(target)}`);
|
|
62
|
-
process.exit(ExitCode.FatalError);
|
|
63
|
-
}
|
|
64
|
-
if (await canCreateDatabases(target) === !1) {
|
|
65
|
-
log.syncError(`The database "${target.database}" does not exist on ${where}.`);
|
|
66
|
-
log.syncError(`The user "${target.username}" is not allowed to create databases, so I cannot create it for you.`);
|
|
67
|
-
log.syncError(` Grant it with: ALTER ROLE "${target.username}" CREATEDB;`);
|
|
68
|
-
log.syncError(` Or create the database yourself with: ${manualCreateHint(target)}`);
|
|
69
|
-
process.exit(ExitCode.FatalError);
|
|
70
|
-
}
|
|
71
|
-
log.warn(`The database "${target.database}" does not exist on ${where}.`);
|
|
72
|
-
await log.flush();
|
|
73
|
-
const timeoutMs = Number(process.env.DB_CREATE_DATABASE_TIMEOUT_MS || 120000), answer = await confirmWithTimeout("Would you like to create it?", timeoutMs);
|
|
74
|
-
if (answer === UNANSWERED) {
|
|
75
|
-
log.syncError(`No answer after ${Math.round(timeoutMs / 1000)}s, so nothing was created.`);
|
|
76
|
-
log.syncError(" Re-run with --create-database, or set DB_CREATE_DATABASE=always, to skip this question.");
|
|
77
|
-
log.syncError(` ${manualCreateHint(target)}`);
|
|
78
|
-
process.exit(ExitCode.FatalError);
|
|
79
|
-
}
|
|
80
|
-
if (!answer) {
|
|
81
|
-
decide(!1);
|
|
82
|
-
log.info("Nothing was changed. Create it yourself with:");
|
|
83
|
-
log.info(` ${manualCreateHint(target)}`);
|
|
84
|
-
log.info(`Then re-run \`buddy ${commandName}\`, or re-run with --create-database to skip this question.`);
|
|
85
|
-
process.exit(ExitCode.Success);
|
|
86
|
-
}
|
|
87
|
-
decide(!0);
|
|
88
|
-
}
|
|
1
|
+
import process from"node:process";import{confirmOrNull,log}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";export function canPromptInteractively(){if(process.env.CI||process.env.CONTINUOUS_INTEGRATION||process.env.BUILD_NUMBER||process.env.RUN_ID)return!1;return Boolean(process.stdin.isTTY&&process.stdout.isTTY)}export function resolveCreatePolicy(){const value=String(process.env.DB_CREATE_DATABASE||"").toLowerCase();if(value==="always"||value==="true"||value==="1")return"always";if(value==="never"||value==="false"||value==="0")return"never";return"prompt"}function decide(create){process.env.STACKS_CREATE_DATABASE=create?"1":"0"}const UNANSWERED=Symbol("unanswered");async function confirmWithTimeout(message,timeoutMs){let timer;try{return await Promise.race([confirmOrNull({message,initial:!0}).then((v)=>v===null?UNANSWERED:v),new Promise((resolve)=>{timer=setTimeout(()=>resolve(UNANSWERED),timeoutMs)})])}finally{if(timer)clearTimeout(timer)}}export async function preflightDatabase(options={}){const commandName=options.command||"migrate",{canCreateDatabases,describeTarget,manualCreateHint,probeTargetDatabase,resolveConnectionTarget}=await import("@stacksjs/database"),target=resolveConnectionTarget();if(!target)return;const probe=await probeTargetDatabase(target);if(probe.ok||probe.kind!=="missing-database")return;const where=describeTarget(target),standing=resolveCreatePolicy();if(standing==="never"){decide(!1);return}if(options.createDatabase||standing==="always"){decide(!0);return}if(!canPromptInteractively()){log.syncError(`The database "${target.database}" does not exist on ${where}.`);log.syncError("Refusing to create it in a non-interactive shell.");log.syncError(" Create it ahead of time, re-run with --create-database, or set DB_CREATE_DATABASE=always.");log.syncError(` ${manualCreateHint(target)}`);process.exit(ExitCode.FatalError)}if(await canCreateDatabases(target)===!1){log.syncError(`The database "${target.database}" does not exist on ${where}.`);log.syncError(`The user "${target.username}" is not allowed to create databases, so I cannot create it for you.`);log.syncError(` Grant it with: ALTER ROLE "${target.username}" CREATEDB;`);log.syncError(` Or create the database yourself with: ${manualCreateHint(target)}`);process.exit(ExitCode.FatalError)}log.warn(`The database "${target.database}" does not exist on ${where}.`);await log.flush();const timeoutMs=Number(process.env.DB_CREATE_DATABASE_TIMEOUT_MS||120000),answer=await confirmWithTimeout("Would you like to create it?",timeoutMs);if(answer===UNANSWERED){log.syncError(`No answer after ${Math.round(timeoutMs/1000)}s, so nothing was created.`);log.syncError(" Re-run with --create-database, or set DB_CREATE_DATABASE=always, to skip this question.");log.syncError(` ${manualCreateHint(target)}`);process.exit(ExitCode.FatalError)}if(!answer){decide(!1);log.info("Nothing was changed. Create it yourself with:");log.info(` ${manualCreateHint(target)}`);log.info(`Then re-run \`buddy ${commandName}\`, or re-run with --create-database to skip this question.`);process.exit(ExitCode.Success)}decide(!0)}
|
package/dist/global-options.js
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
export function registerGlobalOptions(buddy, options = {}) {
|
|
3
|
-
(options.version === !1 ? buddy : buddy.version(versionDescriptor, "-V, --version")).option("-v, --verbose", "Enable verbose output").option("-q, --quiet", "Suppress non-essential output").option("--debug", "Enable debug output and stack traces").option("--no-interaction", "Do not ask interactive questions").option("--env <environment>", "Target an environment").option("--dry-run", "Preview actions without making changes").option("--force", "Skip confirmation prompts").option("--no-emoji", "Disable emoji in output").option("--no-cache", "Disable command metadata caching");
|
|
4
|
-
}
|
|
1
|
+
import{versionDescriptor}from"./version-info";export function registerGlobalOptions(buddy,options={}){(options.version===!1?buddy:buddy.version(versionDescriptor,"-V, --version")).option("-v, --verbose","Enable verbose output").option("-q, --quiet","Suppress non-essential output").option("--debug","Enable debug output and stack traces").option("--no-interaction","Do not ask interactive questions").option("--env <environment>","Target an environment").option("--dry-run","Preview actions without making changes").option("--force","Skip confirmation prompts").option("--no-emoji","Disable emoji in output").option("--no-cache","Disable command metadata caching")}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export*from"./commands";
|