@stacksjs/buddy 0.70.87 → 0.70.88

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 (143) hide show
  1. package/package.json +2 -2
  2. package/dist/cli.d.ts +0 -1
  3. package/dist/cli.js +0 -165
  4. package/dist/commands/about.d.ts +0 -2
  5. package/dist/commands/about.js +0 -35
  6. package/dist/commands/add.d.ts +0 -2
  7. package/dist/commands/add.js +0 -33
  8. package/dist/commands/auth.d.ts +0 -2
  9. package/dist/commands/auth.js +0 -68
  10. package/dist/commands/build.d.ts +0 -2
  11. package/dist/commands/build.js +0 -153
  12. package/dist/commands/cd.d.ts +0 -20
  13. package/dist/commands/cd.js +0 -39
  14. package/dist/commands/changelog.d.ts +0 -2
  15. package/dist/commands/changelog.js +0 -32
  16. package/dist/commands/clean.d.ts +0 -2
  17. package/dist/commands/clean.js +0 -37
  18. package/dist/commands/cloud.d.ts +0 -2
  19. package/dist/commands/cloud.js +0 -503
  20. package/dist/commands/commit.d.ts +0 -2
  21. package/dist/commands/commit.js +0 -16
  22. package/dist/commands/completion.d.ts +0 -2
  23. package/dist/commands/completion.js +0 -143
  24. package/dist/commands/config-migrate.d.ts +0 -26
  25. package/dist/commands/config-migrate.js +0 -94
  26. package/dist/commands/configure.d.ts +0 -2
  27. package/dist/commands/configure.js +0 -48
  28. package/dist/commands/create.d.ts +0 -2
  29. package/dist/commands/create.js +0 -141
  30. package/dist/commands/deploy.d.ts +0 -107
  31. package/dist/commands/deploy.js +0 -1439
  32. package/dist/commands/dev.d.ts +0 -10
  33. package/dist/commands/dev.js +0 -907
  34. package/dist/commands/dns.d.ts +0 -2
  35. package/dist/commands/dns.js +0 -102
  36. package/dist/commands/doctor.d.ts +0 -2
  37. package/dist/commands/doctor.js +0 -285
  38. package/dist/commands/domains.d.ts +0 -2
  39. package/dist/commands/domains.js +0 -159
  40. package/dist/commands/email.d.ts +0 -2
  41. package/dist/commands/email.js +0 -524
  42. package/dist/commands/env.d.ts +0 -2
  43. package/dist/commands/env.js +0 -246
  44. package/dist/commands/extension.d.ts +0 -8
  45. package/dist/commands/extension.js +0 -78
  46. package/dist/commands/features.d.ts +0 -180
  47. package/dist/commands/features.js +0 -422
  48. package/dist/commands/fresh.d.ts +0 -2
  49. package/dist/commands/fresh.js +0 -39
  50. package/dist/commands/generate.d.ts +0 -2
  51. package/dist/commands/generate.js +0 -104
  52. package/dist/commands/http.d.ts +0 -2
  53. package/dist/commands/http.js +0 -33
  54. package/dist/commands/index.d.ts +0 -53
  55. package/dist/commands/index.js +0 -53
  56. package/dist/commands/install.d.ts +0 -2
  57. package/dist/commands/install.js +0 -22
  58. package/dist/commands/key.d.ts +0 -2
  59. package/dist/commands/key.js +0 -23
  60. package/dist/commands/lint.d.ts +0 -2
  61. package/dist/commands/lint.js +0 -46
  62. package/dist/commands/list.d.ts +0 -2
  63. package/dist/commands/list.js +0 -108
  64. package/dist/commands/mail.d.ts +0 -2
  65. package/dist/commands/mail.js +0 -693
  66. package/dist/commands/maintenance.d.ts +0 -2
  67. package/dist/commands/maintenance.js +0 -141
  68. package/dist/commands/make.d.ts +0 -2
  69. package/dist/commands/make.js +0 -375
  70. package/dist/commands/migrate-project.d.ts +0 -2
  71. package/dist/commands/migrate-project.js +0 -49
  72. package/dist/commands/migrate.d.ts +0 -4
  73. package/dist/commands/migrate.js +0 -455
  74. package/dist/commands/outdated.d.ts +0 -2
  75. package/dist/commands/outdated.js +0 -19
  76. package/dist/commands/package.d.ts +0 -2
  77. package/dist/commands/package.js +0 -17
  78. package/dist/commands/phone.d.ts +0 -2
  79. package/dist/commands/phone.js +0 -188
  80. package/dist/commands/ports.d.ts +0 -2
  81. package/dist/commands/ports.js +0 -118
  82. package/dist/commands/prepublish.d.ts +0 -2
  83. package/dist/commands/prepublish.js +0 -17
  84. package/dist/commands/projects.d.ts +0 -2
  85. package/dist/commands/projects.js +0 -29
  86. package/dist/commands/publish.d.ts +0 -2
  87. package/dist/commands/publish.js +0 -172
  88. package/dist/commands/queue.d.ts +0 -2
  89. package/dist/commands/queue.js +0 -248
  90. package/dist/commands/release.d.ts +0 -2
  91. package/dist/commands/release.js +0 -30
  92. package/dist/commands/route.d.ts +0 -2
  93. package/dist/commands/route.js +0 -21
  94. package/dist/commands/saas.d.ts +0 -2
  95. package/dist/commands/saas.js +0 -25
  96. package/dist/commands/schedule.d.ts +0 -2
  97. package/dist/commands/schedule.js +0 -61
  98. package/dist/commands/search.d.ts +0 -2
  99. package/dist/commands/search.js +0 -84
  100. package/dist/commands/seed.d.ts +0 -2
  101. package/dist/commands/seed.js +0 -71
  102. package/dist/commands/serve.d.ts +0 -25
  103. package/dist/commands/serve.js +0 -182
  104. package/dist/commands/setup.d.ts +0 -12
  105. package/dist/commands/setup.js +0 -215
  106. package/dist/commands/share.d.ts +0 -2
  107. package/dist/commands/share.js +0 -214
  108. package/dist/commands/sms.d.ts +0 -2
  109. package/dist/commands/sms.js +0 -328
  110. package/dist/commands/stacks.d.ts +0 -2
  111. package/dist/commands/stacks.js +0 -69
  112. package/dist/commands/telemetry.d.ts +0 -2
  113. package/dist/commands/telemetry.js +0 -74
  114. package/dist/commands/test.d.ts +0 -2
  115. package/dist/commands/test.js +0 -130
  116. package/dist/commands/tinker.d.ts +0 -2
  117. package/dist/commands/tinker.js +0 -37
  118. package/dist/commands/types.d.ts +0 -2
  119. package/dist/commands/types.js +0 -18
  120. package/dist/commands/upgrade.d.ts +0 -2
  121. package/dist/commands/upgrade.js +0 -98
  122. package/dist/commands/version.d.ts +0 -2
  123. package/dist/commands/version.js +0 -16
  124. package/dist/config.d.ts +0 -43
  125. package/dist/config.js +0 -223
  126. package/dist/custom-cli.d.ts +0 -1
  127. package/dist/custom-cli.js +0 -23
  128. package/dist/index.d.ts +0 -1
  129. package/dist/index.js +0 -1
  130. package/dist/lazy-commands.d.ts +0 -61
  131. package/dist/lazy-commands.js +0 -188
  132. package/dist/migrators/index.d.ts +0 -9
  133. package/dist/migrators/index.js +0 -62
  134. package/dist/migrators/laravel/index.d.ts +0 -2
  135. package/dist/migrators/laravel/index.js +0 -148
  136. package/dist/migrators/laravel/migrations.d.ts +0 -52
  137. package/dist/migrators/laravel/migrations.js +0 -232
  138. package/dist/migrators/laravel/models.d.ts +0 -34
  139. package/dist/migrators/laravel/models.js +0 -134
  140. package/dist/migrators/rails/index.d.ts +0 -2
  141. package/dist/migrators/rails/index.js +0 -11
  142. package/dist/migrators/types.d.ts +0 -44
  143. package/dist/migrators/types.js +0 -0
