@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.
Files changed (112) 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.js +13 -1676
  18. package/dist/commands/desktop-apple.js +12 -399
  19. package/dist/commands/dev.js +6 -1083
  20. package/dist/commands/dns.js +3 -103
  21. package/dist/commands/docs/buddy-commands.js +10 -132
  22. package/dist/commands/docs/buddy-commands.test.js +1 -38
  23. package/dist/commands/docs/framework-repo.js +1 -14
  24. package/dist/commands/docs/framework-repo.test.js +1 -68
  25. package/dist/commands/docs/generated-artifacts.js +3 -70
  26. package/dist/commands/docs/generated-artifacts.test.js +1 -19
  27. package/dist/commands/docs/links.js +2 -85
  28. package/dist/commands/docs/links.test.js +4 -66
  29. package/dist/commands/docs.js +1 -24
  30. package/dist/commands/doctor.js +2 -478
  31. package/dist/commands/domains.js +2 -152
  32. package/dist/commands/email.js +31 -503
  33. package/dist/commands/env.js +1 -312
  34. package/dist/commands/extension.js +1 -239
  35. package/dist/commands/features.js +9 -345
  36. package/dist/commands/fresh.js +1 -46
  37. package/dist/commands/generate.js +2 -152
  38. package/dist/commands/http.js +1 -33
  39. package/dist/commands/index.js +1 -57
  40. package/dist/commands/install.js +1 -22
  41. package/dist/commands/key.js +1 -23
  42. package/dist/commands/link.js +2 -147
  43. package/dist/commands/lint.js +2 -84
  44. package/dist/commands/list.js +1 -140
  45. package/dist/commands/mail.js +15 -1477
  46. package/dist/commands/maintenance.js +1 -141
  47. package/dist/commands/make.js +1 -392
  48. package/dist/commands/migrate-project.js +1 -49
  49. package/dist/commands/migrate.js +27 -625
  50. package/dist/commands/outdated.js +1 -19
  51. package/dist/commands/package.js +1 -17
  52. package/dist/commands/phone.js +17 -181
  53. package/dist/commands/ports.js +2 -118
  54. package/dist/commands/prepublish.js +1 -17
  55. package/dist/commands/projects.js +1 -29
  56. package/dist/commands/protocol/craft-evidence.js +4 -98
  57. package/dist/commands/protocol/craft-evidence.test.js +1 -20
  58. package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
  59. package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
  60. package/dist/commands/protocol/desktop-support.js +2 -32
  61. package/dist/commands/protocol/desktop-workflow.test.js +3 -35
  62. package/dist/commands/protocol/driver-registry.js +2 -71
  63. package/dist/commands/protocol/pantry-evidence.js +4 -144
  64. package/dist/commands/protocol/pantry-evidence.test.js +1 -29
  65. package/dist/commands/protocol/release-manifest.js +3 -102
  66. package/dist/commands/protocol/release-manifest.test.js +2 -34
  67. package/dist/commands/protocol/run-conformance.js +4 -346
  68. package/dist/commands/protocol/run-conformance.test.js +1 -52
  69. package/dist/commands/protocol/run-driver-contracts.js +4 -83
  70. package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
  71. package/dist/commands/protocol/source-manifest.js +3 -113
  72. package/dist/commands/protocol/sync-suite.js +3 -136
  73. package/dist/commands/protocol/sync-suite.test.js +1 -44
  74. package/dist/commands/protocol.js +1 -60
  75. package/dist/commands/publish.js +8 -500
  76. package/dist/commands/queue.js +1 -248
  77. package/dist/commands/release.js +1 -42
  78. package/dist/commands/route.js +1 -21
  79. package/dist/commands/run-tool.js +1 -9
  80. package/dist/commands/saas.js +1 -25
  81. package/dist/commands/schedule.js +1 -61
  82. package/dist/commands/search.js +1 -84
  83. package/dist/commands/seed.js +1 -47
  84. package/dist/commands/serve.js +1 -55
  85. package/dist/commands/setup-ai.js +2 -121
  86. package/dist/commands/setup.js +2 -305
  87. package/dist/commands/share.js +1 -214
  88. package/dist/commands/sms.js +32 -319
  89. package/dist/commands/stacks.js +1 -72
  90. package/dist/commands/telemetry.js +1 -74
  91. package/dist/commands/test.js +1 -130
  92. package/dist/commands/tinker.js +1 -37
  93. package/dist/commands/types.js +1 -18
  94. package/dist/commands/upgrade.js +1 -98
  95. package/dist/commands/user.js +3 -84
  96. package/dist/commands/version.js +1 -14
  97. package/dist/config.js +1 -231
  98. package/dist/custom-cli.js +1 -23
  99. package/dist/database-preflight.js +1 -88
  100. package/dist/global-options.js +1 -4
  101. package/dist/index.js +1 -1
  102. package/dist/lazy-commands.js +1 -241
  103. package/dist/migrators/index.js +2 -62
  104. package/dist/migrators/laravel/index.js +1 -148
  105. package/dist/migrators/laravel/migrations.js +4 -231
  106. package/dist/migrators/laravel/models.js +8 -111
  107. package/dist/migrators/rails/index.js +1 -11
  108. package/dist/production-server.js +1 -257
  109. package/dist/project-setup.js +1 -36
  110. package/dist/serve-entry.js +1 -5
  111. package/dist/version-info.js +1 -5
  112. package/package.json +53 -46
