@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,229 +1,4 @@
1
- import { existsSync, readdirSync, readFileSync } from "node:fs";
2
- import { cp, rm } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import process from "node:process";
5
- import { frameworkPath, projectPath } from "@stacksjs/path";
6
- import { ExitCode } from "@stacksjs/types";
7
- export const FEATURE_NAMES = [
8
- "dashboard",
9
- "commerce",
10
- "cms",
11
- "marketing",
12
- "monitoring",
13
- "realtime",
14
- "queue"
15
- ], FEATURE_FILES = {
16
- cms: [
17
- "app/Actions/Cms/",
18
- "app/Actions/Dashboard/Content/",
19
- "app/Models/Content/",
20
- "app/Models/Tag.ts",
21
- "app/Models/Comment.ts",
22
- "resources/views/dashboard/content/"
23
- ],
24
- commerce: [
25
- "app/Actions/Commerce/",
26
- "app/Actions/Dashboard/Commerce/",
27
- "app/Models/commerce/",
28
- "resources/components/Dashboard/Commerce/",
29
- "resources/views/dashboard/commerce/"
30
- ],
31
- dashboard: [
32
- "app/Actions/Dashboard/",
33
- "resources/components/Dashboard/",
34
- "resources/views/dashboard/",
35
- "routes/dashboard.ts",
36
- "routes/dashboard-api.ts"
37
- ],
38
- marketing: [
39
- "app/Actions/Dashboard/Marketing/",
40
- "app/Models/Campaign.ts",
41
- "app/Models/CampaignSend.ts",
42
- "app/Models/EmailList.ts",
43
- "app/Models/EmailListSubscriber.ts",
44
- "app/Models/SocialPost.ts",
45
- "resources/components/Marketing/",
46
- "resources/views/dashboard/marketing/"
47
- ],
48
- monitoring: [
49
- "app/Actions/Monitoring/",
50
- "app/Actions/TestErrorAction.ts",
51
- "app/Models/Error.ts",
52
- "functions/monitoring/",
53
- "resources/views/dashboard/monitoring/",
54
- "resources/views/dashboard/errors/"
55
- ],
56
- realtime: [
57
- "app/Actions/Realtime/",
58
- "app/Actions/Dashboard/Realtime/",
59
- "app/Models/realtime/",
60
- "app/Broadcasts/",
61
- "functions/realtime/",
62
- "resources/views/dashboard/realtime/"
63
- ],
64
- queue: [
65
- "app/Actions/Queue/",
66
- "app/Actions/Dashboard/Jobs/",
67
- "app/Jobs/",
68
- "app/Models/Job.ts",
69
- "app/Models/FailedJob.ts",
70
- "functions/jobs.ts",
71
- "resources/views/dashboard/queue/",
72
- "resources/views/dashboard/jobs/"
73
- ]
74
- }, FEATURE_TABLES = {
75
- cms: [
76
- "posts",
77
- "pages",
78
- "comments",
79
- "tags",
80
- "authors",
81
- "categories",
82
- "taggable_models",
83
- "categorizable_models",
84
- "commentables"
85
- ],
86
- commerce: [
87
- "products",
88
- "product_variants",
89
- "product_units",
90
- "manufacturers",
91
- "orders",
92
- "order_items",
93
- "order_idempotency",
94
- "carts",
95
- "cart_items",
96
- "payments",
97
- "payment_methods",
98
- "payment_products",
99
- "payment_transactions",
100
- "customers",
101
- "subscribers",
102
- "subscriber_emails",
103
- "subscriptions",
104
- "gift_cards",
105
- "coupons",
106
- "transactions",
107
- "reviews",
108
- "drivers",
109
- "delivery_routes",
110
- "digital_deliveries",
111
- "shipping_methods",
112
- "shipping_rates",
113
- "shipping_zones",
114
- "license_keys",
115
- "loyalty_points",
116
- "loyalty_rewards",
117
- "print_devices",
118
- "receipts",
119
- "tax_rates",
120
- "waitlist_products",
121
- "waitlist_restaurants"
122
- ],
123
- dashboard: [
124
- "boards",
125
- "board_columns",
126
- "cards",
127
- "card_labels",
128
- "card_assignees",
129
- "card_comments",
130
- "labels",
131
- "ci_run_states",
132
- "ci_runner_samples",
133
- "ci_runner_alert_states",
134
- "requests",
135
- "logs"
136
- ],
137
- marketing: [
138
- "campaigns",
139
- "campaign_sends",
140
- "email_lists",
141
- "email_list_subscribers",
142
- "social_posts",
143
- "mail_preferences"
144
- ],
145
- monitoring: ["errors"],
146
- realtime: ["websockets"],
147
- queue: ["jobs", "failed_jobs"]
148
- };
149
- export function migrationTable(filename) {
150
- const inMatch = filename.match(/-in-([a-z0-9_]+)\.sql$/i);
151
- if (inMatch)
152
- return inMatch[1] ?? null;
153
- const createMatch = filename.match(/-create-([a-z0-9_]+)-table\.sql$/i);
154
- if (createMatch)
155
- return createMatch[1] ?? null;
156
- const alterMatch = filename.match(/-alter-([a-z0-9_]+)-/i);
157
- if (alterMatch)
158
- return alterMatch[1] ?? null;
159
- return null;
160
- }
161
- export function migrationFeature(filename) {
162
- const table = migrationTable(filename);
163
- if (!table)
164
- return null;
165
- for (const f of FEATURE_NAMES)
166
- if (FEATURE_TABLES[f].includes(table))
167
- return f;
168
- return null;
169
- }
170
- export function appModelClaimsTable(table, root = projectPath()) {
171
- const modelsDir = join(root, "app/Models");
172
- if (!existsSync(modelsDir))
173
- return !1;
174
- const featureModelFiles = new Set(FEATURE_NAMES.flatMap((feature) => FEATURE_FILES[feature]).filter((path) => path.startsWith("app/Models/") && !path.endsWith("/"))), escaped = table.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), declaration = new RegExp(`\\btable\\s*:\\s*['"]${escaped}['"]`);
175
- for (const entry of readdirSync(modelsDir, { withFileTypes: !0 })) {
176
- if (!entry.isFile() || !/\.[cm]?[jt]s$/.test(entry.name))
177
- continue;
178
- if (featureModelFiles.has(`app/Models/${entry.name}`))
179
- continue;
180
- if (declaration.test(readFileSync(join(modelsDir, entry.name), "utf8")))
181
- return !0;
182
- }
183
- return !1;
184
- }
185
- export function featurePathsPresent(feature, root = projectPath()) {
186
- return FEATURE_FILES[feature].filter((rel) => existsSync(`${root}/${rel}`));
187
- }
188
- export async function deleteFeatureFiles(feature, root = projectPath()) {
189
- const removed = [];
190
- for (const rel of FEATURE_FILES[feature]) {
191
- const full = `${root}/${rel}`;
192
- if (!existsSync(full))
193
- continue;
194
- await rm(full, { recursive: !0, force: !0 });
195
- removed.push(rel);
196
- }
197
- return removed;
198
- }
199
- export async function copyFeatureFiles(feature, options = {}) {
200
- const source = options.source ?? frameworkPath("defaults"), target = options.target ?? projectPath(), force = options.force === !0, copied = [], skipped = [];
201
- for (const rel of FEATURE_FILES[feature]) {
202
- const sourceFull = join(source, rel);
203
- if (!existsSync(sourceFull)) {
204
- skipped.push(rel);
205
- continue;
206
- }
207
- const targetFull = join(target, rel);
208
- if (existsSync(targetFull) && !force) {
209
- skipped.push(rel);
210
- continue;
211
- }
212
- await cp(sourceFull, targetFull, { recursive: !0, force });
213
- copied.push(rel);
214
- }
215
- return { copied, skipped };
216
- }
217
- const FEATURE_DESCRIPTIONS = {
218
- dashboard: "Admin SPA shell + Activity/Log/Request/Deployment/Notification dashboards.",
219
- commerce: "Order/Cart/Product/Customer/Coupon/GiftCard/Shipping + storefront API.",
220
- cms: "Post/Page/Author/Comment/Tag models + content edit dashboards.",
221
- marketing: "/api/email/subscribe, /api/contact, Campaign/EmailList/SocialPost.",
222
- monitoring: "Error model + error-tracking views and actions.",
223
- realtime: "WebSocket broadcaster + Websocket model + realtime-stats actions.",
224
- queue: "Job + FailedJob models + queue dashboard pages."
225
- }, STARTER_TEMPLATES = {
226
- dashboard: `import type { DashboardConfig } from '@stacksjs/types'
1
+ import{existsSync,readdirSync,readFileSync}from"node:fs";import{cp,rm}from"node:fs/promises";import{join}from"node:path";import process from"node:process";import{frameworkPath,projectPath}from"@stacksjs/path";import{ExitCode}from"@stacksjs/types";export const FEATURE_NAMES=["dashboard","commerce","cms","marketing","monitoring","realtime","queue"],FEATURE_FILES={cms:["app/Actions/Cms/","app/Actions/Dashboard/Content/","app/Models/Content/","app/Models/Tag.ts","app/Models/Comment.ts","resources/views/dashboard/content/"],commerce:["app/Actions/Commerce/","app/Actions/Dashboard/Commerce/","app/Models/commerce/","resources/components/Dashboard/Commerce/","resources/views/dashboard/commerce/"],dashboard:["app/Actions/Dashboard/","resources/components/Dashboard/","resources/views/dashboard/","routes/dashboard.ts","routes/dashboard-api.ts"],marketing:["app/Actions/Dashboard/Marketing/","app/Models/Campaign.ts","app/Models/CampaignSend.ts","app/Models/EmailList.ts","app/Models/EmailListSubscriber.ts","app/Models/SocialPost.ts","resources/components/Marketing/","resources/views/dashboard/marketing/"],monitoring:["app/Actions/Monitoring/","app/Actions/TestErrorAction.ts","app/Models/Error.ts","functions/monitoring/","resources/views/dashboard/monitoring/","resources/views/dashboard/errors/"],realtime:["app/Actions/Realtime/","app/Actions/Dashboard/Realtime/","app/Models/realtime/","app/Broadcasts/","functions/realtime/","resources/views/dashboard/realtime/"],queue:["app/Actions/Queue/","app/Actions/Dashboard/Jobs/","app/Jobs/","app/Models/Job.ts","app/Models/FailedJob.ts","functions/jobs.ts","resources/views/dashboard/queue/","resources/views/dashboard/jobs/"]},FEATURE_TABLES={cms:["posts","pages","comments","tags","authors","categories","taggable_models","categorizable_models","commentables"],commerce:["products","product_variants","product_units","manufacturers","orders","order_items","order_idempotency","carts","cart_items","payments","payment_methods","payment_products","payment_transactions","customers","subscribers","subscriber_emails","subscriptions","gift_cards","coupons","transactions","reviews","drivers","delivery_routes","digital_deliveries","shipping_methods","shipping_rates","shipping_zones","license_keys","loyalty_points","loyalty_rewards","print_devices","receipts","tax_rates","waitlist_products","waitlist_restaurants"],dashboard:["boards","board_columns","cards","card_labels","card_assignees","card_comments","labels","ci_run_states","ci_runner_samples","ci_runner_alert_states","requests","logs"],marketing:["campaigns","campaign_sends","email_lists","email_list_subscribers","social_posts","mail_preferences"],monitoring:["errors"],realtime:["websockets"],queue:["jobs","failed_jobs"]};export function migrationTable(filename){const inMatch=filename.match(/-in-([a-z0-9_]+)\.sql$/i);if(inMatch)return inMatch[1]??null;const createMatch=filename.match(/-create-([a-z0-9_]+)-table\.sql$/i);if(createMatch)return createMatch[1]??null;const alterMatch=filename.match(/-alter-([a-z0-9_]+)-/i);if(alterMatch)return alterMatch[1]??null;return null}export function migrationFeature(filename){const table=migrationTable(filename);if(!table)return null;for(const f of FEATURE_NAMES)if(FEATURE_TABLES[f].includes(table))return f;return null}export function appModelClaimsTable(table,root=projectPath()){const modelsDir=join(root,"app/Models");if(!existsSync(modelsDir))return!1;const featureModelFiles=new Set(FEATURE_NAMES.flatMap((feature)=>FEATURE_FILES[feature]).filter((path)=>path.startsWith("app/Models/")&&!path.endsWith("/"))),escaped=table.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),declaration=new RegExp(`\\btable\\s*:\\s*['"]${escaped}['"]`);for(const entry of readdirSync(modelsDir,{withFileTypes:!0})){if(!entry.isFile()||!/\.[cm]?[jt]s$/.test(entry.name))continue;if(featureModelFiles.has(`app/Models/${entry.name}`))continue;if(declaration.test(readFileSync(join(modelsDir,entry.name),"utf8")))return!0}return!1}export function featurePathsPresent(feature,root=projectPath()){return FEATURE_FILES[feature].filter((rel)=>existsSync(`${root}/${rel}`))}export async function deleteFeatureFiles(feature,root=projectPath()){const removed=[];for(const rel of FEATURE_FILES[feature]){const full=`${root}/${rel}`;if(!existsSync(full))continue;await rm(full,{recursive:!0,force:!0});removed.push(rel)}return removed}export async function copyFeatureFiles(feature,options={}){const source=options.source??frameworkPath("defaults"),target=options.target??projectPath(),force=options.force===!0,copied=[],skipped=[];for(const rel of FEATURE_FILES[feature]){const sourceFull=join(source,rel);if(!existsSync(sourceFull)){skipped.push(rel);continue}const targetFull=join(target,rel);if(existsSync(targetFull)&&!force){skipped.push(rel);continue}await cp(sourceFull,targetFull,{recursive:!0,force});copied.push(rel)}return{copied,skipped}}const FEATURE_DESCRIPTIONS={dashboard:"Admin SPA shell + Activity/Log/Request/Deployment/Notification dashboards.",commerce:"Order/Cart/Product/Customer/Coupon/GiftCard/Shipping + storefront API.",cms:"Post/Page/Author/Comment/Tag models + content edit dashboards.",marketing:"/api/email/subscribe, /api/contact, Campaign/EmailList/SocialPost.",monitoring:"Error model + error-tracking views and actions.",realtime:"WebSocket broadcaster + Websocket model + realtime-stats actions.",queue:"Job + FailedJob models + queue dashboard pages."},STARTER_TEMPLATES={dashboard:`import type { DashboardConfig } from '@stacksjs/types'
227
2
 
228
3
  /**
229
4
  * **Dashboard Configuration**
@@ -253,8 +28,7 @@ export default {
253
28
  },
254
29
  },
255
30
  } satisfies DashboardConfig
256
- `,
257
- commerce: `import type { CommerceConfig } from '@stacksjs/types'
31
+ `,commerce:`import type { CommerceConfig } from '@stacksjs/types'
258
32
 
259
33
  /**
260
34
  * **Commerce Configuration**
@@ -271,8 +45,7 @@ export default {
271
45
  /** Default tax rate applied when a product/region rule doesn't override. */
272
46
  defaultTaxRate: 0,
273
47
  } satisfies CommerceConfig
274
- `,
275
- cms: `import type { CmsConfig } from '@stacksjs/types'
48
+ `,cms:`import type { CmsConfig } from '@stacksjs/types'
276
49
 
277
50
  /**
278
51
  * **CMS Configuration**
@@ -283,8 +56,7 @@ export default {
283
56
  export default {
284
57
  enabled: true,
285
58
  } satisfies CmsConfig
286
- `,
287
- marketing: `import type { MarketingConfig } from '@stacksjs/types'
59
+ `,marketing:`import type { MarketingConfig } from '@stacksjs/types'
288
60
 
289
61
  /**
290
62
  * **Marketing Configuration**
@@ -295,8 +67,7 @@ export default {
295
67
  export default {
296
68
  enabled: true,
297
69
  } satisfies MarketingConfig
298
- `,
299
- monitoring: `import type { MonitoringConfig } from '@stacksjs/types'
70
+ `,monitoring:`import type { MonitoringConfig } from '@stacksjs/types'
300
71
 
301
72
  /**
302
73
  * **Monitoring Configuration**
@@ -307,8 +78,7 @@ export default {
307
78
  export default {
308
79
  enabled: true,
309
80
  } satisfies MonitoringConfig
310
- `,
311
- realtime: `import type { RealtimeConfig } from '@stacksjs/types'
81
+ `,realtime:`import type { RealtimeConfig } from '@stacksjs/types'
312
82
 
313
83
  /**
314
84
  * **Realtime Configuration**
@@ -321,8 +91,7 @@ export default {
321
91
  export default {
322
92
  enabled: true,
323
93
  } satisfies RealtimeConfig
324
- `,
325
- queue: `import type { QueueConfig } from '@stacksjs/types'
94
+ `,queue:`import type { QueueConfig } from '@stacksjs/types'
326
95
 
327
96
  /**
328
97
  * **Queue Configuration**
@@ -346,110 +115,5 @@ export default {
346
115
  table: 'failed_jobs',
347
116
  },
348
117
  } satisfies QueueConfig
349
- `
350
- };
351
- export async function setFeatureEnabled(feature, enabled, options) {
352
- const path = options.root ? join(options.root, `config/${feature}.ts`) : projectPath(`config/${feature}.ts`), file = Bun.file(path);
353
- if (!await file.exists()) {
354
- if (!options.createIfMissing)
355
- return "missing";
356
- await Bun.write(path, STARTER_TEMPLATES[feature]);
357
- return "created";
358
- }
359
- const src = await file.text(), enabledRegex = /(^|\{)(\s*)enabled\s*:\s*(true|false)(\s*,?)/m;
360
- if (enabledRegex.test(src)) {
361
- const replaced = src.replace(enabledRegex, (_full, anchor, ws, current, trailing) => {
362
- if (current === String(enabled))
363
- return `${anchor}${ws}enabled: ${current}${trailing}`;
364
- return `${anchor}${ws}enabled: ${enabled}${trailing}`;
365
- });
366
- if (replaced === src)
367
- return "unchanged";
368
- await Bun.write(path, replaced);
369
- return "flipped";
370
- }
371
- const insertRegex = /(export default\s*\{)/;
372
- if (!insertRegex.test(src))
373
- throw Error(`Could not locate \`export default {\` in ${path} \u2014 please add \`enabled: ${enabled}\` manually.`);
374
- const next = src.replace(insertRegex, `$1
375
- enabled: ${enabled},`);
376
- await Bun.write(path, next);
377
- return "flipped";
378
- }
379
- export async function uninstallAllFeatures(options = {}) {
380
- const root = options.root ?? projectPath(), results = [];
381
- for (const feature of FEATURE_NAMES) {
382
- const configOutcome = await setFeatureEnabled(feature, !1, { createIfMissing: !1, root }), filesRemoved = await deleteFeatureFiles(feature, root);
383
- results.push({ feature, configOutcome, filesRemoved });
384
- }
385
- return results;
386
- }
387
- function registerInstallPair(buddy, feature) {
388
- const desc = FEATURE_DESCRIPTIONS[feature], configRel = `config/${feature}.ts`;
389
- buddy.command(`${feature}:install`, `Activate the ${feature} feature bundle. ${desc}`).option("--force", `Overwrite any existing ${feature} files in the project (default skips existing paths so the install is idempotent).`).action(async (options) => {
390
- try {
391
- switch (await setFeatureEnabled(feature, !0, { createIfMissing: !0 })) {
392
- case "created":
393
- console.log(`\u2713 Created ${configRel} with '${feature}' enabled.`);
394
- break;
395
- case "flipped":
396
- console.log(`\u2713 Enabled '${feature}' in ${configRel}.`);
397
- break;
398
- case "unchanged":
399
- console.log(`\u2713 '${feature}' is already enabled in ${configRel}.`);
400
- break;
401
- }
402
- const { copied } = await copyFeatureFiles(feature, { force: options.force === !0 });
403
- if (copied.length > 0) {
404
- console.log(`\u2713 Copied ${copied.length} stamped path(s) from framework defaults:`);
405
- for (const path of copied)
406
- console.log(` - ${path}`);
407
- } else if (featurePathsPresent(feature).length > 0)
408
- console.log(` \u2192 ${feature} scaffolding already in place \u2014 use --force to overwrite.`);
409
- console.log(` \u2192 next ./buddy dev will boot with ${feature} loaded.`);
410
- process.exit(ExitCode.Success);
411
- } catch (err) {
412
- console.error(`\u2717 Failed to install ${feature}:`, err);
413
- process.exit(ExitCode.FatalError);
414
- }
415
- });
416
- buddy.command(`${feature}:uninstall`, `Deactivate the ${feature} feature bundle.`).option("--keep-files", `Don't delete the ${feature} scaffolding (action/model/view files). Flip the flag only.`).action(async (options) => {
417
- try {
418
- switch (await setFeatureEnabled(feature, !1, { createIfMissing: !1 })) {
419
- case "missing":
420
- console.log(`\u2713 '${feature}' is already disabled (${configRel} is absent).`);
421
- break;
422
- case "flipped":
423
- console.log(`\u2713 Disabled '${feature}' in ${configRel}. Custom config preserved.`);
424
- break;
425
- case "unchanged":
426
- console.log(`\u2713 '${feature}' is already disabled in ${configRel}.`);
427
- break;
428
- case "created":
429
- console.log(`\u2717 Unexpected create on uninstall for ${feature}; please re-run with --force or report this bug.`);
430
- break;
431
- }
432
- if (options.keepFiles) {
433
- const stillPresent = featurePathsPresent(feature);
434
- if (stillPresent.length > 0)
435
- console.log(` \u2192 ${stillPresent.length} stamped path(s) preserved (--keep-files).`);
436
- } else {
437
- const removed = await deleteFeatureFiles(feature);
438
- if (removed.length > 0) {
439
- console.log(`\u2713 Removed ${removed.length} stamped path(s):`);
440
- for (const path of removed)
441
- console.log(` - ${path}`);
442
- }
443
- }
444
- console.log(` \u2192 next ./buddy dev will boot without ${feature}.`);
445
- process.exit(ExitCode.Success);
446
- } catch (err) {
447
- console.error(`\u2717 Failed to uninstall ${feature}:`, err);
448
- process.exit(ExitCode.FatalError);
449
- }
450
- });
451
- }
452
- export function features(buddy) {
453
- for (const feature of FEATURE_NAMES)
454
- registerInstallPair(buddy, feature);
455
- }
118
+ `};export async function setFeatureEnabled(feature,enabled,options){const path=options.root?join(options.root,`config/${feature}.ts`):projectPath(`config/${feature}.ts`),file=Bun.file(path);if(!await file.exists()){if(!options.createIfMissing)return"missing";await Bun.write(path,STARTER_TEMPLATES[feature]);return"created"}const src=await file.text(),enabledRegex=/(^|\{)(\s*)enabled\s*:\s*(true|false)(\s*,?)/m;if(enabledRegex.test(src)){const replaced=src.replace(enabledRegex,(_full,anchor,ws,current,trailing)=>{if(current===String(enabled))return`${anchor}${ws}enabled: ${current}${trailing}`;return`${anchor}${ws}enabled: ${enabled}${trailing}`});if(replaced===src)return"unchanged";await Bun.write(path,replaced);return"flipped"}const insertRegex=/(export default\s*\{)/;if(!insertRegex.test(src))throw Error(`Could not locate \`export default {\` in ${path} \u2014 please add \`enabled: ${enabled}\` manually.`);const next=src.replace(insertRegex,`$1
119
+ enabled: ${enabled},`);await Bun.write(path,next);return"flipped"}export async function uninstallAllFeatures(options={}){const root=options.root??projectPath(),results=[];for(const feature of FEATURE_NAMES){const configOutcome=await setFeatureEnabled(feature,!1,{createIfMissing:!1,root}),filesRemoved=await deleteFeatureFiles(feature,root);results.push({feature,configOutcome,filesRemoved})}return results}function registerInstallPair(buddy,feature){const desc=FEATURE_DESCRIPTIONS[feature],configRel=`config/${feature}.ts`;buddy.command(`${feature}:install`,`Activate the ${feature} feature bundle. ${desc}`).option("--force",`Overwrite any existing ${feature} files in the project (default skips existing paths so the install is idempotent).`).action(async(options)=>{try{switch(await setFeatureEnabled(feature,!0,{createIfMissing:!0})){case"created":console.log(`\u2713 Created ${configRel} with '${feature}' enabled.`);break;case"flipped":console.log(`\u2713 Enabled '${feature}' in ${configRel}.`);break;case"unchanged":console.log(`\u2713 '${feature}' is already enabled in ${configRel}.`);break}const{copied}=await copyFeatureFiles(feature,{force:options.force===!0});if(copied.length>0){console.log(`\u2713 Copied ${copied.length} stamped path(s) from framework defaults:`);for(const path of copied)console.log(` - ${path}`)}else if(featurePathsPresent(feature).length>0)console.log(` \u2192 ${feature} scaffolding already in place \u2014 use --force to overwrite.`);console.log(` \u2192 next ./buddy dev will boot with ${feature} loaded.`);process.exit(ExitCode.Success)}catch(err){console.error(`\u2717 Failed to install ${feature}:`,err);process.exit(ExitCode.FatalError)}});buddy.command(`${feature}:uninstall`,`Deactivate the ${feature} feature bundle.`).option("--keep-files",`Don't delete the ${feature} scaffolding (action/model/view files). Flip the flag only.`).action(async(options)=>{try{switch(await setFeatureEnabled(feature,!1,{createIfMissing:!1})){case"missing":console.log(`\u2713 '${feature}' is already disabled (${configRel} is absent).`);break;case"flipped":console.log(`\u2713 Disabled '${feature}' in ${configRel}. Custom config preserved.`);break;case"unchanged":console.log(`\u2713 '${feature}' is already disabled in ${configRel}.`);break;case"created":console.log(`\u2717 Unexpected create on uninstall for ${feature}; please re-run with --force or report this bug.`);break}if(options.keepFiles){const stillPresent=featurePathsPresent(feature);if(stillPresent.length>0)console.log(` \u2192 ${stillPresent.length} stamped path(s) preserved (--keep-files).`)}else{const removed=await deleteFeatureFiles(feature);if(removed.length>0){console.log(`\u2713 Removed ${removed.length} stamped path(s):`);for(const path of removed)console.log(` - ${path}`)}}console.log(` \u2192 next ./buddy dev will boot without ${feature}.`);process.exit(ExitCode.Success)}catch(err){console.error(`\u2717 Failed to uninstall ${feature}:`,err);process.exit(ExitCode.FatalError)}})}export function features(buddy){for(const feature of FEATURE_NAMES)registerInstallPair(buddy,feature)}
@@ -1,46 +1 @@
1
- import process from "node:process";
2
- import { runAction } from "@stacksjs/actions";
3
- import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
4
- import { hasTTY, isCI } from "@stacksjs/env";
5
- import { Action } from "@stacksjs/enums";
6
- import { ExitCode } from "@stacksjs/types";
7
- export function fresh(buddy) {
8
- const descriptions = {
9
- fresh: "Re-installs your npm dependencies",
10
- project: "Target a specific project",
11
- force: "Skip the confirmation prompt (required in CI/non-interactive shells)",
12
- verbose: "Enable verbose output"
13
- };
14
- buddy.command("fresh", descriptions.fresh).option("-p, --project [project]", descriptions.project, { default: !1 }).option("-f, --force", descriptions.force, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
15
- log.debug("Running `buddy fresh` ...", options);
16
- const skipConfirm = options.force === !0 || Boolean(buddy.isForce) || Boolean(buddy.isNoInteraction);
17
- if (!skipConfirm && (isCI || !hasTTY || !process.stdin.isTTY)) {
18
- log.syncError("Refusing to run `buddy fresh` from a non-interactive shell without confirmation.");
19
- log.fatal(" \u27A1\uFE0F Re-run with `--force` to proceed: `buddy fresh --force`");
20
- }
21
- if (!skipConfirm) {
22
- const { confirm } = await import("@stacksjs/cli");
23
- if (!await confirm({
24
- message: "This will remove and reinstall all dependencies. Continue?",
25
- initial: !1
26
- })) {
27
- log.info("Fresh install cancelled");
28
- process.exit(ExitCode.Success);
29
- }
30
- }
31
- const perf = await intro("buddy fresh"), result = await runAction(Action.Fresh, {
32
- ...options,
33
- stdout: "inherit"
34
- });
35
- if (result.isErr) {
36
- await outro("While running `buddy fresh`, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
37
- process.exit(ExitCode.FatalError);
38
- }
39
- await outro("Freshly reinstalled your dependencies", {
40
- startTime: perf,
41
- useSeconds: !0
42
- });
43
- process.exit(ExitCode.Success);
44
- });
45
- onUnknownSubcommand(buddy, "fresh");
46
- }
1
+ import process from"node:process";import{runAction}from"@stacksjs/actions";import{intro,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{hasTTY,isCI}from"@stacksjs/env";import{Action}from"@stacksjs/enums";import{ExitCode}from"@stacksjs/types";export function fresh(buddy){const descriptions={fresh:"Re-installs your npm dependencies",project:"Target a specific project",force:"Skip the confirmation prompt (required in CI/non-interactive shells)",verbose:"Enable verbose output"};buddy.command("fresh",descriptions.fresh).option("-p, --project [project]",descriptions.project,{default:!1}).option("-f, --force",descriptions.force,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy fresh` ...",options);const skipConfirm=options.force===!0||Boolean(buddy.isForce)||Boolean(buddy.isNoInteraction);if(!skipConfirm&&(isCI||!hasTTY||!process.stdin.isTTY)){log.syncError("Refusing to run `buddy fresh` from a non-interactive shell without confirmation.");log.fatal(" \u27A1\uFE0F Re-run with `--force` to proceed: `buddy fresh --force`")}if(!skipConfirm){const{confirm}=await import("@stacksjs/cli");if(!await confirm({message:"This will remove and reinstall all dependencies. Continue?",initial:!1})){log.info("Fresh install cancelled");process.exit(ExitCode.Success)}}const perf=await intro("buddy fresh"),result=await runAction(Action.Fresh,{...options,stdout:"inherit"});if(result.isErr){await outro("While running `buddy fresh`, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Freshly reinstalled your dependencies",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"fresh")}
@@ -1,153 +1,3 @@
1
- import process from "node:process";
2
- import {
3
- generateComponentMeta,
4
- generateCoreSymlink,
5
- generateIdeHelpers,
6
- generateLibEntries,
7
- generateOpenApiSpec,
8
- generatePantryConfig,
9
- generateProjectImages,
10
- generateTypes,
11
- generateVsCodeCustomData,
12
- generateWebTypes,
13
- invoke as startGenerationProcess,
14
- watchTypes
15
- } from "@stacksjs/actions";
16
- import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
17
- import { ExitCode } from "@stacksjs/types";
18
- export function generate(buddy) {
19
- const descriptions = {
20
- command: "Automagically build any of your libraries/packages for production use. Select any of the following packages",
21
- types: "Generate your TypeScript types",
22
- entries: "Generate your function & Component Library Entry Points",
23
- webTypes: "Generate web-types.json for IDEs",
24
- customData: "Generate VS Code custom data (custom-elements.json) for IDEs",
25
- ideHelpers: "Generate IDE helpers",
26
- componentMeta: "Generate component meta information",
27
- coreSymlink: "Generate symlink of the core framework to the project root",
28
- pantry: "Generate the pantry configuration file",
29
- openApi: "Generate the OpenAPI specification",
30
- images: "Generate every image declared in config/images.ts",
31
- og: "Generate the social cards used by link previews",
32
- appStore: "Generate the App Store screenshot set",
33
- appIcons: "Generate the app icon and favicon sets",
34
- select: "What are you trying to generate?",
35
- project: "Target a specific project",
36
- verbose: "Enable verbose output"
37
- };
38
- buddy.command("generate", descriptions.command).option("-t, --types", descriptions.types).option("-e, --entries", descriptions.entries).option("-w, --web-types", descriptions.webTypes).option("-c, --custom-data", descriptions.customData).option("-i, --ide-helpers", descriptions.ideHelpers).option("-c, --component-meta", descriptions.componentMeta).option("-p, --pantry", descriptions.pantry).option("-o, --openapi", descriptions.openApi).option("--images", descriptions.images).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--core-symlink", descriptions.coreSymlink).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
39
- log.debug("Running `buddy generate` ...", options);
40
- await startGenerationProcess(options);
41
- process.exit(ExitCode.Success);
42
- });
43
- buddy.command("generate:types", descriptions.types).option("-p, --project [project]", descriptions.project, { default: !1 }).option("-w, --watch", "Re-run on changes to models/ and config/", { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).alias("types:generate").action(async (options) => {
44
- log.debug("Running `buddy generate:types` ...", options);
45
- await generateTypes(options);
46
- try {
47
- const { buildDatabaseSchema } = await import("@stacksjs/orm");
48
- await buildDatabaseSchema();
49
- } catch (err) {
50
- log.warn(`[generate:db-types] skipped: ${err.message}`);
51
- }
52
- if (options.watch)
53
- await watchTypes(options);
54
- });
55
- buddy.command("generate:db-types", "Refresh database/types.d.ts for db.selectFrom autocomplete (stacksjs/stacks#1923)").option("--dry-run", "Print the would-be file content without writing", { default: !1 }).action(async (options) => {
56
- const { buildDatabaseSchema } = await import("@stacksjs/orm"), result = await buildDatabaseSchema({ dryRun: options.dryRun });
57
- if (options.dryRun)
58
- console.log(result.content);
59
- for (const e of result.errors)
60
- log.warn(`[generate:db-types] ${e.file}: ${e.error}`);
61
- log.info(`[generate:db-types] resolved ${result.tables.length} table(s)`);
62
- });
63
- buddy.command("generate:vschema", "Derive a Vitess VSchema from your models (writes database/vschema.json)").option("--dry-run", "Print the VSchema without writing it", { default: !1 }).option("--out [path]", "Where to write the VSchema", { default: "database/vschema.json" }).action(async (options) => {
64
- const { generateVSchema } = await import("@stacksjs/actions"), result = await generateVSchema({ dryRun: options.dryRun, out: options.out });
65
- if (!result.ok) {
66
- console.error(`
1
+ import process from"node:process";import{generateComponentMeta,generateCoreSymlink,generateIdeHelpers,generateLibEntries,generateOpenApiSpec,generatePantryConfig,generateProjectImages,generateTypes,generateVsCodeCustomData,generateWebTypes,invoke as startGenerationProcess,watchTypes}from"@stacksjs/actions";import{intro,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";export function generate(buddy){const descriptions={command:"Automagically build any of your libraries/packages for production use. Select any of the following packages",types:"Generate your TypeScript types",entries:"Generate your function & Component Library Entry Points",webTypes:"Generate web-types.json for IDEs",customData:"Generate VS Code custom data (custom-elements.json) for IDEs",ideHelpers:"Generate IDE helpers",componentMeta:"Generate component meta information",coreSymlink:"Generate symlink of the core framework to the project root",pantry:"Generate the pantry configuration file",openApi:"Generate the OpenAPI specification",images:"Generate every image declared in config/images.ts",og:"Generate the social cards used by link previews",appStore:"Generate the App Store screenshot set",appIcons:"Generate the app icon and favicon sets",select:"What are you trying to generate?",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("generate",descriptions.command).option("-t, --types",descriptions.types).option("-e, --entries",descriptions.entries).option("-w, --web-types",descriptions.webTypes).option("-c, --custom-data",descriptions.customData).option("-i, --ide-helpers",descriptions.ideHelpers).option("-c, --component-meta",descriptions.componentMeta).option("-p, --pantry",descriptions.pantry).option("-o, --openapi",descriptions.openApi).option("--images",descriptions.images).option("-p, --project [project]",descriptions.project,{default:!1}).option("--core-symlink",descriptions.coreSymlink).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate` ...",options);await startGenerationProcess(options);process.exit(ExitCode.Success)});buddy.command("generate:types",descriptions.types).option("-p, --project [project]",descriptions.project,{default:!1}).option("-w, --watch","Re-run on changes to models/ and config/",{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).alias("types:generate").action(async(options)=>{log.debug("Running `buddy generate:types` ...",options);await generateTypes(options);try{const{buildDatabaseSchema}=await import("@stacksjs/orm");await buildDatabaseSchema()}catch(err){log.warn(`[generate:db-types] skipped: ${err.message}`)}if(options.watch)await watchTypes(options)});buddy.command("generate:db-types","Refresh database/types.d.ts for db.selectFrom autocomplete (stacksjs/stacks#1923)").option("--dry-run","Print the would-be file content without writing",{default:!1}).action(async(options)=>{const{buildDatabaseSchema}=await import("@stacksjs/orm"),result=await buildDatabaseSchema({dryRun:options.dryRun});if(options.dryRun)console.log(result.content);for(const e of result.errors)log.warn(`[generate:db-types] ${e.file}: ${e.error}`);log.info(`[generate:db-types] resolved ${result.tables.length} table(s)`)});buddy.command("generate:vschema","Derive a Vitess VSchema from your models (writes database/vschema.json)").option("--dry-run","Print the VSchema without writing it",{default:!1}).option("--out [path]","Where to write the VSchema",{default:"database/vschema.json"}).action(async(options)=>{const{generateVSchema}=await import("@stacksjs/actions"),result=await generateVSchema({dryRun:options.dryRun,out:options.out});if(!result.ok){console.error(`
67
2
  \u274C ${result.error}
68
- `);
69
- process.exit(ExitCode.FatalError);
70
- }
71
- console.log(result.report);
72
- if (options.dryRun)
73
- console.log(JSON.stringify(result.vschema, null, 2));
74
- else
75
- log.success(`Wrote ${result.path} (${result.tableCount} tables)`);
76
- });
77
- buddy.command("generate:entries", descriptions.entries).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
78
- log.debug("Running `buddy generate:entries` ...", options);
79
- await generateLibEntries(options);
80
- });
81
- buddy.command("generate:web-types", descriptions.webTypes).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
82
- log.debug("Running `buddy generate:web-types` ...", options);
83
- await generateWebTypes(options);
84
- });
85
- buddy.command("generate:vscode-custom-data", descriptions.customData).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
86
- log.debug("Running `buddy generate:vscode-custom-data` ...", options);
87
- await generateVsCodeCustomData(options);
88
- });
89
- buddy.command("generate:ide-helpers", descriptions.ideHelpers).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
90
- log.debug("Running `buddy generate:ide-helpers` ...", options);
91
- await generateIdeHelpers(options);
92
- });
93
- buddy.command("generate:component-meta", descriptions.componentMeta).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
94
- log.debug("Running `buddy generate:component-meta` ...", options);
95
- await generateComponentMeta();
96
- });
97
- buddy.command("generate:pantry-config", descriptions.pantry).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
98
- log.debug("Running `buddy generate:pantry-config` ...", options);
99
- await generatePantryConfig();
100
- });
101
- buddy.command("generate:openapi-spec", descriptions.openApi).alias("generate:openapi").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
102
- log.debug("Running `buddy generate:openapi-spec` ...", options);
103
- const perf = await intro("buddy generate:openapi-spec");
104
- await generateOpenApiSpec();
105
- await outro("Generated OpenAPI specification", {
106
- startTime: perf,
107
- useSeconds: !0
108
- });
109
- });
110
- buddy.command("generate:migrations", "Generate Migrations").action(async (options) => {
111
- log.debug("Running `buddy generate:migrations` ...", options);
112
- const { generateMigrations } = await import("@stacksjs/database"), result = await generateMigrations();
113
- if (result?.isErr) {
114
- log.error("generateMigrations failed", result.error);
115
- process.exit(ExitCode.FatalError);
116
- }
117
- });
118
- buddy.command("generate:core-symlink", "Symlink `.framework` -> storage/framework. A shortcut for core developers.").action(async (options) => {
119
- log.debug("Running `buddy core-symlink` ...", options);
120
- await generateCoreSymlink();
121
- });
122
- buddy.command("generate:images", descriptions.images).alias("images:generate").option("--social", "Only build the social cards").option("--app-store", "Only build the App Store screenshots").option("--app-icons", "Only build the app icons and favicons").option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
123
- log.debug("Running `buddy generate:images` ...", options);
124
- const perf = await intro("buddy generate:images"), only = [];
125
- if (options.social)
126
- only.push("social");
127
- if (options.appStore)
128
- only.push("app-store");
129
- if (options.appIcons)
130
- only.push("app-icons");
131
- await generateProjectImages({ only, verbose: options.verbose });
132
- await outro("Generated images", { startTime: perf, useSeconds: !0 });
133
- });
134
- buddy.command("generate:og", descriptions.og).alias("generate:social").option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
135
- log.debug("Running `buddy generate:og` ...", options);
136
- const perf = await intro("buddy generate:og");
137
- await generateProjectImages({ only: ["social"], verbose: options.verbose });
138
- await outro("Generated social cards", { startTime: perf, useSeconds: !0 });
139
- });
140
- buddy.command("generate:app-store", descriptions.appStore).alias("generate:screenshots").option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
141
- log.debug("Running `buddy generate:app-store` ...", options);
142
- const perf = await intro("buddy generate:app-store");
143
- await generateProjectImages({ only: ["app-store"], verbose: options.verbose });
144
- await outro("Generated App Store screenshots", { startTime: perf, useSeconds: !0 });
145
- });
146
- buddy.command("generate:app-icons", descriptions.appIcons).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
147
- log.debug("Running `buddy generate:app-icons` ...", options);
148
- const perf = await intro("buddy generate:app-icons");
149
- await generateProjectImages({ only: ["app-icons"], verbose: options.verbose });
150
- await outro("Generated app icons", { startTime: perf, useSeconds: !0 });
151
- });
152
- onUnknownSubcommand(buddy, "generate");
153
- }
3
+ `);process.exit(ExitCode.FatalError)}console.log(result.report);if(options.dryRun)console.log(JSON.stringify(result.vschema,null,2));else log.success(`Wrote ${result.path} (${result.tableCount} tables)`)});buddy.command("generate:entries",descriptions.entries).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:entries` ...",options);await generateLibEntries(options)});buddy.command("generate:web-types",descriptions.webTypes).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:web-types` ...",options);await generateWebTypes(options)});buddy.command("generate:vscode-custom-data",descriptions.customData).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:vscode-custom-data` ...",options);await generateVsCodeCustomData(options)});buddy.command("generate:ide-helpers",descriptions.ideHelpers).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:ide-helpers` ...",options);await generateIdeHelpers(options)});buddy.command("generate:component-meta",descriptions.componentMeta).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:component-meta` ...",options);await generateComponentMeta()});buddy.command("generate:pantry-config",descriptions.pantry).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:pantry-config` ...",options);await generatePantryConfig()});buddy.command("generate:openapi-spec",descriptions.openApi).alias("generate:openapi").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:openapi-spec` ...",options);const perf=await intro("buddy generate:openapi-spec");await generateOpenApiSpec();await outro("Generated OpenAPI specification",{startTime:perf,useSeconds:!0})});buddy.command("generate:migrations","Generate Migrations").action(async(options)=>{log.debug("Running `buddy generate:migrations` ...",options);const{generateMigrations}=await import("@stacksjs/database"),result=await generateMigrations();if(result?.isErr){log.error("generateMigrations failed",result.error);process.exit(ExitCode.FatalError)}});buddy.command("generate:core-symlink","Symlink `.framework` -> storage/framework. A shortcut for core developers.").action(async(options)=>{log.debug("Running `buddy core-symlink` ...",options);await generateCoreSymlink()});buddy.command("generate:images",descriptions.images).alias("images:generate").option("--social","Only build the social cards").option("--app-store","Only build the App Store screenshots").option("--app-icons","Only build the app icons and favicons").option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:images` ...",options);const perf=await intro("buddy generate:images"),only=[];if(options.social)only.push("social");if(options.appStore)only.push("app-store");if(options.appIcons)only.push("app-icons");await generateProjectImages({only,verbose:options.verbose});await outro("Generated images",{startTime:perf,useSeconds:!0})});buddy.command("generate:og",descriptions.og).alias("generate:social").option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:og` ...",options);const perf=await intro("buddy generate:og");await generateProjectImages({only:["social"],verbose:options.verbose});await outro("Generated social cards",{startTime:perf,useSeconds:!0})});buddy.command("generate:app-store",descriptions.appStore).alias("generate:screenshots").option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:app-store` ...",options);const perf=await intro("buddy generate:app-store");await generateProjectImages({only:["app-store"],verbose:options.verbose});await outro("Generated App Store screenshots",{startTime:perf,useSeconds:!0})});buddy.command("generate:app-icons",descriptions.appIcons).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy generate:app-icons` ...",options);const perf=await intro("buddy generate:app-icons");await generateProjectImages({only:["app-icons"],verbose:options.verbose});await outro("Generated app icons",{startTime:perf,useSeconds:!0})});onUnknownSubcommand(buddy,"generate")}