@@ -1,188 +0,0 @@
1
- import { getErrorMessage } from "@stacksjs/utils";
2
- import { readFileSync, existsSync } from "node:fs";
3
- const TIMEOUT_MS = 30000;
4
- async function withTimeout(promise, ms = TIMEOUT_MS) {
5
- let timeoutId;
6
- const timeoutPromise = new Promise((_, reject) => {
7
- timeoutId = setTimeout(() => reject(Error(`Operation timed out after ${ms}ms`)), ms);
8
- });
9
- try {
10
- return await Promise.race([promise, timeoutPromise]);
11
- } finally {
12
- clearTimeout(timeoutId);
13
- }
14
- }
15
- function loadAwsCredentials() {
16
- const envPath = ".env.production";
17
- if (existsSync(envPath)) {
18
- const content = readFileSync(envPath, "utf-8");
19
- for (const line of content.split(`
20
- `)) {
21
- const eq = line.indexOf("=");
22
- if (eq > 0 && !line.startsWith("#"))
23
- process.env[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
24
- }
25
- }
26
- }
27
- const descriptions = {
28
- phone: "Phone/voice service management commands",
29
- status: "Show phone service status",
30
- numbers: "List phone numbers",
31
- search: "Search available phone numbers",
32
- setup: "Initialize phone infrastructure"
33
- };
34
- export function phone(buddy) {
35
- buddy.command("phone", descriptions.phone).action(async () => {
36
- console.log(`
37
- \uD83D\uDCDE Phone Service Commands
38
- `);
39
- console.log(" buddy phone:status - Show phone service status");
40
- console.log(" buddy phone:numbers - List phone numbers");
41
- console.log(" buddy phone:search - Search available phone numbers");
42
- console.log(" buddy phone:setup - Initialize phone infrastructure");
43
- console.log("");
44
- process.exit(0);
45
- });
46
- buddy.command("phone:status", descriptions.status).action(async () => {
47
- console.log(`
48
- \uD83D\uDCDE Phone Service Status
49
- `);
50
- loadAwsCredentials();
51
- try {
52
- const { ConnectClient } = await import("@stacksjs/ts-cloud"), connect = new ConnectClient(process.env.AWS_REGION || "us-east-1"), instanceAlias = `${(process.env.APP_NAME || "stacks").toLowerCase().replace(/[^a-z0-9-]/g, "-")}-phone`;
53
- console.log(`Looking for Connect instance: ${instanceAlias}`);
54
- const instance = (await withTimeout(connect.listInstances({ MaxResults: 100 }))).InstanceSummaryList?.find((i) => i.InstanceAlias === instanceAlias);
55
- if (instance) {
56
- console.log(`
57
- \u2705 Phone Service Active
58
- `);
59
- console.log(` Instance ID: ${instance.Id}`);
60
- console.log(` Alias: ${instance.InstanceAlias}`);
61
- console.log(` Status: ${instance.InstanceStatus}`);
62
- console.log(` Inbound Calls: ${instance.InboundCallsEnabled ? "Enabled" : "Disabled"}`);
63
- console.log(` Outbound Calls: ${instance.OutboundCallsEnabled ? "Enabled" : "Disabled"}`);
64
- if (instance.Id)
65
- try {
66
- const numbers = await withTimeout(connect.listPhoneNumbers({ InstanceId: instance.Id }));
67
- if (numbers.ListPhoneNumbersSummaryList && numbers.ListPhoneNumbersSummaryList.length > 0) {
68
- console.log(`
69
- Phone Numbers:`);
70
- for (const num of numbers.ListPhoneNumbersSummaryList)
71
- console.log(` \uD83D\uDCF1 ${num.PhoneNumber} (${num.PhoneNumberType})`);
72
- } else
73
- console.log(`
74
- No phone numbers claimed yet.`);
75
- } catch {
76
- console.log(`
77
- Could not retrieve phone numbers.`);
78
- }
79
- } else {
80
- console.log(`
81
- \u274C Phone service not deployed.`);
82
- console.log(`
83
- \uD83D\uDCA1 To set up phone service:`);
84
- console.log(" 1. Enable phone in config/phone.ts");
85
- console.log(" 2. Run `buddy deploy`");
86
- }
87
- } catch (error) {
88
- console.error("Error checking status:", getErrorMessage(error));
89
- }
90
- process.exit(0);
91
- });
92
- buddy.command("phone:numbers", descriptions.numbers).action(async () => {
93
- console.log(`
94
- \uD83D\uDCDE Phone Numbers
95
- `);
96
- loadAwsCredentials();
97
- try {
98
- const { ConnectClient } = await import("@stacksjs/ts-cloud"), connect = new ConnectClient(process.env.AWS_REGION || "us-east-1"), instanceAlias = `${(process.env.APP_NAME || "stacks").toLowerCase().replace(/[^a-z0-9-]/g, "-")}-phone`, instance = (await withTimeout(connect.listInstances({ MaxResults: 100 }))).InstanceSummaryList?.find((i) => i.InstanceAlias === instanceAlias);
99
- if (!instance?.Id) {
100
- console.log("Phone service not deployed. Run `buddy phone:setup` first.");
101
- process.exit(0);
102
- return;
103
- }
104
- const numbers = await withTimeout(connect.listPhoneNumbers({ InstanceId: instance.Id }));
105
- if (!numbers.ListPhoneNumbersSummaryList || numbers.ListPhoneNumbersSummaryList.length === 0) {
106
- console.log("No phone numbers claimed.");
107
- console.log("\n\uD83D\uDCA1 Use `buddy phone:search` to find available numbers.");
108
- process.exit(0);
109
- return;
110
- }
111
- console.log(`Claimed Phone Numbers:
112
- `);
113
- for (const num of numbers.ListPhoneNumbersSummaryList) {
114
- console.log(` \uD83D\uDCF1 ${num.PhoneNumber}`);
115
- console.log(` Type: ${num.PhoneNumberType}`);
116
- console.log(` Country: ${num.PhoneNumberCountryCode}`);
117
- if (num.PhoneNumberDescription)
118
- console.log(` Description: ${num.PhoneNumberDescription}`);
119
- console.log("");
120
- }
121
- } catch (error) {
122
- console.error("Error listing numbers:", getErrorMessage(error));
123
- }
124
- process.exit(0);
125
- });
126
- buddy.command("phone:search [country]", descriptions.search).option("-t, --type <type>", "Phone number type (TOLL_FREE, DID)", { default: "TOLL_FREE" }).action(async (country, options) => {
127
- const countryCode = country?.toUpperCase() || "US", phoneType = options.type?.toUpperCase() || "TOLL_FREE";
128
- console.log(`
129
- \uD83D\uDCDE Searching for ${phoneType} numbers in ${countryCode}...
130
- `);
131
- loadAwsCredentials();
132
- try {
133
- const { ConnectClient } = await import("@stacksjs/ts-cloud"), connect = new ConnectClient(process.env.AWS_REGION || "us-east-1"), instanceAlias = `${(process.env.APP_NAME || "stacks").toLowerCase().replace(/[^a-z0-9-]/g, "-")}-phone`, instance = (await withTimeout(connect.listInstances({ MaxResults: 100 }))).InstanceSummaryList?.find((i) => i.InstanceAlias === instanceAlias);
134
- if (!instance?.Arn) {
135
- console.log("Phone service not deployed. Run `buddy phone:setup` first.");
136
- process.exit(0);
137
- return;
138
- }
139
- const available = await withTimeout(connect.searchAvailablePhoneNumbers({
140
- TargetArn: instance.Arn,
141
- PhoneNumberCountryCode: countryCode,
142
- PhoneNumberType: phoneType,
143
- MaxResults: 10
144
- }));
145
- if (!available.AvailableNumbersList || available.AvailableNumbersList.length === 0) {
146
- console.log(`No ${phoneType} numbers available in ${countryCode}.`);
147
- console.log(`
148
- \uD83D\uDCA1 Try a different country or number type.`);
149
- process.exit(0);
150
- return;
151
- }
152
- console.log(`Available Phone Numbers:
153
- `);
154
- for (const num of available.AvailableNumbersList)
155
- console.log(` \uD83D\uDCF1 ${num.PhoneNumber}`);
156
- console.log("\n\uD83D\uDCA1 To claim a number, use `buddy phone:claim <number>`");
157
- } catch (error) {
158
- if (getErrorMessage(error).includes("not authorized")) {
159
- console.log("Not authorized to search phone numbers.");
160
- console.log("Make sure your AWS account has Amazon Connect permissions.");
161
- } else
162
- console.error("Error searching numbers:", getErrorMessage(error));
163
- }
164
- process.exit(0);
165
- });
166
- buddy.command("phone:setup", descriptions.setup).action(async () => {
167
- console.log(`
168
- \uD83D\uDCDE Phone Service Setup
169
- `);
170
- console.log("Amazon Connect setup requires manual configuration.");
171
- console.log(`
172
- Steps to set up phone service:
173
- `);
174
- console.log("1. Enable phone in config/phone.ts:");
175
- console.log(" enabled: true");
176
- console.log("");
177
- console.log("2. Run `buddy deploy` to create the Connect instance");
178
- console.log("");
179
- console.log("3. Access the Connect console to:");
180
- console.log(" - Claim phone numbers");
181
- console.log(" - Configure contact flows");
182
- console.log(" - Set up routing profiles");
183
- console.log("");
184
- console.log("4. Use `buddy phone:status` to verify setup");
185
- console.log("");
186
- process.exit(0);
187
- });
188
- }
@@ -1,2 +0,0 @@
1
- import type { CLI } from '@stacksjs/types';
2
- export declare function ports(buddy: CLI): void;
@@ -1,118 +0,0 @@
1
- import { $ } from "bun";
2
- import process from "node:process";
3
- import { intro, italic, onUnknownSubcommand, outro } from "@stacksjs/cli";
4
- import { ports as projectPorts } from "@stacksjs/config";
5
- import { log } from "@stacksjs/logging";
6
- import { findProjectPath, path as p, projectPath } from "@stacksjs/path";
7
- import { ExitCode } from "@stacksjs/types";
8
- import { findStacksProjects } from "@stacksjs/utils";
9
- export function ports(buddy) {
10
- const descriptions = {
11
- command: "Let buddy check your project for potential issues and misconfigurations",
12
- ports: "Check if the ports are available",
13
- project: "Target a specific project",
14
- verbose: "Enable verbose output"
15
- };
16
- buddy.command("ports", descriptions.command).option("-l, --list", "List the used ports", { default: !0 }).option("-c, --check", "Check if the ports are available", {
17
- default: !1
18
- }).option("-p, --project [name]", descriptions.project, {
19
- default: void 0
20
- }).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
21
- log.debug("Running `buddy ports` ...", options);
22
- let perf;
23
- if (!options.quiet)
24
- perf = await intro("buddy ports");
25
- if (options.project) {
26
- const path = await findProjectPath(options.project);
27
- log.debug(`Path: ${path}`);
28
- const ports = await getPortsForProjectPath(path, options);
29
- log.debug(`./buddy ports --quiet response for ${projectPath}`, ports);
30
- outputPorts(ports, options);
31
- } else
32
- outputPorts(projectPorts, options);
33
- if (!options.quiet)
34
- await outro("Exited", { startTime: perf, useSeconds: !1 });
35
- process.exit(ExitCode.Success);
36
- });
37
- buddy.command("ports:list", descriptions.ports).option("-p, --project [name]", descriptions.project, {
38
- default: void 0
39
- }).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
40
- log.debug("Running `buddy ports:list` ...", options);
41
- let perf;
42
- if (!options.quiet)
43
- perf = await intro("buddy ports:list");
44
- if (options.project) {
45
- if (!options.quiet)
46
- log.info(`Listing ports for project: ${italic(options.project)}`);
47
- const path = await findProjectPath(options.project);
48
- log.debug(`Path: ${path}`);
49
- const ports = await getPortsForProjectPath(path, options);
50
- outputPorts(ports, options);
51
- } else
52
- outputPorts(projectPorts, options);
53
- if (!options.quiet)
54
- await outro("Exited", { startTime: perf, useSeconds: !1 });
55
- process.exit(ExitCode.Success);
56
- });
57
- buddy.command("ports:check", descriptions.ports).option("-p, --project [name]", descriptions.project, {
58
- default: projectPath()
59
- }).option("-q, --quiet", "Use minimal output", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
60
- log.debug("Running `buddy ports:check` ...", options);
61
- let perf;
62
- if (!options.quiet)
63
- perf = await intro("buddy ports:check");
64
- const projects = await findStacksProjects(void 0, { quiet: !0 });
65
- log.debug("Running `buddy ports`");
66
- log.debug(`Found ${projects.length} projects`);
67
- log.debug("Projects:", projects);
68
- const projectsPorts = {};
69
- for (const project of projects)
70
- projectsPorts[project] = await getPortsForProjectPath(project, options);
71
- log.info("ProjectsPorts:", projectsPorts);
72
- if (!options.quiet)
73
- await outro("Exited", { startTime: perf, useSeconds: !1 });
74
- process.exit(ExitCode.Success);
75
- });
76
- onUnknownSubcommand(buddy, "ports");
77
- }
78
- async function getPortsForProjectPath(path, options) {
79
- if (!options.quiet)
80
- log.info(`Checking ports for project: ${italic(path)}`);
81
- $.cwd(path);
82
- try {
83
- $.env(await import(`${path}/.env`));
84
- } catch (err) {
85
- if (!options.quiet)
86
- log.warn(`[ports] Failed to load ${path}/.env (${err.message}). Falling back to current environment.`);
87
- }
88
- const projectList = await $`./buddy projects:list --quiet`.text();
89
- log.debug("ProjectListResponse", projectList);
90
- const projects = projectList.split(`
91
- `).filter((line) => line.startsWith(" - ")).map((line) => line.trim().substring(4));
92
- log.debug("Projects:", projects);
93
- const ppath = options.project ?? p.projectPath();
94
- let projectPath = projects.find((project) => project.includes(ppath));
95
- log.debug(`Checking ports for project: ${projectPath}`);
96
- if (projectPath === "" || !projectPath)
97
- projectPath = p.projectPath();
98
- log.debug(`$ Running: ./buddy ports:list --quiet via ${projectPath}`);
99
- const response = await $`./buddy ports:list --quiet`.json();
100
- log.debug(`Response for ./buddy ports:list --quiet via ${projectPath}`, response);
101
- let validJsonString = response.replace(/(\w+)(?=\s*:)/g, '"$1"');
102
- validJsonString = validJsonString.replace(/,(\s*\})/g, "$1");
103
- let ports;
104
- try {
105
- ports = JSON.parse(validJsonString);
106
- } catch {
107
- throw Error(`Failed to parse ports configuration: ${validJsonString.slice(0, 200)}`);
108
- }
109
- log.debug(`Ports for ${projectPath}`, ports);
110
- return ports;
111
- }
112
- function outputPorts(ports, options) {
113
- if (!options.quiet)
114
- console.log("");
115
- console.log(ports);
116
- if (!options.quiet)
117
- console.log("");
118
- }
@@ -1,2 +0,0 @@
1
- import type { CLI } from '@stacksjs/types';
2
- export declare function prepublish(buddy: CLI): void;
@@ -1,17 +0,0 @@
1
- import process from "node:process";
2
- import { runAction } from "@stacksjs/actions";
3
- import { Action } from "@stacksjs/enums";
4
- import { log } from "@stacksjs/logging";
5
- import { onUnknownSubcommand } from "@stacksjs/cli";
6
- export function prepublish(buddy) {
7
- const descriptions = {
8
- command: "Run your prepublish script",
9
- project: "Target a specific project",
10
- verbose: "Enable verbose output"
11
- };
12
- buddy.command("prepublish", descriptions.command).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
13
- log.debug("Running `buddy prepublish` ...", options);
14
- await runAction(Action.Prepublish, options);
15
- });
16
- onUnknownSubcommand(buddy, "prepublish");
17
- }
@@ -1,2 +0,0 @@
1
- import type { CLI } from '@stacksjs/types';
2
- export declare function projects(buddy: CLI): void;
@@ -1,29 +0,0 @@
1
- import process from "node:process";
2
- import { intro, log, onUnknownSubcommand } from "@stacksjs/cli";
3
- import { ExitCode } from "@stacksjs/types";
4
- import { findStacksProjects } from "@stacksjs/utils";
5
- export function projects(buddy) {
6
- const descriptions = {
7
- projects: "Find all Stacks projects on your system",
8
- verbose: "Enable verbose output"
9
- };
10
- buddy.command("projects", descriptions.projects).option("-q, --quiet", "Use minimal output", { default: !1 }).option("-l, --list", "List all local Stacks projects", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
11
- log.debug("Running `buddy projects` ...", options);
12
- if (!options.quiet)
13
- await intro("buddy projects");
14
- const projects = await findStacksProjects(void 0, options);
15
- for (const project of projects)
16
- console.log(" - ", project);
17
- process.exit(ExitCode.Success);
18
- });
19
- buddy.command("projects:list", descriptions.projects).option("-q, --quiet", "Use minimal output", { default: !1 }).option("-l, --list", "List all local Stacks projects", { default: !0 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
20
- log.debug("Running `buddy projects` ...", options);
21
- if (!options.quiet)
22
- await intro("buddy projects:list");
23
- const projects = await findStacksProjects(void 0, options);
24
- for (const project of projects)
25
- console.log(" - ", project);
26
- process.exit(ExitCode.Success);
27
- });
28
- onUnknownSubcommand(buddy, "projects");
29
- }
@@ -1,2 +0,0 @@
1
- import type { CLI } from '@stacksjs/types';
2
- export declare function publish(buddy: CLI): void;
@@ -1,172 +0,0 @@
1
- import { existsSync, mkdirSync } from "node:fs";
2
- import { cp, readdir, stat } from "node:fs/promises";
3
- import { dirname, resolve } from "node:path";
4
- import process from "node:process";
5
- import { italic, log, onUnknownSubcommand } from "@stacksjs/cli";
6
- import { path } from "@stacksjs/path";
7
- import { fs, globSync } from "@stacksjs/storage";
8
- import { ExitCode } from "@stacksjs/types";
9
- export function publish(buddy) {
10
- const descriptions = {
11
- command: "Publish a Stacks default into your userland (app/) directory so you can customize it",
12
- model: "Publish a default model from storage/framework/defaults/app/Models/ to app/Models/",
13
- controller: "Publish a default controller from storage/framework/defaults/app/Controllers/ to app/Controllers/",
14
- middleware: "Publish a default middleware from storage/framework/defaults/app/Middleware/ to app/Middleware/",
15
- action: "Publish a default action from storage/framework/defaults/app/Actions/ to app/Actions/",
16
- core: "Publish a framework package source from node_modules/@stacksjs/<pkg>/ into storage/framework/core/<pkg>/ for editing",
17
- name: "The name of the resource to publish (e.g. Cart, User)",
18
- pkg: "The name of the framework package (e.g. router, orm, faker \u2014 without @stacksjs/ prefix)",
19
- force: "Overwrite an existing userland file",
20
- verbose: "Enable verbose output"
21
- };
22
- buddy.command("publish:model <name>", descriptions.model).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
23
- await publishResource({
24
- kind: "model",
25
- name,
26
- defaultsDir: path.frameworkPath("defaults/app/Models"),
27
- userDir: path.userModelsPath(),
28
- force: !!options.force
29
- });
30
- });
31
- buddy.command("publish:controller <name>", descriptions.controller).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
32
- await publishResource({
33
- kind: "controller",
34
- name,
35
- defaultsDir: path.frameworkPath("defaults/app/Controllers"),
36
- userDir: path.userControllersPath(),
37
- force: !!options.force
38
- });
39
- });
40
- buddy.command("publish:middleware <name>", descriptions.middleware).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
41
- await publishResource({
42
- kind: "middleware",
43
- name,
44
- defaultsDir: path.frameworkPath("defaults/app/Middleware"),
45
- userDir: path.userMiddlewarePath(),
46
- force: !!options.force
47
- });
48
- });
49
- buddy.command("publish:action <name>", descriptions.action).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
50
- await publishResource({
51
- kind: "action",
52
- name,
53
- defaultsDir: path.frameworkPath("defaults/app/Actions"),
54
- userDir: path.userActionsPath(),
55
- force: !!options.force
56
- });
57
- });
58
- buddy.command("publish:core <pkg>", descriptions.core).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (pkg, options) => {
59
- await publishCorePackage(pkg, !!options.force);
60
- });
61
- buddy.command("publish [resource] [name]", descriptions.command).option("--force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (resource, name, options) => {
62
- if (!resource || !name) {
63
- log.error("Usage: buddy publish:<resource> <Name> (e.g. buddy publish:model Cart)");
64
- process.exit(ExitCode.FatalError);
65
- }
66
- const handler = {
67
- model: () => publishResource({
68
- kind: "model",
69
- name,
70
- defaultsDir: path.frameworkPath("defaults/app/Models"),
71
- userDir: path.userModelsPath(),
72
- force: !!options.force
73
- }),
74
- controller: () => publishResource({
75
- kind: "controller",
76
- name,
77
- defaultsDir: path.frameworkPath("defaults/app/Controllers"),
78
- userDir: path.userControllersPath(),
79
- force: !!options.force
80
- }),
81
- middleware: () => publishResource({
82
- kind: "middleware",
83
- name,
84
- defaultsDir: path.frameworkPath("defaults/app/Middleware"),
85
- userDir: path.userMiddlewarePath(),
86
- force: !!options.force
87
- }),
88
- action: () => publishResource({
89
- kind: "action",
90
- name,
91
- defaultsDir: path.frameworkPath("defaults/app/Actions"),
92
- userDir: path.userActionsPath(),
93
- force: !!options.force
94
- }),
95
- core: () => publishCorePackage(name, !!options.force)
96
- }[resource.toLowerCase()];
97
- if (!handler) {
98
- log.error(`Unknown publishable resource: ${italic(resource)}`);
99
- log.info("Available: model, controller, middleware, action, core");
100
- process.exit(ExitCode.FatalError);
101
- }
102
- await handler();
103
- });
104
- onUnknownSubcommand(buddy, "publish");
105
- }
106
- async function publishCorePackage(pkg, force) {
107
- const shortName = pkg.replace(/^@stacksjs\//, "").replace(/^core\//, ""), fail = (msg, hint) => {
108
- process.stderr.write(`${msg}
109
- `);
110
- if (hint)
111
- process.stderr.write(` ${hint}
112
- `);
113
- process.exit(ExitCode.FatalError);
114
- };
115
- if (!shortName || shortName.includes("/") || shortName.includes(".."))
116
- fail(`Invalid package name: ${pkg}`, "Use a short name like `router` or the fully qualified `@stacksjs/router`.");
117
- const sourceDir = resolve(process.cwd(), "node_modules", "@stacksjs", shortName), targetDir = path.frameworkPath(`core/${shortName}`);
118
- try {
119
- if (!(await stat(sourceDir)).isDirectory())
120
- fail(`${sourceDir} is not a directory.`);
121
- } catch {
122
- fail(`Could not find @stacksjs/${shortName} in node_modules.`, "Run `bun install` first, or check the package name.");
123
- }
124
- if (existsSync(targetDir) && !force)
125
- fail(`Already published: ${targetDir.replace(`${process.cwd()}/`, "")}`, "Pass --force to overwrite.");
126
- mkdirSync(dirname(targetDir), { recursive: !0 });
127
- const SKIP = new Set(["node_modules", "dist", ".bun", ".cache", "tsconfig.tsbuildinfo"]);
128
- let copied = 0;
129
- await copyTreeFiltered(sourceDir, targetDir, SKIP, () => copied++);
130
- log.success(`Published @stacksjs/${shortName} \u2192 ${italic(targetDir.replace(`${process.cwd()}/`, ""))} (${copied} files)`);
131
- log.info("Edit freely \u2014 local changes win over the installed package.");
132
- }
133
- async function copyTreeFiltered(sourceDir, targetDir, skip, onFile) {
134
- mkdirSync(targetDir, { recursive: !0 });
135
- const entries = await readdir(sourceDir, { withFileTypes: !0 });
136
- for (const entry of entries) {
137
- if (skip.has(entry.name))
138
- continue;
139
- const src = `${sourceDir}/${entry.name}`, dst = `${targetDir}/${entry.name}`;
140
- if (entry.isDirectory()) {
141
- await copyTreeFiltered(src, dst, skip, onFile);
142
- continue;
143
- }
144
- await cp(src, dst, { force: !0, dereference: !0 });
145
- onFile();
146
- }
147
- }
148
- async function publishResource(ctx) {
149
- const { kind, name, defaultsDir, userDir, force } = ctx, fileName = name.endsWith(".ts") ? name : `${name}.ts`, matches = globSync([`${defaultsDir}/**/${fileName}`], { absolute: !0 });
150
- if (!matches.length) {
151
- log.error(`Could not find default ${kind}: ${italic(fileName)}`);
152
- log.info(`Looked under: ${italic(defaultsDir)}`);
153
- process.exit(ExitCode.FatalError);
154
- }
155
- if (matches.length > 1) {
156
- log.warn(`Multiple defaults match ${italic(fileName)}; using the first:`);
157
- for (const m of matches)
158
- log.info(` ${m}`);
159
- }
160
- const sourcePath = matches[0];
161
- if (!sourcePath)
162
- throw Error(`Could not resolve default ${kind}: ${fileName}`);
163
- const targetPath = `${userDir.replace(/\/$/, "")}/${fileName}`;
164
- if (existsSync(targetPath) && !force) {
165
- log.error(`Already exists: ${italic(targetPath)}`);
166
- log.info("Pass --force to overwrite.");
167
- process.exit(ExitCode.FatalError);
168
- }
169
- mkdirSync(dirname(targetPath), { recursive: !0 });
170
- await fs.promises.copyFile(sourcePath, targetPath);
171
- log.success(`Published ${kind} ${italic(name)} \u2192 ${italic(targetPath.replace(`${process.cwd()}/`, ""))}`);
172
- }
@@ -1,2 +0,0 @@
1
- import type { CLI } from '@stacksjs/types';
2
- export declare function queue(buddy: CLI): void;