@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,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-health
|
|
3
|
+
description: Use when implementing health checks in a Stacks application — service monitoring, health endpoints, or diagnostic checks. Covers @stacksjs/health (currently WIP — Oh Dear integration planned).
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks Health
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/health/src/`
|
|
13
|
+
- Drivers: `storage/framework/core/health/src/drivers/`
|
|
14
|
+
- Notifications: `storage/framework/core/health/src/notifications/`
|
|
15
|
+
- Package: `@stacksjs/health`
|
|
16
|
+
|
|
17
|
+
## Source Files
|
|
18
|
+
```
|
|
19
|
+
health/src/
|
|
20
|
+
├── index.ts # Re-exports drivers and notifications
|
|
21
|
+
├── drivers/
|
|
22
|
+
│ ├── index.ts # Driver exports
|
|
23
|
+
│ └── ohdear.ts # Oh Dear health check driver (WIP)
|
|
24
|
+
└── notifications/
|
|
25
|
+
└── index.ts # Health notifications (WIP)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Current Status
|
|
29
|
+
|
|
30
|
+
**This package is WIP.** Current exports are placeholder markers:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
export const ohdearWip = 1 // Oh Dear driver placeholder
|
|
34
|
+
export const healthNotificationsWip = 1 // Notifications placeholder
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Built-in Health Endpoint
|
|
38
|
+
|
|
39
|
+
The health check functionality currently lives in the router, not this package:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
GET /health
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"status": "ok",
|
|
49
|
+
"uptime": 12345,
|
|
50
|
+
"memory": { "rss": 1234567, "heapUsed": 987654 },
|
|
51
|
+
"pid": 1234,
|
|
52
|
+
"bunVersion": "1.3.0"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This endpoint is registered via `route.health()` in the router.
|
|
57
|
+
|
|
58
|
+
## CLI Commands
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
buddy doctor # Comprehensive system diagnostics
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Planned Features
|
|
65
|
+
- Oh Dear integration for external health monitoring
|
|
66
|
+
- Health check notifications (email, Slack, etc.)
|
|
67
|
+
- Custom health check drivers
|
|
68
|
+
- Database connectivity checks
|
|
69
|
+
- External service status verification
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
- **Package is WIP** — only placeholder exports exist
|
|
73
|
+
- **Health endpoint is in the router** — `GET /health` works via `route.health()`, not this package
|
|
74
|
+
- **`buddy doctor`** — system diagnostics are in the buddy CLI, not this health package
|
|
75
|
+
- **Oh Dear driver planned** — integration with ohdear.app for external monitoring
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-http
|
|
3
|
+
description: Use when working with HTTP utilities in a Stacks application — HTTP status codes, making outbound HTTP requests via HttxClient, reactive fetch composables (useFetch/createFetch), or HTTP-related helpers. Covers @stacksjs/http, @stacksjs/httx, and the fetch composables in @stacksjs/composables.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks HTTP
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/http/src/`
|
|
13
|
+
- Composables (useFetch/createFetch): `storage/framework/core/composables/src/useFetch.ts`, `storage/framework/core/composables/src/createFetch.ts`
|
|
14
|
+
- Buddy CLI command: `storage/framework/core/buddy/src/commands/http.ts`
|
|
15
|
+
- httx dependency (installed): `node_modules/@stacksjs/httx/`
|
|
16
|
+
- Package: `@stacksjs/http` (status codes), `@stacksjs/httx` (HTTP client), `@stacksjs/composables` (useFetch/createFetch)
|
|
17
|
+
|
|
18
|
+
## Source Files
|
|
19
|
+
```
|
|
20
|
+
http/src/
|
|
21
|
+
└── index.ts # Response enum — all HTTP status codes (100-511)
|
|
22
|
+
|
|
23
|
+
composables/src/
|
|
24
|
+
├── useFetch.ts # Chainable reactive fetch composable (builder pattern)
|
|
25
|
+
└── createFetch.ts # Factory for pre-configured useFetch with baseUrl
|
|
26
|
+
|
|
27
|
+
buddy/src/commands/
|
|
28
|
+
└── http.ts # `buddy http [domain]` CLI command using HttxClient
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Response Enum — HTTP Status Codes (index.ts)
|
|
32
|
+
|
|
33
|
+
The `@stacksjs/http` package exports a single `Response` enum with all standard HTTP status codes:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { Response } from '@stacksjs/http'
|
|
37
|
+
|
|
38
|
+
Response.HTTP_OK // 200
|
|
39
|
+
Response.HTTP_CREATED // 201
|
|
40
|
+
Response.HTTP_NO_CONTENT // 204
|
|
41
|
+
Response.HTTP_MOVED_PERMANENTLY // 301
|
|
42
|
+
Response.HTTP_NOT_MODIFIED // 304
|
|
43
|
+
Response.HTTP_BAD_REQUEST // 400
|
|
44
|
+
Response.HTTP_UNAUTHORIZED // 401
|
|
45
|
+
Response.HTTP_FORBIDDEN // 403
|
|
46
|
+
Response.HTTP_NOT_FOUND // 404
|
|
47
|
+
Response.HTTP_UNPROCESSABLE_ENTITY // 422
|
|
48
|
+
Response.HTTP_TOO_MANY_REQUESTS // 429
|
|
49
|
+
Response.HTTP_INTERNAL_SERVER_ERROR // 500
|
|
50
|
+
Response.HTTP_SERVICE_UNAVAILABLE // 503
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Full Status Code Categories
|
|
54
|
+
- **1xx Informational**: `HTTP_CONTINUE` (100), `HTTP_SWITCHING_PROTOCOLS` (101)
|
|
55
|
+
- **2xx Success**: `HTTP_OK` (200), `HTTP_CREATED` (201), `HTTP_ACCEPTED` (202), `HTTP_NON_AUTHORITATIVE_INFORMATION` (203), `HTTP_NO_CONTENT` (204), `HTTP_RESET_CONTENT` (205), `HTTP_PARTIAL_CONTENT` (206)
|
|
56
|
+
- **3xx Redirection**: `HTTP_MULTIPLE_CHOICES` (300), `HTTP_MOVED_PERMANENTLY` (301), `HTTP_FOUND` (302), `HTTP_SEE_OTHER` (303), `HTTP_NOT_MODIFIED` (304), `HTTP_USE_PROXY` (305), `HTTP_UNUSED` (306), `HTTP_TEMPORARY_REDIRECT` (307), `HTTP_PERMANENT_REDIRECT` (308)
|
|
57
|
+
- **4xx Client Error**: `HTTP_BAD_REQUEST` (400) through `HTTP_UNAVAILABLE_FOR_LEGAL_REASONS` (451) — includes `HTTP_I_AM_A_TEAPOT` (418)
|
|
58
|
+
- **5xx Server Error**: `HTTP_INTERNAL_SERVER_ERROR` (500) through `HTTP_NETWORK_AUTHENTICATION_REQUIRED` (511)
|
|
59
|
+
|
|
60
|
+
## HttxClient — Outbound HTTP Client (@stacksjs/httx)
|
|
61
|
+
|
|
62
|
+
The `@stacksjs/httx` package provides the `HttxClient` class for making outbound HTTP requests. It wraps Bun's `fetch()` with retry logic, timeouts, timing data, and Result-based error handling via `ts-error-handling`.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { HttxClient } from '@stacksjs/httx'
|
|
66
|
+
|
|
67
|
+
const client = new HttxClient(config?: Partial<HttxConfig>)
|
|
68
|
+
const result = await client.request<T>(url: string, options: RequestOptions): Promise<Result<HttxResponse<T>, Error>>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### HttxConfig
|
|
72
|
+
```typescript
|
|
73
|
+
interface HttxConfig {
|
|
74
|
+
verbose?: boolean | string[] // Enable debug logging (or filter by category)
|
|
75
|
+
defaultHeaders?: Record<string, string>
|
|
76
|
+
baseUrl?: string // Prepended to all request URLs
|
|
77
|
+
timeout?: number // Request timeout in ms
|
|
78
|
+
retry?: RetryOptions // Default retry configuration
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### RequestOptions
|
|
83
|
+
```typescript
|
|
84
|
+
interface RequestOptions {
|
|
85
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS'
|
|
86
|
+
query?: Record<string, string> // URL query parameters
|
|
87
|
+
form?: boolean // Send body as form-encoded
|
|
88
|
+
multipart?: boolean // Send body as multipart/form-data
|
|
89
|
+
json?: boolean // Send body as JSON
|
|
90
|
+
unix?: string // Unix socket path
|
|
91
|
+
proxy?: string // Proxy URL
|
|
92
|
+
downloadProgress?: (progress: number) => void
|
|
93
|
+
retry?: RetryOptions // Per-request retry override
|
|
94
|
+
stream?: boolean // Stream response
|
|
95
|
+
acceptHeader?: string // Override Accept header
|
|
96
|
+
verbose?: boolean
|
|
97
|
+
timeout?: number
|
|
98
|
+
body?: BodyInit | Record<string, string>
|
|
99
|
+
headers?: HeadersInit
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### RetryOptions
|
|
104
|
+
```typescript
|
|
105
|
+
interface RetryOptions {
|
|
106
|
+
retries?: number // Max retry attempts
|
|
107
|
+
retryDelay?: number // Base delay between retries (ms)
|
|
108
|
+
retryOn?: number[] // HTTP status codes that trigger retry
|
|
109
|
+
shouldRetry?: (error: Error, attempt: number) => boolean // Custom retry predicate
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### HttxResponse
|
|
114
|
+
```typescript
|
|
115
|
+
interface HttxResponse<T = unknown> {
|
|
116
|
+
status: number
|
|
117
|
+
statusText: string
|
|
118
|
+
headers: Headers
|
|
119
|
+
data: T
|
|
120
|
+
timings: {
|
|
121
|
+
start: number
|
|
122
|
+
end: number
|
|
123
|
+
duration: number // Total request duration in ms
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Result Pattern (from ts-error-handling)
|
|
129
|
+
`client.request()` returns a `Result<HttxResponse<T>, Error>`. Use `.match()` to handle success/failure:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const result = await client.request('https://api.example.com/users', {
|
|
133
|
+
method: 'GET',
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
result.match({
|
|
137
|
+
ok: (response) => {
|
|
138
|
+
console.log(response.status) // 200
|
|
139
|
+
console.log(response.timings.duration) // e.g. 142 (ms)
|
|
140
|
+
console.log(response.data) // parsed response body
|
|
141
|
+
},
|
|
142
|
+
err: (error) => {
|
|
143
|
+
console.error(error.message)
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or use `result.isOk` / `result.value` / `result.error` directly.
|
|
149
|
+
|
|
150
|
+
### Error Classes
|
|
151
|
+
```typescript
|
|
152
|
+
class HttxError extends Error {
|
|
153
|
+
readonly context?: Record<string, unknown>
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
class HttxRequestError extends HttxError {
|
|
157
|
+
readonly method: string
|
|
158
|
+
readonly url: string
|
|
159
|
+
readonly statusCode?: number
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
class HttxTimeoutError extends HttxError {
|
|
163
|
+
readonly method: string
|
|
164
|
+
readonly url: string
|
|
165
|
+
readonly timeout: number
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class HttxNetworkError extends HttxError {
|
|
169
|
+
readonly method: string
|
|
170
|
+
readonly url: string
|
|
171
|
+
readonly originalError?: Error
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
class HttxResponseError extends HttxRequestError {
|
|
175
|
+
readonly statusText: string
|
|
176
|
+
readonly responseBody?: unknown
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Utility Exports
|
|
181
|
+
```typescript
|
|
182
|
+
import { debugLog, sleep } from '@stacksjs/httx'
|
|
183
|
+
|
|
184
|
+
debugLog(category: string, message: string | (() => string), verbose?: boolean | string[]): void
|
|
185
|
+
sleep(ms: number): Promise<void>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Config Exports
|
|
189
|
+
```typescript
|
|
190
|
+
import { config, defaultConfig, getConfig } from '@stacksjs/httx'
|
|
191
|
+
|
|
192
|
+
const config: HttxConfig // Synchronous access with default fallback
|
|
193
|
+
const defaultConfig: HttxConfig // Default configuration object
|
|
194
|
+
function getConfig(): Promise<HttxConfig> // Async config loader
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## useFetch — Reactive Fetch Composable (@stacksjs/composables)
|
|
198
|
+
|
|
199
|
+
A chainable, reactive fetch composable using the builder pattern. Uses native `fetch()` under the hood (not HttxClient). Returns reactive `Ref` values from `@stacksjs/stx`.
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { useFetch } from '@stacksjs/composables'
|
|
203
|
+
|
|
204
|
+
// Builder pattern: method -> format -> result
|
|
205
|
+
const { data, error, isFetching } = await useFetch('/api/posts').get().json()
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### FetchBuilder Interface
|
|
209
|
+
```typescript
|
|
210
|
+
interface FetchBuilder {
|
|
211
|
+
get: () => FetchBuilder
|
|
212
|
+
post: (body?: string) => FetchBuilder
|
|
213
|
+
patch: (body?: string) => FetchBuilder
|
|
214
|
+
put: (body?: string) => FetchBuilder
|
|
215
|
+
delete: () => FetchBuilder
|
|
216
|
+
json: () => UseFetchResult
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### UseFetchResult Interface
|
|
221
|
+
```typescript
|
|
222
|
+
interface UseFetchResult {
|
|
223
|
+
data: Ref<any> // Reactive ref — populated with parsed JSON on success
|
|
224
|
+
error: Ref<any> // Reactive ref — populated with error JSON or Error object
|
|
225
|
+
isFetching: Ref<boolean> // Starts as true, becomes false when request completes
|
|
226
|
+
then: (resolve: (value: { data: Ref<any>, error: Ref<any> }) => void) => Promise<void>
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Usage Examples
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { useFetch } from '@stacksjs/composables'
|
|
234
|
+
|
|
235
|
+
// GET request
|
|
236
|
+
const { data, error } = await useFetch('/api/users').get().json()
|
|
237
|
+
|
|
238
|
+
// POST with JSON body
|
|
239
|
+
const { data, error } = await useFetch('/api/users')
|
|
240
|
+
.post(JSON.stringify({ name: 'Alice', email: 'alice@example.com' }))
|
|
241
|
+
.json()
|
|
242
|
+
|
|
243
|
+
// PATCH with body
|
|
244
|
+
const { data, error } = await useFetch('/api/users/1')
|
|
245
|
+
.patch(JSON.stringify({ name: 'Updated' }))
|
|
246
|
+
.json()
|
|
247
|
+
|
|
248
|
+
// DELETE
|
|
249
|
+
const { data, error } = await useFetch('/api/users/1').delete().json()
|
|
250
|
+
|
|
251
|
+
// Synchronous access (reactive — updates when request completes)
|
|
252
|
+
const result = useFetch('/api/items').get().json()
|
|
253
|
+
result.isFetching.value // true (synchronously, before microtask resolves)
|
|
254
|
+
// ... later ...
|
|
255
|
+
result.data.value // parsed JSON response
|
|
256
|
+
result.isFetching.value // false
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### How json() Works Internally
|
|
260
|
+
1. Builds a `RequestInit` with the configured method and `Accept: application/json` header
|
|
261
|
+
2. For POST/PATCH/PUT with a body, also sets `Content-Type: application/json`
|
|
262
|
+
3. Calls native `fetch(url, init)`
|
|
263
|
+
4. On success (`response.ok`), parses JSON into `data.value`
|
|
264
|
+
5. On HTTP error, parses JSON into `error.value`
|
|
265
|
+
6. On network error, sets `error.value` to the caught Error
|
|
266
|
+
7. Always sets `isFetching.value = false` in `finally`
|
|
267
|
+
|
|
268
|
+
## createFetch — Pre-configured Fetch Factory (@stacksjs/composables)
|
|
269
|
+
|
|
270
|
+
Creates a reusable `useFetch` instance with a pre-configured base URL.
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { createFetch } from '@stacksjs/composables'
|
|
274
|
+
|
|
275
|
+
interface CreateFetchOptions {
|
|
276
|
+
baseUrl?: string // Base URL prepended to all requests
|
|
277
|
+
options?: RequestInit // Default options (currently unused in implementation)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const useApi = createFetch({ baseUrl: 'https://api.example.com' })
|
|
281
|
+
|
|
282
|
+
// URL becomes: https://api.example.com/users
|
|
283
|
+
const { data, error } = await useApi('/users').get().json()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### URL Resolution
|
|
287
|
+
`createFetch` joins the base URL and path by stripping trailing/leading slashes:
|
|
288
|
+
- `baseUrl: 'https://api.example.com/'` + `'/users'` → `'https://api.example.com/users'`
|
|
289
|
+
- `baseUrl: 'https://api.example.com'` + `'users'` → `'https://api.example.com/users'`
|
|
290
|
+
|
|
291
|
+
## CLI Command — buddy http
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
buddy http [domain] # Send a GET request (defaults to config.app.url)
|
|
295
|
+
buddy http example.com # GET https://example.com
|
|
296
|
+
buddy http -v example.com # Verbose output
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The CLI command uses `HttxClient` from `@stacksjs/httx`:
|
|
300
|
+
- Prepends `https://` if the URL does not start with `http`
|
|
301
|
+
- Logs status code, status text, and duration
|
|
302
|
+
- Prints response body (string or pretty-printed JSON)
|
|
303
|
+
|
|
304
|
+
## Gotchas
|
|
305
|
+
- **`@stacksjs/http` is status codes only** — it exports a single `Response` enum with HTTP status code constants. It does NOT contain an HTTP client, request helpers, or fetch utilities
|
|
306
|
+
- **The actual HTTP client is `@stacksjs/httx`** — a separate package (not part of `@stacksjs/http`). It is used by `buddy http` and available for general use
|
|
307
|
+
- **`useFetch` uses native `fetch()`, not HttxClient** — despite `@stacksjs/httx` being available, the `useFetch` composable calls the global `fetch()` directly
|
|
308
|
+
- **`useFetch` only supports `.json()` format** — there is no `.text()`, `.blob()`, or `.arrayBuffer()` method. The only terminal method is `.json()`
|
|
309
|
+
- **Method chaining overrides previous method** — calling `.post('body').get()` will send a GET request (last method wins, body is cleared for GET/DELETE)
|
|
310
|
+
- **`createFetch` ignores the `options` parameter** — the `CreateFetchOptions.options` field is declared in the interface but not used in the implementation
|
|
311
|
+
- **`useFetch` body is only sent for POST/PATCH/PUT** — GET and DELETE requests strip the body even if one was set
|
|
312
|
+
- **The `Response` enum name conflicts with the global `Response`** — importing `Response` from `@stacksjs/http` shadows the native Fetch API `Response` type. Use a named import alias if both are needed: `import { Response as HttpStatus } from '@stacksjs/http'`
|
|
313
|
+
- **HttxClient uses Result pattern** — `request()` returns `Result<HttxResponse, Error>` from `ts-error-handling`, not a plain Promise. Use `.match()`, `.isOk`, or `.value`/`.error` to unwrap
|
|
314
|
+
- **`useFetch` returns reactive Refs** — `data`, `error`, and `isFetching` are `Ref<T>` from `@stacksjs/stx`. Access values via `.value` property
|
|
315
|
+
- **No request interceptors or middleware** — neither `useFetch` nor `HttxClient` support request/response interceptors
|
|
316
|
+
- **For API route handling, use `@stacksjs/router`** — `@stacksjs/http` and `@stacksjs/httx` are for outbound requests only, not for defining API endpoints
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacks-i18n
|
|
3
|
+
description: Use when working with internationalization in a Stacks application — translations, locale management, pluralization, date/number/currency formatting, or loading translation files. Covers @stacksjs/i18n with translator, formatter, loader, and pluralization modules.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
|
+
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stacks i18n
|
|
10
|
+
|
|
11
|
+
## Key Paths
|
|
12
|
+
- Core package: `storage/framework/core/i18n/src/`
|
|
13
|
+
- Locale files: `locales/` (en.yml, de.yml)
|
|
14
|
+
- Package: `@stacksjs/i18n`
|
|
15
|
+
|
|
16
|
+
## Source Files
|
|
17
|
+
```
|
|
18
|
+
i18n/src/
|
|
19
|
+
├── index.ts # Main entry point and exports
|
|
20
|
+
├── types.ts # All type definitions
|
|
21
|
+
├── translator.ts # I18n class, global API (t, tc, te, tm)
|
|
22
|
+
├── formatter.ts # Locale-aware formatting (dates, numbers, currency, lists)
|
|
23
|
+
├── loader.ts # File-based translation loader (JSON, YAML, JS/TS)
|
|
24
|
+
└── pluralization.ts # CLDR plural rules for 25+ languages
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Core Types
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
type TranslationMessages = { [key: string]: string | TranslationMessages }
|
|
31
|
+
type Translations = { [locale: string]: TranslationMessages }
|
|
32
|
+
type InterpolationValues = Record<string, string | number | boolean | null | undefined>
|
|
33
|
+
|
|
34
|
+
interface I18nConfig {
|
|
35
|
+
locale: string // default: 'en'
|
|
36
|
+
fallbackLocale: string // default: 'en'
|
|
37
|
+
availableLocales?: string[]
|
|
38
|
+
messages?: Translations
|
|
39
|
+
missingHandler?: (locale: string, key: string) => string | undefined
|
|
40
|
+
warnMissing?: boolean // default: true
|
|
41
|
+
escapeValues?: boolean // default: false
|
|
42
|
+
keySeparator?: string // default: '.'
|
|
43
|
+
pluralSeparator?: string // default: '|'
|
|
44
|
+
dateTimeFormats?: DateTimeFormats
|
|
45
|
+
numberFormats?: NumberFormats
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Translation API
|
|
50
|
+
|
|
51
|
+
### Instance-Based
|
|
52
|
+
```typescript
|
|
53
|
+
import { createI18n, useI18n } from '@stacksjs/i18n'
|
|
54
|
+
|
|
55
|
+
const i18n = createI18n({
|
|
56
|
+
locale: 'en',
|
|
57
|
+
fallbackLocale: 'en',
|
|
58
|
+
messages: {
|
|
59
|
+
en: { greeting: 'Hello, {name}!' },
|
|
60
|
+
de: { greeting: 'Hallo, {name}!' },
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
i18n.t('greeting', { name: 'World' }) // 'Hello, World!'
|
|
65
|
+
i18n.setLocale('de')
|
|
66
|
+
i18n.t('greeting', { name: 'Welt' }) // 'Hallo, Welt!'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Global API
|
|
70
|
+
```typescript
|
|
71
|
+
import { t, tc, te, tm, trans, setLocale, getLocale, addTranslations, configure } from '@stacksjs/i18n'
|
|
72
|
+
|
|
73
|
+
t('greeting', { name: 'World' }) // Translate with interpolation
|
|
74
|
+
tc('items', 5, { count: 5 }) // Plural translation
|
|
75
|
+
te('greeting') // Key exists? → boolean
|
|
76
|
+
tm('section') // Raw message object
|
|
77
|
+
trans('greeting') // Alias for t()
|
|
78
|
+
|
|
79
|
+
setLocale('fr')
|
|
80
|
+
getLocale() // 'fr'
|
|
81
|
+
addTranslations('fr', { greeting: 'Bonjour, {name}!' })
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Lookup Flow
|
|
85
|
+
```
|
|
86
|
+
1. Look up key in target locale
|
|
87
|
+
2. If not found → try fallback locale
|
|
88
|
+
3. If still not found → call missingHandler → warn → return key string
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Pluralization
|
|
92
|
+
|
|
93
|
+
CLDR plural rules, pipe-separated forms:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
addTranslations('en', { items: 'no items | one item | {count} items' })
|
|
97
|
+
tc('items', 0) // 'no items'
|
|
98
|
+
tc('items', 1) // 'one item'
|
|
99
|
+
tc('items', 5) // '5 items'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Supported Languages
|
|
103
|
+
|
|
104
|
+
| Rule | Languages |
|
|
105
|
+
|------|-----------|
|
|
106
|
+
| One/Other | en, de, nl, es, it, pt, sv, da, no, fi, el, he, hu, tr |
|
|
107
|
+
| French (0-1=one) | fr |
|
|
108
|
+
| No plural | zh, ja, ko, vi, th, id, ms |
|
|
109
|
+
| One/Few/Many/Other | ru, uk, pl |
|
|
110
|
+
| One/Few/Other | cs, sk |
|
|
111
|
+
| Full (zero/one/two/few/many/other) | ar, cy |
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { getPluralCategory, addPluralRule, hasPluralRule } from '@stacksjs/i18n'
|
|
115
|
+
getPluralCategory(1, 'en') // 'one'
|
|
116
|
+
getPluralCategory(5, 'en') // 'other'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Formatting
|
|
120
|
+
|
|
121
|
+
### Date/Time
|
|
122
|
+
```typescript
|
|
123
|
+
import { formatDate, formatTime, formatDateTime, formatRelativeTime } from '@stacksjs/i18n'
|
|
124
|
+
|
|
125
|
+
formatDate(new Date(), 'long') // 'March 23, 2026'
|
|
126
|
+
formatDate(new Date(), 'short') // '3/23/26'
|
|
127
|
+
formatTime(new Date(), 'short') // '2:30 PM'
|
|
128
|
+
formatDateTime(new Date(), 'medium', 'short') // 'Mar 23, 2026, 2:30 PM'
|
|
129
|
+
formatRelativeTime(pastDate) // '3 hours ago'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Numbers & Currency
|
|
133
|
+
```typescript
|
|
134
|
+
import { formatNumber, formatCurrency, formatPercent, formatUnit, formatBytes } from '@stacksjs/i18n'
|
|
135
|
+
|
|
136
|
+
formatNumber(1234567) // '1,234,567'
|
|
137
|
+
formatNumber(1234567, { compact: true }) // '1.2M'
|
|
138
|
+
formatCurrency(29.99) // '$29.99'
|
|
139
|
+
formatCurrency(29.99, 'EUR', {}, 'de') // '29,99 €'
|
|
140
|
+
formatPercent(0.85) // '85%'
|
|
141
|
+
formatUnit(60, 'kilometer-per-hour', 'short') // '60 km/h'
|
|
142
|
+
formatBytes(1536) // '1.50 KB'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Lists & Display Names
|
|
146
|
+
```typescript
|
|
147
|
+
import { formatList, getLanguageName, getRegionName, isRTL } from '@stacksjs/i18n'
|
|
148
|
+
|
|
149
|
+
formatList(['Alice', 'Bob', 'Charlie']) // 'Alice, Bob, and Charlie'
|
|
150
|
+
formatList(['A', 'B'], 'disjunction') // 'A or B'
|
|
151
|
+
getLanguageName('de') // 'German'
|
|
152
|
+
getRegionName('JP') // 'Japan'
|
|
153
|
+
isRTL('ar') // true
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### String Collation
|
|
157
|
+
```typescript
|
|
158
|
+
import { sortStrings, compareStrings } from '@stacksjs/i18n'
|
|
159
|
+
sortStrings(['ö', 'a', 'ü'], {}, 'de') // Locale-aware sort
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Translation File Loader
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { loadFromDirectory, loadFile, createLoader } from '@stacksjs/i18n'
|
|
166
|
+
|
|
167
|
+
const translations = await loadFromDirectory({
|
|
168
|
+
directory: './locales',
|
|
169
|
+
extensions: ['.json', '.yaml', '.yml', '.ts', '.js'],
|
|
170
|
+
recursive: false,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const loader = createLoader('./locales')
|
|
174
|
+
const all = await loader.load()
|
|
175
|
+
const fr = await loader.loadLocale('fr', 'messages.yml')
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Locale Files
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
# locales/en.yml
|
|
182
|
+
default:
|
|
183
|
+
button:
|
|
184
|
+
about: About
|
|
185
|
+
back: Back
|
|
186
|
+
intro:
|
|
187
|
+
desc: Rapid Application Development
|
|
188
|
+
hi: 'Hi, {name}!'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Gotchas
|
|
192
|
+
- **Dual API** — instance-based (`createI18n()`) and global (`t()`) both exist. Global uses a singleton
|
|
193
|
+
- **YAML parsed with Bun.YAML** — not a third-party parser
|
|
194
|
+
- **Missing keys return the key itself** — not an error, not empty string
|
|
195
|
+
- **Pluralization uses `|` separator** — not ICU MessageFormat
|
|
196
|
+
- **CLDR rules are built-in** — no external data needed, 25+ languages hardcoded
|
|
197
|
+
- **HTML escaping is opt-in** — `escapeValues: true` in config
|
|
198
|
+
- **Formatting uses Intl APIs** — delegates to `Intl.DateTimeFormat`, `Intl.NumberFormat`, etc.
|