intor 2.3.2 → 2.3.4
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/README.md +10 -0
- package/dist/export/config/index.d.ts +1 -0
- package/dist/export/config/index.js +1 -0
- package/dist/export/index.d.ts +4 -0
- package/dist/export/index.js +4 -0
- package/dist/export/internal/index.d.ts +1 -0
- package/dist/export/next/index.d.ts +1 -0
- package/dist/export/next/index.js +4 -0
- package/dist/export/next/proxy/index.d.ts +1 -0
- package/dist/{exports → export}/next/proxy/index.js +0 -1
- package/dist/export/next/server/index.d.ts +1 -0
- package/dist/export/next/server/index.js +2 -0
- package/dist/export/react/index.d.ts +1 -0
- package/dist/export/react/index.js +10 -0
- package/dist/export/server/index.d.ts +1 -0
- package/dist/export/server/index.js +7 -0
- package/dist/src/adapters/next/navigation/link.d.ts +17 -7
- package/dist/src/adapters/next/navigation/link.js +35 -9
- package/dist/src/adapters/next/navigation/redirect.d.ts +10 -8
- package/dist/src/adapters/next/navigation/redirect.js +19 -18
- package/dist/src/adapters/next/navigation/use-pathname.d.ts +5 -5
- package/dist/src/adapters/next/navigation/use-pathname.js +7 -20
- package/dist/src/adapters/next/navigation/use-router.d.ts +15 -10
- package/dist/src/adapters/next/navigation/use-router.js +51 -17
- package/dist/src/adapters/next/proxy/index.d.ts +0 -1
- package/dist/src/adapters/next/proxy/intor-proxy.d.ts +10 -3
- package/dist/src/adapters/next/proxy/intor-proxy.js +38 -16
- package/dist/src/adapters/next/proxy/utils/set-locale-cookie-edge.d.ts +2 -4
- package/dist/src/adapters/next/proxy/utils/set-locale-cookie-edge.js +2 -7
- package/dist/src/adapters/next/server/get-locale.d.ts +6 -0
- package/dist/src/adapters/next/server/get-locale.js +25 -0
- package/dist/src/adapters/next/server/get-translator.d.ts +7 -5
- package/dist/src/adapters/next/server/get-translator.js +4 -4
- package/dist/src/adapters/next/server/index.d.ts +1 -1
- package/dist/src/client/helpers/get-client-locale.d.ts +11 -0
- package/dist/src/client/helpers/get-client-locale.js +24 -0
- package/dist/src/client/helpers/index.d.ts +1 -0
- package/dist/src/client/react/contexts/config/context.js +0 -1
- package/dist/src/client/react/contexts/config/hook.js +0 -1
- package/dist/src/client/react/contexts/config/provider.d.ts +1 -1
- package/dist/src/client/react/contexts/config/provider.js +5 -2
- package/dist/src/client/react/contexts/config/types.d.ts +6 -5
- package/dist/src/client/react/contexts/intor-provider/intor-provider.d.ts +1 -1
- package/dist/src/client/react/contexts/intor-provider/intor-provider.js +3 -3
- package/dist/src/client/react/contexts/intor-provider/types.d.ts +1 -2
- package/dist/src/client/react/contexts/locale/context.js +0 -1
- package/dist/src/client/react/contexts/locale/hook.js +0 -1
- package/dist/src/client/react/contexts/locale/provider.js +16 -26
- package/dist/src/client/react/contexts/locale/types.d.ts +4 -4
- package/dist/src/client/react/contexts/locale/utils/change-locale.d.ts +14 -16
- package/dist/src/client/react/contexts/locale/utils/change-locale.js +18 -27
- package/dist/src/client/react/contexts/messages/context.js +1 -4
- package/dist/src/client/react/contexts/messages/hook.js +0 -1
- package/dist/src/client/react/contexts/messages/provider.js +18 -11
- package/dist/src/client/react/contexts/messages/types.d.ts +4 -7
- package/dist/src/client/react/contexts/messages/utils/use-refetch-messages.d.ts +10 -6
- package/dist/src/client/react/contexts/messages/utils/use-refetch-messages.js +44 -31
- package/dist/src/client/react/contexts/translator/context.js +1 -4
- package/dist/src/client/react/contexts/translator/hook.d.ts +1 -2
- package/dist/src/client/react/contexts/translator/hook.js +0 -1
- package/dist/src/client/react/contexts/translator/provider.js +21 -24
- package/dist/src/client/react/contexts/translator/types.d.ts +5 -5
- package/dist/src/client/react/contexts/translator-runtime/context.d.ts +3 -0
- package/dist/src/client/react/contexts/translator-runtime/context.js +3 -0
- package/dist/src/client/react/contexts/translator-runtime/hook.d.ts +2 -0
- package/dist/src/client/react/contexts/translator-runtime/hook.js +9 -0
- package/dist/src/client/react/contexts/translator-runtime/index.d.ts +3 -0
- package/dist/src/client/react/contexts/translator-runtime/provider.d.ts +2 -0
- package/dist/src/client/react/contexts/translator-runtime/provider.js +15 -0
- package/dist/src/client/react/contexts/translator-runtime/types.d.ts +13 -0
- package/dist/src/client/react/index.d.ts +4 -3
- package/dist/src/client/react/navigation/index.d.ts +2 -0
- package/dist/src/client/react/navigation/use-navigation-strategy.d.ts +22 -0
- package/dist/src/client/react/navigation/use-navigation-strategy.js +37 -0
- package/dist/src/client/react/navigation/use-navigation-target.d.ts +12 -0
- package/dist/src/client/react/navigation/use-navigation-target.js +27 -0
- package/dist/src/client/react/{hooks → translator}/use-translator.d.ts +4 -4
- package/dist/src/client/react/{hooks → translator}/use-translator.js +4 -9
- package/dist/src/client/shared/utils/build-cookie-string.d.ts +5 -0
- package/dist/src/client/shared/utils/build-cookie-string.js +30 -0
- package/dist/src/client/shared/utils/index.d.ts +1 -0
- package/dist/src/client/shared/utils/locale/detect-browser-locale.d.ts +6 -0
- package/dist/src/client/shared/utils/locale/detect-browser-locale.js +12 -0
- package/dist/src/client/shared/utils/locale/get-locale-cookie-browser.d.ts +6 -0
- package/dist/src/client/shared/utils/locale/get-locale-cookie-browser.js +16 -0
- package/dist/src/client/shared/utils/locale/index.d.ts +4 -0
- package/dist/src/client/shared/utils/locale/set-document-locale.d.ts +6 -0
- package/dist/src/client/shared/utils/locale/set-document-locale.js +12 -0
- package/dist/src/client/shared/utils/locale/set-locale-cookie-browser.d.ts +7 -0
- package/dist/src/client/shared/utils/locale/set-locale-cookie-browser.js +18 -0
- package/dist/src/config/constants/cookie.constants.js +2 -2
- package/dist/src/config/constants/routing.constants.js +6 -0
- package/dist/src/config/define-intor-config.d.ts +16 -0
- package/dist/src/config/define-intor-config.js +18 -4
- package/dist/src/config/index.d.ts +0 -3
- package/dist/src/config/resolvers/resolve-cookie-options.d.ts +0 -9
- package/dist/src/config/resolvers/resolve-cookie-options.js +0 -9
- package/dist/src/config/resolvers/resolve-fallback-locales.d.ts +18 -1
- package/dist/src/config/resolvers/resolve-fallback-locales.js +17 -0
- package/dist/src/config/resolvers/resolve-routing-options.d.ts +0 -11
- package/dist/src/config/resolvers/resolve-routing-options.js +5 -13
- package/dist/src/config/types/cache.types.d.ts +2 -2
- package/dist/src/config/types/cookie.types.d.ts +10 -10
- package/dist/src/config/types/intor-config.types.d.ts +2 -0
- package/dist/src/config/types/loader.types.d.ts +15 -19
- package/dist/src/config/types/logger.types.d.ts +7 -5
- package/dist/src/config/types/routing.types.d.ts +33 -9
- package/dist/src/config/types/translator.types.d.ts +5 -2
- package/dist/src/config/validators/validate-default-locale.d.ts +9 -0
- package/dist/src/config/validators/validate-default-locale.js +9 -0
- package/dist/src/config/validators/validate-supported-locales.d.ts +8 -3
- package/dist/src/config/validators/validate-supported-locales.js +8 -3
- package/dist/src/routing/index.d.ts +1 -0
- package/dist/src/routing/locale/index.d.ts +1 -0
- package/dist/src/routing/locale/resolve-locale.d.ts +16 -0
- package/dist/src/routing/locale/resolve-locale.js +32 -0
- package/dist/src/routing/locale/types.d.ts +36 -0
- package/dist/src/routing/pathname/index.d.ts +1 -0
- package/dist/src/routing/pathname/resolve-pathname.d.ts +19 -0
- package/dist/src/routing/pathname/resolve-pathname.js +53 -0
- package/dist/src/routing/pathname/strategies/all.d.ts +6 -0
- package/dist/src/routing/pathname/strategies/all.js +23 -0
- package/dist/src/routing/pathname/strategies/except-default.d.ts +6 -0
- package/dist/src/routing/pathname/strategies/except-default.js +33 -0
- package/dist/src/routing/pathname/strategies/index.d.ts +3 -0
- package/dist/src/routing/pathname/strategies/none.d.ts +5 -0
- package/dist/src/routing/pathname/strategies/none.js +14 -0
- package/dist/src/routing/pathname/types.d.ts +28 -0
- package/dist/src/routing/resolve-navigation-target.d.ts +20 -0
- package/dist/src/routing/resolve-navigation-target.js +28 -0
- package/dist/src/routing/resolve-routing.d.ts +30 -0
- package/dist/src/routing/resolve-routing.js +38 -0
- package/dist/src/server/helpers/index.d.ts +1 -0
- package/dist/src/server/helpers/local-messages-from-url.d.ts +21 -0
- package/dist/src/server/helpers/local-messages-from-url.js +48 -0
- package/dist/src/server/index.d.ts +4 -2
- package/dist/src/server/intor/index.d.ts +1 -1
- package/dist/src/server/intor/intor.d.ts +12 -6
- package/dist/src/server/intor/intor.js +21 -39
- package/dist/src/server/intor/types.d.ts +5 -10
- package/dist/src/server/messages/index.d.ts +1 -5
- package/dist/src/server/messages/load-local-messages/index.d.ts +1 -1
- package/dist/src/server/messages/load-local-messages/load-local-messages.d.ts +11 -7
- package/dist/src/server/messages/load-local-messages/load-local-messages.js +46 -38
- package/dist/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.d.ts +5 -14
- package/dist/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +12 -29
- package/dist/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/types.d.ts +1 -1
- package/dist/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.d.ts +2 -2
- package/dist/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +8 -5
- package/dist/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/types.d.ts +1 -1
- package/dist/src/server/messages/load-local-messages/read-locale-messages/read-locale-messages.d.ts +2 -2
- package/dist/src/server/messages/load-local-messages/read-locale-messages/read-locale-messages.js +3 -3
- package/dist/src/server/messages/load-local-messages/read-locale-messages/types.d.ts +1 -1
- package/dist/src/server/messages/load-local-messages/types.d.ts +12 -11
- package/dist/src/server/messages/load-messages.d.ts +10 -7
- package/dist/src/server/messages/load-messages.js +21 -21
- package/dist/src/server/messages/load-remote-messages/fetch-locale-messages/fetch-locale-messages.d.ts +1 -1
- package/dist/src/server/messages/load-remote-messages/fetch-locale-messages/fetch-locale-messages.js +6 -1
- package/dist/src/server/messages/load-remote-messages/fetch-locale-messages/types.d.ts +1 -0
- package/dist/src/server/messages/load-remote-messages/index.d.ts +1 -1
- package/dist/src/server/messages/load-remote-messages/load-remote-messages.d.ts +10 -4
- package/dist/src/server/messages/load-remote-messages/load-remote-messages.js +65 -34
- package/dist/src/server/messages/load-remote-messages/types.d.ts +4 -3
- package/dist/src/server/messages/types.d.ts +2 -3
- package/dist/src/server/shared/logger/get-logger.d.ts +1 -1
- package/dist/src/server/shared/logger/get-logger.js +10 -5
- package/dist/src/server/translator/get-translator.d.ts +9 -9
- package/dist/src/server/translator/get-translator.js +6 -10
- package/dist/src/shared/constants/index.d.ts +1 -0
- package/dist/src/shared/error/intor-error.d.ts +4 -4
- package/dist/src/shared/types/generated.d.ts +53 -0
- package/dist/src/shared/types/index.d.ts +2 -0
- package/dist/src/shared/types/routing.d.ts +6 -0
- package/dist/src/shared/types/{translator-instance.types.d.ts → translator-instance.d.ts} +17 -19
- package/dist/src/shared/utils/deep-merge.d.ts +8 -0
- package/dist/src/shared/utils/deep-merge.js +36 -0
- package/dist/src/shared/utils/index.d.ts +4 -8
- package/dist/src/shared/utils/is-external-destination.d.ts +7 -0
- package/dist/src/shared/utils/is-external-destination.js +11 -0
- package/dist/src/shared/utils/locale/get-locale-from-accept-language.d.ts +19 -0
- package/dist/src/shared/utils/locale/get-locale-from-accept-language.js +45 -0
- package/dist/src/shared/utils/locale/get-locale-from-host.d.ts +17 -0
- package/dist/src/shared/utils/locale/get-locale-from-host.js +31 -0
- package/dist/src/shared/utils/locale/get-locale-from-pathname.d.ts +31 -0
- package/dist/src/shared/utils/locale/get-locale-from-pathname.js +52 -0
- package/dist/src/shared/utils/locale/get-locale-from-query.d.ts +20 -0
- package/dist/src/shared/utils/locale/get-locale-from-query.js +33 -0
- package/dist/src/shared/utils/locale/index.d.ts +4 -0
- package/dist/src/shared/utils/normalizers/index.d.ts +3 -0
- package/dist/src/shared/utils/normalizers/normalize-cache-key.d.ts +14 -0
- package/dist/src/shared/utils/{normalize-cache-key.js → normalizers/normalize-cache-key.js} +17 -1
- package/dist/src/shared/utils/normalizers/normalize-locale.d.ts +22 -0
- package/dist/src/shared/utils/{locale → normalizers}/normalize-locale.js +21 -4
- package/dist/src/shared/utils/{pathname → normalizers}/normalize-pathname.d.ts +1 -1
- package/dist/src/shared/utils/{pathname → normalizers}/normalize-pathname.js +1 -1
- package/dist/src/shared/utils/pathname/get-unprefixed-pathname.d.ts +14 -0
- package/dist/src/shared/utils/pathname/get-unprefixed-pathname.js +39 -0
- package/dist/src/shared/utils/pathname/index.d.ts +1 -0
- package/dist/src/shared/utils/pathname/locale-prefix-pathname.d.ts +16 -0
- package/dist/src/{adapters/next/shared/utils → shared/utils/pathname}/locale-prefix-pathname.js +17 -12
- package/dist/src/shared/utils/pathname/localize-pathname.d.ts +23 -0
- package/dist/src/shared/utils/pathname/localize-pathname.js +36 -0
- package/dist/src/shared/utils/pathname/standardize-pathname.d.ts +6 -11
- package/dist/src/shared/utils/pathname/standardize-pathname.js +8 -8
- package/package.json +74 -65
- package/dist/exports/config/index.d.ts +0 -2
- package/dist/exports/config/index.js +0 -4
- package/dist/exports/index.d.ts +0 -5
- package/dist/exports/index.js +0 -11
- package/dist/exports/next/index.d.ts +0 -3
- package/dist/exports/next/index.js +0 -9
- package/dist/exports/next/proxy/index.d.ts +0 -2
- package/dist/exports/next/server/index.d.ts +0 -2
- package/dist/exports/next/server/index.js +0 -2
- package/dist/exports/react/index.d.ts +0 -2
- package/dist/exports/react/index.js +0 -6
- package/dist/exports/server/index.d.ts +0 -2
- package/dist/exports/server/index.js +0 -7
- package/dist/src/adapters/next/navigation/utils/should-full-reload.d.ts +0 -7
- package/dist/src/adapters/next/navigation/utils/should-full-reload.js +0 -19
- package/dist/src/adapters/next/navigation/utils/use-locale-switch.d.ts +0 -16
- package/dist/src/adapters/next/navigation/utils/use-locale-switch.js +0 -58
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-all.d.ts +0 -12
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-all.js +0 -60
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-except-default.d.ts +0 -16
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-except-default.js +0 -81
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-none.d.ts +0 -10
- package/dist/src/adapters/next/proxy/handle-prefix/handle-prefix-none.js +0 -22
- package/dist/src/adapters/next/proxy/utils/create-response.d.ts +0 -17
- package/dist/src/adapters/next/proxy/utils/create-response.js +0 -42
- package/dist/src/adapters/next/proxy/utils/determine-initial-locale.d.ts +0 -8
- package/dist/src/adapters/next/proxy/utils/determine-initial-locale.js +0 -28
- package/dist/src/adapters/next/proxy/utils/set-pathname-header.d.ts +0 -12
- package/dist/src/adapters/next/proxy/utils/set-pathname-header.js +0 -13
- package/dist/src/adapters/next/server/get-i18n-context.d.ts +0 -9
- package/dist/src/adapters/next/server/get-i18n-context.js +0 -47
- package/dist/src/adapters/next/shared/constants/pathname-header-name.d.ts +0 -1
- package/dist/src/adapters/next/shared/constants/pathname-header-name.js +0 -4
- package/dist/src/adapters/next/shared/utils/locale-prefix-pathname.d.ts +0 -16
- package/dist/src/adapters/next/shared/utils/localize-pathname.d.ts +0 -18
- package/dist/src/adapters/next/shared/utils/localize-pathname.js +0 -36
- package/dist/src/client/react/contexts/locale/utils/use-init-locale-cookie.d.ts +0 -8
- package/dist/src/client/react/contexts/locale/utils/use-init-locale-cookie.js +0 -28
- package/dist/src/client/react/contexts/translate-handlers/context.d.ts +0 -2
- package/dist/src/client/react/contexts/translate-handlers/context.js +0 -6
- package/dist/src/client/react/contexts/translate-handlers/hook.d.ts +0 -2
- package/dist/src/client/react/contexts/translate-handlers/hook.js +0 -10
- package/dist/src/client/react/contexts/translate-handlers/index.d.ts +0 -3
- package/dist/src/client/react/contexts/translate-handlers/provider.d.ts +0 -2
- package/dist/src/client/react/contexts/translate-handlers/provider.js +0 -11
- package/dist/src/client/react/contexts/translate-handlers/types.d.ts +0 -7
- package/dist/src/client/shared/utils/get-initial-locale.d.ts +0 -11
- package/dist/src/client/shared/utils/get-initial-locale.js +0 -21
- package/dist/src/shared/types/generated.types.d.ts +0 -30
- package/dist/src/shared/utils/client/build-cookie-string.d.ts +0 -9
- package/dist/src/shared/utils/client/build-cookie-string.js +0 -33
- package/dist/src/shared/utils/client/set-locale-cookie-browser.d.ts +0 -13
- package/dist/src/shared/utils/client/set-locale-cookie-browser.js +0 -21
- package/dist/src/shared/utils/locale/normalize-locale.d.ts +0 -4
- package/dist/src/shared/utils/locale/resolve-preferred-locale.d.ts +0 -5
- package/dist/src/shared/utils/locale/resolve-preferred-locale.js +0 -26
- package/dist/src/shared/utils/merge-messages.d.ts +0 -6
- package/dist/src/shared/utils/merge-messages.js +0 -13
- package/dist/src/shared/utils/normalize-cache-key.d.ts +0 -3
- package/dist/src/shared/utils/pathname/extract-pathname.d.ts +0 -28
- package/dist/src/shared/utils/pathname/extract-pathname.js +0 -58
- package/dist/src/shared/utils/resolve-namespaces.d.ts +0 -10
- package/dist/src/shared/utils/resolve-namespaces.js +0 -33
- /package/dist/src/server/{messages/shared → shared/messages}/global-messages-pool.d.ts +0 -0
- /package/dist/src/server/{messages/shared → shared/messages}/global-messages-pool.js +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
interface IntorErrorOptions {
|
|
2
2
|
message: string;
|
|
3
|
-
code?:
|
|
3
|
+
code?: IntorErrorCode;
|
|
4
4
|
id?: string;
|
|
5
|
-
}
|
|
5
|
+
}
|
|
6
6
|
export declare class IntorError extends Error {
|
|
7
|
-
readonly code?:
|
|
7
|
+
readonly code?: IntorErrorCode;
|
|
8
8
|
readonly id?: string;
|
|
9
9
|
constructor({ message, code, id }: IntorErrorOptions);
|
|
10
10
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { PREFIX_PLACEHOLDER } from "../../shared/constants/prefix-placeholder";
|
|
2
|
+
import type { LocaleMessages } from "intor-translator";
|
|
3
|
+
/**
|
|
4
|
+
* ================================================
|
|
5
|
+
* Generated-aware type system for Intor.
|
|
6
|
+
*
|
|
7
|
+
* This module defines conditional and fallback types that adapt
|
|
8
|
+
* based on whether generated types are present.
|
|
9
|
+
* ================================================
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Internal sentinel key indicating that Intor generated types are present.
|
|
13
|
+
* - Used by conditional types to switch between fallback and generated modes.
|
|
14
|
+
* - Type-level only. Not for runtime or user-facing usage.
|
|
15
|
+
*/
|
|
16
|
+
export type INTOR_GENERATED_KEY = "__intor_generated__";
|
|
17
|
+
/**
|
|
18
|
+
* Conditional type for generated types.
|
|
19
|
+
* - Uses key presence on `IntorGeneratedTypes` to detect generation.
|
|
20
|
+
*/
|
|
21
|
+
export type IfGen<Then, Else = never> = IntorGeneratedTypes extends {
|
|
22
|
+
[K in INTOR_GENERATED_KEY]: true;
|
|
23
|
+
} ? Then : Else;
|
|
24
|
+
/**
|
|
25
|
+
* Config keys provided by generated types.
|
|
26
|
+
* - Excludes internal sentinel
|
|
27
|
+
*/
|
|
28
|
+
type GeneratedConfigKeys = Exclude<keyof IntorGeneratedTypes, INTOR_GENERATED_KEY>;
|
|
29
|
+
/**
|
|
30
|
+
* Union of all configuration keys.
|
|
31
|
+
* - Defaults to `string` if `IntorGeneratedTypes` does not exist.
|
|
32
|
+
*/
|
|
33
|
+
export type GenConfigKeys = IfGen<GeneratedConfigKeys, string>;
|
|
34
|
+
/**
|
|
35
|
+
* Configuration shape for a given config key.
|
|
36
|
+
* - If `IntorGeneratedTypes` is not defined, falls back to default shape.
|
|
37
|
+
* Otherwise, picks `Locales` and `Messages` according to the key.
|
|
38
|
+
*/
|
|
39
|
+
export type GenConfig<CK extends GenConfigKeys> = IfGen<CK extends keyof IntorGeneratedTypes ? IntorGeneratedTypes[CK] extends {
|
|
40
|
+
Locales: infer L extends string;
|
|
41
|
+
Messages: Record<typeof PREFIX_PLACEHOLDER, infer M>;
|
|
42
|
+
} ? {
|
|
43
|
+
Locales: L;
|
|
44
|
+
Messages: Record<L, M>;
|
|
45
|
+
} : never : never, {
|
|
46
|
+
Locales: string;
|
|
47
|
+
Messages: LocaleMessages;
|
|
48
|
+
}>;
|
|
49
|
+
/** Extracts messages for a given config key */
|
|
50
|
+
export type GenMessages<CK extends GenConfigKeys> = GenConfig<CK>["Messages"];
|
|
51
|
+
/** Extracts locales for a given config key */
|
|
52
|
+
export type GenLocale<CK extends GenConfigKeys> = GenConfig<CK>["Locales"];
|
|
53
|
+
export {};
|
|
@@ -1,33 +1,31 @@
|
|
|
1
|
-
import type { IfGen } from "../../shared/types/generated
|
|
1
|
+
import type { IfGen } from "../../shared/types/generated";
|
|
2
2
|
import { type Locale, type Replacement, type ScopedLeafKeys, type LocalizedLeafKeys, type LocaleMessages } from "intor-translator";
|
|
3
|
-
/** Base properties shared by all translator instances. */
|
|
4
|
-
export interface TranslatorBaseProps<M = unknown> {
|
|
5
|
-
/** `messages`: The message object containing all translations. */
|
|
6
|
-
messages: M;
|
|
7
|
-
/** Current locale in use. */
|
|
8
|
-
locale: Locale<M>;
|
|
9
|
-
}
|
|
10
|
-
/** Properties specific to client-side translator behavior. */
|
|
11
|
-
export interface TranslatorClientProps<M = unknown> {
|
|
12
|
-
/** `isLoading`: Indicates whether translations are currently loading. */
|
|
13
|
-
isLoading: boolean;
|
|
14
|
-
/** `setLocale`: Function to update the current locale. */
|
|
15
|
-
setLocale: (locale: Locale<M>) => void;
|
|
16
|
-
}
|
|
17
3
|
/**
|
|
18
4
|
* Conditional key type for TranslatorInstance.
|
|
5
|
+
*
|
|
19
6
|
* - Resolves to `ScopedLeafKeys` if a pre-key `PK` is provided,
|
|
20
7
|
* otherwise resolves to `LocalizedLeafKeys`.
|
|
21
8
|
*/
|
|
22
|
-
type Key<M extends LocaleMessages, PK> = IfGen<PK extends string ? ScopedLeafKeys<M, PK> : LocalizedLeafKeys<M>, string>;
|
|
9
|
+
export type Key<M extends LocaleMessages, PK> = IfGen<PK extends string ? ScopedLeafKeys<M, PK> : LocalizedLeafKeys<M>, string>;
|
|
23
10
|
/**
|
|
24
11
|
* Translator instance type.
|
|
25
|
-
* Combines base props, client props, and core translation methods.
|
|
26
12
|
*/
|
|
27
13
|
export type TranslatorInstance<M extends LocaleMessages, PK extends string | undefined = undefined> = {
|
|
14
|
+
/** `messages`: The message object containing all translations. */
|
|
15
|
+
messages: M;
|
|
16
|
+
/** Current locale in use. */
|
|
17
|
+
locale: Locale<M>;
|
|
28
18
|
/** Check if a given key exists in the messages. */
|
|
29
19
|
hasKey: (key?: Key<M, PK>, targetLocale?: Locale<M>) => boolean;
|
|
30
20
|
/** Translate a given key into its string representation. */
|
|
31
21
|
t: <Result = string>(key?: Key<M, PK>, replacements?: Replacement) => Result;
|
|
32
|
-
}
|
|
33
|
-
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Translator instance type for client-side.
|
|
25
|
+
*/
|
|
26
|
+
export type TranslatorInstanceClient<M extends LocaleMessages, PK extends string | undefined = undefined> = TranslatorInstance<M, PK> & {
|
|
27
|
+
/** `isLoading`: Indicates whether translations are currently loading. */
|
|
28
|
+
isLoading: boolean;
|
|
29
|
+
/** `setLocale`: Function to update the current locale. */
|
|
30
|
+
setLocale: (locale: Locale<M>) => void;
|
|
31
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type PlainObject = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Deeply merges two objects.
|
|
4
|
+
* - Nested objects → merged recursively
|
|
5
|
+
* - Array / primitive → b overwrites a
|
|
6
|
+
*/
|
|
7
|
+
export declare const deepMerge: <T extends PlainObject, U extends PlainObject>(a?: T, b?: U) => (T & U) | T | U | undefined;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deeply merges two objects.
|
|
3
|
+
* - Nested objects → merged recursively
|
|
4
|
+
* - Array / primitive → b overwrites a
|
|
5
|
+
*/
|
|
6
|
+
const deepMerge = (a, b) => {
|
|
7
|
+
if (!a && !b)
|
|
8
|
+
return undefined;
|
|
9
|
+
if (!a)
|
|
10
|
+
return b;
|
|
11
|
+
if (!b)
|
|
12
|
+
return a;
|
|
13
|
+
const result = { ...a };
|
|
14
|
+
for (const key in b) {
|
|
15
|
+
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
|
16
|
+
const av = a[key];
|
|
17
|
+
const bv = b[key];
|
|
18
|
+
if (av &&
|
|
19
|
+
bv &&
|
|
20
|
+
typeof av === "object" &&
|
|
21
|
+
typeof bv === "object" &&
|
|
22
|
+
!Array.isArray(av) &&
|
|
23
|
+
!Array.isArray(bv)) {
|
|
24
|
+
// recursive merge
|
|
25
|
+
result[key] = deepMerge(av, bv);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// overwrite with primitive or array
|
|
29
|
+
result[key] = bv;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export { deepMerge };
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { normalizeCacheKey } from "./
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export { resolvePreferredLocale } from "./locale/resolve-preferred-locale";
|
|
6
|
-
export { extractPathname } from "./pathname/extract-pathname";
|
|
7
|
-
export { normalizePathname } from "./pathname/normalize-pathname";
|
|
8
|
-
export { standardizePathname } from "./pathname/standardize-pathname";
|
|
1
|
+
export { deepMerge } from "./deep-merge";
|
|
2
|
+
export { normalizeCacheKey, normalizeLocale, normalizePathname, } from "./normalizers";
|
|
3
|
+
export { getLocaleFromAcceptLanguage, getLocaleFromPathname, getLocaleFromHost, getLocaleFromQuery, } from "./locale";
|
|
4
|
+
export { localizePathname } from "./pathname";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a navigation target should bypass app routing.
|
|
3
|
+
*
|
|
4
|
+
* Any value with an explicit scheme (e.g. http:, https:, mailto:)
|
|
5
|
+
* is treated as external navigation.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isExternalDestination: (destination: string) => boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a navigation target should bypass app routing.
|
|
3
|
+
*
|
|
4
|
+
* Any value with an explicit scheme (e.g. http:, https:, mailto:)
|
|
5
|
+
* is treated as external navigation.
|
|
6
|
+
*/
|
|
7
|
+
const isExternalDestination = (destination) => {
|
|
8
|
+
return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(destination);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { isExternalDestination };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IntorResolvedConfig } from "../../../config";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve locale from the `Accept-Language` header.
|
|
4
|
+
*
|
|
5
|
+
* - Parses language priorities (`q` values) from the header.
|
|
6
|
+
* - Selects the highest-priority language supported by the application.
|
|
7
|
+
* - Normalizes the matched locale against `supportedLocales`.
|
|
8
|
+
*
|
|
9
|
+
* If no supported locale can be resolved, `undefined` is returned.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* getLocaleFromAcceptLanguage("en-US,en;q=0.8,zh-TW;q=0.9", ["en-US", "zh-TW"])
|
|
14
|
+
* // => "en-US"
|
|
15
|
+
* getLocaleFromAcceptLanguage("fr,ja;q=0.9", ["en", "zh-TW"])
|
|
16
|
+
* // => undefined
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const getLocaleFromAcceptLanguage: (config: IntorResolvedConfig, acceptLanguageHeader: string | undefined) => string | undefined;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { normalizeLocale } from '../normalizers/normalize-locale.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve locale from the `Accept-Language` header.
|
|
5
|
+
*
|
|
6
|
+
* - Parses language priorities (`q` values) from the header.
|
|
7
|
+
* - Selects the highest-priority language supported by the application.
|
|
8
|
+
* - Normalizes the matched locale against `supportedLocales`.
|
|
9
|
+
*
|
|
10
|
+
* If no supported locale can be resolved, `undefined` is returned.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* getLocaleFromAcceptLanguage("en-US,en;q=0.8,zh-TW;q=0.9", ["en-US", "zh-TW"])
|
|
15
|
+
* // => "en-US"
|
|
16
|
+
* getLocaleFromAcceptLanguage("fr,ja;q=0.9", ["en", "zh-TW"])
|
|
17
|
+
* // => undefined
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
const getLocaleFromAcceptLanguage = (config, acceptLanguageHeader) => {
|
|
21
|
+
const { supportedLocales } = config;
|
|
22
|
+
if (!acceptLanguageHeader ||
|
|
23
|
+
!supportedLocales ||
|
|
24
|
+
supportedLocales.length === 0) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const supportedLocalesSet = new Set(supportedLocales);
|
|
28
|
+
// 1. Parse Accept-Language header into language + priority pairs
|
|
29
|
+
const parsedLanguages = acceptLanguageHeader.split(",").map((part) => {
|
|
30
|
+
const [rawLang, rawQ] = part.split(";");
|
|
31
|
+
const lang = rawLang.trim();
|
|
32
|
+
const q = rawQ ? Number.parseFloat(rawQ.split("=")[1]) : 1;
|
|
33
|
+
return {
|
|
34
|
+
lang,
|
|
35
|
+
q: Number.isNaN(q) ? 0 : q, // Invalid q values have lowest priority
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
// 2. Sort by priority (highest first)
|
|
39
|
+
const sortedByPriority = parsedLanguages.toSorted((a, b) => b.q - a.q);
|
|
40
|
+
// 3. Pick the first language explicitly supported
|
|
41
|
+
const preferred = sortedByPriority.find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
|
|
42
|
+
return normalizeLocale(preferred, supportedLocales);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { getLocaleFromAcceptLanguage };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IntorResolvedConfig } from "../../../config";
|
|
2
|
+
/**
|
|
3
|
+
* Extract locale from hostname.
|
|
4
|
+
*
|
|
5
|
+
* Only the left-most subdomain is considered as a locale candidate, if present.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* getLocaleFromHost(config, "en.example.com")
|
|
10
|
+
* // => "en"
|
|
11
|
+
* getLocaleFromHost(config, "example.com")
|
|
12
|
+
* // => undefined
|
|
13
|
+
* getLocaleFromHost(config, "api.jp.example.com")
|
|
14
|
+
* // => undefined
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function getLocaleFromHost(config: IntorResolvedConfig, host: string | undefined): string | undefined;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { normalizeLocale } from '../normalizers/normalize-locale.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract locale from hostname.
|
|
5
|
+
*
|
|
6
|
+
* Only the left-most subdomain is considered as a locale candidate, if present.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* getLocaleFromHost(config, "en.example.com")
|
|
11
|
+
* // => "en"
|
|
12
|
+
* getLocaleFromHost(config, "example.com")
|
|
13
|
+
* // => undefined
|
|
14
|
+
* getLocaleFromHost(config, "api.jp.example.com")
|
|
15
|
+
* // => undefined
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
function getLocaleFromHost(config, host) {
|
|
19
|
+
if (!host)
|
|
20
|
+
return;
|
|
21
|
+
const { supportedLocales } = config;
|
|
22
|
+
// Remove port (e.g. localhost:3000)
|
|
23
|
+
const hostname = host.split(":")[0];
|
|
24
|
+
const parts = hostname.split(".");
|
|
25
|
+
if (parts.length < 2)
|
|
26
|
+
return;
|
|
27
|
+
const candidate = parts[0];
|
|
28
|
+
return normalizeLocale(candidate, supportedLocales);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { getLocaleFromHost };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IntorResolvedConfig } from "../../../config/types/intor-config.types";
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the locale from a pathname, if present.
|
|
4
|
+
*
|
|
5
|
+
* - Normalizes the raw pathname.
|
|
6
|
+
* - Strips the configured basePath.
|
|
7
|
+
* - Inspects the first path segment to determine whether
|
|
8
|
+
* it matches a supported locale.
|
|
9
|
+
*
|
|
10
|
+
* If no locale segment is found, `undefined` is returned.
|
|
11
|
+
*
|
|
12
|
+
* Note:
|
|
13
|
+
* - The pathname is treated as a canonical source.
|
|
14
|
+
* - Only exact matches against `supportedLocales` are accepted.
|
|
15
|
+
* - ___Locale normalization is intentionally not applied here.___
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* getLocaleFromPathname(config, "/en/about")
|
|
20
|
+
* // => "en"
|
|
21
|
+
* getLocaleFromPathname(config, "/zh-TW")
|
|
22
|
+
* // => "zh-TW"
|
|
23
|
+
* getLocaleFromPathname(config, "/about")
|
|
24
|
+
* // => undefined
|
|
25
|
+
*
|
|
26
|
+
* // config.routing.basePath: "/app"
|
|
27
|
+
* getLocaleFromPathname(config, "/app/en/dashboard")
|
|
28
|
+
* // => "en"
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function getLocaleFromPathname(config: IntorResolvedConfig, pathname: string): string | undefined;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { normalizePathname } from '../normalizers/normalize-pathname.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts the locale from a pathname, if present.
|
|
5
|
+
*
|
|
6
|
+
* - Normalizes the raw pathname.
|
|
7
|
+
* - Strips the configured basePath.
|
|
8
|
+
* - Inspects the first path segment to determine whether
|
|
9
|
+
* it matches a supported locale.
|
|
10
|
+
*
|
|
11
|
+
* If no locale segment is found, `undefined` is returned.
|
|
12
|
+
*
|
|
13
|
+
* Note:
|
|
14
|
+
* - The pathname is treated as a canonical source.
|
|
15
|
+
* - Only exact matches against `supportedLocales` are accepted.
|
|
16
|
+
* - ___Locale normalization is intentionally not applied here.___
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* getLocaleFromPathname(config, "/en/about")
|
|
21
|
+
* // => "en"
|
|
22
|
+
* getLocaleFromPathname(config, "/zh-TW")
|
|
23
|
+
* // => "zh-TW"
|
|
24
|
+
* getLocaleFromPathname(config, "/about")
|
|
25
|
+
* // => undefined
|
|
26
|
+
*
|
|
27
|
+
* // config.routing.basePath: "/app"
|
|
28
|
+
* getLocaleFromPathname(config, "/app/en/dashboard")
|
|
29
|
+
* // => "en"
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function getLocaleFromPathname(config, pathname) {
|
|
33
|
+
const { routing, supportedLocales } = config;
|
|
34
|
+
const { basePath } = routing;
|
|
35
|
+
// 1. Normalize pathname
|
|
36
|
+
const normalizedPathname = normalizePathname(pathname);
|
|
37
|
+
// 2. Strip basePath
|
|
38
|
+
let prefixedPathname = normalizedPathname;
|
|
39
|
+
if (basePath && normalizedPathname === basePath) {
|
|
40
|
+
prefixedPathname = "/";
|
|
41
|
+
}
|
|
42
|
+
else if (basePath && normalizedPathname.startsWith(basePath + "/")) {
|
|
43
|
+
prefixedPathname = normalizedPathname.slice(basePath.length);
|
|
44
|
+
}
|
|
45
|
+
// 3. Detect locale segment
|
|
46
|
+
const firstSegment = prefixedPathname.split("/").find(Boolean);
|
|
47
|
+
return firstSegment && supportedLocales.includes(firstSegment)
|
|
48
|
+
? firstSegment
|
|
49
|
+
: undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { getLocaleFromPathname };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IntorResolvedConfig } from "../../../config/types/intor-config.types";
|
|
2
|
+
/**
|
|
3
|
+
* Extracts locale from URL query parameters.
|
|
4
|
+
*
|
|
5
|
+
* - Reads the configured locale query key.
|
|
6
|
+
* - Normalizes the value against supported locales.
|
|
7
|
+
*
|
|
8
|
+
* If no valid locale is found, `undefined` is returned.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* getLocaleFromQuery(config, { locale: "en" })
|
|
13
|
+
* // => "en"
|
|
14
|
+
* getLocaleFromQuery(config, {})
|
|
15
|
+
* // => undefined
|
|
16
|
+
* getLocaleFromQuery(config, { locale: ["zh-TW"] })
|
|
17
|
+
* // => "zh-TW"
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function getLocaleFromQuery(config: IntorResolvedConfig, query: Record<string, string | string[] | undefined> | undefined): string | undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { normalizeLocale } from '../normalizers/normalize-locale.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts locale from URL query parameters.
|
|
5
|
+
*
|
|
6
|
+
* - Reads the configured locale query key.
|
|
7
|
+
* - Normalizes the value against supported locales.
|
|
8
|
+
*
|
|
9
|
+
* If no valid locale is found, `undefined` is returned.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* getLocaleFromQuery(config, { locale: "en" })
|
|
14
|
+
* // => "en"
|
|
15
|
+
* getLocaleFromQuery(config, {})
|
|
16
|
+
* // => undefined
|
|
17
|
+
* getLocaleFromQuery(config, { locale: ["zh-TW"] })
|
|
18
|
+
* // => "zh-TW"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
function getLocaleFromQuery(config, query) {
|
|
22
|
+
if (!query)
|
|
23
|
+
return;
|
|
24
|
+
const { supportedLocales, routing } = config;
|
|
25
|
+
const key = routing.locale.queryKey ?? "locale";
|
|
26
|
+
const raw = query[key];
|
|
27
|
+
if (!raw)
|
|
28
|
+
return;
|
|
29
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
30
|
+
return normalizeLocale(value, supportedLocales);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { getLocaleFromQuery };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getLocaleFromAcceptLanguage } from "./get-locale-from-accept-language";
|
|
2
|
+
export { getLocaleFromPathname } from "./get-locale-from-pathname";
|
|
3
|
+
export { getLocaleFromHost } from "./get-locale-from-host";
|
|
4
|
+
export { getLocaleFromQuery } from "./get-locale-from-query";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type RawCacheKey = string | boolean | Array<string | number | boolean | undefined | null>;
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a value into a stable cache key string.
|
|
4
|
+
*
|
|
5
|
+
* - Supports primitive values and structured array keys.
|
|
6
|
+
* - Produces deterministic output suitable for cache identifiers.
|
|
7
|
+
*
|
|
8
|
+
* Notes:
|
|
9
|
+
* - `null`, `undefined`, or empty arrays return `null`.
|
|
10
|
+
* - Special tokens are used for boolean, null, and undefined values
|
|
11
|
+
* to preserve semantic differences.
|
|
12
|
+
*/
|
|
13
|
+
export declare const normalizeCacheKey: (key?: RawCacheKey, delimiter?: string) => string | null;
|
|
14
|
+
export {};
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
const CACHE_KEY_DELIMITER = "|";
|
|
2
|
-
// Helper FC
|
|
3
2
|
const sanitize = (k) => k
|
|
4
3
|
.replaceAll(/[\u200B-\u200D\uFEFF]/g, "")
|
|
5
4
|
.replaceAll(/[\r\n]/g, "")
|
|
6
5
|
.trim();
|
|
6
|
+
/**
|
|
7
|
+
* Normalizes a value into a stable cache key string.
|
|
8
|
+
*
|
|
9
|
+
* - Supports primitive values and structured array keys.
|
|
10
|
+
* - Produces deterministic output suitable for cache identifiers.
|
|
11
|
+
*
|
|
12
|
+
* Notes:
|
|
13
|
+
* - `null`, `undefined`, or empty arrays return `null`.
|
|
14
|
+
* - Special tokens are used for boolean, null, and undefined values
|
|
15
|
+
* to preserve semantic differences.
|
|
16
|
+
*/
|
|
7
17
|
const normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
18
|
+
// Treat nullish values as "no cache key"
|
|
8
19
|
if (key === null || key === undefined)
|
|
9
20
|
return null;
|
|
10
21
|
if (Array.isArray(key)) {
|
|
22
|
+
// Empty array produces no meaningful cache key
|
|
11
23
|
if (key.length === 0)
|
|
12
24
|
return null;
|
|
13
25
|
const normalized = key.map((k) => {
|
|
26
|
+
// Preserve semantic differences for special values
|
|
14
27
|
if (k === null)
|
|
15
28
|
return "__null";
|
|
16
29
|
if (k === undefined)
|
|
@@ -19,10 +32,13 @@ const normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
|
19
32
|
return k ? "__true" : "__false";
|
|
20
33
|
return sanitize(String(k));
|
|
21
34
|
});
|
|
35
|
+
// Join segments into a single deterministic cache key
|
|
22
36
|
return normalized.join(delimiter);
|
|
23
37
|
}
|
|
38
|
+
// Normalize boolean primitives explicitly
|
|
24
39
|
if (typeof key === "boolean")
|
|
25
40
|
return key ? "__true" : "__false";
|
|
41
|
+
// Fallback: stringify primitive values
|
|
26
42
|
return String(key);
|
|
27
43
|
};
|
|
28
44
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a locale string and resolves the best match
|
|
3
|
+
* from a list of supported locales.
|
|
4
|
+
*
|
|
5
|
+
* Resolution strategy:
|
|
6
|
+
*
|
|
7
|
+
* 1. Exact canonical match (BCP 47)
|
|
8
|
+
* 2. Base language fallback
|
|
9
|
+
* - Falls back by base language when no exact match is found
|
|
10
|
+
* (e.g. `"en"` → `"en-US"`).
|
|
11
|
+
* - Script and region subtags are ignored during this step
|
|
12
|
+
* (e.g. `"zh-Hans"` → `"zh-Hant-TW"`)
|
|
13
|
+
* - Preference is determined by the order of `supportedLocales`.
|
|
14
|
+
*
|
|
15
|
+
* Returns `undefined` if no suitable match is found.
|
|
16
|
+
*
|
|
17
|
+
* Notes:
|
|
18
|
+
* - Invalid locale inputs are ignored gracefully.
|
|
19
|
+
* - Always returns an original entry from `supportedLocales`.
|
|
20
|
+
* - Requires `Intl` locale support in the runtime.
|
|
21
|
+
*/
|
|
22
|
+
export declare const normalizeLocale: <Locale extends string>(locale: string | undefined, supportedLocales?: readonly Locale[]) => Locale | undefined;
|
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
// Util
|
|
2
1
|
const toCanonical = (input) => {
|
|
3
2
|
try {
|
|
4
|
-
return Intl.getCanonicalLocales(input)[0]
|
|
3
|
+
return Intl.getCanonicalLocales(input)[0];
|
|
5
4
|
}
|
|
6
5
|
catch {
|
|
7
6
|
return;
|
|
8
7
|
}
|
|
9
8
|
};
|
|
10
9
|
/**
|
|
11
|
-
* Normalizes
|
|
10
|
+
* Normalizes a locale string and resolves the best match
|
|
11
|
+
* from a list of supported locales.
|
|
12
|
+
*
|
|
13
|
+
* Resolution strategy:
|
|
14
|
+
*
|
|
15
|
+
* 1. Exact canonical match (BCP 47)
|
|
16
|
+
* 2. Base language fallback
|
|
17
|
+
* - Falls back by base language when no exact match is found
|
|
18
|
+
* (e.g. `"en"` → `"en-US"`).
|
|
19
|
+
* - Script and region subtags are ignored during this step
|
|
20
|
+
* (e.g. `"zh-Hans"` → `"zh-Hant-TW"`)
|
|
21
|
+
* - Preference is determined by the order of `supportedLocales`.
|
|
22
|
+
*
|
|
23
|
+
* Returns `undefined` if no suitable match is found.
|
|
24
|
+
*
|
|
25
|
+
* Notes:
|
|
26
|
+
* - Invalid locale inputs are ignored gracefully.
|
|
27
|
+
* - Always returns an original entry from `supportedLocales`.
|
|
28
|
+
* - Requires `Intl` locale support in the runtime.
|
|
12
29
|
*/
|
|
13
|
-
const normalizeLocale = (locale
|
|
30
|
+
const normalizeLocale = (locale, supportedLocales = []) => {
|
|
14
31
|
if (!locale || supportedLocales.length === 0)
|
|
15
32
|
return;
|
|
16
33
|
const canonicalLocale = toCanonical(locale);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* - Trims leading and trailing whitespace (code points ≤ 32).
|
|
5
5
|
* - Collapses consecutive slashes into a single slash.
|
|
6
|
-
* - Ensures a leading slash and removes trailing slashes.
|
|
6
|
+
* - Ensures a single leading slash and removes redundant trailing slashes.
|
|
7
7
|
* - Optionally removes the leading slash.
|
|
8
8
|
* - Avoids intermediate array allocations for performance.
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* - Trims leading and trailing whitespace (code points ≤ 32).
|
|
5
5
|
* - Collapses consecutive slashes into a single slash.
|
|
6
|
-
* - Ensures a leading slash and removes trailing slashes.
|
|
6
|
+
* - Ensures a single leading slash and removes redundant trailing slashes.
|
|
7
7
|
* - Optionally removes the leading slash.
|
|
8
8
|
* - Avoids intermediate array allocations for performance.
|
|
9
9
|
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IntorResolvedConfig } from "../../../config/types/intor-config.types";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a canonical, locale-agnostic pathname.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* // config.supportedLocales: ["en-US"]
|
|
8
|
+
* // config.routing.basePath: "/app"
|
|
9
|
+
* // config.routing.prefix: "all"
|
|
10
|
+
* getUnprefixedPathname(config, "/app/en-US/about" );
|
|
11
|
+
* // => "/about"
|
|
12
|
+
*```
|
|
13
|
+
*/
|
|
14
|
+
export declare function getUnprefixedPathname(config: IntorResolvedConfig, rawPathname: string): string;
|