@stacksjs/defaults 0.75.318 → 0.75.321

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 (252) hide show
  1. package/ai/skills/stacks-browse/SKILL.md +8 -0
  2. package/ai/skills/stacks-browse/scripts/browse.ts +16 -6
  3. package/ai/skills/stacks-browse/scripts/chrome.ts +4 -0
  4. package/ai/skills/stacks-database/SKILL.md +1 -1
  5. package/ai/skills/stacks-desktop/SKILL.md +23 -0
  6. package/ai/skills/stacks-migrations/SKILL.md +2 -2
  7. package/ai/skills/stacks-native/CATALOG.md +8 -8
  8. package/app/Actions/Cms/AuthorUpdateAction.ts +4 -4
  9. package/app/Actions/Cms/CategorizableUpdateAction.ts +4 -4
  10. package/app/Actions/Cms/PostUpdateAction.ts +4 -5
  11. package/app/Actions/Cms/TaggableUpdateAction.ts +4 -2
  12. package/app/Actions/Commerce/CustomerStoreAction.ts +4 -6
  13. package/app/Actions/Commerce/CustomerUpdateAction.ts +4 -6
  14. package/app/Actions/Commerce/PaymentStoreAction.ts +5 -8
  15. package/app/Actions/Commerce/PaymentUpdateAction.ts +20 -17
  16. package/app/Actions/Dashboard/Commerce/commerce-product-records.test.ts +7 -0
  17. package/app/Actions/Dashboard/Commerce/commerce-product-records.ts +14 -3
  18. package/app/Actions/Dashboard/Commerce/review-records.test.ts +12 -0
  19. package/app/Actions/Dashboard/Commerce/review-records.ts +10 -5
  20. package/app/Actions/Dashboard/Content/AuthorStoreAction.ts +2 -0
  21. package/app/Actions/Dashboard/Content/CategoryStoreAction.ts +4 -1
  22. package/app/Actions/Dashboard/Content/PageStoreAction.ts +2 -0
  23. package/app/Actions/Dashboard/Content/PostStoreAction.ts +2 -0
  24. package/app/Actions/Dashboard/Content/TagStoreAction.ts +2 -0
  25. package/app/Actions/Dashboard/Content/content-input.ts +9 -4
  26. package/app/Actions/Dashboard/Content/content-record-input.test.ts +20 -1
  27. package/app/Actions/Dashboard/Marketing/CampaignIndexAction.ts +1 -1
  28. package/app/Actions/Dashboard/Marketing/ListIndexAction.ts +1 -1
  29. package/app/Actions/Dashboard/Models/ModelStoreAction.ts +5 -1
  30. package/app/Actions/Dashboard/Models/ModelUpdateAction.ts +5 -1
  31. package/app/Actions/Dashboard/Notifications/NotificationDeliveryOverviewAction.ts +1 -1
  32. package/app/Actions/Storefront/AddToCartAction.ts +5 -2
  33. package/app/Actions/Storefront/PlaceOrderAction.ts +6 -11
  34. package/app/Actions/Storefront/SubmitReviewAction.ts +6 -5
  35. package/app/Models/Activity.ts +1 -0
  36. package/app/Models/AnalyticsEvent.ts +1 -0
  37. package/app/Models/AutomationRun.ts +1 -1
  38. package/app/Models/BoardColumn.ts +0 -1
  39. package/app/Models/Campaign.ts +1 -1
  40. package/app/Models/CampaignSend.ts +3 -3
  41. package/app/Models/Card.ts +0 -1
  42. package/app/Models/CardComment.ts +0 -2
  43. package/app/Models/Content/Author.ts +2 -0
  44. package/app/Models/Content/Categorizable.ts +1 -0
  45. package/app/Models/Content/Menu.ts +2 -0
  46. package/app/Models/Content/MenuItem.ts +2 -0
  47. package/app/Models/Content/PageRevision.ts +2 -0
  48. package/app/Models/Content/Post.ts +2 -0
  49. package/app/Models/Content/Redirect.ts +2 -0
  50. package/app/Models/EmailListSubscriber.ts +2 -2
  51. package/app/Models/Error.ts +5 -0
  52. package/app/Models/Forms/Form.ts +2 -0
  53. package/app/Models/Forms/FormField.ts +2 -0
  54. package/app/Models/Forms/FormSubmission.ts +2 -0
  55. package/app/Models/Label.ts +0 -1
  56. package/app/Models/Log.ts +3 -1
  57. package/app/Models/MagicLinkToken.ts +0 -7
  58. package/app/Models/PaymentProduct.ts +1 -0
  59. package/app/Models/PaymentTransaction.ts +1 -0
  60. package/app/Models/Release.ts +3 -0
  61. package/app/Models/Request.ts +1 -0
  62. package/app/Models/SenderDomain.ts +2 -0
  63. package/app/Models/SmsOptOut.ts +0 -7
  64. package/app/Models/Subscription.ts +2 -0
  65. package/app/Models/commerce/Auction.ts +1 -0
  66. package/app/Models/commerce/AuctionItem.ts +1 -0
  67. package/app/Models/commerce/Cart.ts +83 -2
  68. package/app/Models/commerce/Category.ts +5 -1
  69. package/app/Models/commerce/Coupon.ts +4 -1
  70. package/app/Models/commerce/DigitalDelivery.ts +1 -0
  71. package/app/Models/commerce/GiftCard.ts +1 -0
  72. package/app/Models/commerce/LoyaltyPoint.ts +1 -0
  73. package/app/Models/commerce/LoyaltyReward.ts +3 -1
  74. package/app/Models/commerce/Order.ts +4 -1
  75. package/app/Models/commerce/OrderItem.ts +1 -0
  76. package/app/Models/commerce/Payment.ts +1 -0
  77. package/app/Models/commerce/Product.ts +15 -0
  78. package/app/Models/commerce/ProductVariant.ts +2 -0
  79. package/app/Models/commerce/Receipt.ts +1 -0
  80. package/app/Models/commerce/Review.ts +3 -1
  81. package/app/Models/commerce/Transaction.ts +1 -0
  82. package/app/Models/realtime/Websocket.ts +4 -1
  83. package/functions/dashboard-form.test.ts +10 -1
  84. package/functions/dashboard-form.ts +17 -0
  85. package/ide/vscode/package.json +1 -1
  86. package/package.json +4 -4
  87. package/resources/components/Dashboard/Analytics/AnalyticsPageHeader.stx +1 -1
  88. package/resources/components/Dashboard/App/RequestDetailsDialog.stx +1 -1
  89. package/resources/components/Dashboard/Auth/AccessTokenCreateDialog.stx +1 -1
  90. package/resources/components/Dashboard/Auth/ForgotPassword.stx +1 -1
  91. package/resources/components/Dashboard/Auth/Login.stx +1 -1
  92. package/resources/components/Dashboard/Auth/Register.stx +1 -1
  93. package/resources/components/Dashboard/Auth/ResetPassword.stx +1 -1
  94. package/resources/components/Dashboard/Auth/TwoFactorLogin.stx +1 -1
  95. package/resources/components/Dashboard/CodeEditor.stx +1 -1
  96. package/resources/components/Dashboard/Commerce/CommerceCategoriesDashboard.stx +1 -1
  97. package/resources/components/Dashboard/Commerce/CommerceCategoriesTable.stx +1 -1
  98. package/resources/components/Dashboard/Commerce/CommerceCategoryDeleteDialog.stx +1 -1
  99. package/resources/components/Dashboard/Commerce/CommerceCategoryDetailsDialog.stx +1 -1
  100. package/resources/components/Dashboard/Commerce/CommerceCategoryDialog.stx +4 -13
  101. package/resources/components/Dashboard/Commerce/CommerceCouponDeleteDialog.stx +1 -1
  102. package/resources/components/Dashboard/Commerce/CommerceCouponDetailsDialog.stx +1 -1
  103. package/resources/components/Dashboard/Commerce/CommerceCouponDialog.stx +1 -1
  104. package/resources/components/Dashboard/Commerce/CommerceCouponsTable.stx +1 -1
  105. package/resources/components/Dashboard/Commerce/CommerceCustomerDeleteDialog.stx +1 -1
  106. package/resources/components/Dashboard/Commerce/CommerceCustomerDetailsDialog.stx +1 -1
  107. package/resources/components/Dashboard/Commerce/CommerceCustomerDialog.stx +1 -1
  108. package/resources/components/Dashboard/Commerce/CommerceCustomersTable.stx +1 -1
  109. package/resources/components/Dashboard/Commerce/CommerceGiftCardDeleteDialog.stx +1 -1
  110. package/resources/components/Dashboard/Commerce/CommerceGiftCardDetailsDialog.stx +1 -1
  111. package/resources/components/Dashboard/Commerce/CommerceGiftCardDialog.stx +1 -1
  112. package/resources/components/Dashboard/Commerce/CommerceGiftCardsTable.stx +1 -1
  113. package/resources/components/Dashboard/Commerce/CommerceManufacturerDeleteDialog.stx +1 -1
  114. package/resources/components/Dashboard/Commerce/CommerceManufacturerDialog.stx +1 -1
  115. package/resources/components/Dashboard/Commerce/CommerceManufacturersTable.stx +1 -1
  116. package/resources/components/Dashboard/Commerce/CommerceOrderDeleteDialog.stx +1 -1
  117. package/resources/components/Dashboard/Commerce/CommerceOrderDetailsDialog.stx +1 -1
  118. package/resources/components/Dashboard/Commerce/CommerceOrderDialog.stx +1 -1
  119. package/resources/components/Dashboard/Commerce/CommerceOrdersTable.stx +1 -1
  120. package/resources/components/Dashboard/Commerce/CommercePaymentsTable.stx +1 -1
  121. package/resources/components/Dashboard/Commerce/CommercePosCart.stx +1 -1
  122. package/resources/components/Dashboard/Commerce/CommercePosCatalog.stx +1 -1
  123. package/resources/components/Dashboard/Commerce/CommercePosCheckoutDialog.stx +1 -1
  124. package/resources/components/Dashboard/Commerce/CommercePosReceiptDialog.stx +1 -1
  125. package/resources/components/Dashboard/Commerce/CommerceProductDeleteDialog.stx +1 -1
  126. package/resources/components/Dashboard/Commerce/CommerceProductDialog.stx +27 -2
  127. package/resources/components/Dashboard/Commerce/CommerceProductsTable.stx +1 -1
  128. package/resources/components/Dashboard/Commerce/CommerceReviewDeleteDialog.stx +1 -1
  129. package/resources/components/Dashboard/Commerce/CommerceReviewEditDialog.stx +7 -5
  130. package/resources/components/Dashboard/Commerce/CommerceReviewsDashboard.stx +12 -4
  131. package/resources/components/Dashboard/Commerce/CommerceReviewsTable.stx +3 -3
  132. package/resources/components/Dashboard/Commerce/CommerceTaxDeleteDialog.stx +1 -1
  133. package/resources/components/Dashboard/Commerce/CommerceTaxDialog.stx +1 -1
  134. package/resources/components/Dashboard/Commerce/CommerceTaxesTable.stx +1 -1
  135. package/resources/components/Dashboard/Commerce/CommerceUnitDeleteDialog.stx +1 -1
  136. package/resources/components/Dashboard/Commerce/CommerceUnitDialog.stx +1 -1
  137. package/resources/components/Dashboard/Commerce/CommerceUnitsTable.stx +1 -1
  138. package/resources/components/Dashboard/Commerce/CommerceVariantDeleteDialog.stx +1 -1
  139. package/resources/components/Dashboard/Commerce/CommerceVariantDialog.stx +1 -1
  140. package/resources/components/Dashboard/Commerce/CommerceVariantsTable.stx +1 -1
  141. package/resources/components/Dashboard/Commerce/Delivery/CourierDeleteDialog.stx +1 -1
  142. package/resources/components/Dashboard/Commerce/Delivery/CourierDialog.stx +1 -1
  143. package/resources/components/Dashboard/Commerce/Delivery/CouriersTable.stx +1 -1
  144. package/resources/components/Dashboard/Commerce/Delivery/DeliveryPagination.stx +1 -1
  145. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDeleteDialog.stx +1 -1
  146. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDialog.stx +1 -1
  147. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +1 -1
  148. package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveryDeleteDialog.stx +1 -1
  149. package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveryDialog.stx +1 -1
  150. package/resources/components/Dashboard/Commerce/Delivery/DigitalDeliveryTable.stx +1 -1
  151. package/resources/components/Dashboard/Commerce/Delivery/LicenseKeyDeleteDialog.stx +1 -1
  152. package/resources/components/Dashboard/Commerce/Delivery/LicenseKeyDialog.stx +1 -1
  153. package/resources/components/Dashboard/Commerce/Delivery/LicenseKeysTable.stx +1 -1
  154. package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodDeleteDialog.stx +1 -1
  155. package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodDialog.stx +1 -1
  156. package/resources/components/Dashboard/Commerce/Delivery/ShippingMethodsTable.stx +1 -1
  157. package/resources/components/Dashboard/Commerce/Delivery/ShippingRateDeleteDialog.stx +1 -1
  158. package/resources/components/Dashboard/Commerce/Delivery/ShippingRateDialog.stx +1 -1
  159. package/resources/components/Dashboard/Commerce/Delivery/ShippingRatesTable.stx +1 -1
  160. package/resources/components/Dashboard/Commerce/Delivery/ShippingZoneDeleteDialog.stx +1 -1
  161. package/resources/components/Dashboard/Commerce/Delivery/ShippingZoneDialog.stx +1 -1
  162. package/resources/components/Dashboard/Commerce/Delivery/ShippingZonesTable.stx +1 -1
  163. package/resources/components/Dashboard/Commerce/PaymentDetailsDialog.stx +1 -1
  164. package/resources/components/Dashboard/Commerce/PaymentRefundDialog.stx +1 -1
  165. package/resources/components/Dashboard/Commerce/PrintDeviceDeleteDialog.stx +1 -1
  166. package/resources/components/Dashboard/Commerce/PrintDeviceDetailsDialog.stx +1 -1
  167. package/resources/components/Dashboard/Commerce/PrintDeviceDialog.stx +1 -1
  168. package/resources/components/Dashboard/Commerce/PrintDevicesTable.stx +1 -1
  169. package/resources/components/Dashboard/Commerce/PrintLogDeleteDialog.stx +1 -1
  170. package/resources/components/Dashboard/Commerce/PrintLogDetailsDialog.stx +1 -1
  171. package/resources/components/Dashboard/Commerce/PrintLogsTable.stx +1 -1
  172. package/resources/components/Dashboard/Commerce/ProductWaitlistDeleteDialog.stx +1 -1
  173. package/resources/components/Dashboard/Commerce/ProductWaitlistEntryDialog.stx +1 -1
  174. package/resources/components/Dashboard/Commerce/ProductWaitlistTable.stx +1 -1
  175. package/resources/components/Dashboard/Commerce/RestaurantWaitlistDeleteDialog.stx +1 -1
  176. package/resources/components/Dashboard/Commerce/RestaurantWaitlistEntryDialog.stx +1 -1
  177. package/resources/components/Dashboard/Commerce/RestaurantWaitlistTable.stx +1 -1
  178. package/resources/components/Dashboard/Content/AuthorEditorDialog.stx +1 -1
  179. package/resources/components/Dashboard/Content/BlogPostEditorDialog.stx +1 -1
  180. package/resources/components/Dashboard/Content/CreateFolderDialog.stx +1 -1
  181. package/resources/components/Dashboard/Content/FileDetailsDrawer.stx +1 -1
  182. package/resources/components/Dashboard/Content/FileUploadDialog.stx +1 -1
  183. package/resources/components/Dashboard/Content/PageEditorDialog.stx +1 -1
  184. package/resources/components/Dashboard/Content/PostEditorDialog.stx +1 -1
  185. package/resources/components/Dashboard/Content/SeoEditorDialog.stx +1 -1
  186. package/resources/components/Dashboard/Content/TaxonomyEditorDialog.stx +1 -1
  187. package/resources/components/Dashboard/CreateRecordModal.stx +1 -1
  188. package/resources/components/Dashboard/Deployments/DeploymentPreviewDialog.stx +1 -1
  189. package/resources/components/Dashboard/Elements/DropdownNavigation.stx +1 -1
  190. package/resources/components/Dashboard/Email/CapturedMailList.stx +1 -1
  191. package/resources/components/Dashboard/Email/EmailSettingsList.stx +1 -1
  192. package/resources/components/Dashboard/Email/EmailSettingsNavigation.stx +1 -1
  193. package/resources/components/Dashboard/Email/EmailSidebar.stx +1 -1
  194. package/resources/components/Dashboard/Email/InboxComposer.stx +1 -1
  195. package/resources/components/Dashboard/Email/InboxMessageDetail.stx +1 -1
  196. package/resources/components/Dashboard/Email/InboxMessageList.stx +1 -1
  197. package/resources/components/Dashboard/Infrastructure/CloudDetailsDialog.stx +1 -1
  198. package/resources/components/Dashboard/Infrastructure/CloudResourceButton.stx +1 -1
  199. package/resources/components/Dashboard/Infrastructure/DnsRecordDialog.stx +1 -1
  200. package/resources/components/Dashboard/Infrastructure/LogDetailsDialog.stx +1 -1
  201. package/resources/components/Dashboard/Infrastructure/MailboxDetailsDialog.stx +1 -1
  202. package/resources/components/Dashboard/Infrastructure/ServerInspectorDialog.stx +1 -1
  203. package/resources/components/Dashboard/Jobs/JobTable.stx +1 -1
  204. package/resources/components/Dashboard/Library/SourceScaffoldDialog.stx +1 -1
  205. package/resources/components/Dashboard/Management/AssignmentDrawer.stx +1 -1
  206. package/resources/components/Dashboard/Marketing/CampaignDeleteDialog.stx +1 -1
  207. package/resources/components/Dashboard/Marketing/CampaignDeliveryDialog.stx +1 -1
  208. package/resources/components/Dashboard/Marketing/CampaignDialog.stx +1 -1
  209. package/resources/components/Dashboard/Marketing/CampaignsTable.stx +1 -1
  210. package/resources/components/Dashboard/Marketing/MarketingListDeleteDialog.stx +1 -1
  211. package/resources/components/Dashboard/Marketing/MarketingListDialog.stx +1 -1
  212. package/resources/components/Dashboard/Marketing/MarketingListsTable.stx +1 -1
  213. package/resources/components/Dashboard/Marketing/RecoveryCampaignDialog.stx +1 -1
  214. package/resources/components/Dashboard/Marketing/SocialPostDeleteDialog.stx +1 -1
  215. package/resources/components/Dashboard/Marketing/SocialPostDialog.stx +1 -1
  216. package/resources/components/Dashboard/Marketing/SocialPostsTable.stx +1 -1
  217. package/resources/components/Dashboard/MobileSidebar.stx +1 -1
  218. package/resources/components/Dashboard/Modals/BaseModal.stx +1 -1
  219. package/resources/components/Dashboard/Modals/Popups/Alert.stx +1 -1
  220. package/resources/components/Dashboard/Modals/Popups/Toast.stx +1 -1
  221. package/resources/components/Dashboard/Modals/ToastWrapper.stx +1 -1
  222. package/resources/components/Dashboard/Models/EditRecordModal.stx +1 -1
  223. package/resources/components/Dashboard/Models/ModelRecordActions.stx +1 -1
  224. package/resources/components/Dashboard/Monitoring/ErrorTable.stx +1 -1
  225. package/resources/components/Dashboard/Notifications/NotificationDeliveryDialog.stx +1 -1
  226. package/resources/components/Dashboard/Notifications/NotificationDeliveryTable.stx +1 -1
  227. package/resources/components/Dashboard/Operations/RecoveryDestinationDialog.stx +1 -1
  228. package/resources/components/Dashboard/Operations/RecoveryPointTable.stx +1 -1
  229. package/resources/components/Dashboard/Operations/RecoveryPolicyDialog.stx +1 -1
  230. package/resources/components/Dashboard/Operations/RecoveryRestoreDialog.stx +1 -1
  231. package/resources/components/Dashboard/Operations/SchedulerTaskTable.stx +1 -1
  232. package/resources/components/Dashboard/UI/Checkbox.stx +1 -1
  233. package/resources/components/Dashboard/UI/ConfirmDialog.stx +1 -1
  234. package/resources/components/Dashboard/UI/Drawer.stx +1 -1
  235. package/resources/components/Dashboard/UI/Dropdown.stx +1 -1
  236. package/resources/components/Dashboard/UI/Input.stx +1 -1
  237. package/resources/components/Dashboard/UI/Modal.stx +1 -1
  238. package/resources/components/Dashboard/UI/Pagination.stx +1 -1
  239. package/resources/components/Dashboard/UI/SearchFilter.stx +1 -1
  240. package/resources/components/Dashboard/UI/Select.stx +1 -1
  241. package/resources/components/Dashboard/UI/Table.stx +1 -1
  242. package/resources/components/Dashboard/UI/Tabs.stx +1 -1
  243. package/resources/components/Dashboard/UI/Textarea.stx +1 -1
  244. package/resources/components/Dashboard/UI/Toggle.stx +1 -1
  245. package/resources/components/Dashboard/UI/WindowControls.stx +1 -1
  246. package/resources/components/NativeActionSheet.stx +1 -1
  247. package/resources/components/NativeContextMenu.stx +1 -1
  248. package/resources/components/NativeHealthButton.stx +1 -1
  249. package/resources/components/NativePermissionButton.stx +1 -1
  250. package/resources/components/NativePullToRefresh.stx +1 -1
  251. package/resources/components/NativeSegmentedControl.stx +1 -1
  252. package/resources/components/NativeSheet.stx +1 -1
