@stacksjs/stx 0.2.95 → 0.2.97
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/dist/a11y.js +598 -2
- package/dist/analytics.js +159 -2
- package/dist/analyzer.js +240 -2
- package/dist/animation.js +688 -2
- package/dist/app-shell.js +220 -2
- package/dist/app.js +79 -2
- package/dist/assets.js +155 -2
- package/dist/ast.js +630 -2
- package/dist/async-components.js +428 -2
- package/dist/auth.js +12 -2
- package/dist/broadcasting.js +102 -2
- package/dist/browser-composables.js +565 -2
- package/dist/build-assets.js +29 -2
- package/dist/build-mode-detector.js +50 -2
- package/dist/build-optimizer.js +433 -2
- package/dist/build-views.js +180 -2
- package/dist/build.js +33 -2
- package/dist/builtins/drawer.js +37 -2
- package/dist/builtins/escape.js +3 -2
- package/dist/builtins/icon.js +83 -2
- package/dist/builtins/index.js +34 -2
- package/dist/builtins/modal.js +38 -2
- package/dist/builtins/safe-image.js +51 -2
- package/dist/builtins/stx-image.js +200 -2
- package/dist/builtins/stx-link.js +41 -2
- package/dist/builtins/stx-loading-indicator.js +35 -2
- package/dist/builtins/suspense.js +24 -2
- package/dist/builtins/toast.js +42 -2
- package/dist/builtins/tooltip.js +106 -2
- package/dist/builtins/transition-group.js +22 -2
- package/dist/bundle-analyzer/collector.js +233 -2
- package/dist/bundle-analyzer/index.js +82 -2
- package/dist/bundle-analyzer/report.js +318 -2
- package/dist/bundle-analyzer/treemap.js +594 -2
- package/dist/caching.js +131 -2
- package/dist/cli.js +11317 -10982
- package/dist/client/directive.js +14 -2
- package/dist/client/index.js +2 -2
- package/dist/client-helpers.js +312 -2
- package/dist/client-script-bundler.js +216 -6
- package/dist/client-script.js +754 -2
- package/dist/client.js +73 -4
- package/dist/component-hmr.js +585 -2
- package/dist/component-library.d.ts +6 -0
- package/dist/component-library.js +683 -0
- package/dist/component-processing.js +613 -2
- package/dist/component-registry.js +90 -2
- package/dist/component-renderer.js +660 -2
- package/dist/components.js +213 -2
- package/dist/composables/index.js +220 -2
- package/dist/composables/use-battery.js +101 -2
- package/dist/composables/use-broadcast-channel.js +80 -2
- package/dist/composables/use-channel.js +124 -2
- package/dist/composables/use-clipboard.js +79 -2
- package/dist/composables/use-color-mode.js +131 -2
- package/dist/composables/use-cookie.js +86 -2
- package/dist/composables/use-device-orientation.js +181 -2
- package/dist/composables/use-event-listener.js +27 -2
- package/dist/composables/use-event-source.js +166 -2
- package/dist/composables/use-eye-dropper.js +142 -2
- package/dist/composables/use-fetch.js +223 -2
- package/dist/composables/use-fullscreen.js +110 -2
- package/dist/composables/use-geolocation.js +101 -2
- package/dist/composables/use-idle.js +182 -2
- package/dist/composables/use-intersection-observer.js +168 -2
- package/dist/composables/use-keyboard.js +224 -2
- package/dist/composables/use-media-query.js +62 -2
- package/dist/composables/use-meta.js +48 -2
- package/dist/composables/use-mouse.js +286 -2
- package/dist/composables/use-mutation-observer.js +129 -2
- package/dist/composables/use-network.js +85 -2
- package/dist/composables/use-notification.js +94 -2
- package/dist/composables/use-permissions.js +132 -2
- package/dist/composables/use-query.js +0 -1
- package/dist/composables/use-resize-observer.js +157 -2
- package/dist/composables/use-router.js +51 -2
- package/dist/composables/use-share.js +104 -2
- package/dist/composables/use-speech.js +294 -2
- package/dist/composables/use-storage.js +130 -2
- package/dist/composables/use-text-selection.js +205 -4
- package/dist/composables/use-timer.js +183 -2
- package/dist/composables/use-utilities.js +176 -2
- package/dist/composables/use-wake-lock.js +122 -2
- package/dist/composables/use-websocket.js +165 -2
- package/dist/composables/use-window.js +163 -2
- package/dist/composables.js +552 -2
- package/dist/composition-api.js +190 -2
- package/dist/computed.js +376 -8
- package/dist/conditionals.js +599 -2
- package/dist/config.js +751 -2
- package/dist/craft-bridge.js +432 -2
- package/dist/craft-compiler.js +810 -2
- package/dist/craft-components.js +945 -2
- package/dist/craft-entry.js +5 -2
- package/dist/craft-ssr.js +559 -2
- package/dist/csp.js +220 -2
- package/dist/csrf.js +38 -2
- package/dist/custom-directives.js +136 -2
- package/dist/defer.js +156 -2
- package/dist/deploy/config-generators.js +214 -2
- package/dist/deploy/index.js +203 -2
- package/dist/deploy/netlify.js +167 -2
- package/dist/dev-server/crosswind.js +379 -2
- package/dist/dev-server/index.js +7 -2
- package/dist/dev-server/keyboard-shortcuts.js +81 -2
- package/dist/dev-server/native-window.js +91 -2
- package/dist/dev-server/port-utils.js +40 -2
- package/dist/dev-server/serve-app.js +682 -2
- package/dist/dev-server/serve-file.js +439 -2
- package/dist/dev-server/serve-markdown.js +281 -2
- package/dist/dev-server/serve-multi.js +579 -2
- package/dist/dev-server/terminal-colors.js +45 -2
- package/dist/dev-server/theme-selector.js +111 -2
- package/dist/dev-server/types.js +43 -2
- package/dist/dev-server.js +4 -2
- package/dist/devtools.js +462 -18
- package/dist/directive-api.js +355 -2
- package/dist/docs.js +567 -2
- package/dist/doctor.js +123 -2
- package/dist/document-shell.js +105 -2
- package/dist/dynamic-components.js +78 -2
- package/dist/edge-runtime.js +539 -2
- package/dist/env.js +9 -2
- package/dist/error-boundaries.js +62 -12
- package/dist/error-handling.js +1 -2
- package/dist/errors/codes.js +97 -2
- package/dist/errors/formatter.js +196 -2
- package/dist/errors/index.js +44 -2
- package/dist/errors/logger.js +250 -2
- package/dist/errors/sanitizer.js +181 -2
- package/dist/errors/types.js +86 -2
- package/dist/events.js +382 -2
- package/dist/expressions.js +650 -2
- package/dist/formatter.js +265 -2
- package/dist/forms-validation.js +510 -4
- package/dist/forms.js +709 -2
- package/dist/head.js +224 -2
- package/dist/heatmap.js +566 -2
- package/dist/hot-reload.js +367 -2
- package/dist/html-masking.js +73 -2
- package/dist/hydration-runtime.js +195 -2
- package/dist/hydration.js +654 -2
- package/dist/i18n.js +633 -2
- package/dist/image-optimization/auto-sibling.js +88 -2
- package/dist/image-optimization/build-plugin.js +241 -2
- package/dist/image-optimization/component.js +244 -2
- package/dist/image-optimization/directive.js +203 -2
- package/dist/image-optimization/index.js +54 -2
- package/dist/image-optimization/processor.js +262 -2
- package/dist/image-optimization/serve.js +102 -2
- package/dist/includes.js +733 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +134 -2
- package/dist/init.js +505 -2
- package/dist/inline-assets.js +82 -2
- package/dist/interactive.js +383 -2
- package/dist/internal-markdown.js +141 -2
- package/dist/island-chunking.js +52 -2
- package/dist/js-ts.js +57 -2
- package/dist/jsx-runtime.js +289 -2
- package/dist/keep-alive.js +421 -2
- package/dist/lazy-loader.js +245 -2
- package/dist/loading-indicator.js +322 -2
- package/dist/loops.js +643 -2
- package/dist/manifest.js +31 -2
- package/dist/markdown.js +68 -2
- package/dist/media/client/blur-up.js +217 -2
- package/dist/media/client/index.js +53 -2
- package/dist/media/client/lazy-load.js +283 -2
- package/dist/media/client/upload-handler.js +354 -2
- package/dist/media/image/component.js +574 -2
- package/dist/media/image/directive.js +160 -2
- package/dist/media/image/editing.js +193 -2
- package/dist/media/image/index.js +80 -2
- package/dist/media/image/placeholder.js +188 -2
- package/dist/media/image/processor/cache.js +51 -2
- package/dist/media/image/processor/index.js +3 -2
- package/dist/media/image/processor/optimizer.js +202 -2
- package/dist/media/image/processor/responsive.js +162 -2
- package/dist/media/image/srcset.js +194 -2
- package/dist/media/index.js +198 -2
- package/dist/media/manager/embed.js +253 -2
- package/dist/media/protected/component.js +235 -2
- package/dist/media/protected/index.js +20 -2
- package/dist/media/protected/signature.js +205 -2
- package/dist/media/shared/cache.js +132 -2
- package/dist/media/shared/hash.js +35 -2
- package/dist/media/shared/index.js +2 -2
- package/dist/media/types.js +0 -1
- package/dist/media/upload/component.js +320 -2
- package/dist/media/upload/index.js +1 -2
- package/dist/media/video/directive.js +142 -2
- package/dist/media/video/index.js +583 -2
- package/dist/media/video/processor/cache.js +52 -2
- package/dist/media/video/processor/index.js +4 -2
- package/dist/media/video/processor/streaming.js +197 -2
- package/dist/media/video/processor/thumbnail.js +134 -2
- package/dist/media/video/processor/transcoder.js +283 -2
- package/dist/method-spoofing.js +17 -2
- package/dist/middleware.js +40 -2
- package/dist/misc-directives.js +222 -2
- package/dist/native-build.js +511 -2
- package/dist/parser/directive-parser.js +239 -2
- package/dist/parser/expression-parser.js +358 -2
- package/dist/parser/index.js +23 -2
- package/dist/parser/tokenizer.js +534 -2
- package/dist/partial-hydration.js +427 -2
- package/dist/performance-utils.js +430 -2
- package/dist/placeholder.js +35 -2
- package/dist/plugin-system.js +214 -2
- package/dist/plugin.js +173 -2
- package/dist/precompiler.js +660 -81
- package/dist/process.js +711 -2
- package/dist/production-build.js +596 -2
- package/dist/production-builder.js +132 -2
- package/dist/production-server.js +188 -2
- package/dist/props.js +224 -2
- package/dist/public-env.js +19 -2
- package/dist/pwa/audit.js +255 -2
- package/dist/pwa/directives.js +332 -2
- package/dist/pwa/icons.js +109 -2
- package/dist/pwa/index.js +47 -2
- package/dist/pwa/inject.js +102 -2
- package/dist/pwa/manifest.js +186 -2
- package/dist/pwa/offline.js +259 -2
- package/dist/pwa/precache.js +116 -2
- package/dist/pwa/service-worker.js +860 -2
- package/dist/pwa/workbox-strategies.js +167 -2
- package/dist/pwa/workbox.js +382 -2
- package/dist/pwa.js +427 -427
- package/dist/reactive-bindings.js +266 -2
- package/dist/reactive.js +569 -2
- package/dist/reactivity.js +559 -2
- package/dist/release.js +1 -2
- package/dist/render.js +165 -2
- package/dist/route-middleware.js +17 -2
- package/dist/router.js +9 -2
- package/dist/routes.js +14 -2
- package/dist/runtime-injection.js +120 -2
- package/dist/runtime.js +94 -2
- package/dist/safe-evaluator.js +444 -2
- package/dist/scaffolding.js +897 -2
- package/dist/screenshot.js +87 -2
- package/dist/script-classifier.js +32 -2
- package/dist/script-validation.js +158 -2
- package/dist/seo.js +457 -2
- package/dist/serve.js +237 -2
- package/dist/server-bindings.js +108 -2
- package/dist/server-components.js +338 -11
- package/dist/signal-processing.js +946 -2
- package/dist/signals-api.js +154 -2
- package/dist/signals.js +5287 -2
- package/dist/site-builder/build.js +224 -2
- package/dist/site-builder/i18n.js +140 -2
- package/dist/site-builder/index.js +15 -2
- package/dist/site-builder/robots.js +26 -2
- package/dist/site-builder/router.js +27 -2
- package/dist/site-builder/seo.js +36 -2
- package/dist/site-builder/sitemap.js +26 -2
- package/dist/site-builder/theme.js +33 -2
- package/dist/site-builder/types.js +0 -1
- package/dist/slots.js +201 -2
- package/dist/source-maps.js +350 -2
- package/dist/spa-shell.js +34 -2
- package/dist/ssg.js +389 -389
- package/dist/ssr.js +355 -2
- package/dist/state-management.js +533 -2
- package/dist/store-imports.js +13 -2
- package/dist/store-loader.js +72 -5
- package/dist/stores-client.js +132 -2
- package/dist/story/addons.js +261 -2
- package/dist/story/analytics.js +235 -2
- package/dist/story/auto-stories.js +158 -2
- package/dist/story/bookmarks.js +277 -2
- package/dist/story/bun-test.js +102 -2
- package/dist/story/cli.js +155 -2
- package/dist/story/collect/analyzer.js +305 -2
- package/dist/story/collect/index.js +27 -2
- package/dist/story/collect/parser.js +129 -2
- package/dist/story/collect/scanner.js +101 -2
- package/dist/story/collect/tree.js +110 -2
- package/dist/story/commands/build.js +172 -2
- package/dist/story/commands/dev.js +78 -2
- package/dist/story/commands/index.js +3 -2
- package/dist/story/commands/preview.js +56 -2
- package/dist/story/compiled-output.js +151 -2
- package/dist/story/composition.js +261 -2
- package/dist/story/config-watcher.js +67 -2
- package/dist/story/config.js +64 -2
- package/dist/story/context.js +27 -2
- package/dist/story/controls/index.js +320 -2
- package/dist/story/crosswind.js +189 -2
- package/dist/story/desktop-preview.js +105 -2
- package/dist/story/docs-generator.js +186 -2
- package/dist/story/errors.js +239 -2
- package/dist/story/figma-export.js +224 -2
- package/dist/story/generator.js +165 -2
- package/dist/story/hmr.js +131 -2
- package/dist/story/hot-swap.js +207 -2
- package/dist/story/index.js +49 -2
- package/dist/story/interactions.js +225 -2
- package/dist/story/keyboard-shortcuts.js +345 -2
- package/dist/story/output.js +153 -2
- package/dist/story/performance.js +252 -2
- package/dist/story/presets.js +289 -2
- package/dist/story/props-validation.js +215 -2
- package/dist/story/renderer.js +209 -2
- package/dist/story/search-index.js +106 -2
- package/dist/story/search.js +140 -2
- package/dist/story/server.js +965 -2
- package/dist/story/setup.js +78 -2
- package/dist/story/snapshots.js +170 -2
- package/dist/story/testing.js +163 -2
- package/dist/story/theme.js +170 -2
- package/dist/story/types.js +0 -2
- package/dist/story/ui/code-panel.js +175 -2
- package/dist/story/ui/controls-panel.js +168 -2
- package/dist/story/ui/index.js +4 -2
- package/dist/story/ui/navigation.js +250 -2
- package/dist/story/ui/preview.js +251 -2
- package/dist/story/visual-testing.js +247 -2
- package/dist/streaming.js +537 -2
- package/dist/strict-lint.js +288 -2
- package/dist/style-scoping.js +50 -2
- package/dist/suspense.js +398 -2
- package/dist/teleport.js +109 -2
- package/dist/template-compiler.js +63 -2
- package/dist/template-hydrator.js +82 -2
- package/dist/template-tag-balance.js +93 -2
- package/dist/testing.js +581 -2
- package/dist/transitions.js +443 -2
- package/dist/type-checker.js +581 -2
- package/dist/types/component-types.d.ts +54 -0
- package/dist/types/component-types.js +0 -1
- package/dist/types/config-types.js +0 -1
- package/dist/types/context-types.js +0 -1
- package/dist/types/csp-types.js +0 -1
- package/dist/types/directive-types.js +3 -2
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +1 -2
- package/dist/types/pwa-types.js +0 -1
- package/dist/types.js +1 -2
- package/dist/typescript-templates.js +386 -4
- package/dist/utils.js +942 -2
- package/dist/validator.js +171 -2
- package/dist/variable-extractor.js +1094 -2
- package/dist/view-composers.js +29 -2
- package/dist/virtual-scrolling.js +454 -2
- package/dist/visual-editor.js +688 -28
- package/dist/vue-template.js +475 -2
- package/dist/web-components/css-scoping.js +177 -2
- package/dist/web-components/index.js +13 -2
- package/dist/web-components/reactive-generator.js +121 -56
- package/dist/web-components.js +1447 -2
- package/dist/x-element.js +17 -5
- package/package.json +5 -6
- package/dist/chunk-04n64bnt.js +0 -5
- package/dist/chunk-06w68hyg.js +0 -7
- package/dist/chunk-07y6m5xx.js +0 -3
- package/dist/chunk-095s3972.js +0 -99
- package/dist/chunk-09k66d8a.js +0 -3
- package/dist/chunk-0a61y94n.js +0 -24
- package/dist/chunk-0b9w2w1y.js +0 -1
- package/dist/chunk-0dx4q6yq.js +0 -3
- package/dist/chunk-0dz85jrp.js +0 -3
- package/dist/chunk-0jd0pndq.js +0 -3
- package/dist/chunk-0p0nyq50.js +0 -6
- package/dist/chunk-0p1h3p3w.js +0 -3
- package/dist/chunk-0qakwen3.js +0 -1
- package/dist/chunk-0qnz93q2.js +0 -3
- package/dist/chunk-10debkj5.js +0 -71
- package/dist/chunk-15nesxgt.js +0 -5224
- package/dist/chunk-1sr54zp8.js +0 -3
- package/dist/chunk-1v49fwr5.js +0 -3
- package/dist/chunk-1xz0w746.js +0 -1539
- package/dist/chunk-1z5nhbjt.js +0 -90
- package/dist/chunk-1zgsgk4b.js +0 -1
- package/dist/chunk-20swzkx3.js +0 -216
- package/dist/chunk-27zsyhrd.js +0 -4
- package/dist/chunk-29y0hk5z.js +0 -3
- package/dist/chunk-2cdvw21b.js +0 -274
- package/dist/chunk-2j21d3ka.js +0 -161
- package/dist/chunk-2jxbwnkz.js +0 -2
- package/dist/chunk-31dr4bys.js +0 -6
- package/dist/chunk-35faj94w.js +0 -15
- package/dist/chunk-39gm08bn.js +0 -39
- package/dist/chunk-3a4qsygv.js +0 -51
- package/dist/chunk-3te20hqw.js +0 -3
- package/dist/chunk-43t7faps.js +0 -24
- package/dist/chunk-44hd3kab.js +0 -1
- package/dist/chunk-47kpewks.js +0 -71
- package/dist/chunk-4aj7ftqb.js +0 -1
- package/dist/chunk-4d2y57k7.js +0 -3
- package/dist/chunk-4deg33rw.js +0 -57
- package/dist/chunk-4k7d8p8d.js +0 -188
- package/dist/chunk-4qcy5tx6.js +0 -53
- package/dist/chunk-4x7kae4j.js +0 -3
- package/dist/chunk-55nwdnsd.js +0 -3
- package/dist/chunk-55yp0q8t.js +0 -201
- package/dist/chunk-5f43yz6z.js +0 -12
- package/dist/chunk-5shey2e4.js +0 -3
- package/dist/chunk-6b5k6w2q.js +0 -7
- package/dist/chunk-6djzdes9.js +0 -14
- package/dist/chunk-6e4c6g46.js +0 -3
- package/dist/chunk-6eqbxcrd.js +0 -8
- package/dist/chunk-7074g241.js +0 -3
- package/dist/chunk-7b6s3g65.js +0 -179
- package/dist/chunk-7cgmq685.js +0 -33
- package/dist/chunk-7dkz6z2s.js +0 -3
- package/dist/chunk-7ed3tean.js +0 -3
- package/dist/chunk-7gd339hd.js +0 -109
- package/dist/chunk-7j5e8sdj.js +0 -3
- package/dist/chunk-7n8g0nfn.js +0 -38
- package/dist/chunk-7sqdeqsw.js +0 -1
- package/dist/chunk-80g54ncj.js +0 -3
- package/dist/chunk-8a5bxece.js +0 -4
- package/dist/chunk-8ahwt6a4.js +0 -721
- package/dist/chunk-8b3z0zd5.js +0 -8
- package/dist/chunk-8dhdpa5h.js +0 -4
- package/dist/chunk-8n9nnqr6.js +0 -3
- package/dist/chunk-8qc1bsym.js +0 -3
- package/dist/chunk-8va64c9n.js +0 -3
- package/dist/chunk-8vtm0m84.js +0 -3
- package/dist/chunk-8xj7c3mf.js +0 -8
- package/dist/chunk-988dw6q3.js +0 -9
- package/dist/chunk-9b6cec0v.js +0 -321
- package/dist/chunk-9cf97f9p.js +0 -3
- package/dist/chunk-9ecv8aqj.js +0 -14
- package/dist/chunk-9eq3ht5f.js +0 -8
- package/dist/chunk-9jtj77jx.js +0 -3
- package/dist/chunk-9t14se2t.js +0 -83
- package/dist/chunk-9wmq2272.js +0 -3
- package/dist/chunk-9zbk5zx5.js +0 -57
- package/dist/chunk-a2g2qb2y.js +0 -386
- package/dist/chunk-a3hyn4we.js +0 -79
- package/dist/chunk-a87qqft6.js +0 -194
- package/dist/chunk-ah88wzbg.js +0 -10
- package/dist/chunk-akf1r75r.js +0 -102
- package/dist/chunk-amaa1bev.js +0 -2
- package/dist/chunk-avx8aydt.js +0 -3
- package/dist/chunk-ay9qf4zj.js +0 -6
- package/dist/chunk-aywxfqev.js +0 -3
- package/dist/chunk-azkegjd8.js +0 -61
- package/dist/chunk-b77wjyn7.js +0 -84
- package/dist/chunk-baf1hfwh.js +0 -231
- package/dist/chunk-bdk6g1vj.js +0 -3
- package/dist/chunk-bhqgmyqw.js +0 -36
- package/dist/chunk-bk3j0n82.js +0 -341
- package/dist/chunk-bndmdahk.js +0 -3
- package/dist/chunk-bpgg59wa.js +0 -3
- package/dist/chunk-bs3gmfxz.js +0 -5
- package/dist/chunk-bxc7kjsk.js +0 -32
- package/dist/chunk-c7jg8w13.js +0 -3
- package/dist/chunk-ckxjqqn9.js +0 -3
- package/dist/chunk-cn8az1b4.js +0 -1
- package/dist/chunk-d0zjtdw4.js +0 -29
- package/dist/chunk-d1qh1x2g.js +0 -3
- package/dist/chunk-djddhmcc.js +0 -60
- package/dist/chunk-dqn9gyhb.js +0 -21
- package/dist/chunk-drjq2zwg.js +0 -3
- package/dist/chunk-dvfs1h3c.js +0 -117
- package/dist/chunk-e2q9c5vq.js +0 -8
- package/dist/chunk-e98v1bc6.js +0 -12
- package/dist/chunk-ejayeex8.js +0 -2
- package/dist/chunk-ejh8fyak.js +0 -3
- package/dist/chunk-ek2w6zvy.js +0 -4
- package/dist/chunk-ewa88139.js +0 -6
- package/dist/chunk-fjk3x41y.js +0 -3
- package/dist/chunk-frg705zq.js +0 -302
- package/dist/chunk-fzm3y0r3.js +0 -267
- package/dist/chunk-g1vt329s.js +0 -21
- package/dist/chunk-g4ps1dj8.js +0 -140
- package/dist/chunk-gkzq8zw4.js +0 -23
- package/dist/chunk-gz5fmp3q.js +0 -3
- package/dist/chunk-h0hjy0kn.js +0 -292
- package/dist/chunk-h5jxydqq.js +0 -147
- package/dist/chunk-h5wa62ek.js +0 -145
- package/dist/chunk-h7aq56qj.js +0 -28
- package/dist/chunk-h82kjdr4.js +0 -83
- package/dist/chunk-hbehnm18.js +0 -3
- package/dist/chunk-hbgxbgam.js +0 -58
- package/dist/chunk-hc2mf5h6.js +0 -4
- package/dist/chunk-hjm2xab3.js +0 -3
- package/dist/chunk-hjv76kcw.js +0 -1
- package/dist/chunk-hrnnh4tq.js +0 -142
- package/dist/chunk-ht43ds42.js +0 -236
- package/dist/chunk-hxx3za24.js +0 -62
- package/dist/chunk-hy8820vc.js +0 -6
- package/dist/chunk-j447q024.js +0 -28
- package/dist/chunk-j58vh0w6.js +0 -314
- package/dist/chunk-j8tn8enq.js +0 -3
- package/dist/chunk-jc0fc4ht.js +0 -11
- package/dist/chunk-jcs0ymw7.js +0 -3
- package/dist/chunk-jjamhxpm.js +0 -139
- package/dist/chunk-jjb05d21.js +0 -3
- package/dist/chunk-jjdq01dv.js +0 -128
- package/dist/chunk-jnmgm2xw.js +0 -5
- package/dist/chunk-jpndqst5.js +0 -3
- package/dist/chunk-jt0ezawy.js +0 -351
- package/dist/chunk-jz73j3qs.js +0 -169
- package/dist/chunk-k21df0pg.js +0 -10
- package/dist/chunk-k848dzsa.js +0 -429
- package/dist/chunk-kdfe4t91.js +0 -3
- package/dist/chunk-keawsbpn.js +0 -5
- package/dist/chunk-kgym7ch9.js +0 -8
- package/dist/chunk-khdn7jwe.js +0 -3
- package/dist/chunk-km25cwz6.js +0 -3
- package/dist/chunk-knm8a8yx.js +0 -398
- package/dist/chunk-krqn0ddk.js +0 -3
- package/dist/chunk-ktkmvaa8.js +0 -1
- package/dist/chunk-kx6eb6ma.js +0 -4
- package/dist/chunk-kypas8vy.js +0 -4
- package/dist/chunk-m167kjhv.js +0 -4
- package/dist/chunk-m491r0rj.js +0 -358
- package/dist/chunk-m8448qby.js +0 -11
- package/dist/chunk-mgj88zeq.js +0 -64
- package/dist/chunk-mhgk632d.js +0 -3
- package/dist/chunk-mv4fb50w.js +0 -1
- package/dist/chunk-n5kg7fpx.js +0 -7
- package/dist/chunk-n98x35xd.js +0 -8
- package/dist/chunk-n9dhs1dw.js +0 -106
- package/dist/chunk-nd9rmddh.js +0 -6
- package/dist/chunk-ngxfwzq3.js +0 -3
- package/dist/chunk-nhv099jv.js +0 -19
- package/dist/chunk-nm15ccsg.js +0 -5
- package/dist/chunk-npfmdb6y.js +0 -71
- package/dist/chunk-nvwb4x04.js +0 -3
- package/dist/chunk-nw34xajc.js +0 -8
- package/dist/chunk-p077sw22.js +0 -3
- package/dist/chunk-p1h8065h.js +0 -3
- package/dist/chunk-p3e0cqtt.js +0 -34
- package/dist/chunk-p3fpb79v.js +0 -477
- package/dist/chunk-p52yzjq6.js +0 -498
- package/dist/chunk-p73meypx.js +0 -134
- package/dist/chunk-pa9zb7ty.js +0 -4
- package/dist/chunk-payfb24w.js +0 -207
- package/dist/chunk-pcm1vd8w.js +0 -3
- package/dist/chunk-pcntd9h4.js +0 -3
- package/dist/chunk-pg1fvqb9.js +0 -167
- package/dist/chunk-psc3wfcf.js +0 -1115
- package/dist/chunk-pznnww6k.js +0 -6
- package/dist/chunk-q6zhd9yf.js +0 -3
- package/dist/chunk-qa59zejf.js +0 -246
- package/dist/chunk-qvrbjpdc.js +0 -3
- package/dist/chunk-qygvvygy.js +0 -12
- package/dist/chunk-r0jcmpv6.js +0 -68
- package/dist/chunk-r5m9xtm7.js +0 -3
- package/dist/chunk-rh80q1nd.js +0 -1
- package/dist/chunk-rkffm9sy.js +0 -128
- package/dist/chunk-rpx5fa65.js +0 -3
- package/dist/chunk-rqxf5hns.js +0 -3
- package/dist/chunk-rtr974rc.js +0 -30
- package/dist/chunk-rvptcndz.js +0 -3
- package/dist/chunk-rw26rpek.js +0 -171
- package/dist/chunk-rw7937v4.js +0 -19
- package/dist/chunk-rwrv9wbf.js +0 -3
- package/dist/chunk-rz2ec6g7.js +0 -347
- package/dist/chunk-s6ja2bdg.js +0 -66
- package/dist/chunk-scpkdrdb.js +0 -4
- package/dist/chunk-shv88d2d.js +0 -10
- package/dist/chunk-t0c9wvpr.js +0 -3
- package/dist/chunk-tffh3b1e.js +0 -35
- package/dist/chunk-tg2f1mzq.js +0 -11
- package/dist/chunk-trfswy66.js +0 -77
- package/dist/chunk-tzwtg722.js +0 -3
- package/dist/chunk-v7f8jj15.js +0 -4
- package/dist/chunk-v8j49spx.js +0 -3
- package/dist/chunk-v97390pe.js +0 -1
- package/dist/chunk-vcr5pzpx.js +0 -233
- package/dist/chunk-veeerpwa.js +0 -3
- package/dist/chunk-vg5kt6az.js +0 -4
- package/dist/chunk-vgv7jvyz.js +0 -219
- package/dist/chunk-vjbefncc.js +0 -3
- package/dist/chunk-vmxjghsm.js +0 -3
- package/dist/chunk-vw7vqd76.js +0 -3
- package/dist/chunk-vx22he47.js +0 -1
- package/dist/chunk-w3b6m427.js +0 -45
- package/dist/chunk-wazkqv7n.js +0 -3
- package/dist/chunk-wf7zrjsw.js +0 -138
- package/dist/chunk-wfg2gm11.js +0 -3
- package/dist/chunk-wg9k6h8w.js +0 -12
- package/dist/chunk-wkz2vwkr.js +0 -81
- package/dist/chunk-wvef3ngh.js +0 -127
- package/dist/chunk-wvf31nzs.js +0 -3
- package/dist/chunk-x05nxhyv.js +0 -262
- package/dist/chunk-x0770gt9.js +0 -4
- package/dist/chunk-x24s4heg.js +0 -1166
- package/dist/chunk-x3r64r0c.js +0 -6
- package/dist/chunk-x5g9w4hh.js +0 -5
- package/dist/chunk-xgkv66q5.js +0 -2230
- package/dist/chunk-xqq1vxb6.js +0 -1
- package/dist/chunk-xs03kc1h.js +0 -196
- package/dist/chunk-xv34zbp4.js +0 -3
- package/dist/chunk-xw36p73h.js +0 -90
- package/dist/chunk-xyg1r5w0.js +0 -4
- package/dist/chunk-xys2sxh6.js +0 -16
- package/dist/chunk-y0qg6rrv.js +0 -3
- package/dist/chunk-y1k17c8b.js +0 -21
- package/dist/chunk-y5xz0jc4.js +0 -141
- package/dist/chunk-y6xsqe9a.js +0 -10
- package/dist/chunk-yb1t2h8h.js +0 -11
- package/dist/chunk-ygvyc6wv.js +0 -90
- package/dist/chunk-yj4x5ehw.js +0 -21
- package/dist/chunk-yn38c15w.js +0 -4
- package/dist/chunk-ynhngsdh.js +0 -3
- package/dist/chunk-yrsb6j3z.js +0 -3
- package/dist/chunk-yywfvfph.js +0 -2
- package/dist/chunk-zcxzdrn7.js +0 -5
- package/dist/chunk-zen6ax1y.js +0 -27
- package/dist/chunk-zf2pek72.js +0 -3
- package/dist/chunk-zk3d0jjf.js +0 -7
- package/dist/chunk-zy3rp1ab.js +0 -93
package/dist/i18n.js
CHANGED
|
@@ -1,2 +1,633 @@
|
|
|
1
|
-
|
|
2
|
-
import{
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { ErrorCodes, inlineError } from "./error-handling.js";
|
|
3
|
+
import { safeEvaluateObject } from "./safe-evaluator.js";
|
|
4
|
+
let resolvedLoadLocale;
|
|
5
|
+
async function resolveLoadLocale() {
|
|
6
|
+
if (resolvedLoadLocale !== void 0)
|
|
7
|
+
return resolvedLoadLocale;
|
|
8
|
+
try {
|
|
9
|
+
resolvedLoadLocale = (await import("@stacksjs/ts-i18n")).loadLocale ?? null;
|
|
10
|
+
} catch {
|
|
11
|
+
resolvedLoadLocale = null;
|
|
12
|
+
}
|
|
13
|
+
return resolvedLoadLocale;
|
|
14
|
+
}
|
|
15
|
+
export const defaultI18nConfig = {
|
|
16
|
+
defaultLocale: "en",
|
|
17
|
+
locale: "en",
|
|
18
|
+
translationsDir: "translations",
|
|
19
|
+
format: "yaml",
|
|
20
|
+
fallbackToKey: !0,
|
|
21
|
+
cache: !0
|
|
22
|
+
};
|
|
23
|
+
const translationsCache = {}, pendingLoads = {}, loadingStates = {};
|
|
24
|
+
export function clearTranslationCache(locale) {
|
|
25
|
+
if (locale)
|
|
26
|
+
delete translationsCache[locale];
|
|
27
|
+
else
|
|
28
|
+
for (const key of Object.keys(translationsCache))
|
|
29
|
+
delete translationsCache[key];
|
|
30
|
+
}
|
|
31
|
+
export function getTranslationCacheStats() {
|
|
32
|
+
const entries = Object.entries(translationsCache).map(([locale, entry]) => ({
|
|
33
|
+
locale,
|
|
34
|
+
loadedAt: new Date(entry.loadedAt),
|
|
35
|
+
keyCount: countKeys(entry.translations)
|
|
36
|
+
}));
|
|
37
|
+
return {
|
|
38
|
+
size: Object.keys(translationsCache).length,
|
|
39
|
+
locales: Object.keys(translationsCache),
|
|
40
|
+
entries
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function countKeys(obj, count = 0) {
|
|
44
|
+
for (const value of Object.values(obj)) {
|
|
45
|
+
count++;
|
|
46
|
+
if (value && typeof value === "object" && !Array.isArray(value))
|
|
47
|
+
count = countKeys(value, count);
|
|
48
|
+
}
|
|
49
|
+
return count;
|
|
50
|
+
}
|
|
51
|
+
function isCacheStale(entry, maxAge = 0) {
|
|
52
|
+
if (maxAge <= 0)
|
|
53
|
+
return !1;
|
|
54
|
+
return Date.now() - entry.loadedAt > maxAge;
|
|
55
|
+
}
|
|
56
|
+
export function getLoadingState(locale) {
|
|
57
|
+
if (translationsCache[locale])
|
|
58
|
+
return "loaded";
|
|
59
|
+
return loadingStates[locale] || "idle";
|
|
60
|
+
}
|
|
61
|
+
export function isLoading(locale) {
|
|
62
|
+
return loadingStates[locale] === "loading";
|
|
63
|
+
}
|
|
64
|
+
export function isLoaded(locale) {
|
|
65
|
+
return !!translationsCache[locale];
|
|
66
|
+
}
|
|
67
|
+
export async function preloadTranslations(config, options) {
|
|
68
|
+
const { locales, parallel = !0, priority = {}, onLocaleLoaded, onComplete, onError } = config, sortedLocales = parallel ? locales : [...locales].sort((a, b) => (priority[b] || 0) - (priority[a] || 0));
|
|
69
|
+
if (parallel) {
|
|
70
|
+
const promises = sortedLocales.map(async (locale) => {
|
|
71
|
+
try {
|
|
72
|
+
await loadTranslationLazy(locale, options);
|
|
73
|
+
onLocaleLoaded?.(locale);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
onError?.(locale, error instanceof Error ? error : Error(String(error)));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
await Promise.all(promises);
|
|
79
|
+
} else
|
|
80
|
+
for (const locale of sortedLocales)
|
|
81
|
+
try {
|
|
82
|
+
await loadTranslationLazy(locale, options);
|
|
83
|
+
onLocaleLoaded?.(locale);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
onError?.(locale, error instanceof Error ? error : Error(String(error)));
|
|
86
|
+
}
|
|
87
|
+
onComplete?.();
|
|
88
|
+
}
|
|
89
|
+
export function preloadTranslationsBackground(config, options) {
|
|
90
|
+
queueMicrotask(() => {
|
|
91
|
+
preloadTranslations(config, options).catch((error) => {
|
|
92
|
+
if (options.debug)
|
|
93
|
+
console.error("Background preload error:", error);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export async function loadTranslationLazy(locale, options) {
|
|
98
|
+
if ({ ...defaultI18nConfig, ...options.i18n }.cache && translationsCache[locale]) {
|
|
99
|
+
const entry = translationsCache[locale], maxAge = options.i18n?.cacheMaxAge ?? 0;
|
|
100
|
+
if (!isCacheStale(entry, maxAge))
|
|
101
|
+
return entry.translations;
|
|
102
|
+
}
|
|
103
|
+
if (pendingLoads[locale]?.state === "loading")
|
|
104
|
+
return pendingLoads[locale].promise;
|
|
105
|
+
loadingStates[locale] = "loading";
|
|
106
|
+
const loadPromise = loadTranslationInternal(locale, options).then((translations) => {
|
|
107
|
+
loadingStates[locale] = "loaded";
|
|
108
|
+
delete pendingLoads[locale];
|
|
109
|
+
return translations;
|
|
110
|
+
}).catch((error) => {
|
|
111
|
+
loadingStates[locale] = "error";
|
|
112
|
+
pendingLoads[locale] = {
|
|
113
|
+
promise: loadPromise,
|
|
114
|
+
state: "error",
|
|
115
|
+
error: error instanceof Error ? error : Error(String(error))
|
|
116
|
+
};
|
|
117
|
+
throw error;
|
|
118
|
+
});
|
|
119
|
+
pendingLoads[locale] = {
|
|
120
|
+
promise: loadPromise,
|
|
121
|
+
state: "loading"
|
|
122
|
+
};
|
|
123
|
+
return loadPromise;
|
|
124
|
+
}
|
|
125
|
+
export function getTranslationSync(locale) {
|
|
126
|
+
return translationsCache[locale]?.translations;
|
|
127
|
+
}
|
|
128
|
+
export async function getTranslationAsync(locale, options) {
|
|
129
|
+
const cached = getTranslationSync(locale);
|
|
130
|
+
if (cached)
|
|
131
|
+
return cached;
|
|
132
|
+
return loadTranslationLazy(locale, options);
|
|
133
|
+
}
|
|
134
|
+
export async function waitForLocale(locale, timeoutMs) {
|
|
135
|
+
if (translationsCache[locale])
|
|
136
|
+
return translationsCache[locale].translations;
|
|
137
|
+
if (pendingLoads[locale]) {
|
|
138
|
+
if (timeoutMs)
|
|
139
|
+
return Promise.race([
|
|
140
|
+
pendingLoads[locale].promise,
|
|
141
|
+
new Promise((_, reject) => setTimeout(() => reject(Error(`Timeout waiting for locale: ${locale}`)), timeoutMs))
|
|
142
|
+
]);
|
|
143
|
+
return pendingLoads[locale].promise;
|
|
144
|
+
}
|
|
145
|
+
throw Error(`Locale "${locale}" is not loading. Call loadTranslationLazy first.`);
|
|
146
|
+
}
|
|
147
|
+
export function getLoadingLocales() {
|
|
148
|
+
return Object.entries(loadingStates).filter(([_, state]) => state === "loading").map(([locale]) => locale);
|
|
149
|
+
}
|
|
150
|
+
export function cancelPendingLoads(locale) {
|
|
151
|
+
if (locale) {
|
|
152
|
+
delete pendingLoads[locale];
|
|
153
|
+
delete loadingStates[locale];
|
|
154
|
+
} else {
|
|
155
|
+
for (const key of Object.keys(pendingLoads))
|
|
156
|
+
delete pendingLoads[key];
|
|
157
|
+
for (const key of Object.keys(loadingStates))
|
|
158
|
+
delete loadingStates[key];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function loadTranslationInternal(locale, options) {
|
|
162
|
+
const i18nConfig = {
|
|
163
|
+
...defaultI18nConfig,
|
|
164
|
+
...options.i18n
|
|
165
|
+
}, translationsDir = path.isAbsolute(i18nConfig.translationsDir) ? i18nConfig.translationsDir : path.resolve(options.root || process.cwd(), i18nConfig.translationsDir);
|
|
166
|
+
try {
|
|
167
|
+
const loadLocale = await resolveLoadLocale(), tree = loadLocale ? await loadLocale(locale, {
|
|
168
|
+
translationsDir,
|
|
169
|
+
defaultLocale: i18nConfig.defaultLocale,
|
|
170
|
+
sources: formatToSources(i18nConfig.format)
|
|
171
|
+
}) : await loadTranslationFromFile(locale, i18nConfig, translationsDir);
|
|
172
|
+
if (tree === void 0) {
|
|
173
|
+
if (locale !== i18nConfig.defaultLocale)
|
|
174
|
+
return loadTranslationInternal(i18nConfig.defaultLocale, options);
|
|
175
|
+
return {};
|
|
176
|
+
}
|
|
177
|
+
const translations = tree;
|
|
178
|
+
if (i18nConfig.cache)
|
|
179
|
+
translationsCache[locale] = {
|
|
180
|
+
translations,
|
|
181
|
+
loadedAt: Date.now(),
|
|
182
|
+
locale
|
|
183
|
+
};
|
|
184
|
+
return translations;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
if (options.debug)
|
|
187
|
+
console.error(`Error loading translation file for locale "${locale}":`, error);
|
|
188
|
+
if (locale !== i18nConfig.defaultLocale)
|
|
189
|
+
return loadTranslationInternal(i18nConfig.defaultLocale, options);
|
|
190
|
+
return {};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async function loadTranslationFromFile(locale, i18nConfig, translationsDir) {
|
|
194
|
+
const translationFile = path.join(translationsDir, `${locale}${getFileExtension(i18nConfig.format)}`);
|
|
195
|
+
try {
|
|
196
|
+
const imported = await import(translationFile);
|
|
197
|
+
return imported.default || imported;
|
|
198
|
+
} catch (importError) {
|
|
199
|
+
try {
|
|
200
|
+
const fileContent = await Bun.file(translationFile).text();
|
|
201
|
+
if (i18nConfig.format === "yaml" || i18nConfig.format === "yml")
|
|
202
|
+
return parseSimpleYaml(fileContent);
|
|
203
|
+
if (i18nConfig.format === "json")
|
|
204
|
+
return JSON.parse(fileContent);
|
|
205
|
+
throw importError;
|
|
206
|
+
} catch {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function getFileExtension(format) {
|
|
212
|
+
switch (format) {
|
|
213
|
+
case "yaml":
|
|
214
|
+
return ".yaml";
|
|
215
|
+
case "yml":
|
|
216
|
+
return ".yml";
|
|
217
|
+
case "js":
|
|
218
|
+
return ".js";
|
|
219
|
+
case "ts":
|
|
220
|
+
return ".ts";
|
|
221
|
+
case "json":
|
|
222
|
+
default:
|
|
223
|
+
return ".json";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function parseSimpleYaml(content) {
|
|
227
|
+
const result = {}, lines = content.split(`
|
|
228
|
+
`), stack = [{ obj: result, indent: -1 }];
|
|
229
|
+
for (const rawLine of lines) {
|
|
230
|
+
const line = rawLine.replace(/#.*$/, "").trimEnd();
|
|
231
|
+
if (!line.trim())
|
|
232
|
+
continue;
|
|
233
|
+
const indent = line.search(/\S/);
|
|
234
|
+
if (indent === -1)
|
|
235
|
+
continue;
|
|
236
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent)
|
|
237
|
+
stack.pop();
|
|
238
|
+
const currentObj = stack[stack.length - 1].obj, match = line.match(/^(\s*)(\S[^:]*):\s*(.*)$/);
|
|
239
|
+
if (match) {
|
|
240
|
+
const [, , key, rawValue] = match, trimmedKey = key.trim(), trimmedValue = rawValue.trim();
|
|
241
|
+
if (trimmedValue === "") {
|
|
242
|
+
currentObj[trimmedKey] = {};
|
|
243
|
+
stack.push({ obj: currentObj[trimmedKey], indent });
|
|
244
|
+
} else
|
|
245
|
+
currentObj[trimmedKey] = parseYamlValue(trimmedValue);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
function parseYamlValue(value) {
|
|
251
|
+
if (value.startsWith("'") && value.endsWith("'") || value.startsWith('"') && value.endsWith('"'))
|
|
252
|
+
return value.slice(1, -1);
|
|
253
|
+
const lowerValue = value.toLowerCase();
|
|
254
|
+
if (lowerValue === "true" || lowerValue === "yes")
|
|
255
|
+
return !0;
|
|
256
|
+
if (lowerValue === "false" || lowerValue === "no")
|
|
257
|
+
return !1;
|
|
258
|
+
if (lowerValue === "null" || lowerValue === "~")
|
|
259
|
+
return null;
|
|
260
|
+
const num = Number(value);
|
|
261
|
+
if (!Number.isNaN(num) && value !== "")
|
|
262
|
+
return num;
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
265
|
+
function formatToSources(format) {
|
|
266
|
+
switch (format) {
|
|
267
|
+
case "yaml":
|
|
268
|
+
case "yml":
|
|
269
|
+
return ["yaml"];
|
|
270
|
+
case "js":
|
|
271
|
+
case "ts":
|
|
272
|
+
return ["ts"];
|
|
273
|
+
case "json":
|
|
274
|
+
default:
|
|
275
|
+
return ["json"];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
export async function loadTranslation(locale, options) {
|
|
279
|
+
return loadTranslationLazy(locale, options);
|
|
280
|
+
}
|
|
281
|
+
function selectPluralForm(forms, count) {
|
|
282
|
+
for (const form of forms) {
|
|
283
|
+
const trimmed = form.trim(), exactMatch = trimmed.match(/^\{(\d+)\}\s*(.*)$/);
|
|
284
|
+
if (exactMatch) {
|
|
285
|
+
const exactCount = Number.parseInt(exactMatch[1], 10);
|
|
286
|
+
if (count === exactCount)
|
|
287
|
+
return exactMatch[2];
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const rangeMatch = trimmed.match(/^\[(\d+),(\d+|\*)\]\s*(.*)$/);
|
|
291
|
+
if (rangeMatch) {
|
|
292
|
+
const min = Number.parseInt(rangeMatch[1], 10), max = rangeMatch[2] === "*" ? Number.POSITIVE_INFINITY : Number.parseInt(rangeMatch[2], 10);
|
|
293
|
+
if (count >= min && count <= max)
|
|
294
|
+
return rangeMatch[3];
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (forms.length === 2)
|
|
299
|
+
return count === 1 ? forms[0].trim() : forms[1].trim();
|
|
300
|
+
if (count < forms.length)
|
|
301
|
+
return forms[count].trim();
|
|
302
|
+
return forms[forms.length - 1].trim();
|
|
303
|
+
}
|
|
304
|
+
export function formatICU(message, params = {}) {
|
|
305
|
+
return parseICUMessage(message, params);
|
|
306
|
+
}
|
|
307
|
+
function parseICUMessage(message, params) {
|
|
308
|
+
let result = "", i = 0;
|
|
309
|
+
while (i < message.length)
|
|
310
|
+
if (message[i] === "{") {
|
|
311
|
+
const endIndex = findMatchingBrace(message, i);
|
|
312
|
+
if (endIndex === -1) {
|
|
313
|
+
result += message[i];
|
|
314
|
+
i++;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
const placeholder = message.slice(i + 1, endIndex);
|
|
318
|
+
result += formatICUPlaceholder(placeholder, params);
|
|
319
|
+
i = endIndex + 1;
|
|
320
|
+
} else if (message[i] === "'" && i + 1 < message.length)
|
|
321
|
+
if (message[i + 1] === "'") {
|
|
322
|
+
result += "'";
|
|
323
|
+
i += 2;
|
|
324
|
+
} else if (message[i + 1] === "{" || message[i + 1] === "}") {
|
|
325
|
+
result += message[i + 1];
|
|
326
|
+
i += 2;
|
|
327
|
+
} else {
|
|
328
|
+
result += message[i];
|
|
329
|
+
i++;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
result += message[i];
|
|
333
|
+
i++;
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
function findMatchingBrace(message, start) {
|
|
338
|
+
let depth = 0;
|
|
339
|
+
for (let i = start;i < message.length; i++)
|
|
340
|
+
if (message[i] === "{")
|
|
341
|
+
depth++;
|
|
342
|
+
else if (message[i] === "}") {
|
|
343
|
+
depth--;
|
|
344
|
+
if (depth === 0)
|
|
345
|
+
return i;
|
|
346
|
+
}
|
|
347
|
+
return -1;
|
|
348
|
+
}
|
|
349
|
+
function formatICUPlaceholder(placeholder, params) {
|
|
350
|
+
const parts = splitICUParts(placeholder);
|
|
351
|
+
if (parts.length === 0)
|
|
352
|
+
return `{${placeholder}}`;
|
|
353
|
+
const varName = parts[0].trim(), value = params[varName];
|
|
354
|
+
if (parts.length === 1)
|
|
355
|
+
return value !== void 0 ? String(value) : `{${varName}}`;
|
|
356
|
+
switch (parts[1].trim().toLowerCase()) {
|
|
357
|
+
case "plural":
|
|
358
|
+
return formatICUPlural(value, parts.slice(2).join(","), params);
|
|
359
|
+
case "select":
|
|
360
|
+
return formatICUSelect(value, parts.slice(2).join(","));
|
|
361
|
+
case "selectordinal":
|
|
362
|
+
return formatICUSelectOrdinal(value, parts.slice(2).join(","));
|
|
363
|
+
case "number":
|
|
364
|
+
return formatICUNumber(value, parts[2]?.trim());
|
|
365
|
+
case "date":
|
|
366
|
+
return formatICUDate(value, parts[2]?.trim());
|
|
367
|
+
case "time":
|
|
368
|
+
return formatICUTime(value, parts[2]?.trim());
|
|
369
|
+
default:
|
|
370
|
+
return value !== void 0 ? String(value) : `{${placeholder}}`;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function splitICUParts(placeholder) {
|
|
374
|
+
const parts = [];
|
|
375
|
+
let current = "", depth = 0;
|
|
376
|
+
for (let i = 0;i < placeholder.length; i++) {
|
|
377
|
+
const char = placeholder[i];
|
|
378
|
+
if (char === "{") {
|
|
379
|
+
depth++;
|
|
380
|
+
current += char;
|
|
381
|
+
} else if (char === "}") {
|
|
382
|
+
depth--;
|
|
383
|
+
current += char;
|
|
384
|
+
} else if (char === "," && depth === 0) {
|
|
385
|
+
parts.push(current);
|
|
386
|
+
current = "";
|
|
387
|
+
} else
|
|
388
|
+
current += char;
|
|
389
|
+
}
|
|
390
|
+
if (current)
|
|
391
|
+
parts.push(current);
|
|
392
|
+
return parts;
|
|
393
|
+
}
|
|
394
|
+
function formatICUPlural(value, options, params) {
|
|
395
|
+
const count = Number(value) || 0, parsedOptions = parseICUOptions(options), exactKey = `=${count}`;
|
|
396
|
+
if (parsedOptions[exactKey])
|
|
397
|
+
return formatICUPluralContent(parsedOptions[exactKey], count, params);
|
|
398
|
+
const category = getPluralCategory(count);
|
|
399
|
+
if (parsedOptions[category])
|
|
400
|
+
return formatICUPluralContent(parsedOptions[category], count, params);
|
|
401
|
+
if (parsedOptions.other)
|
|
402
|
+
return formatICUPluralContent(parsedOptions.other, count, params);
|
|
403
|
+
return String(count);
|
|
404
|
+
}
|
|
405
|
+
function formatICUPluralContent(content, count, params) {
|
|
406
|
+
const replaced = content.replace(/#/g, String(count));
|
|
407
|
+
return parseICUMessage(replaced, params);
|
|
408
|
+
}
|
|
409
|
+
function getPluralCategory(n) {
|
|
410
|
+
const absN = Math.abs(n), i = Math.floor(absN), v = String(n).includes(".") ? String(n).split(".")[1].length : 0;
|
|
411
|
+
if (i === 1 && v === 0)
|
|
412
|
+
return "one";
|
|
413
|
+
return "other";
|
|
414
|
+
}
|
|
415
|
+
function formatICUSelect(value, options) {
|
|
416
|
+
const key = String(value || ""), parsedOptions = parseICUOptions(options);
|
|
417
|
+
if (parsedOptions[key])
|
|
418
|
+
return parsedOptions[key];
|
|
419
|
+
return parsedOptions.other || String(value);
|
|
420
|
+
}
|
|
421
|
+
function formatICUSelectOrdinal(value, options) {
|
|
422
|
+
const count = Number(value) || 0, parsedOptions = parseICUOptions(options), category = getOrdinalCategory(count);
|
|
423
|
+
if (parsedOptions[category])
|
|
424
|
+
return parsedOptions[category].replace(/#/g, String(count));
|
|
425
|
+
if (parsedOptions.other)
|
|
426
|
+
return parsedOptions.other.replace(/#/g, String(count));
|
|
427
|
+
return String(count);
|
|
428
|
+
}
|
|
429
|
+
function getOrdinalCategory(n) {
|
|
430
|
+
const absN = Math.abs(n), mod10 = absN % 10, mod100 = absN % 100;
|
|
431
|
+
if (mod10 === 1 && mod100 !== 11)
|
|
432
|
+
return "one";
|
|
433
|
+
if (mod10 === 2 && mod100 !== 12)
|
|
434
|
+
return "two";
|
|
435
|
+
if (mod10 === 3 && mod100 !== 13)
|
|
436
|
+
return "few";
|
|
437
|
+
return "other";
|
|
438
|
+
}
|
|
439
|
+
function parseICUOptions(options) {
|
|
440
|
+
const result = {}, regex = /(\w+|=\d+)\s*\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g;
|
|
441
|
+
let match = regex.exec(options);
|
|
442
|
+
while (match !== null) {
|
|
443
|
+
result[match[1]] = match[2];
|
|
444
|
+
match = regex.exec(options);
|
|
445
|
+
}
|
|
446
|
+
return result;
|
|
447
|
+
}
|
|
448
|
+
function formatICUNumber(value, style) {
|
|
449
|
+
const num = Number(value);
|
|
450
|
+
if (Number.isNaN(num))
|
|
451
|
+
return String(value);
|
|
452
|
+
switch (style) {
|
|
453
|
+
case "integer":
|
|
454
|
+
return Math.floor(num).toLocaleString();
|
|
455
|
+
case "percent":
|
|
456
|
+
return `${(num * 100).toFixed(0)}%`;
|
|
457
|
+
case "currency":
|
|
458
|
+
return num.toLocaleString(void 0, { style: "currency", currency: "USD" });
|
|
459
|
+
default:
|
|
460
|
+
return num.toLocaleString();
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
function formatICUDate(value, style) {
|
|
464
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
465
|
+
if (Number.isNaN(date.getTime()))
|
|
466
|
+
return String(value);
|
|
467
|
+
const options = {};
|
|
468
|
+
switch (style) {
|
|
469
|
+
case "short":
|
|
470
|
+
options.dateStyle = "short";
|
|
471
|
+
break;
|
|
472
|
+
case "medium":
|
|
473
|
+
options.dateStyle = "medium";
|
|
474
|
+
break;
|
|
475
|
+
case "long":
|
|
476
|
+
options.dateStyle = "long";
|
|
477
|
+
break;
|
|
478
|
+
case "full":
|
|
479
|
+
options.dateStyle = "full";
|
|
480
|
+
break;
|
|
481
|
+
default:
|
|
482
|
+
options.dateStyle = "medium";
|
|
483
|
+
}
|
|
484
|
+
return date.toLocaleDateString(void 0, options);
|
|
485
|
+
}
|
|
486
|
+
function formatICUTime(value, style) {
|
|
487
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
488
|
+
if (Number.isNaN(date.getTime()))
|
|
489
|
+
return String(value);
|
|
490
|
+
const options = {};
|
|
491
|
+
switch (style) {
|
|
492
|
+
case "short":
|
|
493
|
+
options.timeStyle = "short";
|
|
494
|
+
break;
|
|
495
|
+
case "medium":
|
|
496
|
+
options.timeStyle = "medium";
|
|
497
|
+
break;
|
|
498
|
+
case "long":
|
|
499
|
+
options.timeStyle = "long";
|
|
500
|
+
break;
|
|
501
|
+
case "full":
|
|
502
|
+
options.timeStyle = "full";
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
options.timeStyle = "short";
|
|
506
|
+
}
|
|
507
|
+
return date.toLocaleTimeString(void 0, options);
|
|
508
|
+
}
|
|
509
|
+
export function isICUFormat(message) {
|
|
510
|
+
return /\{[^}]+,\s*(?:plural|select|selectordinal|number|date|time)\s*,/.test(message);
|
|
511
|
+
}
|
|
512
|
+
export function getTranslation(key, translations, fallbackToKey = !0, params = {}) {
|
|
513
|
+
const parts = key.split(".");
|
|
514
|
+
let value = translations;
|
|
515
|
+
for (const part of parts) {
|
|
516
|
+
if (value === void 0 || value === null)
|
|
517
|
+
break;
|
|
518
|
+
value = value[part];
|
|
519
|
+
}
|
|
520
|
+
if (value === void 0 || value === null)
|
|
521
|
+
return fallbackToKey ? key : "";
|
|
522
|
+
let result = String(value);
|
|
523
|
+
if (isICUFormat(result))
|
|
524
|
+
return formatICU(result, params);
|
|
525
|
+
if (result.includes("|") && "count" in params) {
|
|
526
|
+
const count = Number(params.count), forms = result.split("|");
|
|
527
|
+
result = selectPluralForm(forms, count);
|
|
528
|
+
}
|
|
529
|
+
for (const [paramKey, paramValue] of Object.entries(params)) {
|
|
530
|
+
const escapedKey = paramKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
531
|
+
result = result.replace(new RegExp(`:${escapedKey}`, "g"), String(paramValue));
|
|
532
|
+
}
|
|
533
|
+
return result;
|
|
534
|
+
}
|
|
535
|
+
export async function processTranslateDirective(template, context, filePath, options) {
|
|
536
|
+
let output = template;
|
|
537
|
+
const fixedTranslateRegex = /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]*\})\s*)?\)([\s\S]*?)@endtranslate/g, i18nConfig = {
|
|
538
|
+
...defaultI18nConfig,
|
|
539
|
+
...options.i18n
|
|
540
|
+
}, translations = await loadTranslation(i18nConfig.locale, options);
|
|
541
|
+
context.__translations = translations;
|
|
542
|
+
context.__locale = i18nConfig.locale;
|
|
543
|
+
context.__i18nConfig = i18nConfig;
|
|
544
|
+
output = await replaceAsync(output, fixedTranslateRegex, async (_match, key, paramsStr, content, _offset) => {
|
|
545
|
+
try {
|
|
546
|
+
let params = {};
|
|
547
|
+
if (paramsStr)
|
|
548
|
+
try {
|
|
549
|
+
const approaches = [
|
|
550
|
+
() => JSON.parse(paramsStr),
|
|
551
|
+
() => {
|
|
552
|
+
const jsonStr = `{"data":${paramsStr}}`, parsed = JSON.parse(jsonStr);
|
|
553
|
+
return typeof parsed.data === "object" ? parsed.data : {};
|
|
554
|
+
},
|
|
555
|
+
() => {
|
|
556
|
+
return safeEvaluateObject(paramsStr, context);
|
|
557
|
+
}
|
|
558
|
+
];
|
|
559
|
+
for (const approach of approaches)
|
|
560
|
+
try {
|
|
561
|
+
params = approach();
|
|
562
|
+
if (Object.keys(params).length > 0)
|
|
563
|
+
break;
|
|
564
|
+
} catch {}
|
|
565
|
+
} catch (error) {
|
|
566
|
+
if (options.debug)
|
|
567
|
+
console.error("Error parsing parameters for @translate directive:", error);
|
|
568
|
+
}
|
|
569
|
+
return getTranslation(key, translations, i18nConfig.fallbackToKey, params) || content.trim();
|
|
570
|
+
} catch (error) {
|
|
571
|
+
if (options.debug)
|
|
572
|
+
console.error("Error processing @translate directive:", error);
|
|
573
|
+
return inlineError("Translate", `Error in @translate('${key}'): ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.EVALUATION_ERROR);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
const inlineTranslateRegex = /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]+\})\s*)?\)/g;
|
|
577
|
+
if (options.debug) {
|
|
578
|
+
console.warn(`Processing translations in template. Sections: ${output.includes("<h2>Translation with Parameters</h2>") ? "Parameters section found" : "Parameters section missing"}`);
|
|
579
|
+
const matches = [...output.matchAll(inlineTranslateRegex)];
|
|
580
|
+
console.warn(`Found ${matches.length} @translate matches`);
|
|
581
|
+
matches.forEach((m, i) => console.warn(`Match ${i}: ${m[0]}, Key: ${m[1]}, Params: ${m[2] || "none"}`));
|
|
582
|
+
}
|
|
583
|
+
output = await replaceAsync(output, /@translate\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\{[^}]*\})\s*)?\)/g, async (_match, key, paramsStr, _offset) => {
|
|
584
|
+
try {
|
|
585
|
+
let params = {};
|
|
586
|
+
if (paramsStr)
|
|
587
|
+
try {
|
|
588
|
+
const approaches = [
|
|
589
|
+
() => JSON.parse(paramsStr),
|
|
590
|
+
() => {
|
|
591
|
+
const jsonStr = `{"data":${paramsStr}}`, parsed = JSON.parse(jsonStr);
|
|
592
|
+
return typeof parsed.data === "object" ? parsed.data : {};
|
|
593
|
+
},
|
|
594
|
+
() => {
|
|
595
|
+
return safeEvaluateObject(paramsStr, context);
|
|
596
|
+
}
|
|
597
|
+
];
|
|
598
|
+
for (const approach of approaches)
|
|
599
|
+
try {
|
|
600
|
+
params = approach();
|
|
601
|
+
if (Object.keys(params).length > 0)
|
|
602
|
+
break;
|
|
603
|
+
} catch {}
|
|
604
|
+
} catch (error) {
|
|
605
|
+
if (options.debug)
|
|
606
|
+
console.error("Error parsing parameters for @translate directive:", error);
|
|
607
|
+
}
|
|
608
|
+
return getTranslation(key, translations, i18nConfig.fallbackToKey, params);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
if (options.debug)
|
|
611
|
+
console.error("Error processing @translate directive:", error);
|
|
612
|
+
return inlineError("Translate", `Error in @translate('${key}'): ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.EVALUATION_ERROR);
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
return output;
|
|
616
|
+
}
|
|
617
|
+
async function replaceAsync(str, regex, asyncFn) {
|
|
618
|
+
const promises = [];
|
|
619
|
+
str.replace(regex, (match, ...args) => {
|
|
620
|
+
const promise = asyncFn(match, ...args).then((replacement) => ({
|
|
621
|
+
match,
|
|
622
|
+
replacement
|
|
623
|
+
}));
|
|
624
|
+
promises.push(promise);
|
|
625
|
+
return match;
|
|
626
|
+
});
|
|
627
|
+
return (await Promise.all(promises)).reduce((str, { match, replacement }) => str.replace(match, replacement), str);
|
|
628
|
+
}
|
|
629
|
+
export function createTranslateFilter(translations, fallbackToKey = !0) {
|
|
630
|
+
return (value, params = {}) => {
|
|
631
|
+
return getTranslation(value, translations, fallbackToKey, params);
|
|
632
|
+
};
|
|
633
|
+
}
|