@@ -1,141 +1 @@
1
- import process from "node:process";
2
- import { intro, log, outro } from "@stacksjs/cli";
3
- import { ExitCode } from "@stacksjs/types";
4
- export function maintenance(buddy) {
5
- buddy.command("coming-soon", "Put the application into coming soon mode").option("--message [message]", "The message to display", { default: !1 }).option("--secret [token]", "The secret phrase to bypass coming soon mode", { default: !1 }).option("--allow [ip...]", "IP addresses allowed to access the application", { default: !1 }).option("--status [code]", "The HTTP status code to return", { default: "200" }).option("--verbose", "Enable verbose output", { default: !1 }).example("buddy coming-soon").example("buddy coming-soon --secret=trailhead").example('buddy coming-soon --message="Opening soon"').action(async (options) => {
6
- const perf = await intro("buddy coming-soon");
7
- try {
8
- const { comingSoon } = await import("@stacksjs/server");
9
- await comingSoon({
10
- message: options.message || void 0,
11
- secret: options.secret || void 0,
12
- allowed: Array.isArray(options.allow) ? options.allow : options.allow ? [options.allow] : void 0,
13
- status: options.status ? Number.parseInt(options.status, 10) : 200
14
- });
15
- if (options.secret) {
16
- log.info("");
17
- log.info(`Preview URL: your-app.com/${options.secret}`);
18
- }
19
- await outro("Application is now in coming soon mode", {
20
- startTime: perf,
21
- useSeconds: !0
22
- });
23
- } catch (error) {
24
- log.error("Failed to enable coming soon mode:", error);
25
- process.exit(ExitCode.FatalError);
26
- }
27
- process.exit(ExitCode.Success);
28
- });
29
- buddy.command("launch", "Bring the application out of coming soon mode").alias("coming-soon:off").option("--verbose", "Enable verbose output", { default: !1 }).example("buddy launch").action(async () => {
30
- const perf = await intro("buddy launch");
31
- try {
32
- const { isComingSoon, launch } = await import("@stacksjs/server");
33
- if (!await isComingSoon()) {
34
- log.info("Application is not in coming soon mode.");
35
- process.exit(ExitCode.Success);
36
- }
37
- await launch();
38
- await outro("Application is now launched", {
39
- startTime: perf,
40
- useSeconds: !0
41
- });
42
- } catch (error) {
43
- log.error("Failed to disable coming soon mode:", error);
44
- process.exit(ExitCode.FatalError);
45
- }
46
- process.exit(ExitCode.Success);
47
- });
48
- buddy.command("coming-soon:status", "Check if the application is in coming soon mode").option("--verbose", "Enable verbose output", { default: !1 }).action(async () => {
49
- try {
50
- const { comingSoonPayload, isComingSoon } = await import("@stacksjs/server");
51
- if (await isComingSoon()) {
52
- const payload = await comingSoonPayload();
53
- log.warn("Application is in coming soon mode");
54
- if (payload) {
55
- if (payload.message)
56
- log.info(`Message: ${payload.message}`);
57
- if (payload.secret)
58
- log.info(`Secret: ${payload.secret}`);
59
- if (payload.allowed?.length)
60
- log.info(`Allowed IPs: ${payload.allowed.join(", ")}`);
61
- if (payload.time)
62
- log.info(`Started: ${new Date(payload.time).toLocaleString()}`);
63
- }
64
- } else
65
- log.success("Application is launched");
66
- } catch (error) {
67
- log.error("Failed to check coming soon status:", error);
68
- process.exit(ExitCode.FatalError);
69
- }
70
- process.exit(ExitCode.Success);
71
- });
72
- buddy.command("down", "Put the application into maintenance mode").option("--message [message]", "The message to display", { default: !1 }).option("--retry [seconds]", "The number of seconds after which the request may be retried", { default: !1 }).option("--secret [token]", "The secret phrase to bypass maintenance mode", { default: !1 }).option("--allow [ip...]", "IP addresses allowed to access the application", { default: !1 }).option("--redirect [url]", "Redirect all requests to a given URL", { default: !1 }).option("--status [code]", "The HTTP status code to return", { default: !1 }).option("--verbose", "Enable verbose output", { default: !1 }).example("buddy down").example('buddy down --message="Upgrading database"').example("buddy down --secret=my-secret-token").example("buddy down --retry=60").example("buddy down --allow=192.168.1.1 --allow=192.168.1.2").action(async (options) => {
73
- const perf = await intro("buddy down");
74
- try {
75
- const { down } = await import("@stacksjs/server");
76
- await down({
77
- message: options.message || void 0,
78
- retry: options.retry ? Number.parseInt(options.retry, 10) : void 0,
79
- secret: options.secret || void 0,
80
- allowed: Array.isArray(options.allow) ? options.allow : options.allow ? [options.allow] : void 0,
81
- redirect: options.redirect || void 0,
82
- status: options.status ? Number.parseInt(options.status, 10) : 503
83
- });
84
- if (options.secret) {
85
- log.info("");
86
- log.info(`Bypass URL: your-app.com/${options.secret}`);
87
- }
88
- await outro("Application is now in maintenance mode", {
89
- startTime: perf,
90
- useSeconds: !0
91
- });
92
- } catch (error) {
93
- log.error("Failed to enable maintenance mode:", error);
94
- process.exit(ExitCode.FatalError);
95
- }
96
- process.exit(ExitCode.Success);
97
- });
98
- buddy.command("up", "Bring the application out of maintenance mode").option("--verbose", "Enable verbose output", { default: !1 }).example("buddy up").action(async () => {
99
- const perf = await intro("buddy up");
100
- try {
101
- const { up, isDownForMaintenance } = await import("@stacksjs/server");
102
- if (!await isDownForMaintenance()) {
103
- log.info("Application is already live.");
104
- process.exit(ExitCode.Success);
105
- }
106
- await up();
107
- await outro("Application is now live", {
108
- startTime: perf,
109
- useSeconds: !0
110
- });
111
- } catch (error) {
112
- log.error("Failed to bring application up:", error);
113
- process.exit(ExitCode.FatalError);
114
- }
115
- process.exit(ExitCode.Success);
116
- });
117
- buddy.command("status", "Check whether the application is in maintenance or coming-soon mode").alias("maintenance:status").option("--verbose", "Enable verbose output", { default: !1 }).action(async () => {
118
- try {
119
- const { activeSiteModePayload } = await import("@stacksjs/server"), payload = await activeSiteModePayload();
120
- if (payload) {
121
- const mode = payload.mode ?? "maintenance";
122
- log.warn(`Application is in ${mode} mode`);
123
- if (payload.message)
124
- log.info(`Message: ${payload.message}`);
125
- if (payload.retry)
126
- log.info(`Retry-After: ${payload.retry} seconds`);
127
- if (payload.secret)
128
- log.info(`Secret: ${payload.secret}`);
129
- if (payload.allowed?.length)
130
- log.info(`Allowed IPs: ${payload.allowed.join(", ")}`);
131
- if (payload.time)
132
- log.info(`Started: ${new Date(payload.time).toLocaleString()}`);
133
- } else
134
- log.success("Application is live");
135
- } catch (error) {
136
- log.error("Failed to check site-mode status:", error);
137
- process.exit(ExitCode.FatalError);
138
- }
139
- process.exit(ExitCode.Success);
140
- });
141
- }
1
+ import process from"node:process";import{intro,log,outro}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";export function maintenance(buddy){buddy.command("coming-soon","Put the application into coming soon mode").option("--message [message]","The message to display",{default:!1}).option("--secret [token]","The secret phrase to bypass coming soon mode",{default:!1}).option("--allow [ip...]","IP addresses allowed to access the application",{default:!1}).option("--status [code]","The HTTP status code to return",{default:"200"}).option("--verbose","Enable verbose output",{default:!1}).example("buddy coming-soon").example("buddy coming-soon --secret=trailhead").example('buddy coming-soon --message="Opening soon"').action(async(options)=>{const perf=await intro("buddy coming-soon");try{const{comingSoon}=await import("@stacksjs/server");await comingSoon({message:options.message||void 0,secret:options.secret||void 0,allowed:Array.isArray(options.allow)?options.allow:options.allow?[options.allow]:void 0,status:options.status?Number.parseInt(options.status,10):200});if(options.secret){log.info("");log.info(`Preview URL: your-app.com/${options.secret}`)}await outro("Application is now in coming soon mode",{startTime:perf,useSeconds:!0})}catch(error){log.error("Failed to enable coming soon mode:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)});buddy.command("launch","Bring the application out of coming soon mode").alias("coming-soon:off").option("--verbose","Enable verbose output",{default:!1}).example("buddy launch").action(async()=>{const perf=await intro("buddy launch");try{const{isComingSoon,launch}=await import("@stacksjs/server");if(!await isComingSoon()){log.info("Application is not in coming soon mode.");process.exit(ExitCode.Success)}await launch();await outro("Application is now launched",{startTime:perf,useSeconds:!0})}catch(error){log.error("Failed to disable coming soon mode:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)});buddy.command("coming-soon:status","Check if the application is in coming soon mode").option("--verbose","Enable verbose output",{default:!1}).action(async()=>{try{const{comingSoonPayload,isComingSoon}=await import("@stacksjs/server");if(await isComingSoon()){const payload=await comingSoonPayload();log.warn("Application is in coming soon mode");if(payload){if(payload.message)log.info(`Message: ${payload.message}`);if(payload.secret)log.info(`Secret: ${payload.secret}`);if(payload.allowed?.length)log.info(`Allowed IPs: ${payload.allowed.join(", ")}`);if(payload.time)log.info(`Started: ${new Date(payload.time).toLocaleString()}`)}}else log.success("Application is launched")}catch(error){log.error("Failed to check coming soon status:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)});buddy.command("down","Put the application into maintenance mode").option("--message [message]","The message to display",{default:!1}).option("--retry [seconds]","The number of seconds after which the request may be retried",{default:!1}).option("--secret [token]","The secret phrase to bypass maintenance mode",{default:!1}).option("--allow [ip...]","IP addresses allowed to access the application",{default:!1}).option("--redirect [url]","Redirect all requests to a given URL",{default:!1}).option("--status [code]","The HTTP status code to return",{default:!1}).option("--verbose","Enable verbose output",{default:!1}).example("buddy down").example('buddy down --message="Upgrading database"').example("buddy down --secret=my-secret-token").example("buddy down --retry=60").example("buddy down --allow=192.168.1.1 --allow=192.168.1.2").action(async(options)=>{const perf=await intro("buddy down");try{const{down}=await import("@stacksjs/server");await down({message:options.message||void 0,retry:options.retry?Number.parseInt(options.retry,10):void 0,secret:options.secret||void 0,allowed:Array.isArray(options.allow)?options.allow:options.allow?[options.allow]:void 0,redirect:options.redirect||void 0,status:options.status?Number.parseInt(options.status,10):503});if(options.secret){log.info("");log.info(`Bypass URL: your-app.com/${options.secret}`)}await outro("Application is now in maintenance mode",{startTime:perf,useSeconds:!0})}catch(error){log.error("Failed to enable maintenance mode:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)});buddy.command("up","Bring the application out of maintenance mode").option("--verbose","Enable verbose output",{default:!1}).example("buddy up").action(async()=>{const perf=await intro("buddy up");try{const{up,isDownForMaintenance}=await import("@stacksjs/server");if(!await isDownForMaintenance()){log.info("Application is already live.");process.exit(ExitCode.Success)}await up();await outro("Application is now live",{startTime:perf,useSeconds:!0})}catch(error){log.error("Failed to bring application up:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)});buddy.command("status","Check whether the application is in maintenance or coming-soon mode").alias("maintenance:status").option("--verbose","Enable verbose output",{default:!1}).action(async()=>{try{const{activeSiteModePayload}=await import("@stacksjs/server"),payload=await activeSiteModePayload();if(payload){const mode=payload.mode??"maintenance";log.warn(`Application is in ${mode} mode`);if(payload.message)log.info(`Message: ${payload.message}`);if(payload.retry)log.info(`Retry-After: ${payload.retry} seconds`);if(payload.secret)log.info(`Secret: ${payload.secret}`);if(payload.allowed?.length)log.info(`Allowed IPs: ${payload.allowed.join(", ")}`);if(payload.time)log.info(`Started: ${new Date(payload.time).toLocaleString()}`)}else log.success("Application is live")}catch(error){log.error("Failed to check site-mode status:",error);process.exit(ExitCode.FatalError)}process.exit(ExitCode.Success)})}
@@ -1,392 +1 @@
1
- import process from "node:process";
2
- import {
3
- createFactory,
4
- createMiddleware,
5
- createMigration,
6
- createModel,
7
- createNotification,
8
- createPage,
9
- invoke,
10
- makeAction,
11
- makeCertificate,
12
- makeCommand,
13
- makeComponent,
14
- makeDatabase,
15
- makeFunction,
16
- makeJob,
17
- makeLanguage,
18
- makeMail,
19
- makePage,
20
- makePolicy,
21
- makeQueueTable,
22
- makeResource,
23
- makeStack,
24
- setDryRun
25
- } from "@stacksjs/actions";
26
- import { intro, italic, onUnknownSubcommand, outro } from "@stacksjs/cli";
27
- import { log } from "@stacksjs/logging";
28
- import { ExitCode } from "@stacksjs/types";
29
- export function make(buddy) {
30
- const descriptions = {
31
- action: "Create a new action",
32
- command: "Create a new CLI command",
33
- model: "Create a new model",
34
- middleware: "Create a new middleware",
35
- component: "Create a new component",
36
- page: "Create a new page",
37
- function: "Create a new function",
38
- job: "Create a new job",
39
- language: "Create a new language",
40
- database: "Create a new database",
41
- migration: "Create a new migration",
42
- factory: "Create a new factory",
43
- notification: "Create a new notification",
44
- mail: "Create a new Mailable + companion stx template",
45
- policy: "Create a new authorization policy",
46
- resource: "Create a new API resource",
47
- name: "The name of the action",
48
- queue: "Make queue migration",
49
- queueTable: "Create the queue jobs table migration",
50
- stack: "Create a new stack",
51
- certificate: "Create a new SSL Certificate",
52
- select: "What are you trying to make?",
53
- project: "Target a specific project",
54
- verbose: "Enable verbose output"
55
- };
56
- buddy.command("make [make]", "The make command").option("-a, --action [action]", descriptions.action, { default: !1 }).option("-c, --component [component]", descriptions.component, { default: !1 }).option("-d, --database [database]", descriptions.database, { default: !1 }).option("-f, --factory [factory]", descriptions.factory, { default: !1 }).option("-fn, --function [function]", descriptions.function, { default: !1 }).option("-l, --language [language]", descriptions.language, { default: !1 }).option("-m, --model [model]", descriptions.model, { default: !1 }).option("-mw, --middleware [middleware]", descriptions.middleware, { default: !1 }).option("-p, --page [page]", descriptions.page, { default: !1 }).option("-mg, --migration [migration]", descriptions.migration, { default: !1 }).option("-n, --notification [notification]", descriptions.notification, { default: !1 }).option("-qt, --queue-table", descriptions.queue, { default: !1 }).option("-s, --stack [stack]", descriptions.stack, { default: !1 }).option("--dry-run", "Preview the files that would be generated without writing", { default: !1 }).option("--with-validation", "Include a validation rules block in the generated stub", { default: !1 }).option("--with-auth", "Include auth-aware boilerplate in the generated stub", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (make, options) => {
57
- log.debug("Running `buddy make` ...", options);
58
- if (!buddy.args[0]) {
59
- console.error("You need to specify a name. Read more about the documentation here.");
60
- process.exit(ExitCode.FatalError);
61
- }
62
- setDryRun(Boolean(options.dryRun || options["dry-run"]));
63
- if (make) {
64
- options.name = buddy.args[1] ?? make;
65
- switch (make) {
66
- case "action":
67
- await makeAction(options);
68
- break;
69
- case "certificate":
70
- await makeCertificate();
71
- break;
72
- case "command":
73
- await makeCommand(options);
74
- break;
75
- case "component":
76
- await makeComponent(options);
77
- break;
78
- case "database":
79
- makeDatabase(options);
80
- break;
81
- case "function":
82
- await makeFunction(options);
83
- break;
84
- case "job":
85
- await makeJob(options);
86
- break;
87
- case "language":
88
- await makeLanguage(options);
89
- break;
90
- case "mail":
91
- await makeMail(options);
92
- break;
93
- case "migration":
94
- await createMigration(options);
95
- break;
96
- case "middleware":
97
- await createMiddleware(options);
98
- break;
99
- case "model":
100
- await createModel(options);
101
- break;
102
- case "page":
103
- await createPage(options);
104
- break;
105
- case "notification":
106
- await createNotification(options);
107
- break;
108
- case "policy":
109
- await makePolicy(options);
110
- break;
111
- case "resource":
112
- await makeResource(options);
113
- break;
114
- case "queue-table":
115
- await makeQueueTable();
116
- break;
117
- case "stack":
118
- await makeStack(options);
119
- break;
120
- case "factory":
121
- await createFactory(options);
122
- break;
123
- default: {
124
- console.error(`Unknown make subcommand: ${make}`);
125
- console.error("Valid subcommands: action, certificate, command, component, database, factory, function, job, language, mail, middleware, migration, model, notification, page, policy, queue-table, resource, stack");
126
- process.exit(ExitCode.InvalidArgument);
127
- }
128
- }
129
- }
130
- await invoke(options);
131
- process.exit(ExitCode.Success);
132
- });
133
- buddy.command("make:action [name]", descriptions.action).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--dry-run", "Preview the file without writing", { default: !1 }).option("--with-validation", "Generate a stub that calls validate()", { default: !1 }).option("--with-auth", "Generate a stub that requires an authenticated user", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
134
- log.info("Running `buddy make:action` ...");
135
- log.debug("Running `buddy make:action` ...", name, options);
136
- name = name ?? options.name;
137
- options.name = name;
138
- if (!name) {
139
- console.error("You need to specify a name. Read more about the documentation here.");
140
- process.exit(ExitCode.FatalError);
141
- }
142
- setDryRun(Boolean(options.dryRun || options["dry-run"]));
143
- await makeAction(options);
144
- });
145
- buddy.command("make:certificate", descriptions.certificate).alias("make:cert").example("buddy make:certificate").action(async (options) => {
146
- log.debug("Running `buddy make:certificate` ...", options);
147
- await makeCertificate();
148
- });
149
- buddy.command("scaffold:crud [name]", "Generate model, migration, and CRUD actions").alias("make:crud").alias("make:scaffold").option("-n, --name [name]", "Resource name (PascalCase)", { default: !1 }).option("-f, --fields [fields]", "Comma-separated field list, e.g. title:string,body:text,published:boolean", { default: "" }).option("--dry-run", "Preview the generated files without writing", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy scaffold:crud Post --fields=title:string,body:text,published:boolean").action(async (name, options) => {
150
- name = name ?? options.name;
151
- if (!name) {
152
- console.error("scaffold:crud requires a resource name. Example: buddy scaffold:crud Post --fields=title:string,body:text");
153
- process.exit(ExitCode.FatalError);
154
- }
155
- const { scaffoldCrud } = await import("@stacksjs/actions");
156
- setDryRun(Boolean(options.dryRun || options["dry-run"]));
157
- try {
158
- await scaffoldCrud(name, options);
159
- } catch (err) {
160
- console.error("scaffold:crud failed:", err);
161
- process.exit(ExitCode.FatalError);
162
- }
163
- });
164
- buddy.command("make:command [name]", descriptions.command).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-s, --signature [signature]", "The command signature (CLI name)", { default: !1 }).option("-d, --description [description]", "The command description", { default: !1 }).option("--no-register", "Do not register in Commands.ts").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy make:command SendEmails").example("buddy make:command SendEmails --signature=send-emails").action(async (name, options) => {
165
- log.debug("Running `buddy make:command` ...", options);
166
- const perf = await intro("buddy make:command");
167
- name = name ?? options.name;
168
- options.name = name;
169
- if (!name) {
170
- console.error("You need to specify a command name.");
171
- console.error("Example: buddy make:command SendEmails");
172
- process.exit(ExitCode.FatalError);
173
- }
174
- if (!await makeCommand(options)) {
175
- await outro("While running the make:command command, there was an issue", {
176
- startTime: perf,
177
- useSeconds: !0
178
- });
179
- process.exit(ExitCode.FatalError);
180
- }
181
- await outro(`Created your ${italic(name)} command.`, {
182
- startTime: perf,
183
- useSeconds: !0
184
- });
185
- process.exit(ExitCode.Success);
186
- });
187
- buddy.command("make:component [name]", descriptions.component).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
188
- log.debug("Running `buddy make:component` ...", options);
189
- name = name ?? options.name;
190
- options.name = name;
191
- if (!name) {
192
- console.error("You need to specify a name. Read more about the documentation here.");
193
- process.exit(ExitCode.FatalError);
194
- }
195
- await makeComponent(options);
196
- });
197
- buddy.command("make:database [name]", descriptions.database).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action((name, options) => {
198
- log.debug("Running `buddy make:database` ...", options);
199
- name = name ?? options.name;
200
- options.name = name;
201
- if (!name) {
202
- console.error("You need to specify a database name via the `--name` option, or as the command\u2019s argument.");
203
- console.error("Example: `buddy make:database my-cool-database`");
204
- console.error("Or: `buddy make:database --name=my-cool-database`");
205
- console.error("Read more about the documentation here: https://stacksjs.com/docs/make/database");
206
- process.exit(ExitCode.FatalError);
207
- }
208
- makeDatabase(options);
209
- });
210
- buddy.command("make:factory [name]", descriptions.factory).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
211
- log.debug("Running `buddy make:factory` ...", options);
212
- name = name ?? options.name;
213
- options.name = name;
214
- if (!name) {
215
- console.error("You need to specify a name. Read more about the documentation here.");
216
- process.exit(ExitCode.FatalError);
217
- }
218
- await createFactory(options);
219
- });
220
- buddy.command("make:function [name]", descriptions.function).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
221
- log.debug("Running `buddy make:function` ...", options);
222
- name = name ?? options.name;
223
- options.name = name;
224
- if (!name) {
225
- console.error("You need to specify a name. Read more about the documentation here.");
226
- process.exit(ExitCode.FatalError);
227
- }
228
- await makeFunction(options);
229
- });
230
- buddy.command("make:lang [name]", descriptions.language).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
231
- log.debug("Running `buddy make:lang` ...", options);
232
- name = name ?? options.name;
233
- options.name = name;
234
- if (!name) {
235
- console.error("You need to specify a name. Read more about the documentation here.");
236
- process.exit(ExitCode.FatalError);
237
- }
238
- await makeLanguage(options);
239
- });
240
- buddy.command("make:migration [name]", descriptions.migration).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
241
- log.debug("Running `buddy make:migration` ...", options);
242
- name = name ?? options.name;
243
- options.name = name;
244
- if (!name) {
245
- console.error("You need to specify a migration name");
246
- process.exit(ExitCode.FatalError);
247
- }
248
- await createMigration(options);
249
- });
250
- buddy.command("make:model [name]", descriptions.model).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
251
- log.debug("Running `buddy make:model` ...", options);
252
- name = name ?? options.name;
253
- options.name = name;
254
- if (!name) {
255
- console.error("You need to specify a model name");
256
- process.exit(ExitCode.FatalError);
257
- }
258
- await createModel(options);
259
- });
260
- buddy.command("make:mail [name]", descriptions.mail).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-f, --force", "Overwrite existing files", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy make:mail OrderShipped").example("buddy make:mail welcome-back // PascalCases to WelcomeBack, kebab-cases to welcome-back").example("buddy make:mail Welcome --force // overwrite existing files").action(async (name, options) => {
261
- log.debug("Running `buddy make:mail` ...", options);
262
- const perf = await intro("buddy make:mail");
263
- name = name ?? options.name;
264
- options.name = name;
265
- if (!name) {
266
- console.error("You need to specify a name (e.g. `buddy make:mail OrderShipped`).");
267
- process.exit(ExitCode.FatalError);
268
- }
269
- await makeMail(options);
270
- await outro(`Created your ${italic(name)} mailable.`, {
271
- startTime: perf,
272
- useSeconds: !0
273
- });
274
- process.exit(ExitCode.Success);
275
- });
276
- buddy.command("make:notification [name]", descriptions.notification).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-e, --email", "Is it an email notification?", { default: !0 }).option("-c, --chat", "Is it a chat notification?", { default: !1 }).option("-s, --sms", "Is it a SMS notification?", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
277
- log.debug("Running `buddy make:notification` ...", options);
278
- const perf = await intro("buddy make:notification");
279
- name = name ?? options.name;
280
- options.name = name;
281
- if (!name) {
282
- console.error("You need to specify a name. Read more about the documentation here.");
283
- process.exit(ExitCode.FatalError);
284
- }
285
- if (!await createNotification(options)) {
286
- await outro("While running the make:notification command, there was an issue", {
287
- startTime: perf,
288
- useSeconds: !0
289
- });
290
- process.exit(ExitCode.FatalError);
291
- }
292
- await outro(`Created your ${italic(name)} notification.`, {
293
- startTime: perf,
294
- useSeconds: !0
295
- });
296
- process.exit(ExitCode.Success);
297
- });
298
- buddy.command("make:policy [name]", descriptions.policy).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-m, --model [model]", "The model this policy is for", { default: !1 }).option("--no-register", "Do not register in Gates.ts", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy make:policy PostPolicy").example("buddy make:policy CommentPolicy --model=Comment").action(async (name, options) => {
299
- log.debug("Running `buddy make:policy` ...", options);
300
- const perf = await intro("buddy make:policy");
301
- name = name ?? options.name;
302
- options.name = name;
303
- if (!name) {
304
- console.error("You need to specify a policy name.");
305
- console.error("Example: buddy make:policy PostPolicy");
306
- process.exit(ExitCode.FatalError);
307
- }
308
- if (!await makePolicy(options)) {
309
- await outro("While running the make:policy command, there was an issue", {
310
- startTime: perf,
311
- useSeconds: !0
312
- });
313
- process.exit(ExitCode.FatalError);
314
- }
315
- await outro(`Created your ${italic(name)} policy.`, {
316
- startTime: perf,
317
- useSeconds: !0
318
- });
319
- process.exit(ExitCode.Success);
320
- });
321
- buddy.command("make:resource [name]", descriptions.resource).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-m, --model [model]", "The model this resource is for", { default: !1 }).option("-c, --collection", "Create a collection resource", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).example("buddy make:resource UserResource").example("buddy make:resource PostResource --model=Post").example("buddy make:resource PostCollection --collection").action(async (name, options) => {
322
- log.debug("Running `buddy make:resource` ...", options);
323
- const perf = await intro("buddy make:resource");
324
- name = name ?? options.name;
325
- options.name = name;
326
- if (!name) {
327
- console.error("You need to specify a resource name.");
328
- console.error("Example: buddy make:resource UserResource");
329
- process.exit(ExitCode.FatalError);
330
- }
331
- if (!await makeResource(options)) {
332
- await outro("While running the make:resource command, there was an issue", {
333
- startTime: perf,
334
- useSeconds: !0
335
- });
336
- process.exit(ExitCode.FatalError);
337
- }
338
- await outro(`Created your ${italic(name)} resource.`, {
339
- startTime: perf,
340
- useSeconds: !0
341
- });
342
- process.exit(ExitCode.Success);
343
- });
344
- buddy.command("make:queue-table", descriptions.queueTable).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
345
- log.debug("Running `buddy make queue:table` ...", options);
346
- await makeQueueTable();
347
- });
348
- buddy.command("make:stack [name]", descriptions.stack).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
349
- log.debug("Running `buddy make:stack` ...", options);
350
- name = name ?? options.name;
351
- options.name = name;
352
- if (!name) {
353
- console.error("You need to specify a name. Read more about the documentation here.");
354
- process.exit(ExitCode.FatalError);
355
- }
356
- await makeStack(options);
357
- });
358
- buddy.command("make:view [name]", descriptions.page).alias("make:page [name]").option("-n, --name [name]", descriptions.name, { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
359
- log.debug("Running `buddy make:view` ...", options);
360
- name = name ?? options.name;
361
- options.name = name;
362
- if (!name) {
363
- console.error("You need to specify a name. Read more about the documentation here.");
364
- process.exit(ExitCode.FatalError);
365
- }
366
- await makePage(options);
367
- });
368
- buddy.command("make:job [name]", descriptions.job).option("-n, --name [name]", descriptions.name, { default: !1 }).option("-q, --queue [queue]", "The queue to dispatch to", { default: "default" }).option("-c, --class", "Create a class-based job", { default: !1 }).option("-t, --tries [tries]", "Number of retry attempts", { default: 3 }).option("-b, --backoff [backoff]", "Backoff delay in seconds", { default: 3 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (name, options) => {
369
- log.debug("Running `buddy make:job` ...", options);
370
- const perf = await intro("buddy make:job");
371
- name = name ?? options.name;
372
- options.name = name;
373
- if (!name) {
374
- console.error("You need to specify a job name.");
375
- console.error("Example: buddy make:job SendWelcomeEmail");
376
- process.exit(ExitCode.FatalError);
377
- }
378
- if (!await makeJob(options)) {
379
- await outro("While running the make:job command, there was an issue", {
380
- startTime: perf,
381
- useSeconds: !0
382
- });
383
- process.exit(ExitCode.FatalError);
384
- }
385
- await outro(`Created your ${italic(name)} job.`, {
386
- startTime: perf,
387
- useSeconds: !0
388
- });
389
- process.exit(ExitCode.Success);
390
- });
391
- onUnknownSubcommand(buddy, "make");
392
- }
1
+ import process from"node:process";import{createFactory,createMiddleware,createMigration,createModel,createNotification,createPage,invoke,makeAction,makeCertificate,makeCommand,makeComponent,makeDatabase,makeFunction,makeJob,makeLanguage,makeMail,makePage,makePolicy,makeQueueTable,makeResource,makeStack,setDryRun}from"@stacksjs/actions";import{intro,italic,onUnknownSubcommand,outro}from"@stacksjs/cli";import{log}from"@stacksjs/logging";import{ExitCode}from"@stacksjs/types";export function make(buddy){const descriptions={action:"Create a new action",command:"Create a new CLI command",model:"Create a new model",middleware:"Create a new middleware",component:"Create a new component",page:"Create a new page",function:"Create a new function",job:"Create a new job",language:"Create a new language",database:"Create a new database",migration:"Create a new migration",factory:"Create a new factory",notification:"Create a new notification",mail:"Create a new Mailable + companion stx template",policy:"Create a new authorization policy",resource:"Create a new API resource",name:"The name of the action",queue:"Make queue migration",queueTable:"Create the queue jobs table migration",stack:"Create a new stack",certificate:"Create a new SSL Certificate",select:"What are you trying to make?",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("make [make]","The make command").option("-a, --action [action]",descriptions.action,{default:!1}).option("-c, --component [component]",descriptions.component,{default:!1}).option("-d, --database [database]",descriptions.database,{default:!1}).option("-f, --factory [factory]",descriptions.factory,{default:!1}).option("-fn, --function [function]",descriptions.function,{default:!1}).option("-l, --language [language]",descriptions.language,{default:!1}).option("-m, --model [model]",descriptions.model,{default:!1}).option("-mw, --middleware [middleware]",descriptions.middleware,{default:!1}).option("-p, --page [page]",descriptions.page,{default:!1}).option("-mg, --migration [migration]",descriptions.migration,{default:!1}).option("-n, --notification [notification]",descriptions.notification,{default:!1}).option("-qt, --queue-table",descriptions.queue,{default:!1}).option("-s, --stack [stack]",descriptions.stack,{default:!1}).option("--dry-run","Preview the files that would be generated without writing",{default:!1}).option("--with-validation","Include a validation rules block in the generated stub",{default:!1}).option("--with-auth","Include auth-aware boilerplate in the generated stub",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(make,options)=>{log.debug("Running `buddy make` ...",options);if(!buddy.args[0]){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}setDryRun(Boolean(options.dryRun||options["dry-run"]));if(make){options.name=buddy.args[1]??make;switch(make){case"action":await makeAction(options);break;case"certificate":await makeCertificate();break;case"command":await makeCommand(options);break;case"component":await makeComponent(options);break;case"database":makeDatabase(options);break;case"function":await makeFunction(options);break;case"job":await makeJob(options);break;case"language":await makeLanguage(options);break;case"mail":await makeMail(options);break;case"migration":await createMigration(options);break;case"middleware":await createMiddleware(options);break;case"model":await createModel(options);break;case"page":await createPage(options);break;case"notification":await createNotification(options);break;case"policy":await makePolicy(options);break;case"resource":await makeResource(options);break;case"queue-table":await makeQueueTable();break;case"stack":await makeStack(options);break;case"factory":await createFactory(options);break;default:{console.error(`Unknown make subcommand: ${make}`);console.error("Valid subcommands: action, certificate, command, component, database, factory, function, job, language, mail, middleware, migration, model, notification, page, policy, queue-table, resource, stack");process.exit(ExitCode.InvalidArgument)}}}await invoke(options);process.exit(ExitCode.Success)});buddy.command("make:action [name]",descriptions.action).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--dry-run","Preview the file without writing",{default:!1}).option("--with-validation","Generate a stub that calls validate()",{default:!1}).option("--with-auth","Generate a stub that requires an authenticated user",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.info("Running `buddy make:action` ...");log.debug("Running `buddy make:action` ...",name,options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}setDryRun(Boolean(options.dryRun||options["dry-run"]));await makeAction(options)});buddy.command("make:certificate",descriptions.certificate).alias("make:cert").example("buddy make:certificate").action(async(options)=>{log.debug("Running `buddy make:certificate` ...",options);await makeCertificate()});buddy.command("scaffold:crud [name]","Generate model, migration, and CRUD actions").alias("make:crud").alias("make:scaffold").option("-n, --name [name]","Resource name (PascalCase)",{default:!1}).option("-f, --fields [fields]","Comma-separated field list, e.g. title:string,body:text,published:boolean",{default:""}).option("--dry-run","Preview the generated files without writing",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy scaffold:crud Post --fields=title:string,body:text,published:boolean").action(async(name,options)=>{name=name??options.name;if(!name){console.error("scaffold:crud requires a resource name. Example: buddy scaffold:crud Post --fields=title:string,body:text");process.exit(ExitCode.FatalError)}const{scaffoldCrud}=await import("@stacksjs/actions");setDryRun(Boolean(options.dryRun||options["dry-run"]));try{await scaffoldCrud(name,options)}catch(err){console.error("scaffold:crud failed:",err);process.exit(ExitCode.FatalError)}});buddy.command("make:command [name]",descriptions.command).option("-n, --name [name]",descriptions.name,{default:!1}).option("-s, --signature [signature]","The command signature (CLI name)",{default:!1}).option("-d, --description [description]","The command description",{default:!1}).option("--no-register","Do not register in Commands.ts").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy make:command SendEmails").example("buddy make:command SendEmails --signature=send-emails").action(async(name,options)=>{log.debug("Running `buddy make:command` ...",options);const perf=await intro("buddy make:command");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a command name.");console.error("Example: buddy make:command SendEmails");process.exit(ExitCode.FatalError)}if(!await makeCommand(options)){await outro("While running the make:command command, there was an issue",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro(`Created your ${italic(name)} command.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("make:component [name]",descriptions.component).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:component` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await makeComponent(options)});buddy.command("make:database [name]",descriptions.database).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action((name,options)=>{log.debug("Running `buddy make:database` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a database name via the `--name` option, or as the command\u2019s argument.");console.error("Example: `buddy make:database my-cool-database`");console.error("Or: `buddy make:database --name=my-cool-database`");console.error("Read more about the documentation here: https://stacksjs.com/docs/make/database");process.exit(ExitCode.FatalError)}makeDatabase(options)});buddy.command("make:factory [name]",descriptions.factory).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:factory` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await createFactory(options)});buddy.command("make:function [name]",descriptions.function).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:function` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await makeFunction(options)});buddy.command("make:lang [name]",descriptions.language).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:lang` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await makeLanguage(options)});buddy.command("make:migration [name]",descriptions.migration).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:migration` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a migration name");process.exit(ExitCode.FatalError)}await createMigration(options)});buddy.command("make:model [name]",descriptions.model).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:model` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a model name");process.exit(ExitCode.FatalError)}await createModel(options)});buddy.command("make:mail [name]",descriptions.mail).option("-n, --name [name]",descriptions.name,{default:!1}).option("-f, --force","Overwrite existing files",{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy make:mail OrderShipped").example("buddy make:mail welcome-back // PascalCases to WelcomeBack, kebab-cases to welcome-back").example("buddy make:mail Welcome --force // overwrite existing files").action(async(name,options)=>{log.debug("Running `buddy make:mail` ...",options);const perf=await intro("buddy make:mail");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name (e.g. `buddy make:mail OrderShipped`).");process.exit(ExitCode.FatalError)}await makeMail(options);await outro(`Created your ${italic(name)} mailable.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("make:notification [name]",descriptions.notification).option("-n, --name [name]",descriptions.name,{default:!1}).option("-e, --email","Is it an email notification?",{default:!0}).option("-c, --chat","Is it a chat notification?",{default:!1}).option("-s, --sms","Is it a SMS notification?",{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:notification` ...",options);const perf=await intro("buddy make:notification");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}if(!await createNotification(options)){await outro("While running the make:notification command, there was an issue",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro(`Created your ${italic(name)} notification.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("make:policy [name]",descriptions.policy).option("-n, --name [name]",descriptions.name,{default:!1}).option("-m, --model [model]","The model this policy is for",{default:!1}).option("--no-register","Do not register in Gates.ts",{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy make:policy PostPolicy").example("buddy make:policy CommentPolicy --model=Comment").action(async(name,options)=>{log.debug("Running `buddy make:policy` ...",options);const perf=await intro("buddy make:policy");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a policy name.");console.error("Example: buddy make:policy PostPolicy");process.exit(ExitCode.FatalError)}if(!await makePolicy(options)){await outro("While running the make:policy command, there was an issue",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro(`Created your ${italic(name)} policy.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("make:resource [name]",descriptions.resource).option("-n, --name [name]",descriptions.name,{default:!1}).option("-m, --model [model]","The model this resource is for",{default:!1}).option("-c, --collection","Create a collection resource",{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).example("buddy make:resource UserResource").example("buddy make:resource PostResource --model=Post").example("buddy make:resource PostCollection --collection").action(async(name,options)=>{log.debug("Running `buddy make:resource` ...",options);const perf=await intro("buddy make:resource");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a resource name.");console.error("Example: buddy make:resource UserResource");process.exit(ExitCode.FatalError)}if(!await makeResource(options)){await outro("While running the make:resource command, there was an issue",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro(`Created your ${italic(name)} resource.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("make:queue-table",descriptions.queueTable).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy make queue:table` ...",options);await makeQueueTable()});buddy.command("make:stack [name]",descriptions.stack).option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:stack` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await makeStack(options)});buddy.command("make:view [name]",descriptions.page).alias("make:page [name]").option("-n, --name [name]",descriptions.name,{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:view` ...",options);name=name??options.name;options.name=name;if(!name){console.error("You need to specify a name. Read more about the documentation here.");process.exit(ExitCode.FatalError)}await makePage(options)});buddy.command("make:job [name]",descriptions.job).option("-n, --name [name]",descriptions.name,{default:!1}).option("-q, --queue [queue]","The queue to dispatch to",{default:"default"}).option("-c, --class","Create a class-based job",{default:!1}).option("-t, --tries [tries]","Number of retry attempts",{default:3}).option("-b, --backoff [backoff]","Backoff delay in seconds",{default:3}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(name,options)=>{log.debug("Running `buddy make:job` ...",options);const perf=await intro("buddy make:job");name=name??options.name;options.name=name;if(!name){console.error("You need to specify a job name.");console.error("Example: buddy make:job SendWelcomeEmail");process.exit(ExitCode.FatalError)}if(!await makeJob(options)){await outro("While running the make:job command, there was an issue",{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}await outro(`Created your ${italic(name)} job.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"make")}
@@ -1,49 +1 @@
1
- import { existsSync } from "node:fs";
2
- import { writeFile } from "node:fs/promises";
3
- import { join, resolve } from "node:path";
4
- import process from "node:process";
5
- import { log, onUnknownSubcommand } from "@stacksjs/cli";
6
- import { ExitCode } from "@stacksjs/types";
7
- import { DRIVERS, renderReport, runMigrator } from "../migrators";
8
- export function migrateProject(buddy) {
9
- buddy.command("migrate:project [target]", "Port an existing project (Laravel, Rails) into a Stacks project.").option("--from <framework>", `Source framework \u2014 one of: ${Object.keys(DRIVERS).join(", ")}`, { default: "laravel" }).option("--source <path>", "Path to the existing source project. Defaults to the current working directory.", { default: !1 }).option("--dry-run", "Show what would be translated without writing files.", { default: !1 }).option("--verbose", "Print the per-entry table after the summary.", { default: !1 }).action(async (target, options) => {
10
- const from = options.from ?? "laravel";
11
- if (!(from in DRIVERS)) {
12
- log.error(`Unknown source framework: '${from}'. Supported: ${Object.keys(DRIVERS).join(", ")}.`);
13
- process.exit(ExitCode.FatalError);
14
- }
15
- const sourcePath = options.source ? resolve(process.cwd(), String(options.source)) : process.cwd();
16
- if (!existsSync(sourcePath)) {
17
- log.error(`Source project not found: ${sourcePath}`);
18
- process.exit(ExitCode.FatalError);
19
- }
20
- const targetPath = target ? resolve(process.cwd(), target) : process.cwd();
21
- log.info(`Migrating ${from} project: ${sourcePath} \u2192 ${targetPath}`);
22
- if (options.dryRun)
23
- log.info("(dry run \u2014 no files will be written)");
24
- try {
25
- const report = await runMigrator({
26
- source: sourcePath,
27
- target: targetPath,
28
- from,
29
- dryRun: options.dryRun === !0
30
- }), translated = report.entries.filter((e) => e.status === "translated").length, copied = report.entries.filter((e) => e.status === "copied").length, skipped = report.entries.filter((e) => e.status === "skipped").length, failed = report.entries.filter((e) => e.status === "failed").length;
31
- log.info(`Translated: ${translated} | Copied: ${copied} | Skipped: ${skipped} | Failed: ${failed}`);
32
- if (options.verbose)
33
- for (const e of report.entries) {
34
- const arrow = e.target ? ` \u2192 ${e.target}` : "", note = e.note ? ` \u2014 ${e.note}` : "";
35
- log.info(` [${e.status}] ${e.source}${arrow}${note}`);
36
- }
37
- if (!options.dryRun) {
38
- const reportPath = join(targetPath, "MIGRATION_REPORT.md");
39
- await writeFile(reportPath, renderReport(report));
40
- log.success(`Report written to ${reportPath}`);
41
- }
42
- process.exit(ExitCode.Success);
43
- } catch (err) {
44
- log.error(`Migration failed: ${err instanceof Error ? err.message : String(err)}`);
45
- process.exit(ExitCode.FatalError);
46
- }
47
- });
48
- onUnknownSubcommand(buddy, "migrate:project");
49
- }
1
+ import{existsSync}from"node:fs";import{writeFile}from"node:fs/promises";import{join,resolve}from"node:path";import process from"node:process";import{log,onUnknownSubcommand}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";import{DRIVERS,renderReport,runMigrator}from"../migrators";export function migrateProject(buddy){buddy.command("migrate:project [target]","Port an existing project (Laravel, Rails) into a Stacks project.").option("--from <framework>",`Source framework \u2014 one of: ${Object.keys(DRIVERS).join(", ")}`,{default:"laravel"}).option("--source <path>","Path to the existing source project. Defaults to the current working directory.",{default:!1}).option("--dry-run","Show what would be translated without writing files.",{default:!1}).option("--verbose","Print the per-entry table after the summary.",{default:!1}).action(async(target,options)=>{const from=options.from??"laravel";if(!(from in DRIVERS)){log.error(`Unknown source framework: '${from}'. Supported: ${Object.keys(DRIVERS).join(", ")}.`);process.exit(ExitCode.FatalError)}const sourcePath=options.source?resolve(process.cwd(),String(options.source)):process.cwd();if(!existsSync(sourcePath)){log.error(`Source project not found: ${sourcePath}`);process.exit(ExitCode.FatalError)}const targetPath=target?resolve(process.cwd(),target):process.cwd();log.info(`Migrating ${from} project: ${sourcePath} \u2192 ${targetPath}`);if(options.dryRun)log.info("(dry run \u2014 no files will be written)");try{const report=await runMigrator({source:sourcePath,target:targetPath,from,dryRun:options.dryRun===!0}),translated=report.entries.filter((e)=>e.status==="translated").length,copied=report.entries.filter((e)=>e.status==="copied").length,skipped=report.entries.filter((e)=>e.status==="skipped").length,failed=report.entries.filter((e)=>e.status==="failed").length;log.info(`Translated: ${translated} | Copied: ${copied} | Skipped: ${skipped} | Failed: ${failed}`);if(options.verbose)for(const e of report.entries){const arrow=e.target?` \u2192 ${e.target}`:"",note=e.note?` \u2014 ${e.note}`:"";log.info(` [${e.status}] ${e.source}${arrow}${note}`)}if(!options.dryRun){const reportPath=join(targetPath,"MIGRATION_REPORT.md");await writeFile(reportPath,renderReport(report));log.success(`Report written to ${reportPath}`)}process.exit(ExitCode.Success)}catch(err){log.error(`Migration failed: ${err instanceof Error?err.message:String(err)}`);process.exit(ExitCode.FatalError)}});onUnknownSubcommand(buddy,"migrate:project")}