@stacksjs/buddy 0.70.257 → 0.70.259

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.
Files changed (113) hide show
  1. package/dist/cli.d.ts +11 -1
  2. package/dist/cli.js +5 -164
  3. package/dist/commands/about.js +1 -35
  4. package/dist/commands/add.js +1 -25
  5. package/dist/commands/ai-context.js +4 -27
  6. package/dist/commands/auth.js +1 -68
  7. package/dist/commands/build.js +1 -221
  8. package/dist/commands/cd.js +8 -39
  9. package/dist/commands/changelog.js +1 -32
  10. package/dist/commands/clean.js +1 -44
  11. package/dist/commands/cloud.js +2 -519
  12. package/dist/commands/commit.js +1 -16
  13. package/dist/commands/completion.js +6 -42
  14. package/dist/commands/config-migrate.js +6 -94
  15. package/dist/commands/configure.js +2 -45
  16. package/dist/commands/create.js +1 -162
  17. package/dist/commands/deploy.d.ts +10 -4
  18. package/dist/commands/deploy.js +13 -1664
  19. package/dist/commands/desktop-apple.js +12 -399
  20. package/dist/commands/dev.js +6 -1083
  21. package/dist/commands/dns.js +3 -103
  22. package/dist/commands/docs/buddy-commands.js +10 -132
  23. package/dist/commands/docs/buddy-commands.test.js +1 -38
  24. package/dist/commands/docs/framework-repo.js +1 -14
  25. package/dist/commands/docs/framework-repo.test.js +1 -68
  26. package/dist/commands/docs/generated-artifacts.js +3 -70
  27. package/dist/commands/docs/generated-artifacts.test.js +1 -19
  28. package/dist/commands/docs/links.js +2 -85
  29. package/dist/commands/docs/links.test.js +4 -66
  30. package/dist/commands/docs.js +1 -24
  31. package/dist/commands/doctor.js +2 -478
  32. package/dist/commands/domains.js +2 -152
  33. package/dist/commands/email.js +31 -503
  34. package/dist/commands/env.js +1 -312
  35. package/dist/commands/extension.js +1 -239
  36. package/dist/commands/features.js +9 -345
  37. package/dist/commands/fresh.js +1 -46
  38. package/dist/commands/generate.js +2 -152
  39. package/dist/commands/http.js +1 -33
  40. package/dist/commands/index.js +1 -57
  41. package/dist/commands/install.js +1 -22
  42. package/dist/commands/key.js +1 -23
  43. package/dist/commands/link.js +2 -147
  44. package/dist/commands/lint.js +2 -46
  45. package/dist/commands/list.js +1 -140
  46. package/dist/commands/mail.js +15 -1477
  47. package/dist/commands/maintenance.js +1 -141
  48. package/dist/commands/make.js +1 -392
  49. package/dist/commands/migrate-project.js +1 -49
  50. package/dist/commands/migrate.js +27 -625
  51. package/dist/commands/outdated.js +1 -19
  52. package/dist/commands/package.js +1 -17
  53. package/dist/commands/phone.js +17 -181
  54. package/dist/commands/ports.js +2 -118
  55. package/dist/commands/prepublish.js +1 -17
  56. package/dist/commands/projects.js +1 -29
  57. package/dist/commands/protocol/craft-evidence.js +4 -98
  58. package/dist/commands/protocol/craft-evidence.test.js +1 -20
  59. package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
  60. package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
  61. package/dist/commands/protocol/desktop-support.js +2 -32
  62. package/dist/commands/protocol/desktop-workflow.test.js +3 -35
  63. package/dist/commands/protocol/driver-registry.js +2 -71
  64. package/dist/commands/protocol/pantry-evidence.js +4 -144
  65. package/dist/commands/protocol/pantry-evidence.test.js +1 -29
  66. package/dist/commands/protocol/release-manifest.js +3 -102
  67. package/dist/commands/protocol/release-manifest.test.js +2 -34
  68. package/dist/commands/protocol/run-conformance.js +4 -346
  69. package/dist/commands/protocol/run-conformance.test.js +1 -52
  70. package/dist/commands/protocol/run-driver-contracts.js +4 -83
  71. package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
  72. package/dist/commands/protocol/source-manifest.js +3 -113
  73. package/dist/commands/protocol/sync-suite.js +3 -136
  74. package/dist/commands/protocol/sync-suite.test.js +1 -44
  75. package/dist/commands/protocol.js +1 -60
  76. package/dist/commands/publish.js +8 -500
  77. package/dist/commands/queue.js +1 -248
  78. package/dist/commands/release.js +1 -42
  79. package/dist/commands/route.js +1 -21
  80. package/dist/commands/run-tool.js +1 -9
  81. package/dist/commands/saas.js +1 -25
  82. package/dist/commands/schedule.js +1 -61
  83. package/dist/commands/search.js +1 -84
  84. package/dist/commands/seed.js +1 -47
  85. package/dist/commands/serve.js +1 -55
  86. package/dist/commands/setup-ai.js +2 -121
  87. package/dist/commands/setup.js +2 -305
  88. package/dist/commands/share.js +1 -214
  89. package/dist/commands/sms.js +32 -319
  90. package/dist/commands/stacks.js +1 -72
  91. package/dist/commands/telemetry.js +1 -74
  92. package/dist/commands/test.js +1 -130
  93. package/dist/commands/tinker.js +1 -37
  94. package/dist/commands/types.js +1 -18
  95. package/dist/commands/upgrade.js +1 -98
  96. package/dist/commands/user.js +3 -84
  97. package/dist/commands/version.js +1 -14
  98. package/dist/config.js +1 -231
  99. package/dist/custom-cli.js +1 -23
  100. package/dist/database-preflight.js +1 -88
  101. package/dist/global-options.js +1 -4
  102. package/dist/index.js +1 -1
  103. package/dist/lazy-commands.js +1 -241
  104. package/dist/migrators/index.js +2 -62
  105. package/dist/migrators/laravel/index.js +1 -148
  106. package/dist/migrators/laravel/migrations.js +4 -231
  107. package/dist/migrators/laravel/models.js +8 -111
  108. package/dist/migrators/rails/index.js +1 -11
  109. package/dist/production-server.js +1 -257
  110. package/dist/project-setup.js +1 -36
  111. package/dist/serve-entry.js +1 -5
  112. package/dist/version-info.js +1 -5
  113. package/package.json +54 -47
package/dist/config.js CHANGED
@@ -1,231 +1 @@
1
- import { existsSync } from "node:fs";
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)}}
@@ -1,23 +1 @@
1
- import process from "node:process";
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 "node:process";
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)}
@@ -1,4 +1 @@
1
- import { versionDescriptor } from "./version-info";
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 * from "./commands";
1
+ export*from"./commands";