@stacksjs/defaults 0.70.207 → 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,458 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-server
|
|
3
|
+
description: Use when working with the Stacks development or production server — server configuration, server middleware, or server startup. Covers @stacksjs/server and storage/framework/server/.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Server
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/server/src/` (published as `@stacksjs/server`)
|
|
13
|
+
- Server runtime: `storage/framework/server/` (the actual Bun HTTP server + Docker build)
|
|
14
|
+
- Server types: `storage/framework/core/types/src/server.ts`
|
|
15
|
+
- Ports types: `storage/framework/core/types/src/ports.ts`
|
|
16
|
+
- Package (core): `storage/framework/core/server/package.json`
|
|
17
|
+
- Package (runtime): `storage/framework/server/package.json`
|
|
18
|
+
|
|
19
|
+
## Source Files
|
|
20
|
+
```
|
|
21
|
+
core/server/src/
|
|
22
|
+
├── index.ts # Re-exports: config, controllers/base, imports, maintenance
|
|
23
|
+
├── config.ts # config() factory — maps ServerOptions.type to host/port
|
|
24
|
+
├── config-production.ts # Minimal env-based config for compiled production binaries
|
|
25
|
+
├── imports.ts # Auto-import system: scan models/jobs/controllers, register bun plugin
|
|
26
|
+
├── maintenance.ts # Laravel-like maintenance mode (down/up/bypass)
|
|
27
|
+
└── controllers/
|
|
28
|
+
└── base.ts # Base Controller class with json/success/error helpers
|
|
29
|
+
|
|
30
|
+
server/
|
|
31
|
+
├── src/
|
|
32
|
+
│ ├── index.ts # Bun.serve() entry point — HTTP + WebSocket + job worker
|
|
33
|
+
│ └── utils.ts # Docker build helpers (cleanCopy, buildDockerImage, useCustomOrDefaultServerConfig)
|
|
34
|
+
├── build.ts # Full build pipeline: bundle server + app, post-process, optionally build Docker
|
|
35
|
+
├── dev # Shell script for local/remote Docker dev (mounts volumes)
|
|
36
|
+
├── Dockerfile # Multi-stage Bun Docker image (oven/bun:1.3.10)
|
|
37
|
+
├── package.json # stacks-server v0.70.23
|
|
38
|
+
├── tsconfig.json # Extends core tsconfig
|
|
39
|
+
├── tsconfig.docker.json # Docker-specific tsconfig with path aliases
|
|
40
|
+
├── .dockerignore # Excludes Dockerfile, .git, node_modules, etc.
|
|
41
|
+
└── .gitignore # Excludes app/, config/, dist/, storage/ (build artifacts)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Server Entry Point (server/src/index.ts)
|
|
45
|
+
|
|
46
|
+
The runtime server uses `Bun.serve()` directly. It handles two modes based on environment variables:
|
|
47
|
+
|
|
48
|
+
### HTTP Server Mode (default)
|
|
49
|
+
```typescript
|
|
50
|
+
import type { Server, ServerWebSocket } from 'bun'
|
|
51
|
+
|
|
52
|
+
const server = Bun.serve({
|
|
53
|
+
port: Number(process.env.PORT) || 3000,
|
|
54
|
+
development: process.env.APP_ENV?.toLowerCase() !== 'production',
|
|
55
|
+
|
|
56
|
+
async fetch(request: Request, server: Server<any>): Promise<Response | undefined> {
|
|
57
|
+
// Attempt WebSocket upgrade first
|
|
58
|
+
if (server.upgrade(request)) return
|
|
59
|
+
|
|
60
|
+
// Delegate to the Stacks router
|
|
61
|
+
return serverResponse(request)
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
websocket: {
|
|
65
|
+
open(_ws: ServerWebSocket): void {},
|
|
66
|
+
message(_ws: ServerWebSocket, _message: string): void {},
|
|
67
|
+
close(_ws: ServerWebSocket, _code: number, _reason?: string): void {},
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Key details:
|
|
73
|
+
- `serverResponse()` is imported from `@stacksjs/router` and handles all route matching, middleware, and response generation
|
|
74
|
+
- WebSocket upgrade is attempted before HTTP routing
|
|
75
|
+
- `development` mode is enabled when `APP_ENV` is not `production` or `prod`
|
|
76
|
+
- SIGINT handler gracefully exits the process
|
|
77
|
+
|
|
78
|
+
### Queue Worker Mode
|
|
79
|
+
When `QUEUE_WORKER` env var is set, the same entry point runs a single job instead of starting the HTTP server:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
if (process.env.QUEUE_WORKER) {
|
|
83
|
+
const jobName = process.env.JOB.replace(/\.ts$/, '').replace(/[^a-zA-Z0-9_-]/g, '')
|
|
84
|
+
const jobModule = await import(`./app/Jobs/${jobName}`)
|
|
85
|
+
|
|
86
|
+
await retry(() => jobModule.default.handle(), {
|
|
87
|
+
backoffFactor: Number(process.env.JOB_BACKOFF_FACTOR) || 2,
|
|
88
|
+
retries: Number(process.env.JOB_RETRIES) || 3,
|
|
89
|
+
initialDelay: Number(process.env.JOB_INITIAL_DELAY) || 1000,
|
|
90
|
+
jitter: process.env.JOB_JITTER === 'true',
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
process.exit(0)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Environment variables for job execution:
|
|
98
|
+
- `QUEUE_WORKER` -- enables worker mode (any truthy value)
|
|
99
|
+
- `JOB` -- job file name (e.g., `SendEmail.ts`), sanitized to prevent path traversal
|
|
100
|
+
- `JOB_RETRIES` -- retry count (default: 3)
|
|
101
|
+
- `JOB_BACKOFF_FACTOR` -- exponential backoff multiplier (default: 2)
|
|
102
|
+
- `JOB_INITIAL_DELAY` -- initial retry delay in ms (default: 1000)
|
|
103
|
+
- `JOB_JITTER` -- enable jitter on retries (`'true'` to enable)
|
|
104
|
+
|
|
105
|
+
## Server Config (core/server/src/config.ts)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
function config(options: ServerOptions): { host: string, port: number, open: boolean }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Maps a `ServerOptions.type` to a host/port pair using the `ports` config object. Supported types:
|
|
112
|
+
|
|
113
|
+
| Type | Port Source |
|
|
114
|
+
|---------------|---------------------|
|
|
115
|
+
| `frontend` | `ports.frontend` |
|
|
116
|
+
| `backend` | `ports.backend` |
|
|
117
|
+
| `api` | `ports.api` |
|
|
118
|
+
| `admin` | `ports.admin` |
|
|
119
|
+
| `library` | `ports.library` |
|
|
120
|
+
| `desktop` | `ports.desktop` |
|
|
121
|
+
| `docs` | `ports.docs` |
|
|
122
|
+
| `email` | `ports.email` |
|
|
123
|
+
| `inspect` | `ports.inspect` |
|
|
124
|
+
| `system-tray` | `ports.systemTray` |
|
|
125
|
+
| `database` | `ports.database` |
|
|
126
|
+
|
|
127
|
+
All types resolve to `host: 'localhost'`. If no type is provided or it doesn't match, falls back to `host: options.host || 'stacks.localhost'` and `port: options.port || 3000`.
|
|
128
|
+
|
|
129
|
+
### ServerOptions Type
|
|
130
|
+
```typescript
|
|
131
|
+
interface ServerOptions {
|
|
132
|
+
type?: 'frontend' | 'backend' | 'api' | 'library' | 'desktop'
|
|
133
|
+
| 'docs' | 'email' | 'admin' | 'system-tray' | 'database'
|
|
134
|
+
host?: string
|
|
135
|
+
port?: number
|
|
136
|
+
open?: boolean
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Ports Interface
|
|
141
|
+
```typescript
|
|
142
|
+
interface Ports {
|
|
143
|
+
frontend: number
|
|
144
|
+
backend: number // proxies api
|
|
145
|
+
admin: number
|
|
146
|
+
library: number
|
|
147
|
+
desktop: number
|
|
148
|
+
email: number
|
|
149
|
+
docs: number
|
|
150
|
+
inspect: number
|
|
151
|
+
api: number // the bun server
|
|
152
|
+
systemTray: number
|
|
153
|
+
database: number // i.e. DynamoDB local
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Production Config (core/server/src/config-production.ts)
|
|
158
|
+
|
|
159
|
+
Minimal config for compiled binaries -- no runtime file loading, all env-based:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const config = {
|
|
163
|
+
app: {
|
|
164
|
+
name: process.env.APP_NAME || 'Stacks',
|
|
165
|
+
env: process.env.APP_ENV || 'production',
|
|
166
|
+
debug: process.env.APP_DEBUG === 'true' || false,
|
|
167
|
+
url: process.env.APP_URL || 'https://stacksjs.com',
|
|
168
|
+
},
|
|
169
|
+
server: {
|
|
170
|
+
port: Number(process.env.PORT) || 3000,
|
|
171
|
+
host: '0.0.0.0',
|
|
172
|
+
},
|
|
173
|
+
logging: {
|
|
174
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Used by `start.ts` (the production binary entry point) with `SKIP_CONFIG_LOADING=true` to bypass dynamic config imports.
|
|
180
|
+
|
|
181
|
+
## Production Start (core/server/src/start.ts)
|
|
182
|
+
|
|
183
|
+
Entry point for compiled production binaries. Sequence:
|
|
184
|
+
|
|
185
|
+
1. Sets `__STACKS_BINARY_MODE__ = true` on `globalThis` (prevents auto-registration in routes)
|
|
186
|
+
2. Sets `SKIP_CONFIG_LOADING = 'true'` env var
|
|
187
|
+
3. Imports `loadRoutes` and `serve` from `@stacksjs/router`
|
|
188
|
+
4. Loads routes from the `app/Routes.ts` registry via `loadRoutes(routeRegistry)`
|
|
189
|
+
5. Loads ORM auto-generated routes from `../../orm/routes` (model CRUD endpoints)
|
|
190
|
+
6. Calls `serve({ port, host })` to start the Bun HTTP server
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Production startup flow
|
|
194
|
+
loadRoutes(routeRegistry)
|
|
195
|
+
.then(async () => {
|
|
196
|
+
await import('../../orm/routes') // ORM auto-routes (after manual routes)
|
|
197
|
+
serve({ port: config.server.port, host: config.server.host })
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Auto-Imports System (core/server/src/imports.ts)
|
|
202
|
+
|
|
203
|
+
### initiateImports()
|
|
204
|
+
```typescript
|
|
205
|
+
function initiateImports(): void
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Registers a Bun bundler plugin (`bun-plugin-auto-imports`) that makes models, jobs, controllers, and resource functions available globally without explicit imports.
|
|
209
|
+
|
|
210
|
+
Scan order (user overrides framework overrides defaults):
|
|
211
|
+
- **Models**: `app/Models/` > `storage/framework/defaults/app/Models/` > `storage/framework/defaults/app/Models/`
|
|
212
|
+
- **Jobs**: `app/Jobs/`
|
|
213
|
+
- **Controllers**: `app/Controllers/` > `storage/framework/defaults/app/Controllers/`
|
|
214
|
+
- **Functions**: `resources/functions/`
|
|
215
|
+
|
|
216
|
+
Outputs:
|
|
217
|
+
- `.d.ts` file: `storage/framework/types/server-auto-imports.d.ts`
|
|
218
|
+
- ESLint config: `storage/framework/server-auto-imports.json`
|
|
219
|
+
- Runtime index files: `storage/framework/auto-imports/` (see below)
|
|
220
|
+
|
|
221
|
+
### generateAutoImportFiles()
|
|
222
|
+
```typescript
|
|
223
|
+
async function generateAutoImportFiles(): Promise<void>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Generates runtime-importable index files under `storage/framework/auto-imports/`:
|
|
227
|
+
- `functions.ts` -- re-exports from `resources/functions/`
|
|
228
|
+
- `models.ts` -- re-exports default exports from model definition files as named exports
|
|
229
|
+
- `jobs.ts` -- re-exports default exports from job definition files
|
|
230
|
+
- `controllers.ts` -- re-exports default exports from controller definition files
|
|
231
|
+
- `index.ts` -- combined re-export of all above
|
|
232
|
+
- `globals.ts` -- script that assigns all exports to `globalThis`
|
|
233
|
+
|
|
234
|
+
### injectGlobalAutoImports()
|
|
235
|
+
```typescript
|
|
236
|
+
async function injectGlobalAutoImports(): Promise<void>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Dynamically imports `storage/framework/auto-imports/index.ts` and assigns all exports to `globalThis`. Call this early in application startup to make models available globally (e.g., `Post.where('title', 'test')` without imports).
|
|
240
|
+
|
|
241
|
+
### scanDefineModelExports(dir: string): ExportInfo[]
|
|
242
|
+
Internal helper that scans a directory for `.ts` files (excluding `.d.ts`, `index.ts`, `README*`) and returns file names as export info. Used for models, jobs, and controllers that use `export default defineModel(...)` pattern.
|
|
243
|
+
|
|
244
|
+
## Base Controller (core/server/src/controllers/base.ts)
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
class Controller {
|
|
248
|
+
protected json(data: any, status?: number): ResponseData // default status: 200
|
|
249
|
+
protected success(data: any): ResponseData // alias for json(data, 200)
|
|
250
|
+
protected created(data: any): ResponseData // json(data, 201)
|
|
251
|
+
protected noContent(): any // response.noContent()
|
|
252
|
+
protected error(message: string, status?: number): ResponseData // json({ error }, 500)
|
|
253
|
+
protected notFound(message?: string): ResponseData // error(msg, 404)
|
|
254
|
+
protected unauthorized(message?: string): ResponseData // error(msg, 401)
|
|
255
|
+
protected forbidden(message?: string): ResponseData // error(msg, 403)
|
|
256
|
+
protected validate(request: Request, rules: Record<string, any>): Promise<void>
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Usage:
|
|
261
|
+
```typescript
|
|
262
|
+
import { Controller } from '@stacksjs/server'
|
|
263
|
+
|
|
264
|
+
class UserController extends Controller {
|
|
265
|
+
async index() {
|
|
266
|
+
const users = await User.all()
|
|
267
|
+
return this.success(users)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async store(request: Request) {
|
|
271
|
+
await this.validate(request, { name: 'required', email: 'required|email' })
|
|
272
|
+
const user = await User.create(request.body)
|
|
273
|
+
return this.created(user)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async show(id: number) {
|
|
277
|
+
const user = await User.find(id)
|
|
278
|
+
if (!user) return this.notFound('User not found')
|
|
279
|
+
return this.success(user)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Maintenance Mode (core/server/src/maintenance.ts)
|
|
285
|
+
|
|
286
|
+
Laravel-like maintenance mode that writes/removes a `storage/framework/down` file.
|
|
287
|
+
|
|
288
|
+
### Core Functions
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
async function down(options?: Partial<MaintenancePayload>): Promise<void>
|
|
292
|
+
async function up(): Promise<void>
|
|
293
|
+
async function isDownForMaintenance(): Promise<boolean>
|
|
294
|
+
async function maintenancePayload(): Promise<MaintenancePayload | null>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### MaintenancePayload
|
|
298
|
+
```typescript
|
|
299
|
+
interface MaintenancePayload {
|
|
300
|
+
time: number // When maintenance was activated (Date.now())
|
|
301
|
+
message?: string // Display message (default: 'We are currently performing maintenance...')
|
|
302
|
+
retry?: number // Retry-After header value in seconds
|
|
303
|
+
secret?: string // Bypass token
|
|
304
|
+
allowed?: string[] // Allowed IP addresses
|
|
305
|
+
status?: number // HTTP status (default: 503)
|
|
306
|
+
template?: string // Custom template path
|
|
307
|
+
redirect?: string // Redirect URL instead of showing maintenance page
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Bypass Helpers
|
|
312
|
+
```typescript
|
|
313
|
+
function isAllowedIp(ip: string, allowed?: string[]): boolean
|
|
314
|
+
// Localhost IPs ('127.0.0.1', '::1', 'localhost') are always allowed
|
|
315
|
+
|
|
316
|
+
function hasValidBypassCookie(cookies: Record<string, string>, secret: string): boolean
|
|
317
|
+
// Checks for cookie: stacks_maintenance_bypass=<secret>
|
|
318
|
+
|
|
319
|
+
function isSecretPath(path: string, secret: string): boolean
|
|
320
|
+
// Matches /<secret> or /<secret>/...
|
|
321
|
+
|
|
322
|
+
function bypassCookieValue(secret: string): string
|
|
323
|
+
// Returns: 'stacks_maintenance_bypass=<secret>; Path=/; HttpOnly; SameSite=Lax'
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Response Helpers
|
|
327
|
+
```typescript
|
|
328
|
+
function maintenanceHtml(payload: MaintenancePayload): string
|
|
329
|
+
// Returns a styled HTML page with gradient background
|
|
330
|
+
|
|
331
|
+
function maintenanceResponse(payload: MaintenancePayload): Response
|
|
332
|
+
// Returns Response with correct status, Retry-After header, or 302 redirect
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Usage
|
|
336
|
+
```typescript
|
|
337
|
+
import { down, up, isDownForMaintenance } from '@stacksjs/server'
|
|
338
|
+
|
|
339
|
+
// Put app in maintenance mode with bypass secret
|
|
340
|
+
await down({ secret: 'my-bypass-token', retry: 300 })
|
|
341
|
+
|
|
342
|
+
// Check if in maintenance
|
|
343
|
+
if (await isDownForMaintenance()) {
|
|
344
|
+
const payload = await maintenancePayload()
|
|
345
|
+
// ...
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Bring app back up
|
|
349
|
+
await up()
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Docker Build Pipeline (server/build.ts)
|
|
353
|
+
|
|
354
|
+
The build process (`bun build.ts` from `storage/framework/server/`):
|
|
355
|
+
|
|
356
|
+
1. **Stop existing container**: Checks for running `stacks-server` Docker container and stops it
|
|
357
|
+
2. **Clean previous build**: Deletes `app/`, `config/`, `dist/`, `docs/`, `storage/` from server dir
|
|
358
|
+
3. **Bundle server**: `Bun.build()` with `entrypoints: ['./src/index.ts']`, output to `./dist`, ESM format, `target: 'bun'`
|
|
359
|
+
4. **Bundle app**: Scans all `*.ts` and `*.js` files under `app/`, builds to `server/app/`, splitting disabled, `@swc/wasm` externalized
|
|
360
|
+
5. **Post-process app**: Rewrites `storage/framework/server` references to `dist` in output JS files
|
|
361
|
+
6. **Post-process dist**: Strips `export { ENV_KEY, ENV_SECRET, fromEnv };` from bundled output (workaround for bundler issue)
|
|
362
|
+
7. **Build Docker image** (conditional): Only if `cloud.api?.deploy` is truthy
|
|
363
|
+
|
|
364
|
+
### Docker Build (server/src/utils.ts)
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
async function buildDockerImage(): Promise<void>
|
|
368
|
+
async function useCustomOrDefaultServerConfig(): Promise<void>
|
|
369
|
+
async function cleanCopy(sourcePath: string, targetPath: string): Promise<void>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
`buildDockerImage()`:
|
|
373
|
+
- Cleans old CDK artifacts (`cdk.out/`, `cdk.context.json`, `dist.zip`)
|
|
374
|
+
- Removes `.DS_Store`, sourcemaps, cache files
|
|
375
|
+
- Copies `config/`, `docs/`, `storage/`, `.env` into `server/`
|
|
376
|
+
- Optimizes: strips `node_modules`, `src/`, `types/`, `cloud/cdk_out`
|
|
377
|
+
- Runs `docker build --pull -t <app-slug> .`
|
|
378
|
+
|
|
379
|
+
`useCustomOrDefaultServerConfig()`: If a `server/` directory exists at project root, copies it into the framework server directory, otherwise uses defaults.
|
|
380
|
+
|
|
381
|
+
## Dockerfile
|
|
382
|
+
|
|
383
|
+
Multi-stage build based on `oven/bun:1.3.10`:
|
|
384
|
+
|
|
385
|
+
```dockerfile
|
|
386
|
+
# Builder stage
|
|
387
|
+
FROM oven/bun:1.3.10 AS builder
|
|
388
|
+
WORKDIR /usr/src
|
|
389
|
+
COPY ./app ./config ./docs ./dist ./tsconfig.docker.json ./
|
|
390
|
+
|
|
391
|
+
# Release stage
|
|
392
|
+
FROM oven/bun:1.3.10 AS release
|
|
393
|
+
WORKDIR /usr/src
|
|
394
|
+
# Copies app, config, docs, dist, tsconfig from builder
|
|
395
|
+
# Sets up /usr/src/storage as a volume
|
|
396
|
+
# Installs curl for healthcheck
|
|
397
|
+
# Runs as non-root 'bun' user
|
|
398
|
+
EXPOSE 3000/tcp
|
|
399
|
+
ENTRYPOINT ["bun", "run", "dist/index.js"]
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## dev Script (server/dev)
|
|
403
|
+
|
|
404
|
+
Shell script for running the Docker container locally or against remote storage (EFS):
|
|
405
|
+
|
|
406
|
+
```sh
|
|
407
|
+
# Local development (mounts project directories as volumes)
|
|
408
|
+
./dev local
|
|
409
|
+
# docker run -p 3000:3000 -v app:/usr/src/app/app -v config:... -v storage:... stacks
|
|
410
|
+
|
|
411
|
+
# Remote/EFS (default — uses /mnt/efs for storage)
|
|
412
|
+
./dev
|
|
413
|
+
# Same volume mounts but storage points to /mnt/efs
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Environment Variables
|
|
417
|
+
|
|
418
|
+
| Variable | Default | Used In |
|
|
419
|
+
|-----------------------|--------------------|----------------------|
|
|
420
|
+
| `PORT` | `3000` | server/src/index.ts, config-production.ts |
|
|
421
|
+
| `APP_ENV` | `'production'` | config-production.ts, server/src/index.ts |
|
|
422
|
+
| `APP_NAME` | `'Stacks'` | config-production.ts |
|
|
423
|
+
| `APP_URL` | `'https://stacksjs.com'` | config-production.ts |
|
|
424
|
+
| `APP_DEBUG` | `false` | config-production.ts |
|
|
425
|
+
| `LOG_LEVEL` | `'info'` | config-production.ts |
|
|
426
|
+
| `SKIP_CONFIG_LOADING` | unset | start.ts (set to `'true'`) |
|
|
427
|
+
| `QUEUE_WORKER` | unset | server/src/index.ts |
|
|
428
|
+
| `JOB` | required if worker | server/src/index.ts |
|
|
429
|
+
| `JOB_RETRIES` | `3` | server/src/index.ts |
|
|
430
|
+
| `JOB_BACKOFF_FACTOR` | `2` | server/src/index.ts |
|
|
431
|
+
| `JOB_INITIAL_DELAY` | `1000` | server/src/index.ts |
|
|
432
|
+
| `JOB_JITTER` | `'false'` | server/src/index.ts |
|
|
433
|
+
|
|
434
|
+
## CLI Commands
|
|
435
|
+
- `buddy dev` or `bun run dev` -- start development server (uses `storage/framework/server/src/index.ts` with hot reload)
|
|
436
|
+
- `buddy serve` or `bun run serve` -- start production server
|
|
437
|
+
- `buddy build:server` -- run the Docker build pipeline (`storage/framework/server/build.ts`)
|
|
438
|
+
- `buddy down` -- put app in maintenance mode
|
|
439
|
+
- `buddy up` -- bring app out of maintenance mode
|
|
440
|
+
|
|
441
|
+
## Gotchas
|
|
442
|
+
- The server lives in TWO places: `storage/framework/core/server/` is the published `@stacksjs/server` package (config, controllers, imports, maintenance); `storage/framework/server/` is the actual runtime Bun HTTP server and Docker build infrastructure
|
|
443
|
+
- The server runtime (`storage/framework/server/`) has its own `package.json`, `tsconfig.json`, and is excluded from workspaces -- it is a standalone deployable unit
|
|
444
|
+
- The `.gitignore` in `storage/framework/server/` excludes `app/`, `config/`, `dist/`, `storage/` because these are populated at build time by `build.ts`
|
|
445
|
+
- `start.ts` sets `__STACKS_BINARY_MODE__ = true` on `globalThis` -- this flag prevents route auto-registration and is only used for compiled production binaries
|
|
446
|
+
- Port configuration comes from `@stacksjs/config` (`ports` export), not from a standalone `config/ports.ts` file -- the Ports interface is defined in `storage/framework/core/types/src/ports.ts`
|
|
447
|
+
- The `config()` function always sets `open: false` (browser auto-open is commented out)
|
|
448
|
+
- The default host for unnamed server types is `'stacks.localhost'`, not `'localhost'`
|
|
449
|
+
- Production config binds to `0.0.0.0` (all interfaces), while development config uses `localhost`
|
|
450
|
+
- `serverResponse()` from `@stacksjs/router` is the single function that handles ALL HTTP request routing -- the server itself has no routing logic
|
|
451
|
+
- ORM auto-routes are loaded AFTER manual routes in `start.ts` so that `routeExists()` correctly detects conflicts
|
|
452
|
+
- The queue worker mode reuses the same entry point (`server/src/index.ts`) -- when `QUEUE_WORKER` is set, no HTTP server starts; it runs the job and exits
|
|
453
|
+
- Job names are sanitized with `/[^a-zA-Z0-9_-]/g` to prevent path traversal attacks
|
|
454
|
+
- `generateAutoImportFiles()` runs fire-and-forget during `initiateImports()` -- errors are logged but do not block server startup
|
|
455
|
+
- User models/controllers/jobs take priority over framework defaults due to deduplication order (user dirs are scanned first)
|
|
456
|
+
- The Docker image runs as non-root user `bun` with `/usr/src/storage` as a persistent volume
|
|
457
|
+
- `build.ts` strips `export { ENV_KEY, ENV_SECRET, fromEnv }` from bundled output as a workaround for a Bun bundler issue
|
|
458
|
+
- `tsconfig.docker.json` has path aliases that remap `@stacksjs/*` to `core/*/dist` -- this is critical for the Docker build to resolve packages without workspace symlinks
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-shell
|
|
3
|
+
description: Use when executing shell commands in a Stacks application — running system commands, process management, or using the shell operator. Covers @stacksjs/shell which wraps Bun's native $ operator.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Shell
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/shell/src/`
|
|
13
|
+
- Source: `storage/framework/core/shell/src/index.ts`
|
|
14
|
+
- Package: `@stacksjs/shell`
|
|
15
|
+
|
|
16
|
+
## API
|
|
17
|
+
|
|
18
|
+
The entire package is a single re-export of Bun's `$` shell operator:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
export { $ } from 'bun'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { $ } from '@stacksjs/shell'
|
|
28
|
+
|
|
29
|
+
// Run shell commands
|
|
30
|
+
await $`ls -la`
|
|
31
|
+
|
|
32
|
+
// Capture output
|
|
33
|
+
const result = await $`git status`
|
|
34
|
+
console.log(result.text())
|
|
35
|
+
|
|
36
|
+
// Set working directory
|
|
37
|
+
$.cwd('/path/to/dir')
|
|
38
|
+
await $`bun install`
|
|
39
|
+
|
|
40
|
+
// Pipe commands
|
|
41
|
+
await $`cat file.txt | grep "pattern"`
|
|
42
|
+
|
|
43
|
+
// Environment variables
|
|
44
|
+
await $`echo $HOME`
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Bun $ Operator Features
|
|
48
|
+
|
|
49
|
+
- **Template literals** — commands written as tagged template strings
|
|
50
|
+
- **Auto-escaping** — interpolated values are safely escaped
|
|
51
|
+
- **Streaming** — stdout/stderr can be streamed
|
|
52
|
+
- **CWD** — `$.cwd(path)` sets working directory
|
|
53
|
+
- **Env** — `$.env(vars)` sets environment variables
|
|
54
|
+
- **Quiet mode** — `$.quiet()` suppresses output
|
|
55
|
+
- **Throws on error** — non-zero exit codes throw by default
|
|
56
|
+
|
|
57
|
+
## Gotchas
|
|
58
|
+
- **Thin wrapper** — this package literally just re-exports `$` from Bun
|
|
59
|
+
- **Server-side only** — shell commands run in the server environment, not in the browser
|
|
60
|
+
- **For CLI output formatting, use `@stacksjs/cli`** — this package is for raw command execution
|
|
61
|
+
- **Bun-specific** — the `$` operator is a Bun feature, not available in Node.js
|
|
62
|
+
- **Used throughout the framework** — build actions, CLI commands, and dev server all use `$` for process execution
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-slug
|
|
3
|
+
description: Use when generating URL slugs in Stacks — creating unique slugs with database collision detection, the uniqueSlug function with table/column configuration, or basic slugification. Covers @stacksjs/slug.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Slug
|
|
10
|
+
|
|
11
|
+
URL-friendly slug generation with database uniqueness checking.
|
|
12
|
+
|
|
13
|
+
## Key Paths
|
|
14
|
+
- Core package: `storage/framework/core/slug/src/`
|
|
15
|
+
|
|
16
|
+
## Unique Slug (with Database Check)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { uniqueSlug } from '@stacksjs/slug'
|
|
20
|
+
|
|
21
|
+
// Basic usage — checks 'slug' column in inferred table
|
|
22
|
+
const slug = await uniqueSlug('My Blog Post Title')
|
|
23
|
+
// → 'my-blog-post-title'
|
|
24
|
+
|
|
25
|
+
// If 'my-blog-post-title' exists in DB:
|
|
26
|
+
// → 'my-blog-post-title-2'
|
|
27
|
+
|
|
28
|
+
// With options
|
|
29
|
+
const slug = await uniqueSlug('Product Name', {
|
|
30
|
+
table: 'products', // database table to check
|
|
31
|
+
column: 'slug' // column name (default: 'slug')
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### How Collision Detection Works
|
|
36
|
+
1. Slugifies the input string
|
|
37
|
+
2. Queries the database for existing slug
|
|
38
|
+
3. If collision found, appends `-2`, `-3`, etc.
|
|
39
|
+
4. Returns the first available slug
|
|
40
|
+
|
|
41
|
+
## Basic Slugify (No Database Check)
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { slugify } from '@stacksjs/slug'
|
|
45
|
+
|
|
46
|
+
slugify('Hello World!') // 'hello-world'
|
|
47
|
+
slugify('Ünïcödé Têxt') // 'unicode-text'
|
|
48
|
+
slugify(' Extra Spaces ') // 'extra-spaces'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Re-exported from `ts-slug` — handles Unicode transliteration.
|
|
52
|
+
|
|
53
|
+
## Model Usage
|
|
54
|
+
|
|
55
|
+
Models typically use slugs via the `slug` attribute:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
defineModel({
|
|
59
|
+
name: 'Post',
|
|
60
|
+
attributes: {
|
|
61
|
+
title: { validation: { rule: schema.string() } },
|
|
62
|
+
slug: {
|
|
63
|
+
unique: true,
|
|
64
|
+
validation: { rule: schema.string() },
|
|
65
|
+
// Auto-generated from title via uniqueSlug()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## SlugifyOptions
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface SlugifyOptions {
|
|
75
|
+
table?: string // database table for uniqueness check
|
|
76
|
+
column?: string // column name (default: 'slug')
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Gotchas
|
|
81
|
+
- `uniqueSlug()` is async — it queries the database
|
|
82
|
+
- `slugify()` is sync — no database interaction
|
|
83
|
+
- Collision detection appends `-2`, `-3`, etc. (not random suffixes)
|
|
84
|
+
- Unicode characters are transliterated (u → u, e → e, etc.)
|
|
85
|
+
- For string-only slugification without DB, use `slug()` from `@stacksjs/strings` instead
|
|
86
|
+
- Tags and Categories both use unique slugs by default
|
|
87
|
+
- Slug columns should have a unique index in the database
|