@stacksjs/buddy 0.72.7 → 0.72.8

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.
@@ -117,6 +117,12 @@ export declare const FEATURE_NAMES: readonly ['dashboard', 'commerce', 'cms', 'f
117
117
  * ending in `/` are directory trees (recursive remove on uninstall); bare
118
118
  * paths are single files.
119
119
  *
120
+ * A feature must also claim the shared files its own actions IMPORT.
121
+ * `app/Actions/Dashboard/dashboard-response.ts` is the case that bit: five
122
+ * features publish a subdirectory of `app/Actions/Dashboard/`, and the actions
123
+ * in each import `../dashboard-response`. Without it, `<feature>:install`
124
+ * copied 22 actions whose very first import did not resolve.
125
+ *
120
126
  * Manifests intentionally overlap where features share scaffolding —
121
127
  * `dashboard` claims the umbrella `app/Actions/Dashboard/` even though
122
128
  * `app/Actions/Dashboard/Content/` is also claimed by `cms`. Both the
@@ -131,13 +137,13 @@ export declare const FEATURE_NAMES: readonly ['dashboard', 'commerce', 'cms', 'f
131
137
  * ```ts
132
138
  * {
133
139
  * forms: [ 'app/Models/Forms/', ],
134
- * cms: [ 'app/Actions/Cms/', 'app/Actions/Dashboard/Content/', 'app/Models/Content/', 'app/Models/Tag.ts', 'app/Models/Comment.ts', 'resources/views/dashboard/content/', ],
135
- * commerce: [ 'app/Actions/Commerce/', 'app/Actions/Dashboard/Commerce/', 'app/Models/commerce/', 'resources/components/Dashboard/Commerce/', 'resources/views/dashboard/commerce/', ],
140
+ * cms: [ 'app/Actions/Cms/', 'app/Actions/Dashboard/Content/', 'app/Actions/Dashboard/dashboard-response.ts', 'app/Models/Content/', 'app/Models/Tag.ts', 'app/Models/Comment.ts', 'resources/views/dashboard/content/', ],
141
+ * commerce: [ 'app/Actions/Commerce/', 'app/Actions/Dashboard/Commerce/', 'app/Actions/Dashboard/dashboard-response.ts', 'app/Models/commerce/', 'resources/components/Dashboard/Commerce/', 'resources/views/dashboard/commerce/', ],
136
142
  * dashboard: [ 'app/Actions/Dashboard/', 'resources/components/Dashboard/', 'resources/views/dashboard/', 'routes/dashboard.ts', 'routes/dashboard-api.ts', ],
137
- * 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/', ],
143
+ * marketing: [ 'app/Actions/Dashboard/Marketing/', 'app/Actions/Dashboard/dashboard-response.ts', '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/', ],
138
144
  * monitoring: [ 'app/Actions/Monitoring/', 'app/Actions/TestErrorAction.ts', 'app/Models/Error.ts', 'functions/monitoring/', 'resources/views/dashboard/monitoring/', 'resources/views/dashboard/errors/', ],
139
- * realtime: [ 'app/Actions/Realtime/', 'app/Actions/Dashboard/Realtime/', 'app/Models/realtime/', 'app/Broadcasts/', 'functions/realtime/', 'resources/views/dashboard/realtime/', ],
140
- * 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/', ]
145
+ * realtime: [ 'app/Actions/Realtime/', 'app/Actions/Dashboard/Realtime/', 'app/Actions/Dashboard/dashboard-response.ts', 'app/Models/realtime/', 'app/Broadcasts/', 'functions/realtime/', 'resources/views/dashboard/realtime/', ],
146
+ * queue: [ 'app/Actions/Queue/', 'app/Actions/Dashboard/Jobs/', 'app/Actions/Dashboard/dashboard-response.ts', 'app/Jobs/', 'app/Models/Job.ts', 'app/Models/FailedJob.ts', 'functions/jobs.ts', 'resources/views/dashboard/queue/', 'resources/views/dashboard/jobs/', ]
141
147
  * }
142
148
  * ```
143
149
  */
@@ -1,4 +1,4 @@
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","forms","marketing","monitoring","realtime","queue"],FEATURE_FILES={forms:["app/Models/Forms/"],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={forms:["forms","form_fields","form_submissions"],cms:["posts","pages","comments","tags","authors","categories","taggable_models","categorizable_models","commentables","page_revisions","redirects","menus","menu_items"],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","driver_pings","delivery_routes","delivery_stops","digital_deliveries","shipping_methods","shipping_rates","shipping_zones","license_keys","loyalty_points","loyalty_rewards","print_devices","receipts","tax_rates","waitlist_products","waitlist_restaurants","auctions","auction_items","bids","pledges"],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.",forms:"User-defined forms: builder models, conditional fields, public submit + CSV export.",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'
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","forms","marketing","monitoring","realtime","queue"],FEATURE_FILES={forms:["app/Models/Forms/"],cms:["app/Actions/Cms/","app/Actions/Dashboard/Content/","app/Actions/Dashboard/dashboard-response.ts","app/Models/Content/","app/Models/Tag.ts","app/Models/Comment.ts","resources/views/dashboard/content/"],commerce:["app/Actions/Commerce/","app/Actions/Dashboard/Commerce/","app/Actions/Dashboard/dashboard-response.ts","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/Actions/Dashboard/dashboard-response.ts","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/Actions/Dashboard/dashboard-response.ts","app/Models/realtime/","app/Broadcasts/","functions/realtime/","resources/views/dashboard/realtime/"],queue:["app/Actions/Queue/","app/Actions/Dashboard/Jobs/","app/Actions/Dashboard/dashboard-response.ts","app/Jobs/","app/Models/Job.ts","app/Models/FailedJob.ts","functions/jobs.ts","resources/views/dashboard/queue/","resources/views/dashboard/jobs/"]},FEATURE_TABLES={forms:["forms","form_fields","form_submissions"],cms:["posts","pages","comments","tags","authors","categories","taggable_models","categorizable_models","commentables","page_revisions","redirects","menus","menu_items"],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","driver_pings","delivery_routes","delivery_stops","digital_deliveries","shipping_methods","shipping_rates","shipping_zones","license_keys","loyalty_points","loyalty_rewards","print_devices","receipts","tax_rates","waitlist_products","waitlist_restaurants","auctions","auction_items","bids","pledges"],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.",forms:"User-defined forms: builder models, conditional fields, public submit + CSV export.",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'
2
2
 
