@stacksjs/defaults 0.70.206 → 0.70.208
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/TODO.md +21 -0
- package/ai/AGENTS.md +79 -0
- package/ai/README.md +45 -0
- package/ai/claude/launch.json +12 -0
- package/ai/skills/stacks-actions/SKILL.md +128 -0
- package/ai/skills/stacks-ai/SKILL.md +276 -0
- package/ai/skills/stacks-alias/SKILL.md +94 -0
- package/ai/skills/stacks-analytics/SKILL.md +91 -0
- package/ai/skills/stacks-api/SKILL.md +738 -0
- package/ai/skills/stacks-arrays/SKILL.md +277 -0
- package/ai/skills/stacks-auth/SKILL.md +422 -0
- package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
- package/ai/skills/stacks-brandkit/SKILL.md +811 -0
- package/ai/skills/stacks-browse/SKILL.md +127 -0
- package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
- package/ai/skills/stacks-browser/SKILL.md +145 -0
- package/ai/skills/stacks-buddy/SKILL.md +676 -0
- package/ai/skills/stacks-build/SKILL.md +163 -0
- package/ai/skills/stacks-cache/SKILL.md +125 -0
- package/ai/skills/stacks-calendar/SKILL.md +113 -0
- package/ai/skills/stacks-chat/SKILL.md +371 -0
- package/ai/skills/stacks-cli/SKILL.md +112 -0
- package/ai/skills/stacks-cloud/SKILL.md +192 -0
- package/ai/skills/stacks-cms/SKILL.md +217 -0
- package/ai/skills/stacks-collections/SKILL.md +82 -0
- package/ai/skills/stacks-commerce/SKILL.md +114 -0
- package/ai/skills/stacks-composables/SKILL.md +161 -0
- package/ai/skills/stacks-config/SKILL.md +144 -0
- package/ai/skills/stacks-configuration/SKILL.md +154 -0
- package/ai/skills/stacks-cron/SKILL.md +123 -0
- package/ai/skills/stacks-crosswind/SKILL.md +190 -0
- package/ai/skills/stacks-dashboard/SKILL.md +173 -0
- package/ai/skills/stacks-database/SKILL.md +286 -0
- package/ai/skills/stacks-datetime/SKILL.md +269 -0
- package/ai/skills/stacks-dependencies/SKILL.md +111 -0
- package/ai/skills/stacks-deploy/SKILL.md +102 -0
- package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
- package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
- package/ai/skills/stacks-design-output/SKILL.md +55 -0
- package/ai/skills/stacks-design-soft/SKILL.md +156 -0
- package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
- package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
- package/ai/skills/stacks-desktop/SKILL.md +78 -0
- package/ai/skills/stacks-development/SKILL.md +298 -0
- package/ai/skills/stacks-dns/SKILL.md +149 -0
- package/ai/skills/stacks-docs/SKILL.md +109 -0
- package/ai/skills/stacks-email/SKILL.md +236 -0
- package/ai/skills/stacks-enums/SKILL.md +100 -0
- package/ai/skills/stacks-env/SKILL.md +181 -0
- package/ai/skills/stacks-error-handling/SKILL.md +137 -0
- package/ai/skills/stacks-events/SKILL.md +228 -0
- package/ai/skills/stacks-faker/SKILL.md +158 -0
- package/ai/skills/stacks-git/SKILL.md +158 -0
- package/ai/skills/stacks-guard/SKILL.md +98 -0
- package/ai/skills/stacks-health/SKILL.md +75 -0
- package/ai/skills/stacks-http/SKILL.md +316 -0
- package/ai/skills/stacks-i18n/SKILL.md +198 -0
- package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
- package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
- package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
- package/ai/skills/stacks-investigate/SKILL.md +119 -0
- package/ai/skills/stacks-jobs/SKILL.md +136 -0
- package/ai/skills/stacks-lint/SKILL.md +184 -0
- package/ai/skills/stacks-listeners/SKILL.md +99 -0
- package/ai/skills/stacks-logging/SKILL.md +78 -0
- package/ai/skills/stacks-mail/SKILL.md +120 -0
- package/ai/skills/stacks-middleware/SKILL.md +249 -0
- package/ai/skills/stacks-migrations/SKILL.md +105 -0
- package/ai/skills/stacks-models/SKILL.md +267 -0
- package/ai/skills/stacks-new-feature/SKILL.md +206 -0
- package/ai/skills/stacks-notifications/SKILL.md +210 -0
- package/ai/skills/stacks-objects/SKILL.md +205 -0
- package/ai/skills/stacks-office-hours/SKILL.md +134 -0
- package/ai/skills/stacks-orm/SKILL.md +342 -0
- package/ai/skills/stacks-path/SKILL.md +118 -0
- package/ai/skills/stacks-payments/SKILL.md +373 -0
- package/ai/skills/stacks-plan-review/SKILL.md +152 -0
- package/ai/skills/stacks-plugins/SKILL.md +149 -0
- package/ai/skills/stacks-push/SKILL.md +376 -0
- package/ai/skills/stacks-query-builder/SKILL.md +128 -0
- package/ai/skills/stacks-queue/SKILL.md +559 -0
- package/ai/skills/stacks-realtime/SKILL.md +442 -0
- package/ai/skills/stacks-redesign/SKILL.md +182 -0
- package/ai/skills/stacks-registry/SKILL.md +58 -0
- package/ai/skills/stacks-repl/SKILL.md +80 -0
- package/ai/skills/stacks-retro/SKILL.md +122 -0
- package/ai/skills/stacks-review/SKILL.md +135 -0
- package/ai/skills/stacks-router/SKILL.md +231 -0
- package/ai/skills/stacks-routes/SKILL.md +105 -0
- package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
- package/ai/skills/stacks-scheduler/SKILL.md +363 -0
- package/ai/skills/stacks-search-engine/SKILL.md +112 -0
- package/ai/skills/stacks-security/SKILL.md +129 -0
- package/ai/skills/stacks-security-audit/SKILL.md +128 -0
- package/ai/skills/stacks-server/SKILL.md +458 -0
- package/ai/skills/stacks-shell/SKILL.md +62 -0
- package/ai/skills/stacks-slug/SKILL.md +87 -0
- package/ai/skills/stacks-sms/SKILL.md +385 -0
- package/ai/skills/stacks-socials/SKILL.md +303 -0
- package/ai/skills/stacks-storage/SKILL.md +576 -0
- package/ai/skills/stacks-strings/SKILL.md +416 -0
- package/ai/skills/stacks-stx/SKILL.md +176 -0
- package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
- package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
- package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
- package/ai/skills/stacks-testing/SKILL.md +129 -0
- package/ai/skills/stacks-tunnel/SKILL.md +125 -0
- package/ai/skills/stacks-types/SKILL.md +178 -0
- package/ai/skills/stacks-ui/SKILL.md +246 -0
- package/ai/skills/stacks-utils/SKILL.md +444 -0
- package/ai/skills/stacks-validation/SKILL.md +371 -0
- package/ai/skills/stacks-whois/SKILL.md +315 -0
- package/assets/world-map-data.ts +121 -0
- package/bootstrap.ts +114 -0
- package/docs/api-examples.md +46 -0
- package/docs/index.md +24 -0
- package/docs/markdown-examples.md +87 -0
- package/functions/analytics.ts +97 -0
- package/functions/api.ts +143 -0
- package/functions/auth.ts +208 -0
- package/functions/billing/payments.ts +149 -0
- package/functions/blog.ts +120 -0
- package/functions/cms/categorizables.ts +107 -0
- package/functions/cms/pages.ts +108 -0
- package/functions/cms/posts.ts +100 -0
- package/functions/cms/taggables.ts +102 -0
- package/functions/commerce/coupons.ts +128 -0
- package/functions/commerce/customers.ts +128 -0
- package/functions/commerce/gift-cards.ts +119 -0
- package/functions/commerce/orders.ts +112 -0
- package/functions/commerce/payments.ts +119 -0
- package/functions/commerce/products/categories.ts +123 -0
- package/functions/commerce/products/manufacturers.ts +123 -0
- package/functions/commerce/products/products.ts +123 -0
- package/functions/commerce/products/reviews.ts +123 -0
- package/functions/commerce/products/units.ts +123 -0
- package/functions/commerce/products/variants.ts +123 -0
- package/functions/commerce/shippings/delivery-routes.ts +123 -0
- package/functions/commerce/shippings/digital-deliveries.ts +119 -0
- package/functions/commerce/shippings/drivers.ts +123 -0
- package/functions/commerce/shippings/license-keys.ts +123 -0
- package/functions/commerce/shippings/shipping-methods.ts +123 -0
- package/functions/commerce/shippings/shipping-rates.ts +119 -0
- package/functions/commerce/shippings/shipping-zones.ts +119 -0
- package/functions/commerce/taxes.ts +119 -0
- package/functions/commerce/waitlist/products.ts +123 -0
- package/functions/commerce/waitlist/restaurants.ts +123 -0
- package/functions/craft.ts +107 -0
- package/functions/dashboard.ts +153 -0
- package/functions/inbox.ts +95 -0
- package/functions/jobs.ts +86 -0
- package/functions/monitoring/errors.ts +295 -0
- package/functions/queue.ts +111 -0
- package/functions/realtime/websockets.ts +96 -0
- package/functions/realtime.ts +52 -0
- package/functions/releases.ts +49 -0
- package/functions/search.ts +126 -0
- package/functions/toasts.ts +95 -0
- package/functions/uploads.ts +216 -0
- package/ide/.gitignore +4 -0
- package/ide/cursor/rules/auto-imports.mdc +574 -0
- package/ide/cursor/rules/code-style.mdc +12 -0
- package/ide/cursor/rules/documentation.mdc +9 -0
- package/ide/cursor/rules/error-handling-validation.mdc +11 -0
- package/ide/cursor/rules/key-conventions.mdc +11 -0
- package/ide/cursor/rules/project-structure.mdc +169 -0
- package/ide/cursor/rules/readme.mdc +318 -0
- package/ide/cursor/rules/syntax-formatting.mdc +9 -0
- package/ide/cursor/rules/testing.mdc +10 -0
- package/ide/cursor/rules/typescript.mdc +9 -0
- package/ide/cursor/rules/ui-styling.mdc +0 -0
- package/ide/dictionary.txt +397 -0
- package/ide/jetbrains/.fleet/settings.json +4 -0
- package/ide/jetbrains/.idea/.gitignore +5 -0
- package/ide/jetbrains/.idea/.name +1 -0
- package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
- package/ide/jetbrains/.idea/modules.xml +8 -0
- package/ide/jetbrains/.idea/stacks.iml +22 -0
- package/ide/jetbrains/.idea/vcs.xml +6 -0
- package/ide/jetbrains/.idea/webResources.xml +14 -0
- package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
- package/ide/jetbrains/installed.txt +4 -0
- package/ide/jetbrains/options/github-copilot.xml +5 -0
- package/ide/jetbrains/options/nodejs.xml +7 -0
- package/ide/jetbrains/options/templates.xml +124 -0
- package/ide/jetbrains/templates/JavaScript.xml +6 -0
- package/ide/jetbrains/templates/Stacks.xml +8 -0
- package/ide/vscode/.vscode/README.md +23 -0
- package/ide/vscode/.vscode/extensions.json +5 -0
- package/ide/vscode/.vscode/settings.json +176 -0
- package/ide/vscode/.vscode/stacks.code-snippets +181 -0
- package/ide/vscode/LICENSE.md +21 -0
- package/ide/vscode/README.md +36 -0
- package/ide/vscode/logo.png +0 -0
- package/ide/vscode/package.json +79 -0
- package/ide/zed/.zed/settings.json +139 -0
- package/lang/README.md +28 -0
- package/lang/de.yml +14 -0
- package/lang/en.yml +15 -0
- package/package.json +19 -3
- package/project/bootstrap +161 -0
- package/project/buddy +175 -0
- package/project/storage/framework/tsconfig.app.json +50 -0
- package/project/storage/framework/tsconfig.base.json +58 -0
- package/routes/core.ts +78 -0
- package/routes/dashboard-api.ts +233 -0
- package/routes/dashboard.ts +739 -0
- package/routes/email.ts +129 -0
- package/stores/[name].stx +16 -0
- package/stores/git.ts +71 -0
- package/stores/payment.ts +474 -0
- package/stores/queue.ts +43 -0
- package/stores/user.ts +29 -0
- package/stx-components-plugin.ts +25 -0
- package/styles/design-tokens.css +597 -0
- package/types/dashboard.ts +70 -0
- package/types/defaults.ts +438 -0
- package/vcs/github/CODE_OF_CONDUCT.md +83 -0
- package/vcs/github/CONTRIBUTING.md +187 -0
- package/vcs/github/EXPLANATIONS.md +41 -0
- package/vcs/github/FUNDING.yml +1 -0
- package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
- package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- package/vcs/github/SECURITY.md +70 -0
- package/vcs/github/renovate.json +5 -0
- package/vcs/github/stale.yml +14 -0
- package/vcs/github/workflows/README.md +16 -0
- package/vcs/github/workflows/ci.yml +114 -0
- package/vcs/github/workflows/export-size.yml +25 -0
- package/vcs/github/workflows/labeler.yml +13 -0
- package/vcs/github/workflows/release.yml +219 -0
- package/views/[...all].stx +8 -0
- package/views/about.md +3 -0
- package/views/auth/login.stx +1 -0
- package/views/auth/signup.stx +85 -0
- package/views/dashboard/.discovered-models.json +542 -0
- package/views/dashboard/AUDIT.md +904 -0
- package/views/dashboard/[...all].stx +89 -0
- package/views/dashboard/access-tokens/index.stx +177 -0
- package/views/dashboard/actions/index.stx +129 -0
- package/views/dashboard/analytics/blog/index.stx +356 -0
- package/views/dashboard/analytics/browsers/index.stx +263 -0
- package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
- package/views/dashboard/analytics/commerce/web/index.stx +379 -0
- package/views/dashboard/analytics/countries/index.stx +289 -0
- package/views/dashboard/analytics/devices/index.stx +305 -0
- package/views/dashboard/analytics/events/index.stx +536 -0
- package/views/dashboard/analytics/index.stx +88 -0
- package/views/dashboard/analytics/marketing/index.stx +315 -0
- package/views/dashboard/analytics/pages/index.stx +271 -0
- package/views/dashboard/analytics/referrers/index.stx +319 -0
- package/views/dashboard/analytics/web/index.stx +356 -0
- package/views/dashboard/buddy/index.stx +198 -0
- package/views/dashboard/ci/index.stx +462 -0
- package/views/dashboard/cloud/index.stx +452 -0
- package/views/dashboard/commands/index.stx +295 -0
- package/views/dashboard/commerce/categories/index.stx +406 -0
- package/views/dashboard/commerce/coupons/index.stx +485 -0
- package/views/dashboard/commerce/customers/index.stx +410 -0
- package/views/dashboard/commerce/dashboard/index.stx +287 -0
- package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
- package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
- package/views/dashboard/commerce/delivery/drivers.stx +397 -0
- package/views/dashboard/commerce/delivery/index.stx +18 -0
- package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
- package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
- package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
- package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
- package/views/dashboard/commerce/delivery/tabs.ts +25 -0
- package/views/dashboard/commerce/gift-cards/index.stx +561 -0
- package/views/dashboard/commerce/manufacturers/index.stx +308 -0
- package/views/dashboard/commerce/orders/index.stx +247 -0
- package/views/dashboard/commerce/payments/index.stx +535 -0
- package/views/dashboard/commerce/pos/index.stx +653 -0
- package/views/dashboard/commerce/printers/devices/index.stx +273 -0
- package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
- package/views/dashboard/commerce/products/detail.stx +563 -0
- package/views/dashboard/commerce/products/index.stx +370 -0
- package/views/dashboard/commerce/reviews/index.stx +656 -0
- package/views/dashboard/commerce/reviews/index.ts +0 -0
- package/views/dashboard/commerce/taxes/index.stx +377 -0
- package/views/dashboard/commerce/units/index.stx +317 -0
- package/views/dashboard/commerce/variants/index.stx +319 -0
- package/views/dashboard/commerce/waitlist/products.stx +942 -0
- package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
- package/views/dashboard/components/index.stx +330 -0
- package/views/dashboard/composables/index.ts +19 -0
- package/views/dashboard/composables/useChart.ts +77 -0
- package/views/dashboard/composables/useNavigation.ts +99 -0
- package/views/dashboard/composables/useRole.ts +58 -0
- package/views/dashboard/composables/useTheme.ts +74 -0
- package/views/dashboard/content/authors/index.stx +171 -0
- package/views/dashboard/content/blog/index.stx +493 -0
- package/views/dashboard/content/categories/index.stx +169 -0
- package/views/dashboard/content/comments/index.stx +189 -0
- package/views/dashboard/content/dashboard.stx +383 -0
- package/views/dashboard/content/files/index.stx +706 -0
- package/views/dashboard/content/pages/index.stx +174 -0
- package/views/dashboard/content/posts/index.stx +269 -0
- package/views/dashboard/content/seo/index.stx +240 -0
- package/views/dashboard/content/tags/index.stx +167 -0
- package/views/dashboard/data/activity/index.stx +261 -0
- package/views/dashboard/data/dashboard/index.stx +116 -0
- package/views/dashboard/data/subscribers.stx +270 -0
- package/views/dashboard/data/teams.stx +275 -0
- package/views/dashboard/data/users.stx +279 -0
- package/views/dashboard/dependencies/index.stx +178 -0
- package/views/dashboard/deployments/[id].stx +234 -0
- package/views/dashboard/deployments/index.stx +9 -0
- package/views/dashboard/dns/index.stx +163 -0
- package/views/dashboard/environment/index.stx +283 -0
- package/views/dashboard/errors/index.stx +274 -0
- package/views/dashboard/forgot-password.stx +57 -0
- package/views/dashboard/functions/index.stx +159 -0
- package/views/dashboard/health/index.stx +248 -0
- package/views/dashboard/inbox/activity.stx +350 -0
- package/views/dashboard/inbox/index.stx +452 -0
- package/views/dashboard/inbox/settings.stx +290 -0
- package/views/dashboard/index.stx +252 -0
- package/views/dashboard/insights/index.stx +529 -0
- package/views/dashboard/jobs/[id].stx +430 -0
- package/views/dashboard/jobs/history.stx +222 -0
- package/views/dashboard/jobs/index.stx +214 -0
- package/views/dashboard/kanban/[id].stx +899 -0
- package/views/dashboard/kanban/index.stx +260 -0
- package/views/dashboard/layouts/default.stx +565 -0
- package/views/dashboard/layouts/guest.stx +10 -0
- package/views/dashboard/login.stx +48 -0
- package/views/dashboard/logs/index.stx +540 -0
- package/views/dashboard/mailboxes/index.stx +149 -0
- package/views/dashboard/management/permissions/index.stx +490 -0
- package/views/dashboard/marketing/campaigns/index.stx +604 -0
- package/views/dashboard/marketing/lists/index.stx +514 -0
- package/views/dashboard/marketing/reviews/index.stx +475 -0
- package/views/dashboard/marketing/social-posts/index.stx +560 -0
- package/views/dashboard/models/[model].stx +195 -0
- package/views/dashboard/models/index.stx +159 -0
- package/views/dashboard/monitoring/errors/index.stx +415 -0
- package/views/dashboard/notifications/dashboard.stx +383 -0
- package/views/dashboard/notifications/email.stx +336 -0
- package/views/dashboard/notifications/history.stx +373 -0
- package/views/dashboard/notifications/sms.stx +332 -0
- package/views/dashboard/packages/index.stx +195 -0
- package/views/dashboard/queries/[id].stx +381 -0
- package/views/dashboard/queries/history.stx +227 -0
- package/views/dashboard/queries/index.stx +335 -0
- package/views/dashboard/queries/slow.stx +318 -0
- package/views/dashboard/queue/index.stx +427 -0
- package/views/dashboard/realtime/index.stx +429 -0
- package/views/dashboard/register.stx +46 -0
- package/views/dashboard/releases/index.stx +389 -0
- package/views/dashboard/requests/index.stx +462 -0
- package/views/dashboard/serverless/index.stx +475 -0
- package/views/dashboard/servers/[id].stx +299 -0
- package/views/dashboard/servers/index.stx +483 -0
- package/views/dashboard/settings/billing.stx +50 -0
- package/views/dashboard/settings/index.stx +256 -0
- package/views/dashboard/settings/mail.stx +252 -0
- package/views/dashboard/stores/auth.ts +123 -0
- package/views/dashboard/stores/ci.ts +342 -0
- package/views/dashboard/stores/index.ts +129 -0
- package/views/dashboard/stores/kanban.ts +723 -0
- package/views/dashboard/stores/rbac.ts +350 -0
- package/views/dashboard/stx.config.ts +34 -0
- package/views/dashboard/teams/[id].stx +170 -0
- package/views/forum/category.stx +92 -0
- package/views/forum/index.stx +209 -0
- package/views/forum/new-topic.stx +113 -0
- package/views/forum/profile.stx +1 -0
- package/views/forum/topic.stx +143 -0
- package/views/hello-world/[name].stx +47 -0
- package/views/index.stx +21 -0
- package/views/system-tray/index.stx +147 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-email
|
|
3
|
+
description: Use when working with email in a Stacks application — sending emails via SES/SendGrid/Mailgun/Mailtrap/SMTP, email templates with STX, email drivers, the Mail singleton, the EmailSDK for inbox management, or email configuration. Covers @stacksjs/email, config/email.ts, and app/Mail/.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Email
|
|
10
|
+
|
|
11
|
+
Multi-driver email system with template rendering, S3-based inbox management, and 5 built-in drivers.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Core package: `storage/framework/core/email/src/`
|
|
15
|
+
- Configuration: `config/email.ts`
|
|
16
|
+
- Application mail: `app/Mail/`
|
|
17
|
+
- Email layouts: `storage/framework/defaults/resources/emails/layouts/`
|
|
18
|
+
- Email resources: `storage/framework/defaults/resources/emails/`
|
|
19
|
+
|
|
20
|
+
## Source Files
|
|
21
|
+
```
|
|
22
|
+
email/src/
|
|
23
|
+
├── index.ts # All exports
|
|
24
|
+
├── email.ts # Email class + Mail singleton
|
|
25
|
+
├── template.ts # Template rendering engine
|
|
26
|
+
├── types.ts # Types and interfaces
|
|
27
|
+
├── sdk/index.ts # EmailSDK (send + inbox management)
|
|
28
|
+
└── drivers/
|
|
29
|
+
├── base.ts # BaseEmailDriver abstract class
|
|
30
|
+
├── ses.ts # AWS SES driver
|
|
31
|
+
├── sendgrid.ts # SendGrid driver
|
|
32
|
+
├── mailgun.ts # Mailgun driver
|
|
33
|
+
├── mailtrap.ts # Mailtrap driver (sandbox/production)
|
|
34
|
+
└── smtp.ts # Raw SMTP driver (TLS/STARTTLS)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Mail Singleton
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { mail } from '@stacksjs/email'
|
|
41
|
+
|
|
42
|
+
await mail.send({
|
|
43
|
+
from: { name: 'App', address: 'noreply@app.com' },
|
|
44
|
+
to: 'user@example.com',
|
|
45
|
+
subject: 'Welcome',
|
|
46
|
+
html: '<h1>Hello!</h1>',
|
|
47
|
+
text: 'Hello!'
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// Switch driver
|
|
51
|
+
const sendgridMail = mail.use('sendgrid')
|
|
52
|
+
await sendgridMail.send(message)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Email Class
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const email = new Email({
|
|
59
|
+
name: 'WelcomeEmail',
|
|
60
|
+
subject: 'Welcome!',
|
|
61
|
+
to: 'user@example.com',
|
|
62
|
+
from: { name: 'App', address: 'noreply@app.com' },
|
|
63
|
+
template: 'welcome', // looks for welcome.stx or welcome.html
|
|
64
|
+
handle: async () => ({ message: 'sent' }),
|
|
65
|
+
onError: async (err) => ({ message: err.message }),
|
|
66
|
+
onSuccess: () => console.log('Sent!')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const html = await email.renderTemplate()
|
|
70
|
+
await email.send()
|
|
71
|
+
await email.send('override@email.com')
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Template Rendering
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { template, renderHtml, templateExists, listTemplates } from '@stacksjs/email'
|
|
78
|
+
|
|
79
|
+
const { html, text } = await template('welcome', {
|
|
80
|
+
variables: { name: 'John', url: 'https://app.com' },
|
|
81
|
+
layout: 'default', // or false to skip layout
|
|
82
|
+
subject: 'Welcome'
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Raw HTML rendering
|
|
86
|
+
const { html, text } = renderHtml('<h1>Hello {{name}}</h1>', { name: 'World' })
|
|
87
|
+
|
|
88
|
+
templateExists('welcome') // boolean
|
|
89
|
+
listTemplates() // string[]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Variable interpolation uses `{{ variable }}` syntax. Templates can be `.stx` (processed by STX engine) or `.html`.
|
|
93
|
+
|
|
94
|
+
## EmailSDK (Inbox Management via S3)
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { emailSDK, sendEmail, getInbox, searchEmails, deleteEmail } from '@stacksjs/email'
|
|
98
|
+
|
|
99
|
+
// Send
|
|
100
|
+
await sendEmail({ from: { address: 'a@b.com' }, to: 'c@d.com', subject: 'Hi', html: '<p>Hello</p>' })
|
|
101
|
+
|
|
102
|
+
// Send with template
|
|
103
|
+
await emailSDK.sendTemplate({ to: 'user@example.com', templateName: 'welcome', data: { name: 'John' } })
|
|
104
|
+
|
|
105
|
+
// Read inbox (from S3)
|
|
106
|
+
const emails = await getInbox('chris', { limit: 20 })
|
|
107
|
+
const email = await emailSDK.getEmail('chris', messageId)
|
|
108
|
+
|
|
109
|
+
// Search
|
|
110
|
+
const results = await searchEmails('chris', { from: 'boss', after: '2024-01-01', hasAttachments: true })
|
|
111
|
+
|
|
112
|
+
// Manage
|
|
113
|
+
await emailSDK.markAsRead('chris', messageId)
|
|
114
|
+
await emailSDK.markAsUnread('chris', messageId)
|
|
115
|
+
await deleteEmail('chris', messageId)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Built-in Drivers
|
|
119
|
+
|
|
120
|
+
### SES Driver
|
|
121
|
+
- Uses `@aws-sdk/client-ses` SESClient
|
|
122
|
+
- Lazy-loads client on first send
|
|
123
|
+
- Supports `Source` formatting: `"Name" <address>`
|
|
124
|
+
|
|
125
|
+
### SendGrid Driver
|
|
126
|
+
- API key from config/env
|
|
127
|
+
- Multipart content (HTML + text)
|
|
128
|
+
- Attachment support (base64 encoding)
|
|
129
|
+
- Retry with exponential backoff
|
|
130
|
+
|
|
131
|
+
### Mailgun Driver
|
|
132
|
+
- FormData construction with recipients
|
|
133
|
+
- CC/BCC support
|
|
134
|
+
- Attachment handling via FormData
|
|
135
|
+
- Configurable domain and endpoint
|
|
136
|
+
|
|
137
|
+
### Mailtrap Driver
|
|
138
|
+
- Inbox-aware sending
|
|
139
|
+
- Sandbox and production modes
|
|
140
|
+
- Host default: `sandbox.api.mailtrap.io`
|
|
141
|
+
|
|
142
|
+
### SMTP Driver
|
|
143
|
+
- Raw TCP/TLS socket connection
|
|
144
|
+
- STARTTLS upgrade support
|
|
145
|
+
- AUTH LOGIN authentication
|
|
146
|
+
- MIME multipart (text + HTML)
|
|
147
|
+
- 30-second connection timeout
|
|
148
|
+
- Command queue-based protocol
|
|
149
|
+
|
|
150
|
+
## Driver Interface
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
abstract class BaseEmailDriver {
|
|
154
|
+
abstract name: string
|
|
155
|
+
abstract send(message: EmailMessage, options?: TemplateOptions): Promise<EmailResult>
|
|
156
|
+
protected validateMessage(message): boolean
|
|
157
|
+
protected formatAddresses(...): string[]
|
|
158
|
+
protected handleError(error, message): Promise<EmailResult>
|
|
159
|
+
protected handleSuccess(message, messageId?): Promise<EmailResult>
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## config/email.ts
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
{
|
|
167
|
+
from: { name: env.MAIL_FROM_NAME, address: env.MAIL_FROM_ADDRESS },
|
|
168
|
+
domain: 'stacksjs.com',
|
|
169
|
+
mailboxes: ['chris', 'blake', 'glenn'],
|
|
170
|
+
url: env.APP_URL,
|
|
171
|
+
charset: 'UTF-8',
|
|
172
|
+
default: 'ses', // 'ses' | 'sendgrid' | 'mailgun' | 'mailtrap' | 'smtp' | 'postmark'
|
|
173
|
+
server: {
|
|
174
|
+
enabled: true,
|
|
175
|
+
scan: { enabled: true },
|
|
176
|
+
subdomain: 'mail',
|
|
177
|
+
mode: 'server', // 'server' | 'serverless'
|
|
178
|
+
ports: { smtp: 25, smtps: 465, submission: 587, imap: 143, imaps: 993 },
|
|
179
|
+
features: { imap: true, pop3: false, webmail: false, calDAV: false },
|
|
180
|
+
categorization: {
|
|
181
|
+
enabled: true,
|
|
182
|
+
social: { domains: ['facebook', 'twitter', ...] },
|
|
183
|
+
forums: { domains: ['reddit', ...] },
|
|
184
|
+
updates: { substrings: ['noreply', 'no-reply', ...] },
|
|
185
|
+
promotions: { substrings: ['unsubscribe', 'promo', ...] }
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
notifications: { newEmail: true, bounces: true, complaints: true }
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Application Mail Example
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// app/Mail/SubscriptionConfirmation.ts
|
|
196
|
+
export async function sendSubscriptionConfirmation({ to, subscriberUuid }: Options) {
|
|
197
|
+
const { html, text } = await template('subscription-confirmation', {
|
|
198
|
+
variables: {
|
|
199
|
+
unsubscribeUrl: url('email.unsubscribe', { token: subscriberUuid }),
|
|
200
|
+
appName: config.app.name
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
await mail.send({
|
|
205
|
+
from: { name: config.app.name, address: config.email.from.address },
|
|
206
|
+
to,
|
|
207
|
+
subject: 'Confirm your subscription',
|
|
208
|
+
html,
|
|
209
|
+
text
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## CLI Commands
|
|
215
|
+
- `buddy email` / `buddy mail` — email management
|
|
216
|
+
- `buddy email:verify` — check domain verification
|
|
217
|
+
- `buddy email:test [recipient]` — send test email
|
|
218
|
+
- `buddy email:list` — list mailboxes
|
|
219
|
+
- `buddy email:logs -n 50` — view logs
|
|
220
|
+
- `buddy email:status` — server status
|
|
221
|
+
- `buddy email:inbox [mailbox]` — view inbox from S3
|
|
222
|
+
- `buddy mail:user:add <email>` — add mail user
|
|
223
|
+
- `buddy mail:user:list` — list mail users
|
|
224
|
+
- `buddy mail:user:delete <email>` — delete mail user
|
|
225
|
+
|
|
226
|
+
## Gotchas
|
|
227
|
+
- Default driver is `ses` — requires AWS credentials
|
|
228
|
+
- Template rendering supports both `.stx` and `.html` files
|
|
229
|
+
- Variable interpolation uses `{{ }}` double-brace syntax
|
|
230
|
+
- The `mail` singleton auto-registers all 5 drivers on initialization
|
|
231
|
+
- SMTP driver handles TLS handshake manually (not via node:tls)
|
|
232
|
+
- SendGrid/Mailgun retry with exponential backoff on failure
|
|
233
|
+
- Mailtrap requires `inboxId` for sandbox mode
|
|
234
|
+
- EmailSDK reads inbox from S3 (bucket configured via env)
|
|
235
|
+
- Email categorization auto-sorts incoming mail by domain/substring patterns
|
|
236
|
+
- The `text` fallback is auto-generated from HTML via `htmlToText()`
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-enums
|
|
3
|
+
description: Use when working with framework constants in a Stacks application — NpmScript commands, Action identifiers, or any enumerated constants used across the build system, CLI, and actions. Covers @stacksjs/enums.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Enums
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/enums/src/`
|
|
13
|
+
- Source: `storage/framework/core/enums/src/index.ts`
|
|
14
|
+
- Package: `@stacksjs/enums`
|
|
15
|
+
|
|
16
|
+
## NpmScript Enum (45 values)
|
|
17
|
+
|
|
18
|
+
Used by the CLI and build system to run specific npm scripts:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { NpmScript } from '@stacksjs/enums'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Build Scripts
|
|
25
|
+
| Value | Script |
|
|
26
|
+
|-------|--------|
|
|
27
|
+
| `Build` | `'build'` |
|
|
28
|
+
| `BuildComponents` | `'vite build --config ./src/vite-config/src/components.ts'` |
|
|
29
|
+
| `BuildWebComponents` | `'build:web-components'` |
|
|
30
|
+
| `BuildFunctions` | `'build:functions'` |
|
|
31
|
+
| `BuildDocs` | `'build:docs'` |
|
|
32
|
+
| `BuildStacks` | `'build:stacks'` |
|
|
33
|
+
|
|
34
|
+
### Dev Scripts
|
|
35
|
+
| Value | Script |
|
|
36
|
+
|-------|--------|
|
|
37
|
+
| `Dev` | `'dev'` |
|
|
38
|
+
| `DevApi` | `'dev:api'` |
|
|
39
|
+
| `DevDocs` | `'dev:docs'` |
|
|
40
|
+
| `DevDesktop` | `'dev:desktop'` |
|
|
41
|
+
| `DevFunctions` | `'dev:functions'` |
|
|
42
|
+
|
|
43
|
+
### Test Scripts
|
|
44
|
+
| Value | Script |
|
|
45
|
+
|-------|--------|
|
|
46
|
+
| `Test` | `'test'` |
|
|
47
|
+
| `TestUnit` | `'test:unit'` |
|
|
48
|
+
| `TestFeature` | `'test:feature'` |
|
|
49
|
+
| `TestUi` | `'test:ui'` |
|
|
50
|
+
| `TestTypes` | `'test:types'` |
|
|
51
|
+
|
|
52
|
+
### Maintenance Scripts
|
|
53
|
+
`Clean`, `Fresh`, `Lint`, `LintFix`, `Upgrade`, `Generate`, `GenerateTypes`, `GenerateEntries`, `GenerateWebTypes`, `GenerateIdeHelpers`, `GenerateComponentMeta`, `Commit`, `Release`, `KeyGenerate`, `Preinstall`, `Prepublish`
|
|
54
|
+
|
|
55
|
+
## Action Enum (60+ values)
|
|
56
|
+
|
|
57
|
+
Used to dispatch framework actions via the action runner:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { Action } from '@stacksjs/enums'
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Build Actions
|
|
64
|
+
`BuildViews`, `BuildStacks`, `BuildComponentLibs`, `BuildVueComponentLib`, `BuildWebComponentLib`, `BuildFunctionLib`, `BuildCli`, `BuildCore`, `BuildDesktop`, `BuildDocs`, `BuildServer`
|
|
65
|
+
|
|
66
|
+
### Dev Actions
|
|
67
|
+
`DevComponents`, `DevDashboard`, `DevSystemTray`, `Dev`, `DevApi`, `DevDesktop`, `DevDocs`
|
|
68
|
+
|
|
69
|
+
### Database Actions
|
|
70
|
+
`Migrate`, `MigrateFresh`, `MigrateDns`, `Seed`
|
|
71
|
+
|
|
72
|
+
### Queue Actions
|
|
73
|
+
`QueueTable`, `QueueWork`, `QueueRetry`, `QueueFailed`, `QueueClear`, `QueueStatus`, `QueueFlush`, `QueueMonitor`, `QueueInspect`, `QueueSchedule`, `QueueScheduleList`
|
|
74
|
+
|
|
75
|
+
### Domain Actions
|
|
76
|
+
`DomainsAdd`, `DomainsPurchase`, `DomainsRemove`
|
|
77
|
+
|
|
78
|
+
### Search Engine Actions
|
|
79
|
+
`SearchEngineImport`, `SearchEngineFlush`, `SearchEngineListSettings`, `SearchEnginePushSettings`
|
|
80
|
+
|
|
81
|
+
### Other Actions
|
|
82
|
+
`Lint`, `LintFix`, `Test`, `TestUnit`, `TestFeature`, `TestUi`, `Typecheck`, `Deploy`, `ScheduleRun`, `Release`, `RouteList`, `Upgrade`, `UpgradeDeps`
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Action, NpmScript } from '@stacksjs/enums'
|
|
88
|
+
|
|
89
|
+
// Used in buddy CLI commands
|
|
90
|
+
runAction(Action.Migrate, options)
|
|
91
|
+
|
|
92
|
+
// Used in build system
|
|
93
|
+
runNpmScript(NpmScript.BuildComponents)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Gotchas
|
|
97
|
+
- **Action values use path format** — e.g., `Action.BuildViews = 'build/views'`, `Action.QueueWork = 'queue/work'`
|
|
98
|
+
- **NpmScript values are actual script commands** — some are full vite commands, not just script names
|
|
99
|
+
- **Used throughout the framework** — CLI, build system, and actions all reference these enums
|
|
100
|
+
- **Adding new actions** — requires adding the enum value AND creating the action handler file
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-env
|
|
3
|
+
description: Use when working with environment variables in Stacks — the typed env proxy with auto-coercion, .env file loading, AES-256-GCM encryption/decryption of env values, runtime/platform detection, CI provider detection, or the env CLI commands. Covers @stacksjs/env, config/env.ts, and .env files.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Environment
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/env/src/`
|
|
13
|
+
- Environment config: `config/env.ts`
|
|
14
|
+
- Environment file: `.env`
|
|
15
|
+
- Example: `.env.example`
|
|
16
|
+
- Type definitions: `storage/framework/env.d.ts`
|
|
17
|
+
|
|
18
|
+
## Source Files
|
|
19
|
+
```
|
|
20
|
+
env/src/
|
|
21
|
+
├── index.ts # main exports
|
|
22
|
+
├── utils.ts # runtime/platform detection, StacksEnv proxy
|
|
23
|
+
├── plugin.ts # Bun plugin for auto .env loading
|
|
24
|
+
├── parser.ts # .env file parser with encryption support
|
|
25
|
+
├── cli.ts # CLI commands (get, set, encrypt, decrypt, rotate)
|
|
26
|
+
├── crypto.ts # AES-256-GCM + secp256k1 encryption
|
|
27
|
+
└── types.ts # StacksEnv interface (100+ typed vars)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Typed Environment Proxy
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { env } from '@stacksjs/env'
|
|
34
|
+
|
|
35
|
+
env.APP_NAME // string
|
|
36
|
+
env.APP_ENV // 'local' | 'dev' | 'stage' | 'prod'
|
|
37
|
+
env.APP_KEY // string
|
|
38
|
+
env.APP_URL // string
|
|
39
|
+
env.DEBUG // boolean (auto-coerced)
|
|
40
|
+
env.PORT // number (auto-coerced)
|
|
41
|
+
env.DB_CONNECTION // 'sqlite' | 'mysql' | 'postgres' | 'dynamodb'
|
|
42
|
+
env.DB_HOST // string
|
|
43
|
+
env.DB_PORT // number
|
|
44
|
+
env.DB_DATABASE // string
|
|
45
|
+
env.DB_USERNAME // string
|
|
46
|
+
env.DB_PASSWORD // string
|
|
47
|
+
env.AWS_ACCESS_KEY_ID // string
|
|
48
|
+
env.STRIPE_SECRET_KEY // string
|
|
49
|
+
env.MAIL_MAILER // string
|
|
50
|
+
env.QUEUE_DRIVER // string
|
|
51
|
+
env.REDIS_HOST // string
|
|
52
|
+
env[key] // any custom env var
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The `env` proxy auto-coerces: `'true'` → `true`, `'123'` → `123`, etc.
|
|
56
|
+
|
|
57
|
+
## StacksEnv Type (100+ typed variables)
|
|
58
|
+
App, Ports, API, Database, AWS, Mail, Services (Stripe, Meilisearch), Frontend, Realtime, Redis, Pusher, Auth, Storage, Queue, plus `[key: string]` catch-all.
|
|
59
|
+
|
|
60
|
+
## Runtime Detection
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { isBun, isNode, runtime, runtimeInfo, platform, isWindows, isMacOS, isLinux, hasTTY, hasWindow, isCI, isDebug, isMinimal, isColorSupported, provider, providerInfo } from '@stacksjs/env'
|
|
64
|
+
|
|
65
|
+
isBun // true
|
|
66
|
+
isNode // false
|
|
67
|
+
runtime // 'bun'
|
|
68
|
+
platform // 'darwin'
|
|
69
|
+
isWindows // false
|
|
70
|
+
isMacOS // true
|
|
71
|
+
isLinux // false
|
|
72
|
+
hasTTY // true (terminal)
|
|
73
|
+
isCI // false
|
|
74
|
+
isDebug // boolean
|
|
75
|
+
isColorSupported // true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## CI Provider Detection
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
provider // 'github-actions' | 'gitlab-ci' | 'circleci' | 'travis' | 'jenkins' | 'vercel' | 'netlify' | 'heroku' | 'aws' | 'azure' | 'cloudflare' | 'railway' | 'render' | ...
|
|
82
|
+
providerInfo // { name: string, ... }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## .env File Loading
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { loadEnv, autoLoadEnv, envPlugin } from '@stacksjs/env'
|
|
89
|
+
|
|
90
|
+
await loadEnv({ path: '.env', override: false })
|
|
91
|
+
autoLoadEnv() // detects .env, .env.local, .env.{APP_ENV}
|
|
92
|
+
|
|
93
|
+
// Bun plugin (auto-loads .env before app starts)
|
|
94
|
+
envPlugin()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## .env Parser
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { parse } from '@stacksjs/env'
|
|
101
|
+
|
|
102
|
+
const vars = parse(envContent, {
|
|
103
|
+
encryption: true, // decrypt encrypted values
|
|
104
|
+
privateKey: '...' // decryption key
|
|
105
|
+
})
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Encryption (AES-256-GCM)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { aesEncrypt, aesDecrypt, generateKeypair, encryptValue, decryptValue, getPrivateKey } from '@stacksjs/env'
|
|
112
|
+
|
|
113
|
+
// AES-256-GCM symmetric encryption
|
|
114
|
+
const encrypted = aesEncrypt(plaintext, password)
|
|
115
|
+
const decrypted = aesDecrypt(encrypted, password)
|
|
116
|
+
|
|
117
|
+
// Asymmetric encryption (secp256k1 ECIES-style)
|
|
118
|
+
const keypair = generateKeypair()
|
|
119
|
+
const encrypted = encryptValue(value, keypair.publicKey)
|
|
120
|
+
const decrypted = decryptValue(encrypted, keypair.privateKey)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## CLI Commands
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
buddy env:get APP_NAME # get single var
|
|
127
|
+
buddy env:get --all --format json # all vars as JSON
|
|
128
|
+
buddy env:set APP_NAME "My App" # set var
|
|
129
|
+
buddy env:encrypt # encrypt .env file
|
|
130
|
+
buddy env:decrypt # decrypt .env file
|
|
131
|
+
buddy env:keypair # generate encryption keypair
|
|
132
|
+
buddy env:rotate # rotate encryption keys
|
|
133
|
+
buddy env:check # validate env configuration
|
|
134
|
+
buddy env:check --file .env.production # check a specific environment's file
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Tenant isolation on a shared box
|
|
138
|
+
|
|
139
|
+
When several projects share one server - one owns it, the rest attach with
|
|
140
|
+
`cloud.attachTo` - each still deploys from its own repository with its own
|
|
141
|
+
`.env.<environment>`. No project needs another's values.
|
|
142
|
+
|
|
143
|
+
They leak anyway: a tenant's secrets get pasted into the owner's env file under
|
|
144
|
+
a `TENANT_` prefix while debugging a deploy, and stay. That is not just untidy.
|
|
145
|
+
`buddy deploy` ships the whole env file as **every** site's `.env` (ts-cloud
|
|
146
|
+
treats `site.env` as the complete file), so a stray `BUGHQ_STRIPE_SECRET_KEY` in
|
|
147
|
+
the owner's file lands on disk in an unrelated site.
|
|
148
|
+
|
|
149
|
+
Declare who is attached, in `config/cloud.ts`'s default export:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
const config: CloudConfig = {
|
|
153
|
+
tenants: ['bughq', 'analyticshq'],
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
With that:
|
|
158
|
+
|
|
159
|
+
- `buddy deploy` drops those keys before shipping, and logs what it dropped
|
|
160
|
+
- `buddy env:check` lists them per tenant so they can be deleted at source
|
|
161
|
+
|
|
162
|
+
Prefixes are **never** inferred. With no `tenants` declared nothing is treated
|
|
163
|
+
as foreign, because `STRIPE_`, `AWS_` and `MEILISEARCH_` are indistinguishable
|
|
164
|
+
from a slug prefix by shape alone. Slug punctuation is ignored, so
|
|
165
|
+
`analytics-hq` and `analytics_hq` both match `ANALYTICSHQ_`.
|
|
166
|
+
|
|
167
|
+
The API is `partitionTenantEnv(values, { self, tenants })` from
|
|
168
|
+
`@stacksjs/env`, plus `stripForeignTenantEnv` and `foreignTenantKeys`.
|
|
169
|
+
|
|
170
|
+
## Gotchas
|
|
171
|
+
- **A tenant's keys in your env file get shipped everywhere.** `buddy deploy`
|
|
172
|
+
sends the entire env file as each site's `.env`. Declare `tenants` in
|
|
173
|
+
`config/cloud.ts` so they are stripped, then delete them at source
|
|
174
|
+
- Bun natively loads `.env` — no dotenv package needed
|
|
175
|
+
- The `env` proxy auto-coerces strings to booleans/numbers
|
|
176
|
+
- `.env` should never be committed — use `.env.example` as template
|
|
177
|
+
- Encryption uses AES-256-GCM for values and secp256k1 for key exchange
|
|
178
|
+
- `autoLoadEnv()` loads in order: `.env`, `.env.local`, `.env.{APP_ENV}`
|
|
179
|
+
- Runtime detection uses Bun globals and process properties
|
|
180
|
+
- CI provider detection checks environment variables specific to each CI system
|
|
181
|
+
- The `StacksEnv` type provides autocomplete for 100+ known variables
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-error-handling
|
|
3
|
+
description: Use when implementing error handling in Stacks — the Result type (Ok/Err), handleError function, error page rendering (development with stack traces, production with friendly messages), ErrorHandler class, ModelNotFoundException, HTTP error mapping, log file writing, or error configuration. Covers @stacksjs/error-handling and config/errors.ts.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Error Handling
|
|
10
|
+
|
|
11
|
+
Type-safe error handling with Result types, error pages, and structured logging.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Core package: `storage/framework/core/error-handling/src/`
|
|
15
|
+
- Configuration: `config/errors.ts`
|
|
16
|
+
- Error model: `storage/framework/defaults/app/Models/Error.ts`
|
|
17
|
+
|
|
18
|
+
## Result Type (from ts-error-handling)
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { ok, err, fromPromise } from '@stacksjs/error-handling'
|
|
22
|
+
import type { Result, Ok, Err, ResultAsync } from '@stacksjs/error-handling'
|
|
23
|
+
|
|
24
|
+
// Create results
|
|
25
|
+
const success: Ok<string> = ok('data')
|
|
26
|
+
const failure: Err<Error> = err(new Error('failed'))
|
|
27
|
+
|
|
28
|
+
// From promises
|
|
29
|
+
const result: ResultAsync<Data, Error> = fromPromise(fetchData())
|
|
30
|
+
|
|
31
|
+
// Pattern matching
|
|
32
|
+
if (result.isOk()) {
|
|
33
|
+
console.log(result.value)
|
|
34
|
+
} else {
|
|
35
|
+
console.error(result.error)
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Error Handler
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { handleError, ErrorHandler } from '@stacksjs/error-handling'
|
|
43
|
+
|
|
44
|
+
// Function-based
|
|
45
|
+
handleError(error)
|
|
46
|
+
handleError(error, { shouldExit: true })
|
|
47
|
+
|
|
48
|
+
// Class-based
|
|
49
|
+
ErrorHandler.handle(error)
|
|
50
|
+
ErrorHandler.handleError(error, { shouldExit: true })
|
|
51
|
+
ErrorHandler.writeErrorToFile(error)
|
|
52
|
+
ErrorHandler.writeErrorToConsole(error)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Log File Writing
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { writeToLogFile, setLogPath } from '@stacksjs/error-handling'
|
|
59
|
+
|
|
60
|
+
setLogPath('/custom/log/path')
|
|
61
|
+
await writeToLogFile('Error message', { path: '/custom/path' })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Default log path: `storage/logs/stacks.log`
|
|
65
|
+
|
|
66
|
+
## Error Page Rendering
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { ErrorPageHandler, renderError, renderErrorPage, renderProductionErrorPage, createErrorHandler, errorResponse } from '@stacksjs/error-handling'
|
|
70
|
+
|
|
71
|
+
// Development: shows stack trace, source code, file paths
|
|
72
|
+
const devPage = renderErrorPage(error, request)
|
|
73
|
+
|
|
74
|
+
// Production: friendly error message, no internals
|
|
75
|
+
const prodPage = renderProductionErrorPage(error, request)
|
|
76
|
+
|
|
77
|
+
// Auto-detect environment
|
|
78
|
+
const page = renderError(error, request)
|
|
79
|
+
|
|
80
|
+
// Create handler for routes
|
|
81
|
+
const handler = createErrorHandler()
|
|
82
|
+
const response = errorResponse(error, request)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## HTTP Error Mapping
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { HTTP_ERRORS } from '@stacksjs/error-handling'
|
|
89
|
+
|
|
90
|
+
// Maps status codes to error details
|
|
91
|
+
HTTP_ERRORS[400] // { title: 'Bad Request', ... }
|
|
92
|
+
HTTP_ERRORS[401] // { title: 'Unauthorized', ... }
|
|
93
|
+
HTTP_ERRORS[403] // { title: 'Forbidden', ... }
|
|
94
|
+
HTTP_ERRORS[404] // { title: 'Not Found', ... }
|
|
95
|
+
HTTP_ERRORS[500] // { title: 'Internal Server Error', ... }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Custom Exceptions
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { ModelNotFoundException } from '@stacksjs/error-handling'
|
|
102
|
+
|
|
103
|
+
throw new ModelNotFoundException('User not found')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Error Page Types
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
interface HttpError { status: number, title: string, message: string }
|
|
110
|
+
interface StackFrame { file: string, line: number, column: number, function?: string }
|
|
111
|
+
interface CodeSnippet { line: number, code: string, isHighlighted: boolean }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Error Model (storage/framework/defaults/app/Models/Error.ts)
|
|
115
|
+
|
|
116
|
+
Fields: type, message, stack (stacktrace), status, additional_info
|
|
117
|
+
Seeder: 10 records for testing
|
|
118
|
+
|
|
119
|
+
## config/errors.ts
|
|
120
|
+
|
|
121
|
+
Contains comprehensive validation error messages for all field types:
|
|
122
|
+
- String validation: required, minLength, maxLength, email, url, uuid, etc.
|
|
123
|
+
- Number validation: required, min, max, positive, negative, integer, etc.
|
|
124
|
+
- Enum validation: invalid value messages
|
|
125
|
+
- Date validation: format, before, after, etc.
|
|
126
|
+
- File validation: size, type, dimensions, etc.
|
|
127
|
+
|
|
128
|
+
## Gotchas
|
|
129
|
+
- Use `Result<T, E>` types instead of try/catch for recoverable errors
|
|
130
|
+
- `ok()` and `err()` are from `ts-error-handling` (neverthrow-compatible)
|
|
131
|
+
- Error pages automatically detect environment (dev shows stack traces, prod doesn't)
|
|
132
|
+
- `handleError()` logs to both console and file
|
|
133
|
+
- `ModelNotFoundException` is thrown by `findOrFail()` and `firstOrFail()` ORM methods
|
|
134
|
+
- The Error model persists errors to the database for tracking
|
|
135
|
+
- `config/errors.ts` is a comprehensive i18n-ready error message catalog
|
|
136
|
+
- `ErrorHandler.isTestEnvironment` prevents process exit during tests
|
|
137
|
+
- `ERROR_PAGE_CSS` contains built-in styling for error pages
|