@@ -8,6 +8,8 @@ export default defineModel({
8
8
  autoIncrement: true,
9
9
 
10
10
  traits: {
11
+ // So a fresh seed fills its dashboard page (stacksjs/stacks#3000).
12
+ useSeeder: { count: 5 },
11
13
  useUuid: true,
12
14
  useTimestamps: true,
13
15
  useSearch: {
@@ -59,6 +61,7 @@ export default defineModel({
59
61
  notes: {
60
62
  order: 4,
61
63
  fillable: true,
64
+ type: 'text',
62
65
  validation: {
63
66
  rule: schema.string(),
64
67
  },
@@ -132,6 +132,7 @@ export default defineModel({
132
132
 
133
133
  error_message: {
134
134
  fillable: true,
135
+ type: 'text',
135
136
  validation: {
136
137
  rule: schema.string(),
137
138
  message: {
@@ -6,6 +6,8 @@ export default defineModel({
6
6
  table: 'sender_domains',
7
7
  belongsTo: ['Team'],
8
8
  traits: {
9
+ // So a fresh seed fills its dashboard page (stacksjs/stacks#3000).
10
+ useSeeder: { count: 3 },
9
11
  useUuid: true,
10
12
  useTimestamps: true,
11
13
  useApi: { uri: 'sender-domains', routes: ['index', 'store', 'show', 'update', 'destroy'], middleware: ['auth', 'team'] },
@@ -13,13 +13,6 @@ export default defineModel({
13
13
  primaryKey: 'id',
14
14
  autoIncrement: true,
15
15
 
16
- indexes: [
17
- {
18
- name: 'sms_opt_outs_phone_unique',
19
- columns: ['phone'],
20
- unique: true,
21
- },
22
- ],
23
16
 
24
17
  traits: {
25
18
  gdpr: { erasure: 'keep', basis: 'legal_obligation', purpose: 'Honouring SMS STOP replies, keyed by phone number' },
@@ -8,6 +8,8 @@ export default defineModel({
8
8
  autoIncrement: true, // defaults to true
9
9
  belongsTo: ['User'],
10
10
  traits: {
11
+ // So a fresh seed fills its dashboard page (stacksjs/stacks#3000).
12
+ useSeeder: { count: 10 },
11
13
  gdpr: { erasure: 'keep', basis: 'legal_obligation', purpose: 'Billing records' },
12
14
  useUuid: true,
13
15
  },
@@ -75,6 +75,7 @@ export default defineModel({
75
75
  description: {
76
76
  order: 3,
77
77
  fillable: true,
78
+ type: 'text',
78
79
  validation: {
79
80
  rule: schema.string(),
80
81
  },
@@ -74,6 +74,7 @@ export default defineModel({
74
74
  description: {
75
75
  order: 3,
76
76
  fillable: true,
77
+ type: 'text',
77
78
  validation: {
78
79
  rule: schema.string(),
79
80
  },
@@ -136,9 +136,90 @@ export default defineModel({
136
136
  order: 10,
137
137
  fillable: true,
138
138
  validation: {
139
- rule: schema.string().required(),
139
+ // Optional: a cart without a coupon is the common case.
140
+ rule: schema.string(),
141
+ },
142
+ // Stored and shown, never resolved: nothing redeems or joins on it yet,
143
+ // so what it holds is left to the feature that does. No factory, so a
144
+ // seed does not invent one (stacksjs/stacks#3002).
145
+ },
146
+
147
+ // The storefront's anonymous cart: the shopper's signed stacks_cart cookie
148
+ // carries this token, checkout records its progress and the address, and
149
+ // the order is placed from them (stacksjs/stacks#3017). A cart made any
150
+ // other way has none of them.
151
+
152
+ /** Bearer for an anonymous cart, so never returned by the API. No factory: a seeded cart is no shopper's. */
153
+ sessionToken: {
154
+ order: 11,
155
+ unique: true,
156
+ hidden: true,
157
+ validation: {
158
+ rule: schema.string().max(255),
159
+ },
160
+ },
161
+
162
+ checkoutStep: {
163
+ default: 'cart',
164
+ order: 12,
165
+ fillable: true,
166
+ validation: {
167
+ rule: schema.enum(['cart', 'shipping', 'payment', 'placed']),
168
+ },
169
+ },
170
+
171
+ email: {
172
+ personal: true,
173
+ order: 13,
174
+ fillable: true,
175
+ validation: {
176
+ rule: schema.string().email().max(255),
177
+ },
178
+ },
179
+
180
+ shippingName: {
181
+ personal: true,
182
+ order: 14,
183
+ fillable: true,
184
+ validation: {
185
+ rule: schema.string().max(255),
186
+ },
187
+ },
188
+
189
+ shippingAddress: {
190
+ personal: true,
191
+ order: 15,
192
+ fillable: true,
193
+ validation: {
194
+ rule: schema.string().max(255),
195
+ },
196
+ },
197
+
198
+ shippingCity: {
199
+ personal: true,
200
+ order: 16,
201
+ fillable: true,
202
+ validation: {
203
+ rule: schema.string().max(255),
204
+ },
205
+ },
206
+
207
+ shippingState: {
208
+ personal: true,
209
+ order: 17,
210
+ fillable: true,
211
+ validation: {
212
+ rule: schema.string().max(100),
213
+ },
214
+ },
215
+
216
+ shippingZip: {
217
+ personal: true,
218
+ order: 18,
219
+ fillable: true,
220
+ validation: {
221
+ rule: schema.string().max(20),
140
222
  },
141
- factory: () => 'test-coupon-id',
142
223
  },
143
224
  },
144
225
 
@@ -64,6 +64,7 @@ export default defineModel({
64
64
  description: {
65
65
  order: 2,
66
66
  fillable: true,
67
+ type: 'text',
67
68
  validation: {
68
69
  rule: schema.string(),
69
70
  },
@@ -101,7 +102,10 @@ export default defineModel({
101
102
  order: 5,
102
103
  fillable: true,
103
104
  validation: {
104
- rule: schema.string(),
105
+ // Another category's id, so a number like the id it points at. As a
106
+ // string it was a text column, and joining it to categories.id failed
107
+ // on PostgreSQL with "text = bigint" (stacksjs/stacks#3002).
108
+ rule: schema.number(),
105
109
  },
106
110
  factory: () => null, // Most categories won't have a parent
107
111
  },
@@ -55,6 +55,7 @@ export default defineModel({
55
55
  description: {
56
56
  order: 2,
57
57
  fillable: true,
58
+ type: 'text',
58
59
  validation: {
59
60
  rule: schema.string(),
60
61
  },
@@ -145,7 +146,9 @@ export default defineModel({
145
146
  validation: {
146
147
  rule: schema.string(),
147
148
  },
148
- factory: faker => faker.string.uuid(),
149
+ // Stored and shown, never resolved: nothing redeems or joins on it yet,
150
+ // so what it holds is left to the feature that does. No factory, so a
151
+ // seed does not invent one (stacksjs/stacks#3002).
149
152
  },
150
153
 
151
154
  usageLimit: {
@@ -56,6 +56,7 @@ export default defineModel({
56
56
  description: {
57
57
  order: 3,
58
58
  fillable: true,
59
+ type: 'text',
59
60
  validation: {
60
61
  rule: schema.string().required(),
61
62
  },
@@ -125,6 +125,7 @@ export default defineModel({
125
125
  personal: true,
126
126
  order: 9,
127
127
  fillable: true,
128
+ type: 'text',
128
129
  validation: {
129
130
  rule: schema.string(),
130
131
  },
@@ -81,6 +81,7 @@ export default defineModel({
81
81
  description: {
82
82
  order: 5,
83
83
  fillable: true,
84
+ type: 'text',
84
85
  validation: {
85
86
  rule: schema.string(),
86
87
  },
@@ -98,7 +98,9 @@ export default defineModel({
98
98
  validation: {
99
99
  rule: schema.string(),
100
100
  },
101
- factory: faker => faker.helpers.maybe(() => faker.string.uuid(), { probability: 0.4 }),
101
+ // Stored and shown, never resolved: nothing redeems or joins on it yet,
102
+ // so what it holds is left to the feature that does. No factory, so a
103
+ // seed does not invent one (stacksjs/stacks#3002).
102
104
  },
103
105
 
104
106
  isActive: {
@@ -142,6 +142,7 @@ export default defineModel({
142
142
  personal: true,
143
143
  order: 11,
144
144
  fillable: true,
145
+ type: 'text',
145
146
  validation: {
146
147
  rule: schema.string(),
147
148
  },
@@ -199,7 +200,9 @@ export default defineModel({
199
200
  validation: {
200
201
  rule: schema.string(),
201
202
  },
202
- factory: faker => faker.helpers.maybe(() => faker.string.uuid(), { probability: 0.2 }),
203
+ // Stored and shown, never resolved: nothing redeems or joins on it yet,
204
+ // so what it holds is left to the feature that does. No factory, so a
205
+ // seed does not invent one (stacksjs/stacks#3002).
203
206
  },
204
207
  },
205
208
 
@@ -45,6 +45,7 @@ export default defineModel({
45
45
  personal: true,
46
46
  order: 5,
47
47
  fillable: true,
48
+ type: 'text',
48
49
  validation: {
49
50
  rule: schema.string(),
50
51
  },
@@ -179,6 +179,7 @@ export default defineModel({
179
179
  personal: true,
180
180
  order: 15,
181
181
  fillable: true,
182
+ type: 'text',
182
183
  validation: {
183
184
  rule: schema.string(),
184
185
  },
@@ -1,4 +1,5 @@
1
1
  import { defineModel } from '@stacksjs/orm'
2
+ import { slug } from '@stacksjs/strings'
2
3
  import { schema } from '@stacksjs/validation/runtime'
3
4
 
4
5
  export default defineModel({
@@ -56,9 +57,22 @@ export default defineModel({
56
57
  factory: faker => faker.commerce.productName(),
57
58
  },
58
59
 
60
+ // The storefront's address for a product: /products/{slug}, and what a
61
+ // cart line keeps in product_sku (stacksjs/stacks#3005).
62
+ slug: {
63
+ order: 1,
64
+ unique: true,
65
+ fillable: true,
66
+ validation: {
67
+ rule: schema.string().required().max(255),
68
+ },
69
+ factory: (_faker, attributes) => slug(String(attributes.name)),
70
+ },
71
+
59
72
  description: {
60
73
  order: 2,
61
74
  fillable: true,
75
+ type: 'text',
62
76
  validation: {
63
77
  rule: schema.string(),
64
78
  },
@@ -139,6 +153,7 @@ export default defineModel({
139
153
  nutritionalInfo: {
140
154
  order: 10,
141
155
  fillable: true,
156
+ type: 'text',
142
157
  validation: {
143
158
  rule: schema.string(),
144
159
  },
@@ -77,6 +77,7 @@ export default defineModel({
77
77
  description: {
78
78
  order: 5,
79
79
  fillable: true,
80
+ type: 'text',
80
81
  validation: {
81
82
  rule: schema.string(),
82
83
  },
@@ -86,6 +87,7 @@ export default defineModel({
86
87
  options: {
87
88
  order: 6,
88
89
  fillable: true,
90
+ type: 'text',
89
91
  validation: {
90
92
  rule: schema.string(),
91
93
  },
@@ -136,6 +136,7 @@ export default defineModel({
136
136
  order: 8,
137
137
  fillable: true,
138
138
  default: '{}',
139
+ type: 'text',
139
140
  validation: {
140
141
  rule: schema.string(),
141
142
  },
@@ -34,7 +34,9 @@ export default defineModel({
34
34
  observe: true,
35
35
  },
36
36
 
37
- belongsTo: ['Product', 'Customer'],
37
+ // The order a storefront review was left for: one review per product per
38
+ // order, and the proof the reviewer bought it (stacksjs/stacks#3017).
39
+ belongsTo: ['Product', 'Customer', 'Order'],
38
40
 
39
41
  attributes: {
40
42
  /**
@@ -71,6 +71,7 @@ export default defineModel({
71
71
  order: 5,
72
72
  fillable: true,
73
73
  hidden: true,
74
+ type: 'text',
74
75
  validation: {
75
76
  rule: schema.string(),
76
77
  },
@@ -72,7 +72,10 @@ export default defineModel({
72
72
  order: 4,
73
73
  fillable: true,
74
74
  validation: {
75
- rule: schema.number(),
75
+ // A Unix timestamp in milliseconds, so a bigint column: `number()`
76
+ // generated a 32-bit integer that Date.now() overflows on PostgreSQL
77
+ // and MySQL (stacksjs/stacks#2996).
78
+ rule: schema.unix(),
76
79
  message: {
77
80
  date: 'Time must be a valid timestamp',
78
81
  },
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'bun:test'
2
- import { formErrorMessages } from './dashboard-form'
2
+ import { formErrorMessages, slugify } from './dashboard-form'
3
3
 
4
4
  /**
5
5
  * stacksjs/stacks#2918 — this was duplicated across fourteen dialogs. The
@@ -39,3 +39,12 @@ describe('formErrorMessages', () => {
39
39
  expect(formErrorMessages({ Name: 'is required' })).toEqual(['Name: is required'])
40
40
  })
41
41
  })
42
+
43
+ describe('slugify', () => {
44
+ it('turns a name into the slug a dialog proposes', () => {
45
+ expect(slugify('Trail Runner')).toBe('trail-runner')
46
+ expect(slugify(' Café & Bar ')).toBe('cafe-bar')
47
+ expect(slugify('50% off: Summer!')).toBe('50-off-summer')
48
+ expect(slugify('---')).toBe('')
49
+ })
50
+ })
@@ -28,3 +28,20 @@ export function formErrorMessages(errors: Record<string, string>): string[] {
28
28
  return `${label.charAt(0).toUpperCase()}${label.slice(1)}: ${message}`
29
29
  })
30
30
  }
31
+
32
+ /**
33
+ * A slug a dialog proposes from a name: accents folded, lowercase, and every
34
+ * run of anything but a letter or digit one hyphen.
35
+ *
36
+ * The category dialog defined this inline; the product dialog needs the same
37
+ * rule (stacksjs/stacks#3005), so it lives here once.
38
+ */
39
+ export function slugify(value: string): string {
40
+ return value
41
+ .normalize('NFKD')
42
+ .replace(/[̀-ͯ]/g, '')
43
+ .toLowerCase()
44
+ .trim()
45
+ .replace(/[^a-z0-9]+/g, '-')
46
+ .replace(/^-+|-+$/g, '')
47
+ }
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.318",
5
+ "version": "0.75.321",
6
6
  "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/defaults",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.318",
5
+ "version": "0.75.321",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -45,9 +45,9 @@
45
45
  "dependencies": {
46
46
  "@iconify-json/f7": "^1.2.2",
47
47
  "@iconify-json/hugeicons": "^1.2.35",
48
- "@stacksjs/mobile": "0.75.318",
49
- "@stacksjs/sanitizer": "0.2.691",
50
- "@stacksjs/stx": "0.2.691",
48
+ "@stacksjs/mobile": "0.75.321",
49
+ "@stacksjs/sanitizer": "0.2.711",
50
+ "@stacksjs/stx": "0.2.711",
51
51
  "@xterm/addon-fit": "^0.11.0",
52
52
  "@xterm/xterm": "^6.0.0",
53
53
  "ts-qr-codes": "^0.1.8"
@@ -4,7 +4,7 @@ const description = useReactiveProp('description', '')
4
4
  const dateRange = useReactiveProp('dateRange', '')
5
5
  const range = useReactiveProp('range', 'month')
6
6
  const loading = useReactiveProp('loading', false)
7
- const emit = defineEmits()
7
+ const emit = defineEmits(['range-change', 'refresh'])
8
8
  const selectedRange = state('month')
9
9
 
10
10
  effect(() => {
@@ -13,7 +13,7 @@ interface RequestRow {
13
13
  }
14
14
 
15
15
  const request = useReactiveProp('request', null as RequestRow | null)
16
- const emit = defineEmits()
16
+ const emit = defineEmits(['close'])
17
17
 
18
18
  function formatDate(value: string | undefined): string {
19
19
  if (!value)
@@ -28,7 +28,7 @@ const expiryMinutes = state('10080')
28
28
  const selectedScopes = state<string[]>(['read'])
29
29
  const localError = state('')
30
30
  const copied = state(false)
31
- const emit = defineEmits()
31
+ const emit = defineEmits(['submit', 'close'])
32
32
  let wasOpen = false
33
33
 
34
34
  effect(() => {
@@ -1,7 +1,7 @@
1
1
  @import('../UI/Input', '../UI/Button')
2
2
 
3
3
  <script client>
4
- const emit = defineEmits()
4
+ const emit = defineEmits(['submit', 'retry'])
5
5
  const title = useReactiveProp<string>('title', 'Forgot password?')
6
6
  const subtitle = useReactiveProp<string>('subtitle', 'Enter your email and we\'ll send you a reset link')
7
7
  const isLoading = useReactiveProp<boolean>('isLoading', false)
@@ -1,7 +1,7 @@
1
1
  @import('../UI/Input', '../UI/Button')
2
2
 
3
3
  <script client>
4
- const emit = defineEmits()
4
+ const emit = defineEmits(['submit'])
5
5
  const title = useReactiveProp<string>('title', 'Welcome back')
6
6
  const subtitle = useReactiveProp<string>('subtitle', 'Sign in to your account')
7
7
  const isLoading = useReactiveProp<boolean>('isLoading', false)
@@ -1,7 +1,7 @@
1
1
  @import('../UI/Input', '../UI/Button')
2
2
 
3
3
  <script client>
4
- const emit = defineEmits()
4
+ const emit = defineEmits(['submit'])
5
5
  const title = useReactiveProp<string>('title', 'Create an account')
6
6
  const subtitle = useReactiveProp<string>('subtitle', 'Get started with your free account')
7
7
  const isLoading = useReactiveProp<boolean>('isLoading', false)
@@ -13,7 +13,7 @@
13
13
  --}}
14
14
 
15
15
  <script client>
16
- const emit = defineEmits()
16
+ const emit = defineEmits(['submit'])
17
17
  const title = useReactiveProp<string>('title', 'Choose a new password')
18
18
  const subtitle = useReactiveProp<string>('subtitle', 'Set the password you will use to sign in')
19
19
  const isLoading = useReactiveProp<boolean>('isLoading', false)
@@ -1,7 +1,7 @@
1
1
  @import('../UI/Input', '../UI/Button')
2
2
 
3
3
  <script client>
4
- const emit = defineEmits()
4
+ const emit = defineEmits(['submit', 'restart'])
5
5
  const isLoading = useReactiveProp<boolean>('isLoading', false)
6
6
  const error = useReactiveProp<string>('error', '')
7
7
  const code = state('')
@@ -6,7 +6,7 @@ const liveLanguage = useReactiveProp('language', 'text' as CodeEditorLanguage)
6
6
  const liveLabel = useReactiveProp('label', 'Code editor')
7
7
  const liveLoading = useReactiveProp('loading', false)
8
8
  const liveReadonly = useReactiveProp('readonly', false)
9
- const emit = defineEmits()
9
+ const emit = defineEmits(['update:value', 'input', 'save', 'format'])
10
10
 
11
11
  const lineCount = derived(() => Math.max(1, liveValue().split('\n').length))
12
12
  const characterCount = derived(() => liveValue().length)
@@ -17,7 +17,7 @@ interface CategoryWritePayload {
17
17
  slug: string
18
18
  imageUrl: string
19
19
  isActive: boolean
20
- parentCategoryId: string
20
+ parentCategoryId: number | null
21
21
  displayOrder: number
22
22
  }
23
23
 
@@ -10,7 +10,7 @@ const loading = useReactiveProp('loading', false)
10
10
  const sortResetKey = useReactiveProp<unknown>('sortResetKey', '')
11
11
  /** The parent's search and filters: a change returns to the first page. */
12
12
  const pageResetKey = useReactiveProp<unknown>('pageResetKey', '')
13
- const emit = defineEmits()
13
+ const emit = defineEmits(['view', 'edit', 'delete'])
14
14
 
15
15
  function parentName(record: CommerceCategoryRecord): string {
16
16
  if (!record.parentCategoryId)
@@ -4,7 +4,7 @@ import type { CommerceCategoryRecord } from '../../../../app/Actions/Dashboard/C
4
4
  const open = useReactiveProp('open', false)
5
5
  const record = useReactiveProp('record', null as CommerceCategoryRecord | null)
6
6
  const busy = useReactiveProp('busy', false)
7
- const emit = defineEmits()
7
+ const emit = defineEmits(['close', 'confirm'])
8
8
  const description = derived(() => `Delete "${record()?.name || 'Unnamed category'}" permanently? Linked products and child categories may prevent deletion.`)
9
9
  </script>
10
10
 
@@ -4,7 +4,7 @@ import type { CommerceCategoryRecord } from '../../../../app/Actions/Dashboard/C
4
4
  const open = useReactiveProp('open', false)
5
5
  const record = useReactiveProp('record', null as CommerceCategoryRecord | null)
6
6
  const records = useReactiveProp('records', [] as CommerceCategoryRecord[])
7
- const emit = defineEmits()
7
+ const emit = defineEmits(['edit', 'close', 'delete'])
8
8
 
9
9
  function parentName(): string {
10
10
  const parentId = record()?.parentCategoryId
@@ -1,6 +1,6 @@
1
1
  <script client>
2
2
  import type { CommerceCategoryRecord } from '../../../../app/Actions/Dashboard/Commerce/commerce-category-records'
3
- import { formErrorMessages } from '../../../../functions/dashboard-form'
3
+ import { formErrorMessages, slugify } from '../../../../functions/dashboard-form'
4
4
 
5
5
  const open = useReactiveProp('open', false)
6
6
  const mode = useReactiveProp('mode', 'add')
@@ -8,7 +8,7 @@ const record = useReactiveProp('record', null as CommerceCategoryRecord | null)
8
8
  const records = useReactiveProp('records', [] as CommerceCategoryRecord[])
9
9
  const busy = useReactiveProp('busy', false)
10
10
  const errors = useReactiveProp('errors', {} as Record<string, string>)
11
- const emit = defineEmits()
11
+ const emit = defineEmits(['submit', 'close'])
12
12
  const name = state('')
13
13
  const description = state('')
14
14
  const slug = state('')
@@ -19,16 +19,6 @@ const displayOrder = state('0')
19
19
  let hydrationKey = ''
20
20
  let slugTouched = false
21
21
 
22
- function slugify(value: string): string {
23
- return value
24
- .normalize('NFKD')
25
- .replace(/[\u0300-\u036F]/g, '')
26
- .toLowerCase()
27
- .trim()
28
- .replace(/[^a-z0-9]+/g, '-')
29
- .replace(/^-+|-+$/g, '')
30
- }
31
-
32
22
  effect(() => {
33
23
  if (!open()) {
34
24
  hydrationKey = ''
@@ -108,7 +98,8 @@ function submit(): void {
108
98
  slug: slugify(slug()),
109
99
  imageUrl: imageUrl().trim(),
110
100
  isActive: isActive(),
111
- parentCategoryId: parentCategoryId(),
101
+ // The select holds the id as text; the model declares a number (#3013).
102
+ parentCategoryId: parentCategoryId() ? Number(parentCategoryId()) : null,
112
103
  displayOrder: Number(displayOrder()),
113
104
  })
114
105
  }
@@ -4,7 +4,7 @@ import type { CouponRecord } from '../../../../app/Actions/Dashboard/Commerce/co
4
4
  const open = useReactiveProp('open', false)
5
5
  const record = useReactiveProp('record', null as CouponRecord | null)
6
6
  const busy = useReactiveProp('busy', false)
7
- const emit = defineEmits()
7
+ const emit = defineEmits(['close', 'confirm'])
8
8
  const description = derived(() => `Delete "${record()?.code || 'Unnamed coupon'}" permanently? Recorded order relationships may prevent deletion.`)
9
9
  </script>
10
10