@stacksjs/defaults 0.70.58 → 0.70.59
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.
- package/app/Actions/AI/AskAction.ts +40 -0
- package/app/Actions/AI/SummaryAction.ts +40 -0
- package/app/Actions/Auth/AuthUserAction.ts +13 -0
- package/app/Actions/Auth/CreateTokenAction.ts +64 -0
- package/app/Actions/Auth/DisableTwoFactorAction.ts +37 -0
- package/app/Actions/Auth/EnableTwoFactorAction.ts +37 -0
- package/app/Actions/Auth/GenerateAuthenticationAction.ts +51 -0
- package/app/Actions/Auth/GenerateRegistrationAction.ts +53 -0
- package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +26 -0
- package/app/Actions/Auth/ListTokensAction.ts +30 -0
- package/app/Actions/Auth/LoginAction.ts +73 -0
- package/app/Actions/Auth/LogoutAction.ts +16 -0
- package/app/Actions/Auth/LogoutAllAction.ts +28 -0
- package/app/Actions/Auth/RefreshTokenAction.ts +39 -0
- package/app/Actions/Auth/RegisterAction.ts +57 -0
- package/app/Actions/Auth/ResendVerificationAction.ts +24 -0
- package/app/Actions/Auth/RevokeTokenAction.ts +43 -0
- package/app/Actions/Auth/TestAbilitiesAction.ts +61 -0
- package/app/Actions/Auth/VerifyAuthenticationAction.ts +94 -0
- package/app/Actions/Auth/VerifyEmailAction.ts +25 -0
- package/app/Actions/Auth/VerifyRegistrationAction.ts +59 -0
- package/app/Actions/Auth/VerifyTwoFactorLoginAction.ts +57 -0
- package/app/Actions/Billable/CheckoutAction.ts +25 -0
- package/app/Actions/Buddy/BuddyBrowseAction.ts +34 -0
- package/app/Actions/Buddy/BuddyCancelAction.ts +32 -0
- package/app/Actions/Buddy/BuddyCommitAction.ts +25 -0
- package/app/Actions/Buddy/BuddyGitHubConnectAction.ts +40 -0
- package/app/Actions/Buddy/BuddyGitHubDisconnectAction.ts +19 -0
- package/app/Actions/Buddy/BuddyProcessAction.ts +65 -0
- package/app/Actions/Buddy/BuddyProcessStreamAction.ts +128 -0
- package/app/Actions/Buddy/BuddyPushAction.ts +21 -0
- package/app/Actions/Buddy/BuddyRepoOpenAction.ts +44 -0
- package/app/Actions/Buddy/BuddyRepoValidateAction.ts +35 -0
- package/app/Actions/Buddy/BuddySettingsAction.ts +21 -0
- package/app/Actions/Buddy/BuddySettingsUpdateAction.ts +46 -0
- package/app/Actions/Buddy/BuddyStateAction.ts +28 -0
- package/app/Actions/Buddy/BuddyTitleAction.ts +49 -0
- package/app/Actions/Buddy/CommandsAction.ts +802 -0
- package/app/Actions/Buddy/JobCancelAction.ts +32 -0
- package/app/Actions/Buddy/JobRetryAction.ts +49 -0
- package/app/Actions/Buddy/JobsListAction.ts +141 -0
- package/app/Actions/Buddy/ScheduleListAction.ts +52 -0
- package/app/Actions/Buddy/VersionsAction.ts +12 -0
- package/app/Actions/Cms/AuthorDestroyAction.ts +21 -0
- package/app/Actions/Cms/AuthorIndexAction.ts +14 -0
- package/app/Actions/Cms/AuthorShowAction.ts +19 -0
- package/app/Actions/Cms/AuthorStoreAction.ts +20 -0
- package/app/Actions/Cms/AuthorUpdateAction.ts +24 -0
- package/app/Actions/Cms/CategorizableDestroyAction.ts +16 -0
- package/app/Actions/Cms/CategorizableIndexAction.ts +14 -0
- package/app/Actions/Cms/CategorizableShowAction.ts +16 -0
- package/app/Actions/Cms/CategorizableStoreAction.ts +42 -0
- package/app/Actions/Cms/CategorizableUpdateAction.ts +38 -0
- package/app/Actions/Cms/CommentDestroyAction.ts +16 -0
- package/app/Actions/Cms/CommentIndexAction.ts +17 -0
- package/app/Actions/Cms/CommentShowAction.ts +16 -0
- package/app/Actions/Cms/CommentStoreAction.ts +39 -0
- package/app/Actions/Cms/CommentUpdateAction.ts +37 -0
- package/app/Actions/Cms/PageDestroyAction.ts +16 -0
- package/app/Actions/Cms/PageIndexAction.ts +14 -0
- package/app/Actions/Cms/PageStoreAction.ts +31 -0
- package/app/Actions/Cms/PageUpdateAction.ts +27 -0
- package/app/Actions/Cms/PostDestroyAction.ts +17 -0
- package/app/Actions/Cms/PostIndexAction.ts +14 -0
- package/app/Actions/Cms/PostShowAction.ts +16 -0
- package/app/Actions/Cms/PostStoreAction.ts +37 -0
- package/app/Actions/Cms/PostUpdateAction.ts +32 -0
- package/app/Actions/Cms/PostViewsUpdateAction.ts +34 -0
- package/app/Actions/Cms/RssFeedAction.ts +59 -0
- package/app/Actions/Cms/SitemapAction.ts +60 -0
- package/app/Actions/Cms/TaggableDestroyAction.ts +16 -0
- package/app/Actions/Cms/TaggableIndexAction.ts +14 -0
- package/app/Actions/Cms/TaggableShowAction.ts +16 -0
- package/app/Actions/Cms/TaggableStoreAction.ts +36 -0
- package/app/Actions/Cms/TaggableUpdateAction.ts +37 -0
- package/app/Actions/Commerce/CouponDestroyAction.ts +18 -0
- package/app/Actions/Commerce/CouponIndexAction.ts +16 -0
- package/app/Actions/Commerce/CouponShowAction.ts +18 -0
- package/app/Actions/Commerce/CouponStoreAction.ts +21 -0
- package/app/Actions/Commerce/CouponUpdateAction.ts +31 -0
- package/app/Actions/Commerce/CustomerDestroyAction.ts +16 -0
- package/app/Actions/Commerce/CustomerIndexAction.ts +15 -0
- package/app/Actions/Commerce/CustomerShowAction.ts +18 -0
- package/app/Actions/Commerce/CustomerStoreAction.ts +29 -0
- package/app/Actions/Commerce/CustomerUpdateAction.ts +27 -0
- package/app/Actions/Commerce/DriverDestroyAction.ts +18 -0
- package/app/Actions/Commerce/GiftCardDestroyAction.ts +18 -0
- package/app/Actions/Commerce/GiftCardIndexAction.ts +16 -0
- package/app/Actions/Commerce/GiftCardShowAction.ts +18 -0
- package/app/Actions/Commerce/GiftCardStatsAction.ts +30 -0
- package/app/Actions/Commerce/GiftCardStoreAction.ts +35 -0
- package/app/Actions/Commerce/GiftCardUpdateAction.ts +26 -0
- package/app/Actions/Commerce/GiftCardUpdateBalanceAction.ts +36 -0
- package/app/Actions/Commerce/OrderDestroyAction.ts +18 -0
- package/app/Actions/Commerce/OrderExportAction.ts +15 -0
- package/app/Actions/Commerce/OrderIndexAction.ts +15 -0
- package/app/Actions/Commerce/OrderShowAction.ts +18 -0
- package/app/Actions/Commerce/OrderStoreAction.ts +32 -0
- package/app/Actions/Commerce/OrderUpdateAction.ts +34 -0
- package/app/Actions/Commerce/PaymentDestroyAction.ts +16 -0
- package/app/Actions/Commerce/PaymentFetchStatsAction.ts +31 -0
- package/app/Actions/Commerce/PaymentIndexAction.ts +15 -0
- package/app/Actions/Commerce/PaymentMonthlyTrendsAction.ts +21 -0
- package/app/Actions/Commerce/PaymentShowAction.ts +17 -0
- package/app/Actions/Commerce/PaymentStoreAction.ts +24 -0
- package/app/Actions/Commerce/PaymentUpdateAction.ts +35 -0
- package/app/Actions/Commerce/PrintDeviceDestroyAction.ts +18 -0
- package/app/Actions/Commerce/PrintDeviceIndexAction.ts +14 -0
- package/app/Actions/Commerce/PrintDeviceShowAction.ts +17 -0
- package/app/Actions/Commerce/PrintDeviceStoreAction.ts +27 -0
- package/app/Actions/Commerce/PrintDeviceUpdateAction.ts +27 -0
- package/app/Actions/Commerce/Product/ManufacturerDestroyAction.ts +20 -0
- package/app/Actions/Commerce/Product/ManufacturerIndexAction.ts +16 -0
- package/app/Actions/Commerce/Product/ManufacturerShowAction.ts +18 -0
- package/app/Actions/Commerce/Product/ManufacturerStoreAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductCategoryIndexAction.ts +16 -0
- package/app/Actions/Commerce/Product/ProductCategoryStoreAction.ts +16 -0
- package/app/Actions/Commerce/Product/ProductDestroyAction.ts +16 -0
- package/app/Actions/Commerce/Product/ProductIndexAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductManufacturerDestroyAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductManufacturerIndexAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductManufacturerShowAction.ts +16 -0
- package/app/Actions/Commerce/Product/ProductManufacturerStoreAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductManufacturerUpdateAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductShowAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductStoreAction.ts +17 -0
- package/app/Actions/Commerce/Product/ProductUnitDestroyAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductUnitIndexAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductUnitShowAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductUnitStoreAction.ts +15 -0
- package/app/Actions/Commerce/Product/ProductUpdateAction.ts +17 -0
- package/app/Actions/Commerce/Product/ProductVariantDestroyAction.ts +18 -0
- package/app/Actions/Commerce/Product/ProductVariantIndexAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductVariantShowAction.ts +17 -0
- package/app/Actions/Commerce/Product/ProductVariantStoreAction.ts +14 -0
- package/app/Actions/Commerce/Product/ProductVariantUpdateAction.ts +16 -0
- package/app/Actions/Commerce/ReceiptDestroyAction.ts +18 -0
- package/app/Actions/Commerce/ReceiptIndexAction.ts +14 -0
- package/app/Actions/Commerce/ReceiptShowAction.ts +18 -0
- package/app/Actions/Commerce/ReceiptStoreAction.ts +28 -0
- package/app/Actions/Commerce/ReceiptUpdateAction.ts +30 -0
- package/app/Actions/Commerce/ReviewIndexAction.ts +14 -0
- package/app/Actions/Commerce/ReviewShowAction.ts +16 -0
- package/app/Actions/Commerce/ReviewStoreAction.ts +26 -0
- package/app/Actions/Commerce/ReviewUpdateAction.ts +28 -0
- package/app/Actions/Commerce/Shipping/DeliveryRouteDestroyAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DeliveryRouteIndexAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/DeliveryRouteShowAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DeliveryRouteStoreAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/DeliveryRouteUpdateAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DigitalDeliveryDestroyAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DigitalDeliveryIndexAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/DigitalDeliveryShowAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DigitalDeliveryStoreAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DigitalDeliveryUpdateAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DriverIndexAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/DriverShowAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/DriverStoreAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/DriverUpdateAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/LicenseKeyDestroyAction.ts +20 -0
- package/app/Actions/Commerce/Shipping/LicenseKeyIndexAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/LicenseKeyShowAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/LicenseKeyStoreAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/LicenseKeyUpdateAction.ts +18 -0
- package/app/Actions/Commerce/Shipping/ShippingMethodDestroyAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingMethodIndexAction.ts +14 -0
- package/app/Actions/Commerce/Shipping/ShippingMethodShowAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingMethodStoreAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingMethodUpdateAction.ts +15 -0
- package/app/Actions/Commerce/Shipping/ShippingRateDestroyAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingRateIndexAction.ts +14 -0
- package/app/Actions/Commerce/Shipping/ShippingRateShowAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingRateStoreAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingRateUpdateAction.ts +17 -0
- package/app/Actions/Commerce/Shipping/ShippingZoneDestroyAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingZoneIndexAction.ts +14 -0
- package/app/Actions/Commerce/Shipping/ShippingZoneShowAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingZoneStoreAction.ts +16 -0
- package/app/Actions/Commerce/Shipping/ShippingZoneUpdateAction.ts +15 -0
- package/app/Actions/Commerce/TaxRateDestroyAction.ts +16 -0
- package/app/Actions/Commerce/TaxRateIndexAction.ts +14 -0
- package/app/Actions/Commerce/TaxRateShowAction.ts +17 -0
- package/app/Actions/Commerce/TaxRateStoreAction.ts +24 -0
- package/app/Actions/Commerce/TaxRateUpdateAction.ts +24 -0
- package/app/Actions/Commerce/WaitlistProductAnalyticsAction.ts +29 -0
- package/app/Actions/Commerce/WaitlistProductDestroyAction.ts +16 -0
- package/app/Actions/Commerce/WaitlistProductIndexAction.ts +14 -0
- package/app/Actions/Commerce/WaitlistProductQuantityDistributionAction.ts +32 -0
- package/app/Actions/Commerce/WaitlistProductShowAction.ts +16 -0
- package/app/Actions/Commerce/WaitlistProductStatusAction.ts +37 -0
- package/app/Actions/Commerce/WaitlistProductStoreAction.ts +27 -0
- package/app/Actions/Commerce/WaitlistProductTimeSeriesAction.ts +25 -0
- package/app/Actions/Commerce/WaitlistProductUpdateAction.ts +29 -0
- package/app/Actions/Commerce/WaitlistRestaurantDashboardAction.ts +29 -0
- package/app/Actions/Commerce/WaitlistRestaurantDestroyAction.ts +16 -0
- package/app/Actions/Commerce/WaitlistRestaurantIndexAction.ts +14 -0
- package/app/Actions/Commerce/WaitlistRestaurantShowAction.ts +16 -0
- package/app/Actions/Commerce/WaitlistRestaurantStoreAction.ts +31 -0
- package/app/Actions/Commerce/WaitlistRestaurantUpdateAction.ts +33 -0
- package/app/Actions/ContactAction.ts +72 -0
- package/app/Actions/Dashboard/Actions/CreateAction.ts +11 -0
- package/app/Actions/Dashboard/Actions/GetActionCount.ts +12 -0
- package/app/Actions/Dashboard/Actions/GetActions.ts +19 -0
- package/app/Actions/Dashboard/Analytics/BlogAnalyticsAction.ts +58 -0
- package/app/Actions/Dashboard/Analytics/BrowserAnalyticsAction.ts +42 -0
- package/app/Actions/Dashboard/Analytics/CommerceAnalyticsAction.ts +64 -0
- package/app/Actions/Dashboard/Analytics/CountryAnalyticsAction.ts +41 -0
- package/app/Actions/Dashboard/Analytics/DeviceAnalyticsAction.ts +58 -0
- package/app/Actions/Dashboard/Analytics/EventAnalyticsAction.ts +90 -0
- package/app/Actions/Dashboard/Analytics/MarketingAnalyticsAction.ts +76 -0
- package/app/Actions/Dashboard/Analytics/PageAnalyticsAction.ts +45 -0
- package/app/Actions/Dashboard/Analytics/ReferrerAnalyticsAction.ts +72 -0
- package/app/Actions/Dashboard/Analytics/SalesAnalyticsAction.ts +73 -0
- package/app/Actions/Dashboard/Analytics/WebAnalyticsAction.ts +114 -0
- package/app/Actions/Dashboard/Auth/MeAction.ts +84 -0
- package/app/Actions/Dashboard/BuddyDashboardAction.ts +34 -0
- package/app/Actions/Dashboard/Ci/RepoRunJobsAction.ts +60 -0
- package/app/Actions/Dashboard/Ci/RepoRunsAction.ts +67 -0
- package/app/Actions/Dashboard/Ci/RunnerHistoryAction.ts +58 -0
- package/app/Actions/Dashboard/Ci/StatusAction.ts +73 -0
- package/app/Actions/Dashboard/Ci/failure-notifier.ts +214 -0
- package/app/Actions/Dashboard/Ci/runner-pressure-monitor.ts +259 -0
- package/app/Actions/Dashboard/Cloud/CloudIndexAction.ts +61 -0
- package/app/Actions/Dashboard/Commands/CreateCommand.ts +11 -0
- package/app/Actions/Dashboard/Commands/GetAverageCommandTime.ts +12 -0
- package/app/Actions/Dashboard/Commands/GetCommandCount.ts +12 -0
- package/app/Actions/Dashboard/Commands/GetCommandSuccessRate.ts +12 -0
- package/app/Actions/Dashboard/Commands/GetCommands.ts +12 -0
- package/app/Actions/Dashboard/Commerce/CommerceCouponsAction.ts +48 -0
- package/app/Actions/Dashboard/Commerce/CommerceCustomersAction.ts +48 -0
- package/app/Actions/Dashboard/Commerce/CommerceDashboardAction.ts +98 -0
- package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +65 -0
- package/app/Actions/Dashboard/Commerce/CommerceGiftCardsAction.ts +48 -0
- package/app/Actions/Dashboard/Commerce/CommerceOrdersAction.ts +51 -0
- package/app/Actions/Dashboard/Commerce/CommercePaymentsAction.ts +59 -0
- package/app/Actions/Dashboard/Commerce/CommerceProductsAction.ts +50 -0
- package/app/Actions/Dashboard/Commerce/CommerceTaxesAction.ts +46 -0
- package/app/Actions/Dashboard/Commerce/PosIndexAction.ts +57 -0
- package/app/Actions/Dashboard/Commerce/ReviewIndexAction.ts +51 -0
- package/app/Actions/Dashboard/Content/AuthorIndexAction.ts +51 -0
- package/app/Actions/Dashboard/Content/CategoryIndexAction.ts +27 -0
- package/app/Actions/Dashboard/Content/CommentIndexAction.ts +41 -0
- package/app/Actions/Dashboard/Content/ContentDashboardAction.ts +54 -0
- package/app/Actions/Dashboard/Content/FileIndexAction.ts +24 -0
- package/app/Actions/Dashboard/Content/PageIndexAction.ts +25 -0
- package/app/Actions/Dashboard/Content/PostIndexAction.ts +102 -0
- package/app/Actions/Dashboard/Content/SeoIndexAction.ts +17 -0
- package/app/Actions/Dashboard/Content/TagIndexAction.ts +23 -0
- package/app/Actions/Dashboard/CreateDnsRecords.ts +11 -0
- package/app/Actions/Dashboard/CreateMailbox.ts +11 -0
- package/app/Actions/Dashboard/DashboardActivityAction.ts +58 -0
- package/app/Actions/Dashboard/DashboardHealthAction.ts +52 -0
- package/app/Actions/Dashboard/DashboardHomeAction.ts +83 -0
- package/app/Actions/Dashboard/DashboardStatsAction.ts +48 -0
- package/app/Actions/Dashboard/Data/AccessTokenIndexAction.ts +65 -0
- package/app/Actions/Dashboard/Data/ActivityIndexAction.ts +28 -0
- package/app/Actions/Dashboard/Data/DataDashboardAction.ts +67 -0
- package/app/Actions/Dashboard/Data/SubscriberIndexAction.ts +48 -0
- package/app/Actions/Dashboard/Data/TeamIndexAction.ts +43 -0
- package/app/Actions/Dashboard/Data/UserIndexAction.ts +48 -0
- package/app/Actions/Dashboard/Deployments/CreateDeployment.ts +11 -0
- package/app/Actions/Dashboard/Deployments/GetAverageDeploymentTime.ts +15 -0
- package/app/Actions/Dashboard/Deployments/GetDeployScript.ts +12 -0
- package/app/Actions/Dashboard/Deployments/GetDeploymentCount.ts +12 -0
- package/app/Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput.ts +12 -0
- package/app/Actions/Dashboard/Deployments/GetDeployments.ts +20 -0
- package/app/Actions/Dashboard/Deployments/GetRecentDeployments.ts +12 -0
- package/app/Actions/Dashboard/Deployments/UpdateDeployScript.ts +11 -0
- package/app/Actions/Dashboard/GetDnsRecords.ts +12 -0
- package/app/Actions/Dashboard/GetEmailInboxes.ts +12 -0
- package/app/Actions/Dashboard/GetProjects.ts +13 -0
- package/app/Actions/Dashboard/GetRecentCommits.ts +13 -0
- package/app/Actions/Dashboard/Inbox/InboxIndexAction.ts +144 -0
- package/app/Actions/Dashboard/Inbox/InboxShowAction.ts +89 -0
- package/app/Actions/Dashboard/Infrastructure/CommandIndexAction.ts +18 -0
- package/app/Actions/Dashboard/Infrastructure/DnsIndexAction.ts +101 -0
- package/app/Actions/Dashboard/Infrastructure/EnvironmentIndexAction.ts +67 -0
- package/app/Actions/Dashboard/Infrastructure/InsightsAction.ts +29 -0
- package/app/Actions/Dashboard/Infrastructure/LogIndexAction.ts +50 -0
- package/app/Actions/Dashboard/Infrastructure/MailboxIndexAction.ts +85 -0
- package/app/Actions/Dashboard/Infrastructure/PermissionIndexAction.ts +54 -0
- package/app/Actions/Dashboard/Infrastructure/RequestIndexAction.ts +44 -0
- package/app/Actions/Dashboard/Infrastructure/ServerIndexAction.ts +101 -0
- package/app/Actions/Dashboard/Jobs/CreateJob.ts +11 -0
- package/app/Actions/Dashboard/Jobs/GetAverageJobTime.ts +12 -0
- package/app/Actions/Dashboard/Jobs/GetJobHistory.ts +12 -0
- package/app/Actions/Dashboard/Jobs/GetJobs.ts +11 -0
- package/app/Actions/Dashboard/Jobs/GetJobsPerMinute.ts +12 -0
- package/app/Actions/Dashboard/Jobs/JobIndexAction.ts +136 -0
- package/app/Actions/Dashboard/Jobs/JobRetryAction.ts +23 -0
- package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +49 -0
- package/app/Actions/Dashboard/Kanban/BoardDestroyAction.ts +84 -0
- package/app/Actions/Dashboard/Kanban/BoardShowAction.ts +215 -0
- package/app/Actions/Dashboard/Kanban/BoardStoreAction.ts +98 -0
- package/app/Actions/Dashboard/Kanban/BoardUpdateAction.ts +96 -0
- package/app/Actions/Dashboard/Kanban/BoardsIndexAction.ts +81 -0
- package/app/Actions/Dashboard/Kanban/BoardsReorderAction.ts +80 -0
- package/app/Actions/Dashboard/Kanban/CardAssigneesSyncAction.ts +103 -0
- package/app/Actions/Dashboard/Kanban/CardCommentDestroyAction.ts +33 -0
- package/app/Actions/Dashboard/Kanban/CardCommentStoreAction.ts +82 -0
- package/app/Actions/Dashboard/Kanban/CardDestroyAction.ts +48 -0
- package/app/Actions/Dashboard/Kanban/CardLabelsSyncAction.ts +103 -0
- package/app/Actions/Dashboard/Kanban/CardShowAction.ts +122 -0
- package/app/Actions/Dashboard/Kanban/CardStoreAction.ts +112 -0
- package/app/Actions/Dashboard/Kanban/CardUpdateAction.ts +91 -0
- package/app/Actions/Dashboard/Kanban/CardsReorderAction.ts +148 -0
- package/app/Actions/Dashboard/Kanban/ColumnDestroyAction.ts +59 -0
- package/app/Actions/Dashboard/Kanban/ColumnStoreAction.ts +94 -0
- package/app/Actions/Dashboard/Kanban/ColumnUpdateAction.ts +89 -0
- package/app/Actions/Dashboard/Kanban/ColumnsReorderAction.ts +85 -0
- package/app/Actions/Dashboard/Kanban/LabelDestroyAction.ts +41 -0
- package/app/Actions/Dashboard/Kanban/LabelStoreAction.ts +70 -0
- package/app/Actions/Dashboard/Kanban/LabelUpdateAction.ts +83 -0
- package/app/Actions/Dashboard/Kanban/UsersListAction.ts +36 -0
- package/app/Actions/Dashboard/Library/CreateComponent.ts +11 -0
- package/app/Actions/Dashboard/Library/CreateFunction.ts +11 -0
- package/app/Actions/Dashboard/Library/DependencyIndexAction.ts +92 -0
- package/app/Actions/Dashboard/Library/GetAverageReleaseTime.ts +12 -0
- package/app/Actions/Dashboard/Library/GetComponents.ts +24 -0
- package/app/Actions/Dashboard/Library/GetComponentsDownloadCount.ts +12 -0
- package/app/Actions/Dashboard/Library/GetDownloadCount.ts +12 -0
- package/app/Actions/Dashboard/Library/GetFunctions.ts +22 -0
- package/app/Actions/Dashboard/Library/GetFunctionsDownloadCount.ts +12 -0
- package/app/Actions/Dashboard/Library/GetReleaseCount.ts +12 -0
- package/app/Actions/Dashboard/Library/GetReleases.ts +28 -0
- package/app/Actions/Dashboard/Library/PackageIndexAction.ts +26 -0
- package/app/Actions/Dashboard/Marketing/CampaignIndexAction.ts +45 -0
- package/app/Actions/Dashboard/Marketing/ListIndexAction.ts +43 -0
- package/app/Actions/Dashboard/Marketing/SocialPostIndexAction.ts +47 -0
- package/app/Actions/Dashboard/Models/GetModels.ts +39 -0
- package/app/Actions/Dashboard/Models/GetSubscriberCount.ts +12 -0
- package/app/Actions/Dashboard/Models/GetUserCount.ts +12 -0
- package/app/Actions/Dashboard/Models/ModelShowAction.ts +131 -0
- package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +169 -0
- package/app/Actions/Dashboard/Notifications/CreateNotification.ts +11 -0
- package/app/Actions/Dashboard/Notifications/GetAverageNotificationTime.ts +12 -0
- package/app/Actions/Dashboard/Notifications/GetNotificationCount.ts +12 -0
- package/app/Actions/Dashboard/Notifications/GetNotificationDeliveryRate.ts +12 -0
- package/app/Actions/Dashboard/Notifications/GetNotificationHistory.ts +12 -0
- package/app/Actions/Dashboard/Notifications/GetNotifications.ts +12 -0
- package/app/Actions/Dashboard/Notifications/NotificationDashboardAction.ts +43 -0
- package/app/Actions/Dashboard/Queries/QueryIndexAction.ts +22 -0
- package/app/Actions/Dashboard/Queue/QueueRetryFailedAction.ts +22 -0
- package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +98 -0
- package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +46 -0
- package/app/Actions/Dashboard/Rbac/PermissionDestroyAction.ts +33 -0
- package/app/Actions/Dashboard/Rbac/PermissionStoreAction.ts +53 -0
- package/app/Actions/Dashboard/Rbac/PermissionsIndexAction.ts +34 -0
- package/app/Actions/Dashboard/Rbac/RoleDestroyAction.ts +35 -0
- package/app/Actions/Dashboard/Rbac/RolePermissionsShowAction.ts +45 -0
- package/app/Actions/Dashboard/Rbac/RolePermissionsSyncAction.ts +63 -0
- package/app/Actions/Dashboard/Rbac/RoleStoreAction.ts +58 -0
- package/app/Actions/Dashboard/Rbac/RolesIndexAction.ts +36 -0
- package/app/Actions/Dashboard/Rbac/UserRolesShowAction.ts +40 -0
- package/app/Actions/Dashboard/Rbac/UserRolesSyncAction.ts +65 -0
- package/app/Actions/Dashboard/Rbac/UsersListAction.ts +39 -0
- package/app/Actions/Dashboard/Realtime/RealtimeStatsAction.ts +50 -0
- package/app/Actions/Dashboard/Releases/ReleaseIndexAction.ts +21 -0
- package/app/Actions/Dashboard/Requests/GetAverageRequestTime.ts +12 -0
- package/app/Actions/Dashboard/Requests/GetRequestCount.ts +12 -0
- package/app/Actions/Dashboard/Requests/GetRequestSuccessRate.ts +12 -0
- package/app/Actions/Dashboard/Requests/GetRequests.ts +12 -0
- package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +26 -0
- package/app/Actions/Dashboard/ServiceHealthAction.ts +243 -0
- package/app/Actions/Dashboard/Settings/MailSettingsGetAction.ts +20 -0
- package/app/Actions/Dashboard/Settings/MailSettingsUpdateAction.ts +10 -0
- package/app/Actions/Dashboard/Settings/SettingsIndexAction.ts +40 -0
- package/app/Actions/Dashboard/Settings/UpdateAiConfig.ts +27 -0
- package/app/Actions/Dashboard/Settings/UpdateAnalyticsConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateAppConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateCacheConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateCliConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateCloudConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateDatabaseConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateDnsConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateDocsConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateEmailConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateEnvConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateErrorsConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateFileSystemsConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateGitConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateHashingConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateLibraryConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateLoggerConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateNotificationConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdatePaymentConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdatePortsConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateQueueConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateSearchEngineConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateSecurityConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateServicesConfig.ts +38 -0
- package/app/Actions/Dashboard/Settings/UpdateStorageConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateTeamConfig.ts +11 -0
- package/app/Actions/Dashboard/Settings/UpdateUiConfig.ts +11 -0
- package/app/Actions/HealthAction.ts +112 -0
- package/app/Actions/InstallAction.ts +83 -0
- package/app/Actions/Locale/SetLocaleAction.ts +51 -0
- package/app/Actions/LogAction.ts +42 -0
- package/app/Actions/Logs/LogFetchStatsAction.ts +50 -0
- package/app/Actions/Logs/LogIndexOrmAction.ts +13 -0
- package/app/Actions/Logs/LogShowOrmAction.ts +17 -0
- package/app/Actions/Logs/LogStoreOrmAction.ts +16 -0
- package/app/Actions/Logs/LogUpdateOrmAction.ts +20 -0
- package/app/Actions/Monitoring/ErrorDestroyAction.ts +25 -0
- package/app/Actions/Monitoring/ErrorGroupAction.ts +21 -0
- package/app/Actions/Monitoring/ErrorIgnoreAction.ts +25 -0
- package/app/Actions/Monitoring/ErrorIndexAction.ts +14 -0
- package/app/Actions/Monitoring/ErrorResolveAction.ts +25 -0
- package/app/Actions/Monitoring/ErrorShowAction.ts +19 -0
- package/app/Actions/Monitoring/ErrorStatsAction.ts +14 -0
- package/app/Actions/Monitoring/ErrorTimelineAction.ts +14 -0
- package/app/Actions/Monitoring/ErrorUnresolveAction.ts +25 -0
- package/app/Actions/NotifyUser.ts +10 -0
- package/app/Actions/Password/PasswordResetAction.ts +54 -0
- package/app/Actions/Password/SendPasswordResetEmailAction.ts +66 -0
- package/app/Actions/Password/VerifyResetTokenAction.ts +27 -0
- package/app/Actions/Payment/CancelSubscriptionAction.ts +20 -0
- package/app/Actions/Payment/CreateCheckoutAction.ts +28 -0
- package/app/Actions/Payment/CreateInvoiceSubscription.ts +18 -0
- package/app/Actions/Payment/CreatePaymentIntentAction.ts +31 -0
- package/app/Actions/Payment/CreateSetupIntentAction.ts +20 -0
- package/app/Actions/Payment/CreateSubscriptionAction.ts +23 -0
- package/app/Actions/Payment/DeleteDefaultPaymentAction.ts +18 -0
- package/app/Actions/Payment/FetchActiveSubscriptionAction.ts +18 -0
- package/app/Actions/Payment/FetchDefaultPaymentMethodAction.ts +18 -0
- package/app/Actions/Payment/FetchPaymentCustomerAction.ts +18 -0
- package/app/Actions/Payment/FetchPaymentMethodsAction.ts +18 -0
- package/app/Actions/Payment/FetchProductAction.ts +15 -0
- package/app/Actions/Payment/FetchTransactionHistoryAction.ts +18 -0
- package/app/Actions/Payment/FetchUserSubscriptionsAction.ts +18 -0
- package/app/Actions/Payment/SetDefaultPaymentAction.ts +20 -0
- package/app/Actions/Payment/SetUserDefaultPaymentAction.ts +20 -0
- package/app/Actions/Payment/StorePaymentMethodAction.ts +20 -0
- package/app/Actions/Payment/StoreTransactionAction.ts +20 -0
- package/app/Actions/Payment/UpdateCustomerAction.ts +24 -0
- package/app/Actions/Payment/UpdateDefaultPaymentMethodAction.ts +18 -0
- package/app/Actions/Payment/UpdateSubscriptionAction.ts +22 -0
- package/app/Actions/Queue/FetchQueuesAction.ts +14 -0
- package/app/Actions/README.md +61 -0
- package/app/Actions/Realtime/FetchWebsocketsAction.ts +14 -0
- package/app/Actions/RobotsAction.ts +61 -0
- package/app/Actions/SendWelcomeEmail.ts +40 -0
- package/app/Actions/SitemapAction.ts +234 -0
- package/app/Actions/Storefront/AddToCartAction.ts +153 -0
- package/app/Actions/Storefront/CheckoutContactAction.ts +50 -0
- package/app/Actions/Storefront/CheckoutShippingAction.ts +61 -0
- package/app/Actions/Storefront/GetCartAction.ts +58 -0
- package/app/Actions/Storefront/PlaceOrderAction.ts +195 -0
- package/app/Actions/Storefront/SubmitReviewAction.ts +140 -0
- package/app/Actions/Storefront/UpdateCartItemAction.ts +83 -0
- package/app/Actions/Storefront/_shipping.ts +64 -0
- package/app/Actions/SubscriberEmailAction.ts +60 -0
- package/app/Actions/TestErrorAction.ts +163 -0
- package/app/Actions/UnsubscribeAction.ts +107 -0
- package/app/Actions/UploadTestAction.ts +57 -0
- package/app/Broadcasts/OrderShipped.ts +57 -0
- package/app/Commands/Inspire.ts +57 -0
- package/app/Commands/README.md +84 -0
- package/app/Commands.ts +38 -0
- package/app/Controllers/ComingSoonController.ts +9 -0
- package/app/Controllers/QueryController.ts +373 -0
- package/app/Events.ts +14 -0
- package/app/Gates.ts +107 -0
- package/app/Jobs/ExampleJob.ts +20 -0
- package/app/Jobs/ExampleTwoJob.ts +12 -0
- package/app/Jobs/PruneModelsJob.ts +61 -0
- package/app/Jobs/PruneQueryLogsJob.ts +51 -0
- package/app/Jobs/README.md +79 -0
- package/app/Jobs/SendCampaignJob.ts +201 -0
- package/app/Jobs/SendEmailJob.ts +52 -0
- package/app/Jobs/SendPasswordResetEmailJob.ts +44 -0
- package/app/Jobs/SyncSearchIndexJob.ts +64 -0
- package/app/Listener.ts +84 -0
- package/app/Listeners/Console.ts +22 -0
- package/app/Listeners/README.md +47 -0
- package/app/Mail/OrderConfirmation.ts +60 -0
- package/app/Mail/SubscriptionConfirmation.ts +41 -0
- package/app/Middleware/Abilities.ts +53 -0
- package/app/Middleware/Api.ts +26 -0
- package/app/Middleware/Auth.ts +59 -0
- package/app/Middleware/Can.ts +68 -0
- package/app/Middleware/Compress.ts +213 -0
- package/app/Middleware/Cors.ts +320 -0
- package/app/Middleware/Csrf.ts +224 -0
- package/app/Middleware/EnsureEmailIsVerified.ts +28 -0
- package/app/Middleware/Env.ts +24 -0
- package/app/Middleware/EnvDevelopment.ts +19 -0
- package/app/Middleware/EnvLocal.ts +19 -0
- package/app/Middleware/EnvNotDevelopment.ts +19 -0
- package/app/Middleware/EnvNotLocal.ts +19 -0
- package/app/Middleware/EnvNotProduction.ts +19 -0
- package/app/Middleware/EnvNotStaging.ts +19 -0
- package/app/Middleware/EnvProduction.ts +19 -0
- package/app/Middleware/EnvStaging.ts +19 -0
- package/app/Middleware/Guest.ts +25 -0
- package/app/Middleware/Logger.ts +20 -0
- package/app/Middleware/Maintenance.ts +36 -0
- package/app/Middleware/Permission.ts +42 -0
- package/app/Middleware/README.md +48 -0
- package/app/Middleware/Role.ts +42 -0
- package/app/Middleware/Signed.ts +31 -0
- package/app/Middleware/Team.ts +36 -0
- package/app/Middleware/Throttle.ts +96 -0
- package/app/Middleware.ts +35 -0
- package/app/Models/Activity.ts +94 -0
- package/app/Models/Board.ts +103 -0
- package/app/Models/BoardColumn.ts +87 -0
- package/app/Models/Campaign.ts +239 -0
- package/app/Models/CampaignSend.ts +107 -0
- package/app/Models/Card.ts +117 -0
- package/app/Models/CardComment.ts +68 -0
- package/app/Models/Comment.ts +108 -0
- package/app/Models/Content/Author.ts +104 -0
- package/app/Models/Content/Page.ts +99 -0
- package/app/Models/Content/Post.ts +144 -0
- package/app/Models/Deployment.ts +116 -0
- package/app/Models/EmailList.ts +126 -0
- package/app/Models/EmailListSubscriber.ts +91 -0
- package/app/Models/Error.ts +70 -0
- package/app/Models/FailedJob.ts +62 -0
- package/app/Models/Job.ts +63 -0
- package/app/Models/Label.ts +66 -0
- package/app/Models/Log.ts +110 -0
- package/app/Models/Notification.ts +118 -0
- package/app/Models/PaymentMethod.ts +98 -0
- package/app/Models/PaymentProduct.ts +91 -0
- package/app/Models/PaymentTransaction.ts +78 -0
- package/app/Models/README.md +31 -0
- package/app/Models/Release.ts +89 -0
- package/app/Models/Request.ts +114 -0
- package/app/Models/SocialPost.ts +136 -0
- package/app/Models/Subscriber.ts +89 -0
- package/app/Models/SubscriberEmail.ts +55 -0
- package/app/Models/Subscription.ts +153 -0
- package/app/Models/Tag.ts +82 -0
- package/app/Models/Team.ts +72 -0
- package/app/Models/User.ts +134 -0
- package/app/Models/commerce/Cart.ts +139 -0
- package/app/Models/commerce/CartItem.ts +137 -0
- package/app/Models/commerce/Category.ts +105 -0
- package/app/Models/commerce/Coupon.ts +181 -0
- package/app/Models/commerce/Customer.ts +132 -0
- package/app/Models/commerce/DeliveryRoute.ts +93 -0
- package/app/Models/commerce/DigitalDelivery.ts +105 -0
- package/app/Models/commerce/Driver.ts +97 -0
- package/app/Models/commerce/GiftCard.ts +191 -0
- package/app/Models/commerce/LicenseKey.ts +87 -0
- package/app/Models/commerce/LoyaltyPoint.ts +107 -0
- package/app/Models/commerce/LoyaltyReward.ts +124 -0
- package/app/Models/commerce/Manufacturer.ts +84 -0
- package/app/Models/commerce/Order.ts +142 -0
- package/app/Models/commerce/OrderItem.ts +51 -0
- package/app/Models/commerce/Payment.ts +163 -0
- package/app/Models/commerce/PrintDevice.ts +117 -0
- package/app/Models/commerce/Product.ts +148 -0
- package/app/Models/commerce/ProductUnit.ts +107 -0
- package/app/Models/commerce/ProductVariant.ts +106 -0
- package/app/Models/commerce/Receipt.ts +128 -0
- package/app/Models/commerce/Review.ts +140 -0
- package/app/Models/commerce/ShippingMethod.ts +97 -0
- package/app/Models/commerce/ShippingRate.ts +74 -0
- package/app/Models/commerce/ShippingZone.ts +111 -0
- package/app/Models/commerce/TaxRate.ts +114 -0
- package/app/Models/commerce/Transaction.ts +126 -0
- package/app/Models/commerce/WaitlistProduct.ts +149 -0
- package/app/Models/commerce/WaitlistRestaurant.ts +187 -0
- package/app/Models/realtime/Websocket.ts +77 -0
- package/app/Notifications/README.md +31 -0
- package/app/Notifications/Welcome.ts +32 -0
- package/app/Policies/PostPolicy.ts +131 -0
- package/app/README.md +23 -0
- package/app/Routes.ts +47 -0
- package/app/Scheduler.ts +28 -0
- package/app/Storefront/CartCookie.ts +109 -0
- package/package.json +3 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Action } from '@stacksjs/actions'
|
|
2
|
+
import { db } from '@stacksjs/database'
|
|
3
|
+
import { response } from '@stacksjs/router'
|
|
4
|
+
import { readCartCookie } from '../../Storefront/CartCookie'
|
|
5
|
+
|
|
6
|
+
const CART_COOKIE = 'stacks_cart'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Change the quantity of a cart line, or remove it (quantity=0).
|
|
10
|
+
* Scoped by the caller's cart cookie so one shopper can't poke at
|
|
11
|
+
* another's cart by guessing item ids.
|
|
12
|
+
*/
|
|
13
|
+
export default new Action({
|
|
14
|
+
name: 'UpdateCartItemAction',
|
|
15
|
+
description: 'Update or remove a cart item by id, scoped to caller cookie.',
|
|
16
|
+
method: 'POST',
|
|
17
|
+
|
|
18
|
+
async handle(request: any) {
|
|
19
|
+
const itemId = Number(request.get('item_id') ?? 0)
|
|
20
|
+
const quantity = Math.max(0, Math.min(99, Number(request.get('quantity') ?? 1)))
|
|
21
|
+
|
|
22
|
+
// HMAC-verified cookie. Tampered tokens look like "no cookie" so
|
|
23
|
+
// an attacker can't probe for the existence of arbitrary carts.
|
|
24
|
+
const token = readCartCookie(request, CART_COOKIE)
|
|
25
|
+
if (!token)
|
|
26
|
+
return response.json({ error: 'No active cart' }, { status: 400 })
|
|
27
|
+
|
|
28
|
+
const cart = await (db as any)
|
|
29
|
+
.selectFrom('carts')
|
|
30
|
+
.where('session_token', '=', token)
|
|
31
|
+
.selectAll()
|
|
32
|
+
.executeTakeFirst()
|
|
33
|
+
|
|
34
|
+
if (!cart)
|
|
35
|
+
return response.json({ error: 'Cart not found' }, { status: 404 })
|
|
36
|
+
|
|
37
|
+
const item = await (db as any)
|
|
38
|
+
.selectFrom('cart_items')
|
|
39
|
+
.where('id', '=', itemId)
|
|
40
|
+
.where('cart_id', '=', cart.id)
|
|
41
|
+
.selectAll()
|
|
42
|
+
.executeTakeFirst()
|
|
43
|
+
|
|
44
|
+
if (!item)
|
|
45
|
+
return response.json({ error: 'Item not in your cart' }, { status: 404 })
|
|
46
|
+
|
|
47
|
+
if (quantity === 0) {
|
|
48
|
+
await (db as any).deleteFrom('cart_items').where('id', '=', item.id).execute()
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await (db as any)
|
|
52
|
+
.updateTable('cart_items')
|
|
53
|
+
.set({
|
|
54
|
+
quantity,
|
|
55
|
+
total_price: quantity * Number(item.unit_price),
|
|
56
|
+
})
|
|
57
|
+
.where('id', '=', item.id)
|
|
58
|
+
.execute()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const items = await (db as any)
|
|
62
|
+
.selectFrom('cart_items')
|
|
63
|
+
.where('cart_id', '=', cart.id)
|
|
64
|
+
.selectAll()
|
|
65
|
+
.execute()
|
|
66
|
+
|
|
67
|
+
const totalItems = items.reduce((s: number, i: any) => s + Number(i.quantity), 0)
|
|
68
|
+
const subtotal = items.reduce((s: number, i: any) => s + Number(i.total_price || 0), 0)
|
|
69
|
+
|
|
70
|
+
await (db as any)
|
|
71
|
+
.updateTable('carts')
|
|
72
|
+
.set({ total_items: totalItems, subtotal, total: subtotal })
|
|
73
|
+
.where('id', '=', cart.id)
|
|
74
|
+
.execute()
|
|
75
|
+
|
|
76
|
+
const wantsHtml = (request.headers?.get?.('accept') || '').includes('text/html')
|
|
77
|
+
const xhr = request.headers?.get?.('x-requested-with') === 'XMLHttpRequest'
|
|
78
|
+
if (wantsHtml && !xhr)
|
|
79
|
+
return response.redirect('/cart')
|
|
80
|
+
|
|
81
|
+
return response.json({ ok: true, total_items: totalItems, subtotal })
|
|
82
|
+
},
|
|
83
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipping rules used by both the cart view and the place-order action.
|
|
3
|
+
*
|
|
4
|
+
* Centralized so a copy in cart.stx and another in PlaceOrderAction.ts
|
|
5
|
+
* can't drift — when finance changes "free shipping over $40" to
|
|
6
|
+
* "free over $50" you don't want one of the two surfaces (the price
|
|
7
|
+
* the shopper sees vs. the total they're charged) to lag the other.
|
|
8
|
+
*
|
|
9
|
+
* Override per-app by setting `STOREFRONT_FREE_SHIPPING_THRESHOLD` and
|
|
10
|
+
* `STOREFRONT_FLAT_SHIPPING` in the environment, or by editing this
|
|
11
|
+
* file in the application's own `app/Actions/Storefront/_shipping.ts`
|
|
12
|
+
* if the rule needs more logic than two numbers (per-region, weight-
|
|
13
|
+
* based, etc.).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const DEFAULT_FREE_SHIPPING_THRESHOLD = 40
|
|
17
|
+
const DEFAULT_FLAT_SHIPPING = 5
|
|
18
|
+
|
|
19
|
+
export const FREE_SHIPPING_THRESHOLD = numFromEnv(
|
|
20
|
+
'STOREFRONT_FREE_SHIPPING_THRESHOLD',
|
|
21
|
+
DEFAULT_FREE_SHIPPING_THRESHOLD,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
export const FLAT_SHIPPING = numFromEnv(
|
|
25
|
+
'STOREFRONT_FLAT_SHIPPING',
|
|
26
|
+
DEFAULT_FLAT_SHIPPING,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compute the shipping fee for a given subtotal. Empty cart → 0,
|
|
31
|
+
* otherwise free at/above the threshold, otherwise the flat rate.
|
|
32
|
+
*/
|
|
33
|
+
export function shippingFor(subtotal: number): number {
|
|
34
|
+
if (!Number.isFinite(subtotal) || subtotal <= 0)
|
|
35
|
+
return 0
|
|
36
|
+
if (subtotal >= FREE_SHIPPING_THRESHOLD)
|
|
37
|
+
return 0
|
|
38
|
+
return FLAT_SHIPPING
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Return `{ subtotal, shipping, total }` for a given subtotal — the
|
|
43
|
+
* shape both the cart view and the place-order action want, with the
|
|
44
|
+
* shipping rule applied consistently.
|
|
45
|
+
*/
|
|
46
|
+
export function totalsFor(subtotal: number): {
|
|
47
|
+
subtotal: number
|
|
48
|
+
shipping: number
|
|
49
|
+
total: number
|
|
50
|
+
} {
|
|
51
|
+
const sub = Number.isFinite(subtotal) ? subtotal : 0
|
|
52
|
+
const shipping = shippingFor(sub)
|
|
53
|
+
return { subtotal: sub, shipping, total: sub + shipping }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function numFromEnv(name: string, fallback: number): number {
|
|
57
|
+
const raw = (typeof process !== 'undefined' && process.env)
|
|
58
|
+
? process.env[name]
|
|
59
|
+
: undefined
|
|
60
|
+
if (raw === undefined || raw === '')
|
|
61
|
+
return fallback
|
|
62
|
+
const parsed = Number(raw)
|
|
63
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback
|
|
64
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Action } from '@stacksjs/actions'
|
|
2
|
+
import { isUniqueViolation, Subscriber, SubscriberEmail } from '@stacksjs/orm'
|
|
3
|
+
import { rateLimit } from '@stacksjs/router'
|
|
4
|
+
import { sendSubscriptionConfirmation } from '../Mail/SubscriptionConfirmation'
|
|
5
|
+
|
|
6
|
+
export default new Action({
|
|
7
|
+
name: 'SubscriberEmailAction',
|
|
8
|
+
description: 'Save emails from subscribe page and send confirmation email',
|
|
9
|
+
method: 'POST',
|
|
10
|
+
|
|
11
|
+
async handle(request: RequestInstance) {
|
|
12
|
+
// Per-IP throttle. The endpoint is unauthenticated and skipCsrf'd so
|
|
13
|
+
// bots will find it; without this they can flood the subscribers
|
|
14
|
+
// table within minutes and burn through SES/SendGrid quota. 10/min
|
|
15
|
+
// is generous for a real human filling the same form repeatedly.
|
|
16
|
+
await rateLimit('email-subscribe', 10).per('minute')
|
|
17
|
+
|
|
18
|
+
const email = request.get('email')
|
|
19
|
+
const source = request.get('source') || 'homepage'
|
|
20
|
+
|
|
21
|
+
if (!email || !email.includes('@')) {
|
|
22
|
+
return { success: false, message: 'A valid email is required' }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Check if subscriber already exists
|
|
26
|
+
const existingSubscriber = await Subscriber.where('email', email).first()
|
|
27
|
+
if (existingSubscriber) {
|
|
28
|
+
return { success: true, message: 'Already subscribed' }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Create subscriber record. The check above is a fast path; two requests
|
|
32
|
+
// for the same email can still both pass it and race into the
|
|
33
|
+
// subscribers.email unique index (#1957). Treat the loser's unique
|
|
34
|
+
// violation as the same "already subscribed" success — the response
|
|
35
|
+
// contract (and its enumeration semantics) is unchanged.
|
|
36
|
+
let subscriber: any
|
|
37
|
+
try {
|
|
38
|
+
subscriber = await Subscriber.create({ email, status: 'subscribed', source })
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (isUniqueViolation(err))
|
|
42
|
+
return { success: true, message: 'Already subscribed' }
|
|
43
|
+
throw err
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Log the email event
|
|
47
|
+
await SubscriberEmail.create({ email, source })
|
|
48
|
+
|
|
49
|
+
// Send subscription confirmation email asynchronously (do not block the response)
|
|
50
|
+
sendSubscriptionConfirmation({
|
|
51
|
+
to: email,
|
|
52
|
+
subscriberUuid: subscriber.uuid,
|
|
53
|
+
}).catch((err: unknown) => {
|
|
54
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
55
|
+
console.error(`Failed to send confirmation email to ${email}:`, message)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
return { success: true, subscriber }
|
|
59
|
+
},
|
|
60
|
+
})
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Error Action
|
|
3
|
+
*
|
|
4
|
+
* Browse /test-error for a visual index of every error scenario.
|
|
5
|
+
* Append ?type=<scenario> to trigger a specific exception.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { EnhancedRequest } from 'bun-router'
|
|
9
|
+
import { dirname, join } from 'node:path'
|
|
10
|
+
import process from 'node:process'
|
|
11
|
+
import { fileURLToPath } from 'node:url'
|
|
12
|
+
|
|
13
|
+
class DatabaseError extends Error {
|
|
14
|
+
constructor(message: string, public query?: string) {
|
|
15
|
+
super(message)
|
|
16
|
+
this.name = 'DatabaseError'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class ValidationError extends Error {
|
|
21
|
+
constructor(message: string, public field?: string) {
|
|
22
|
+
super(message)
|
|
23
|
+
this.name = 'ValidationError'
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const ERROR_SCENARIOS = [
|
|
28
|
+
{
|
|
29
|
+
type: 'database',
|
|
30
|
+
title: 'DatabaseError',
|
|
31
|
+
description: 'Deep call stack with a missing-table SQL error — shows code snippets and collapsed framework frames.',
|
|
32
|
+
status: 500,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'validation',
|
|
36
|
+
title: 'ValidationError',
|
|
37
|
+
description: '422-style validation failure with a field hint.',
|
|
38
|
+
status: 422,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'auth',
|
|
42
|
+
title: 'AuthenticationError',
|
|
43
|
+
description: 'Unauthorized access with an expired token message.',
|
|
44
|
+
status: 401,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'notfound',
|
|
48
|
+
title: 'NotFoundError',
|
|
49
|
+
description: 'Missing resource — useful for testing 404-style traces.',
|
|
50
|
+
status: 404,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'generic',
|
|
54
|
+
title: 'Error',
|
|
55
|
+
description: 'Plain unhandled exception with a minimal stack.',
|
|
56
|
+
status: 500,
|
|
57
|
+
},
|
|
58
|
+
] as const
|
|
59
|
+
|
|
60
|
+
function innerDatabaseCall(): never {
|
|
61
|
+
throw new DatabaseError(
|
|
62
|
+
`SQLSTATE[42S02]: Base table or view not found: 1146 Table 'app.nonexistent_table' doesn't exist`,
|
|
63
|
+
`SELECT * FROM nonexistent_table WHERE id = 1`,
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function queryBuilder() {
|
|
68
|
+
return innerDatabaseCall()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function repository() {
|
|
72
|
+
return queryBuilder()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function service() {
|
|
76
|
+
return repository()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function renderPreviewIndex(requestUrl: string): Promise<Response> {
|
|
80
|
+
const base = new URL(requestUrl)
|
|
81
|
+
base.search = ''
|
|
82
|
+
|
|
83
|
+
const scenarios = ERROR_SCENARIOS.map(s => ({
|
|
84
|
+
...s,
|
|
85
|
+
href: `${base.pathname}?type=${s.type}`,
|
|
86
|
+
}))
|
|
87
|
+
|
|
88
|
+
const viewsRoot = join(dirname(fileURLToPath(import.meta.url)), '../../resources/views/errors')
|
|
89
|
+
const { renderTemplate } = await import('@stacksjs/stx')
|
|
90
|
+
const body = await renderTemplate(join(viewsRoot, 'tester.stx'), {
|
|
91
|
+
context: { scenarios },
|
|
92
|
+
injectCSS: true,
|
|
93
|
+
templateOnly: true,
|
|
94
|
+
processClientScripts: false,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
const html = `<!DOCTYPE html>
|
|
98
|
+
<html lang="en">
|
|
99
|
+
<head>
|
|
100
|
+
<meta charset="UTF-8">
|
|
101
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
102
|
+
<title>Error Page Tester — Stacks</title>
|
|
103
|
+
</head>
|
|
104
|
+
<body class="min-h-dvh antialiased font-sans dark:text-white bg-neutral-50 dark:bg-neutral-900 scheme-light-dark">
|
|
105
|
+
${body}
|
|
106
|
+
</body>
|
|
107
|
+
</html>`
|
|
108
|
+
|
|
109
|
+
return new Response(html, {
|
|
110
|
+
status: 200,
|
|
111
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default {
|
|
116
|
+
name: 'Test Error Action',
|
|
117
|
+
description: 'Demonstrates the Laravel-style error page',
|
|
118
|
+
|
|
119
|
+
async handle(request: EnhancedRequest): Promise<Response> {
|
|
120
|
+
// Production short-circuits to 404 so even an accidental or userland
|
|
121
|
+
// re-registration can't expose the exception generator in prod —
|
|
122
|
+
// mirrors the mailable-preview guard in defaults/routes/core.ts
|
|
123
|
+
// (stacksjs/stacks#1900 A3; added for #1955). Production-only (not
|
|
124
|
+
// the registration gate's local-env allowlist) so a deliberate
|
|
125
|
+
// re-registration in staging still works.
|
|
126
|
+
const env = (process.env.APP_ENV ?? process.env.NODE_ENV ?? '').toLowerCase()
|
|
127
|
+
if (env === 'production')
|
|
128
|
+
return new Response('Not Found', { status: 404 })
|
|
129
|
+
|
|
130
|
+
const url = new URL(request.url)
|
|
131
|
+
const errorType = url.searchParams.get('type')
|
|
132
|
+
|
|
133
|
+
if (!errorType) {
|
|
134
|
+
return await renderPreviewIndex(request.url)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
switch (errorType) {
|
|
138
|
+
case 'validation':
|
|
139
|
+
throw new ValidationError('The email field must be a valid email address.', 'email')
|
|
140
|
+
|
|
141
|
+
case 'auth': {
|
|
142
|
+
const authError = new Error('Unauthorized: Invalid or expired authentication token.')
|
|
143
|
+
authError.name = 'AuthenticationError'
|
|
144
|
+
throw authError
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
case 'notfound': {
|
|
148
|
+
const notFoundError = new Error('Resource not found: User with ID 42 does not exist.')
|
|
149
|
+
notFoundError.name = 'NotFoundError'
|
|
150
|
+
throw notFoundError
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'generic':
|
|
154
|
+
throw new Error('Something went wrong while processing your request.')
|
|
155
|
+
|
|
156
|
+
case 'database':
|
|
157
|
+
default:
|
|
158
|
+
service()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return Response.json({ message: 'No error occurred' })
|
|
162
|
+
},
|
|
163
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Action } from '@stacksjs/actions'
|
|
2
|
+
import { EmailList, EmailListSubscriber, Subscriber } from '@stacksjs/orm'
|
|
3
|
+
|
|
4
|
+
export default new Action({
|
|
5
|
+
name: 'UnsubscribeAction',
|
|
6
|
+
description: 'Handle email unsubscription via token (subscriber UUID or per-list pivot UUID)',
|
|
7
|
+
method: 'GET',
|
|
8
|
+
|
|
9
|
+
async handle(request: RequestInstance) {
|
|
10
|
+
const token = request.get('token')
|
|
11
|
+
|
|
12
|
+
if (!token) {
|
|
13
|
+
return new Response(unsubscribePage('Missing token', 'The unsubscribe link is invalid.', false), {
|
|
14
|
+
headers: { 'Content-Type': 'text/html' },
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Two flavors of token can land here:
|
|
19
|
+
// 1. EmailListSubscriber.uuid → per-list (newsletter) unsubscribe.
|
|
20
|
+
// We only flip this one row; other lists + transactional mail
|
|
21
|
+
// keep flowing.
|
|
22
|
+
// 2. Subscriber.uuid → legacy global unsubscribe (drops every list).
|
|
23
|
+
//
|
|
24
|
+
// We try the per-list pivot first because it's the safer scope —
|
|
25
|
+
// if a recipient kept an old link around, we'd rather honor it as
|
|
26
|
+
// a single-list unsubscribe than nuke their entire subscription.
|
|
27
|
+
// UUIDs are universally unique so the lookups never collide.
|
|
28
|
+
try {
|
|
29
|
+
const pivot = await EmailListSubscriber.where('uuid', token).first()
|
|
30
|
+
|
|
31
|
+
if (pivot) {
|
|
32
|
+
const subscriber = await Subscriber.find(pivot.subscriber_id)
|
|
33
|
+
const list = await EmailList.find(pivot.email_list_id)
|
|
34
|
+
const listName = list?.name ?? 'this list'
|
|
35
|
+
|
|
36
|
+
if (pivot.status === 'unsubscribed') {
|
|
37
|
+
return new Response(unsubscribePage('Already unsubscribed', `${subscriber?.email ?? 'You'} has already been unsubscribed from ${listName}.`, true), {
|
|
38
|
+
headers: { 'Content-Type': 'text/html' },
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await pivot.update({
|
|
43
|
+
status: 'unsubscribed',
|
|
44
|
+
unsubscribed_at: new Date().toISOString(),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return new Response(unsubscribePage('Unsubscribed', `${subscriber?.email ?? 'You'} has been successfully unsubscribed from ${listName}. You will no longer receive emails from this list.`, true), {
|
|
48
|
+
headers: { 'Content-Type': 'text/html' },
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const subscriber = await Subscriber.where('uuid', token).first()
|
|
53
|
+
|
|
54
|
+
if (!subscriber) {
|
|
55
|
+
return new Response(unsubscribePage('Invalid link', 'This unsubscribe link is invalid or has already been used.', false), {
|
|
56
|
+
headers: { 'Content-Type': 'text/html' },
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (subscriber.status === 'unsubscribed') {
|
|
61
|
+
return new Response(unsubscribePage('Already unsubscribed', `${subscriber.email} has already been unsubscribed.`, true), {
|
|
62
|
+
headers: { 'Content-Type': 'text/html' },
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
await subscriber.update({
|
|
67
|
+
status: 'unsubscribed',
|
|
68
|
+
unsubscribed_at: new Date().toISOString(),
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return new Response(unsubscribePage('Unsubscribed', `${subscriber.email} has been successfully unsubscribed. You will no longer receive emails from us.`, true), {
|
|
72
|
+
headers: { 'Content-Type': 'text/html' },
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
catch (error: unknown) {
|
|
76
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
77
|
+
console.error('Unsubscribe error:', message)
|
|
78
|
+
return new Response(unsubscribePage('Error', 'Something went wrong. Please try again later.', false), {
|
|
79
|
+
headers: { 'Content-Type': 'text/html' },
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
function unsubscribePage(title: string, message: string, success: boolean): string {
|
|
86
|
+
const icon = success ? '✓' : '✗'
|
|
87
|
+
const iconColor = success ? '#22c55e' : '#ef4444'
|
|
88
|
+
|
|
89
|
+
return `<!DOCTYPE html>
|
|
90
|
+
<html lang="en">
|
|
91
|
+
<head>
|
|
92
|
+
<meta charset="UTF-8">
|
|
93
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
94
|
+
<title>${title}</title>
|
|
95
|
+
</head>
|
|
96
|
+
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #0e0e0e; color: #d4d4d4; display: flex; align-items: center; justify-content: center; min-height: 100vh;">
|
|
97
|
+
<div style="max-width: 480px; margin: 0 auto; padding: 40px 20px; text-align: center;">
|
|
98
|
+
<div style="width: 64px; height: 64px; border-radius: 50%; background-color: ${iconColor}20; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 24px;">
|
|
99
|
+
<span style="font-size: 28px; color: ${iconColor};">${icon}</span>
|
|
100
|
+
</div>
|
|
101
|
+
<h1 style="color: #ececec; font-size: 24px; font-weight: 600; margin: 0 0 12px;">${title}</h1>
|
|
102
|
+
<p style="color: #a0a0a0; font-size: 16px; line-height: 1.6; margin: 0 0 32px;">${message}</p>
|
|
103
|
+
<a href="https://stacksjs.com" style="color: #888; font-size: 13px; text-decoration: none;">stacksjs.com</a>
|
|
104
|
+
</div>
|
|
105
|
+
</body>
|
|
106
|
+
</html>`
|
|
107
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Action } from '@stacksjs/actions'
|
|
2
|
+
import { Storage } from '@stacksjs/storage'
|
|
3
|
+
|
|
4
|
+
interface Request {
|
|
5
|
+
file: (key: string) => any
|
|
6
|
+
hasFile: (key: string) => boolean
|
|
7
|
+
get: (key: string, defaultValue?: any) => any
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default new Action({
|
|
11
|
+
name: 'Upload Test',
|
|
12
|
+
description: 'Test file upload to public directory',
|
|
13
|
+
|
|
14
|
+
async handle(request?: Request) {
|
|
15
|
+
if (!request) {
|
|
16
|
+
return { success: false, message: 'No request provided' }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Check if file was uploaded
|
|
20
|
+
if (!request.hasFile('file')) {
|
|
21
|
+
return { success: false, message: 'No file uploaded' }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const file = request.file('file')
|
|
25
|
+
if (!file) {
|
|
26
|
+
return { success: false, message: 'File is empty' }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get optional directory from request
|
|
30
|
+
const directory = request.get('directory', 'uploads')
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Store to public directory using UploadedFile methods
|
|
34
|
+
const path = await file.storePublicly(directory)
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
message: 'File uploaded successfully',
|
|
39
|
+
data: {
|
|
40
|
+
path,
|
|
41
|
+
name: file.name,
|
|
42
|
+
size: file.getSize(),
|
|
43
|
+
mimeType: file.mimeType,
|
|
44
|
+
extension: file.extension,
|
|
45
|
+
isImage: file.isImage(),
|
|
46
|
+
url: `/storage/${path}`,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
message: error instanceof Error ? error.message : 'Upload failed',
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { RealtimeInstance } from '@stacksjs/types'
|
|
2
|
+
import { channel } from '@stacksjs/realtime'
|
|
3
|
+
|
|
4
|
+
interface OrderData {
|
|
5
|
+
orderId: string
|
|
6
|
+
userId: string
|
|
7
|
+
products: Array<{
|
|
8
|
+
id: string
|
|
9
|
+
name: string
|
|
10
|
+
quantity: number
|
|
11
|
+
}>
|
|
12
|
+
totalAmount: number
|
|
13
|
+
shippingAddress: {
|
|
14
|
+
street: string
|
|
15
|
+
city: string
|
|
16
|
+
country: string
|
|
17
|
+
postalCode: string
|
|
18
|
+
}
|
|
19
|
+
shippedAt?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
/**
|
|
24
|
+
* The event name.
|
|
25
|
+
*/
|
|
26
|
+
event: 'OrderShipped',
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Handle the broadcast event.
|
|
30
|
+
* This method is called when the event is triggered.
|
|
31
|
+
*/
|
|
32
|
+
async handle(data: OrderData): Promise<void> {
|
|
33
|
+
await channel(`orders.${data.orderId}`).private(this.event, data)
|
|
34
|
+
},
|
|
35
|
+
} satisfies RealtimeInstance
|
|
36
|
+
|
|
37
|
+
// Usage example:
|
|
38
|
+
/*
|
|
39
|
+
const orderData = {
|
|
40
|
+
orderId: '12345',
|
|
41
|
+
userId: 'user_123',
|
|
42
|
+
products: [
|
|
43
|
+
{ id: 'prod_1', name: 'Widget', quantity: 2 },
|
|
44
|
+
{ id: 'prod_2', name: 'Gadget', quantity: 1 },
|
|
45
|
+
],
|
|
46
|
+
totalAmount: 99.99,
|
|
47
|
+
shippingAddress: {
|
|
48
|
+
street: '123 Main St',
|
|
49
|
+
city: 'Anytown',
|
|
50
|
+
country: 'USA',
|
|
51
|
+
postalCode: '12345',
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Trigger the broadcast
|
|
56
|
+
await broadcast('OrderShipped', orderData)
|
|
57
|
+
*/
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CLI } from '@stacksjs/types'
|
|
2
|
+
// triggered via `$your-cli inspire` and `buddy inspire`
|
|
3
|
+
import process from 'node:process'
|
|
4
|
+
import { log, quotes } from '@stacksjs/cli'
|
|
5
|
+
import { ExitCode } from '@stacksjs/types'
|
|
6
|
+
|
|
7
|
+
// for enhanced type-safety & autocompletion,
|
|
8
|
+
// you may want to define the options' interface
|
|
9
|
+
interface InspireOptions {
|
|
10
|
+
two: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function (cli: CLI) {
|
|
14
|
+
cli
|
|
15
|
+
.command('inspire', 'Inspire yourself with a random quote')
|
|
16
|
+
.option('--two, -t', 'Inspire yourself with two random quotes', {
|
|
17
|
+
default: false,
|
|
18
|
+
})
|
|
19
|
+
.alias('insp')
|
|
20
|
+
.action((options: InspireOptions) => {
|
|
21
|
+
try {
|
|
22
|
+
if (options.two) {
|
|
23
|
+
const randomQuotes = quotes.random(2)
|
|
24
|
+
randomQuotes.toArray().forEach((quote: string, index: number) => {
|
|
25
|
+
console.log(`${index + 1}. ${quote}`)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const quote = quotes.random(1).first()
|
|
30
|
+
console.log(`\n"${quote}"\n`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log('✓ Have a great day!')
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Error:', error)
|
|
37
|
+
}
|
|
38
|
+
process.exit(ExitCode.Success)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
cli.command('inspire:two', 'Inspire yourself with two random quotes').action(() => {
|
|
42
|
+
console.log('')
|
|
43
|
+
quotes.random(2).toArray().forEach((quote: string, index: number) => {
|
|
44
|
+
console.log(`${index + 1}. "${quote}"`)
|
|
45
|
+
})
|
|
46
|
+
console.log('')
|
|
47
|
+
console.log('✓ Have a great day!')
|
|
48
|
+
process.exit(ExitCode.Success)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
cli.on('inspire:*', () => {
|
|
52
|
+
log.error('Invalid command: %s\nSee --help for a list of available commands.', cli.args.join(' '))
|
|
53
|
+
process.exit(1)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
return cli // TODO: this may not be needed
|
|
57
|
+
}
|