3
3
  /**
4
4
  * **Dashboard Configuration**
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/buddy",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.72.7",
5
+ "version": "0.72.8",
6
6
  "description": "Meet Buddy. The Stacks runtime.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -95,55 +95,55 @@
95
95
  "prepublishOnly": "bun run build"
96
96
  },
97
97
  "dependencies": {
98
- "@stacksjs/actions": "^0.72.7",
99
- "@stacksjs/ai": "^0.72.7",
100
- "@stacksjs/alias": "^0.72.7",
101
- "@stacksjs/arrays": "^0.72.7",
102
- "@stacksjs/auth": "^0.72.7",
103
- "@stacksjs/build": "^0.72.7",
104
- "@stacksjs/cache": "^0.72.7",
105
- "@stacksjs/cli": "^0.72.7",
98
+ "@stacksjs/actions": "^0.72.8",
99
+ "@stacksjs/ai": "^0.72.8",
100
+ "@stacksjs/alias": "^0.72.8",
101
+ "@stacksjs/arrays": "^0.72.8",
102
+ "@stacksjs/auth": "^0.72.8",
103
+ "@stacksjs/build": "^0.72.8",
104
+ "@stacksjs/cache": "^0.72.8",
105
+ "@stacksjs/cli": "^0.72.8",
106
106
  "@stacksjs/clapp": "^0.2.12",
107
- "@stacksjs/cloud": "^0.72.7",
108
- "@stacksjs/collections": "^0.72.7",
109
- "@stacksjs/config": "^0.72.7",
110
- "@stacksjs/database": "^0.72.7",
111
- "@stacksjs/desktop-build": "^0.72.7",
112
- "@stacksjs/dns": "^0.72.7",
113
- "@stacksjs/email": "^0.72.7",
114
- "@stacksjs/enums": "^0.72.7",
115
- "@stacksjs/error-handling": "^0.72.7",
116
- "@stacksjs/events": "^0.72.7",
117
- "@stacksjs/git": "^0.72.7",
107
+ "@stacksjs/cloud": "^0.72.8",
108
+ "@stacksjs/collections": "^0.72.8",
109
+ "@stacksjs/config": "^0.72.8",
110
+ "@stacksjs/database": "^0.72.8",
111
+ "@stacksjs/desktop-build": "^0.72.8",
112
+ "@stacksjs/dns": "^0.72.8",
113
+ "@stacksjs/email": "^0.72.8",
114
+ "@stacksjs/enums": "^0.72.8",
115
+ "@stacksjs/error-handling": "^0.72.8",
116
+ "@stacksjs/events": "^0.72.8",
117
+ "@stacksjs/git": "^0.72.8",
118
118
  "@stacksjs/gitit": "^0.2.5",
119
- "@stacksjs/health": "^0.72.7",
119
+ "@stacksjs/health": "^0.72.8",
120
120
  "@stacksjs/dnsx": "^0.2.3",
121
121
  "@stacksjs/httx": "^0.1.10",
122
- "@stacksjs/image": "^0.72.7",
123
- "@stacksjs/lint": "^0.72.7",
124
- "@stacksjs/logging": "^0.72.7",
125
- "@stacksjs/notifications": "^0.72.7",
126
- "@stacksjs/objects": "^0.72.7",
127
- "@stacksjs/orm": "^0.72.7",
128
- "@stacksjs/path": "^0.72.7",
129
- "@stacksjs/skills": "^0.72.7",
130
- "@stacksjs/payments": "^0.72.7",
131
- "@stacksjs/realtime": "^0.72.7",
132
- "@stacksjs/router": "^0.72.7",
122
+ "@stacksjs/image": "^0.72.8",
123
+ "@stacksjs/lint": "^0.72.8",
124
+ "@stacksjs/logging": "^0.72.8",
125
+ "@stacksjs/notifications": "^0.72.8",
126
+ "@stacksjs/objects": "^0.72.8",
127
+ "@stacksjs/orm": "^0.72.8",
128
+ "@stacksjs/path": "^0.72.8",
129
+ "@stacksjs/skills": "^0.72.8",
130
+ "@stacksjs/payments": "^0.72.8",
131
+ "@stacksjs/realtime": "^0.72.8",
132
+ "@stacksjs/router": "^0.72.8",
133
133
  "@stacksjs/rpx": "^0.11.42",
134
- "@stacksjs/search-engine": "^0.72.7",
135
- "@stacksjs/security": "^0.72.7",
136
- "@stacksjs/server": "^0.72.7",
137
- "@stacksjs/cms": "^0.72.7",
138
- "@stacksjs/sites": "^0.72.7",
139
- "@stacksjs/storage": "^0.72.7",
140
- "@stacksjs/strings": "^0.72.7",
141
- "@stacksjs/testing": "^0.72.7",
142
- "@stacksjs/tunnel": "^0.72.7",
143
- "@stacksjs/types": "^0.72.7",
144
- "@stacksjs/ui": "^0.72.7",
145
- "@stacksjs/utils": "^0.72.7",
146
- "@stacksjs/validation": "^0.72.7",
134
+ "@stacksjs/search-engine": "^0.72.8",
135
+ "@stacksjs/security": "^0.72.8",
136
+ "@stacksjs/server": "^0.72.8",
137
+ "@stacksjs/cms": "^0.72.8",
138
+ "@stacksjs/sites": "^0.72.8",
139
+ "@stacksjs/storage": "^0.72.8",
140
+ "@stacksjs/strings": "^0.72.8",
141
+ "@stacksjs/testing": "^0.72.8",
142
+ "@stacksjs/tunnel": "^0.72.8",
143
+ "@stacksjs/types": "^0.72.8",
144
+ "@stacksjs/ui": "^0.72.8",
145
+ "@stacksjs/utils": "^0.72.8",
146
+ "@stacksjs/validation": "^0.72.8",
147
147
  "@stacksjs/ts-cloud": "^0.8.3",
148
148
  "ajv": "^8.20.0",
149
149
  "ajv-formats": "^3.0.1",