@fluojs/i18n 1.0.0-beta.1

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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +537 -0
  3. package/README.md +537 -0
  4. package/dist/adapters.d.ts +180 -0
  5. package/dist/adapters.d.ts.map +1 -0
  6. package/dist/adapters.js +266 -0
  7. package/dist/errors.d.ts +17 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +19 -0
  10. package/dist/http.d.ts +120 -0
  11. package/dist/http.d.ts.map +1 -0
  12. package/dist/http.js +179 -0
  13. package/dist/icu.d.ts +59 -0
  14. package/dist/icu.d.ts.map +1 -0
  15. package/dist/icu.js +142 -0
  16. package/dist/index.d.ts +5 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +3 -0
  19. package/dist/loaders/fs.d.ts +43 -0
  20. package/dist/loaders/fs.d.ts.map +1 -0
  21. package/dist/loaders/fs.js +79 -0
  22. package/dist/loaders/remote.d.ts +146 -0
  23. package/dist/loaders/remote.d.ts.map +1 -0
  24. package/dist/loaders/remote.js +268 -0
  25. package/dist/loaders/shared.d.ts +54 -0
  26. package/dist/loaders/shared.d.ts.map +1 -0
  27. package/dist/loaders/shared.js +89 -0
  28. package/dist/locale-resolution.d.ts +86 -0
  29. package/dist/locale-resolution.d.ts.map +1 -0
  30. package/dist/locale-resolution.js +201 -0
  31. package/dist/module.d.ts +22 -0
  32. package/dist/module.d.ts.map +1 -0
  33. package/dist/module.js +60 -0
  34. package/dist/options.d.ts +9 -0
  35. package/dist/options.d.ts.map +1 -0
  36. package/dist/options.js +169 -0
  37. package/dist/service.d.ts +104 -0
  38. package/dist/service.d.ts.map +1 -0
  39. package/dist/service.js +348 -0
  40. package/dist/typegen.d.ts +60 -0
  41. package/dist/typegen.d.ts.map +1 -0
  42. package/dist/typegen.js +215 -0
  43. package/dist/types.d.ts +154 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +1 -0
  46. package/dist/validation.d.ts +74 -0
  47. package/dist/validation.d.ts.map +1 -0
  48. package/dist/validation.js +123 -0
  49. package/package.json +97 -0
@@ -0,0 +1,180 @@
1
+ import { type AcceptLanguageLocalePolicyOptions } from './locale-resolution.js';
2
+ import type { I18nLocale } from './types.js';
3
+ /**
4
+ * Locale metadata resolved for a non-HTTP transport context.
5
+ */
6
+ export interface LocaleAdapterContext {
7
+ /** Locale selected for the active context. */
8
+ readonly locale: I18nLocale;
9
+ /** Optional resolver name or application-defined source that selected the locale. */
10
+ readonly source?: string;
11
+ }
12
+ /**
13
+ * Input shared by opt-in non-HTTP locale resolvers.
14
+ */
15
+ export interface LocaleAdapterResolverInput<TContext> {
16
+ /** Transport-specific context supplied by the application boundary. */
17
+ readonly context: TContext;
18
+ /** Supported locale allow-list. Empty or omitted lists allow any syntactically valid locale. */
19
+ readonly supportedLocales?: readonly I18nLocale[];
20
+ /** Default locale used when no resolver selects a supported locale. */
21
+ readonly defaultLocale: I18nLocale;
22
+ }
23
+ /**
24
+ * Result returned by one non-HTTP locale resolver.
25
+ */
26
+ export interface LocaleAdapterResolverResult {
27
+ /** Locale selected by the resolver. */
28
+ readonly locale: I18nLocale;
29
+ /** Resolver name or application-defined source that selected the locale. */
30
+ readonly source?: string;
31
+ }
32
+ /**
33
+ * Explicit locale resolver used by `resolveLocale(...)` in application-defined order.
34
+ */
35
+ export type LocaleAdapterResolver<TContext> = (input: LocaleAdapterResolverInput<TContext>) => unknown;
36
+ /**
37
+ * Adapter-owned locale metadata store for transport contexts that have session, socket, call, or request state.
38
+ */
39
+ export interface LocaleAdapterStore<TContext> {
40
+ /** Reads previously stored locale metadata from the context. */
41
+ get(context: TContext): LocaleAdapterContext | undefined;
42
+ /** Stores locale metadata on or alongside the context. */
43
+ set(context: TContext, locale: LocaleAdapterContext): void;
44
+ }
45
+ /**
46
+ * Options for resolving a locale from an ordered non-HTTP resolver chain.
47
+ */
48
+ export interface ResolveLocaleOptions<TContext> {
49
+ /** Supported locale allow-list. Empty or omitted lists allow any syntactically valid locale. */
50
+ readonly supportedLocales?: readonly I18nLocale[];
51
+ /** Default locale returned when no resolver selects a supported locale. */
52
+ readonly defaultLocale: I18nLocale;
53
+ /** Resolver chain executed in array order. */
54
+ readonly resolvers?: readonly LocaleAdapterResolver<TContext>[];
55
+ }
56
+ /**
57
+ * Options for resolving and storing a locale in a transport-local store.
58
+ */
59
+ export interface BindLocaleOptions<TContext> extends ResolveLocaleOptions<TContext> {
60
+ /** Store used to persist the selected locale metadata for the active context. */
61
+ readonly store: LocaleAdapterStore<TContext>;
62
+ }
63
+ /**
64
+ * Options for creating an `Accept-Language`-style header resolver without importing HTTP types.
65
+ */
66
+ export interface HeaderLocaleResolverOptions<TContext> {
67
+ /** Reads the relevant header value from a WebSocket handshake, gRPC metadata object, or server request abstraction. */
68
+ readonly getHeader: (context: TContext) => string | readonly string[] | undefined;
69
+ /** Resolver source label returned with matches. Defaults to `accept-language`. */
70
+ readonly source?: string;
71
+ }
72
+ /**
73
+ * Options for creating an opt-in `Accept-Language` policy resolver without importing HTTP types.
74
+ */
75
+ export interface HeaderLocalePolicyResolverOptions<TContext> extends HeaderLocaleResolverOptions<TContext>, AcceptLanguageLocalePolicyOptions {
76
+ }
77
+ /**
78
+ * Options for creating a query parameter resolver.
79
+ */
80
+ export interface QueryLocaleResolverOptions<TContext> {
81
+ /** Reads a query value from a socket handshake, RPC metadata bag, CLI args object, or request abstraction. */
82
+ readonly getQueryValue: (context: TContext) => string | readonly string[] | undefined;
83
+ /** Resolver source label returned with matches. Defaults to `query`. */
84
+ readonly source?: string;
85
+ }
86
+ /**
87
+ * Options for creating a cookie resolver.
88
+ */
89
+ export interface CookieLocaleResolverOptions<TContext> {
90
+ /** Reads a cookie value from the application-provided context abstraction. */
91
+ readonly getCookieValue: (context: TContext) => string | undefined;
92
+ /** Resolver source label returned with matches. Defaults to `cookie`. */
93
+ readonly source?: string;
94
+ }
95
+ /**
96
+ * Options for creating a storage-backed resolver.
97
+ */
98
+ export interface StorageLocaleResolverOptions<TContext> {
99
+ /** Reads a stored locale from local storage, server session state, socket data, or CLI configuration. */
100
+ readonly getStoredLocale: (context: TContext) => string | undefined;
101
+ /** Resolver source label returned with matches. Defaults to `storage`. */
102
+ readonly source?: string;
103
+ }
104
+ /**
105
+ * Creates an in-memory per-object locale store backed by `WeakMap`.
106
+ *
107
+ * @returns A store suitable for socket, call, or request objects without mutating them.
108
+ */
109
+ export declare function createWeakMapLocaleStore<TContext extends object>(): LocaleAdapterStore<TContext>;
110
+ /**
111
+ * Stores locale metadata through an application-provided store abstraction.
112
+ *
113
+ * @param store Store that owns persistence for the transport context.
114
+ * @param context Transport context to update.
115
+ * @param locale Locale selected for the context.
116
+ * @param metadata Additional locale metadata such as a resolver source.
117
+ */
118
+ export declare function setAdapterLocale<TContext>(store: LocaleAdapterStore<TContext>, context: TContext, locale: I18nLocale, metadata?: Omit<LocaleAdapterContext, 'locale'>): void;
119
+ /**
120
+ * Reads locale metadata from an application-provided store abstraction.
121
+ *
122
+ * @param store Store that owns persistence for the transport context.
123
+ * @param context Transport context to inspect.
124
+ * @returns Stored locale metadata, or `undefined` when the context has no locale.
125
+ */
126
+ export declare function getAdapterLocale<TContext>(store: LocaleAdapterStore<TContext>, context: TContext): LocaleAdapterContext | undefined;
127
+ /**
128
+ * Runs an explicit non-HTTP resolver chain and returns selected locale metadata.
129
+ *
130
+ * @param context Transport context supplied by the application boundary.
131
+ * @param options Default locale, supported locales, and ordered resolvers.
132
+ * @returns Locale metadata selected by the first valid resolver or the configured default locale.
133
+ * @throws {TypeError} When the configured default locale is invalid or unsupported.
134
+ */
135
+ export declare function resolveLocale<TContext>(context: TContext, options: ResolveLocaleOptions<TContext>): LocaleAdapterContext;
136
+ /**
137
+ * Runs a resolver chain and stores the selected locale metadata in the provided transport-local store.
138
+ *
139
+ * @param context Transport context supplied by the application boundary.
140
+ * @param options Default locale, supported locales, ordered resolvers, and metadata store.
141
+ * @returns Stored locale metadata selected by the first valid resolver or the configured default locale.
142
+ * @throws {TypeError} When the configured default locale is invalid or unsupported.
143
+ */
144
+ export declare function bindLocale<TContext>(context: TContext, options: BindLocaleOptions<TContext>): LocaleAdapterContext;
145
+ /**
146
+ * Creates a resolver that selects the first supported locale from an `Accept-Language`-style header.
147
+ *
148
+ * @param options Header accessor and optional source label.
149
+ * @returns Locale resolver that remains independent of HTTP, WebSocket, gRPC, and browser APIs.
150
+ */
151
+ export declare function createHeaderLocaleResolver<TContext>(options: HeaderLocaleResolverOptions<TContext>): LocaleAdapterResolver<TContext>;
152
+ /**
153
+ * Creates an opt-in header policy resolver that normalizes supported locale ranges and can select wildcard fallbacks.
154
+ *
155
+ * @param options Header accessor, source, normalization, and wildcard policy options.
156
+ * @returns Locale resolver that treats `*` as fallback-only and preserves explicit locale preferences first.
157
+ */
158
+ export declare function createHeaderLocalePolicyResolver<TContext>(options: HeaderLocalePolicyResolverOptions<TContext>): LocaleAdapterResolver<TContext>;
159
+ /**
160
+ * Creates a resolver that reads the first query parameter value from an application-owned abstraction.
161
+ *
162
+ * @param options Query accessor and optional source label.
163
+ * @returns Locale resolver that ignores empty, invalid, and unsupported query values.
164
+ */
165
+ export declare function createQueryLocaleResolver<TContext>(options: QueryLocaleResolverOptions<TContext>): LocaleAdapterResolver<TContext>;
166
+ /**
167
+ * Creates a resolver that reads locale from an application-owned cookie abstraction.
168
+ *
169
+ * @param options Cookie accessor and optional source label.
170
+ * @returns Locale resolver that ignores empty, invalid, and unsupported cookie values.
171
+ */
172
+ export declare function createCookieLocaleResolver<TContext>(options: CookieLocaleResolverOptions<TContext>): LocaleAdapterResolver<TContext>;
173
+ /**
174
+ * Creates a resolver that reads locale from storage, session, socket, call, request, or CLI configuration state.
175
+ *
176
+ * @param options Storage accessor and optional source label.
177
+ * @returns Locale resolver that ignores empty, invalid, and unsupported stored values.
178
+ */
179
+ export declare function createStorageLocaleResolver<TContext>(options: StorageLocaleResolverOptions<TContext>): LocaleAdapterResolver<TContext>;
180
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iCAAiC,EAMvC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,QAAQ;IAClD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,gGAAgG;IAChG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,0BAA0B,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC;AAEvG;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,QAAQ;IAC1C,gEAAgE;IAChE,GAAG,CAAC,OAAO,EAAE,QAAQ,GAAG,oBAAoB,GAAG,SAAS,CAAC;IACzD,0DAA0D;IAC1D,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,QAAQ;IAC5C,gGAAgG;IAChG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,QAAQ,CAAE,SAAQ,oBAAoB,CAAC,QAAQ,CAAC;IACjF,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B,CAAC,QAAQ;IACnD,uHAAuH;IACvH,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClF,kFAAkF;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iCAAiC,CAAC,QAAQ,CACzD,SAAQ,2BAA2B,CAAC,QAAQ,CAAC,EAC3C,iCAAiC;CAAG;AAExC;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,QAAQ;IAClD,8GAA8G;IAC9G,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACtF,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B,CAAC,QAAQ;IACnD,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,CAAC;IACnE,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B,CAAC,QAAQ;IACpD,yGAAyG;IACzG,QAAQ,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,CAAC;IACpE,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,SAAS,MAAM,KAAK,kBAAkB,CAAC,QAAQ,CAAC,CAWhG;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EACvC,KAAK,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EACnC,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GAClD,IAAI,CAEN;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EACvC,KAAK,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EACnC,OAAO,EAAE,QAAQ,GAChB,oBAAoB,GAAG,SAAS,CAElC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,oBAAoB,CAsBxH;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAAG,oBAAoB,CAIlH;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EACjD,OAAO,EAAE,2BAA2B,CAAC,QAAQ,CAAC,GAC7C,qBAAqB,CAAC,QAAQ,CAAC,CAgBjC;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,QAAQ,EACvD,OAAO,EAAE,iCAAiC,CAAC,QAAQ,CAAC,GACnD,qBAAqB,CAAC,QAAQ,CAAC,CAiBjC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAChD,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,qBAAqB,CAAC,QAAQ,CAAC,CAajC;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EACjD,OAAO,EAAE,2BAA2B,CAAC,QAAQ,CAAC,GAC7C,qBAAqB,CAAC,QAAQ,CAAC,CAYjC;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAClD,OAAO,EAAE,4BAA4B,CAAC,QAAQ,CAAC,GAC9C,qBAAqB,CAAC,QAAQ,CAAC,CAYjC"}
@@ -0,0 +1,266 @@
1
+ import { isSupportedLocale, isValidLocale, normalizeLocaleResolverResult, parseLocalePreferences, selectLocaleFromAcceptLanguagePolicy } from './locale-resolution.js';
2
+
3
+ /**
4
+ * Locale metadata resolved for a non-HTTP transport context.
5
+ */
6
+
7
+ /**
8
+ * Input shared by opt-in non-HTTP locale resolvers.
9
+ */
10
+
11
+ /**
12
+ * Result returned by one non-HTTP locale resolver.
13
+ */
14
+
15
+ /**
16
+ * Explicit locale resolver used by `resolveLocale(...)` in application-defined order.
17
+ */
18
+
19
+ /**
20
+ * Adapter-owned locale metadata store for transport contexts that have session, socket, call, or request state.
21
+ */
22
+
23
+ /**
24
+ * Options for resolving a locale from an ordered non-HTTP resolver chain.
25
+ */
26
+
27
+ /**
28
+ * Options for resolving and storing a locale in a transport-local store.
29
+ */
30
+
31
+ /**
32
+ * Options for creating an `Accept-Language`-style header resolver without importing HTTP types.
33
+ */
34
+
35
+ /**
36
+ * Options for creating an opt-in `Accept-Language` policy resolver without importing HTTP types.
37
+ */
38
+
39
+ /**
40
+ * Options for creating a query parameter resolver.
41
+ */
42
+
43
+ /**
44
+ * Options for creating a cookie resolver.
45
+ */
46
+
47
+ /**
48
+ * Options for creating a storage-backed resolver.
49
+ */
50
+
51
+ /**
52
+ * Creates an in-memory per-object locale store backed by `WeakMap`.
53
+ *
54
+ * @returns A store suitable for socket, call, or request objects without mutating them.
55
+ */
56
+ export function createWeakMapLocaleStore() {
57
+ const locales = new WeakMap();
58
+ return {
59
+ get(context) {
60
+ return locales.get(context);
61
+ },
62
+ set(context, locale) {
63
+ locales.set(context, Object.freeze({
64
+ ...locale
65
+ }));
66
+ }
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Stores locale metadata through an application-provided store abstraction.
72
+ *
73
+ * @param store Store that owns persistence for the transport context.
74
+ * @param context Transport context to update.
75
+ * @param locale Locale selected for the context.
76
+ * @param metadata Additional locale metadata such as a resolver source.
77
+ */
78
+ export function setAdapterLocale(store, context, locale, metadata = {}) {
79
+ store.set(context, Object.freeze({
80
+ ...metadata,
81
+ locale
82
+ }));
83
+ }
84
+
85
+ /**
86
+ * Reads locale metadata from an application-provided store abstraction.
87
+ *
88
+ * @param store Store that owns persistence for the transport context.
89
+ * @param context Transport context to inspect.
90
+ * @returns Stored locale metadata, or `undefined` when the context has no locale.
91
+ */
92
+ export function getAdapterLocale(store, context) {
93
+ return store.get(context);
94
+ }
95
+
96
+ /**
97
+ * Runs an explicit non-HTTP resolver chain and returns selected locale metadata.
98
+ *
99
+ * @param context Transport context supplied by the application boundary.
100
+ * @param options Default locale, supported locales, and ordered resolvers.
101
+ * @returns Locale metadata selected by the first valid resolver or the configured default locale.
102
+ * @throws {TypeError} When the configured default locale is invalid or unsupported.
103
+ */
104
+ export function resolveLocale(context, options) {
105
+ if (!isValidLocale(options.defaultLocale)) {
106
+ throw new TypeError('defaultLocale must be a syntactically valid locale string.');
107
+ }
108
+ if (!isSupportedLocale(options.defaultLocale, options.supportedLocales)) {
109
+ throw new TypeError('defaultLocale must be listed in supportedLocales when supportedLocales is provided.');
110
+ }
111
+ for (const resolver of options.resolvers ?? []) {
112
+ const result = normalizeLocaleResolverResult(resolver({
113
+ context,
114
+ defaultLocale: options.defaultLocale,
115
+ supportedLocales: options.supportedLocales
116
+ }));
117
+ if (result === undefined || !isValidLocale(result.locale) || !isSupportedLocale(result.locale, options.supportedLocales)) {
118
+ continue;
119
+ }
120
+ return Object.freeze({
121
+ locale: result.locale,
122
+ source: result.source
123
+ });
124
+ }
125
+ return Object.freeze({
126
+ locale: options.defaultLocale,
127
+ source: 'default'
128
+ });
129
+ }
130
+
131
+ /**
132
+ * Runs a resolver chain and stores the selected locale metadata in the provided transport-local store.
133
+ *
134
+ * @param context Transport context supplied by the application boundary.
135
+ * @param options Default locale, supported locales, ordered resolvers, and metadata store.
136
+ * @returns Stored locale metadata selected by the first valid resolver or the configured default locale.
137
+ * @throws {TypeError} When the configured default locale is invalid or unsupported.
138
+ */
139
+ export function bindLocale(context, options) {
140
+ const resolved = resolveLocale(context, options);
141
+ setAdapterLocale(options.store, context, resolved.locale, {
142
+ source: resolved.source
143
+ });
144
+ return getAdapterLocale(options.store, context) ?? resolved;
145
+ }
146
+
147
+ /**
148
+ * Creates a resolver that selects the first supported locale from an `Accept-Language`-style header.
149
+ *
150
+ * @param options Header accessor and optional source label.
151
+ * @returns Locale resolver that remains independent of HTTP, WebSocket, gRPC, and browser APIs.
152
+ */
153
+ export function createHeaderLocaleResolver(options) {
154
+ const source = options.source ?? 'accept-language';
155
+ return ({
156
+ context,
157
+ supportedLocales
158
+ }) => {
159
+ for (const preference of parseLocalePreferences(options.getHeader(context))) {
160
+ if (preference.locale === '*') {
161
+ continue;
162
+ }
163
+ if (isSupportedLocale(preference.locale, supportedLocales)) {
164
+ return {
165
+ locale: preference.locale,
166
+ source
167
+ };
168
+ }
169
+ }
170
+ return undefined;
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Creates an opt-in header policy resolver that normalizes supported locale ranges and can select wildcard fallbacks.
176
+ *
177
+ * @param options Header accessor, source, normalization, and wildcard policy options.
178
+ * @returns Locale resolver that treats `*` as fallback-only and preserves explicit locale preferences first.
179
+ */
180
+ export function createHeaderLocalePolicyResolver(options) {
181
+ const source = options.source ?? 'accept-language';
182
+ return ({
183
+ context,
184
+ defaultLocale,
185
+ supportedLocales
186
+ }) => {
187
+ const locale = selectLocaleFromAcceptLanguagePolicy(parseLocalePreferences(options.getHeader(context)), defaultLocale, supportedLocales, options);
188
+ if (locale === undefined) {
189
+ return undefined;
190
+ }
191
+ return {
192
+ locale,
193
+ source
194
+ };
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Creates a resolver that reads the first query parameter value from an application-owned abstraction.
200
+ *
201
+ * @param options Query accessor and optional source label.
202
+ * @returns Locale resolver that ignores empty, invalid, and unsupported query values.
203
+ */
204
+ export function createQueryLocaleResolver(options) {
205
+ const source = options.source ?? 'query';
206
+ return ({
207
+ context,
208
+ supportedLocales
209
+ }) => {
210
+ const rawValue = options.getQueryValue(context);
211
+ const locale = Array.isArray(rawValue) ? rawValue[0] : rawValue;
212
+ if (locale === undefined || !isValidLocale(locale) || !isSupportedLocale(locale, supportedLocales)) {
213
+ return undefined;
214
+ }
215
+ return {
216
+ locale,
217
+ source
218
+ };
219
+ };
220
+ }
221
+
222
+ /**
223
+ * Creates a resolver that reads locale from an application-owned cookie abstraction.
224
+ *
225
+ * @param options Cookie accessor and optional source label.
226
+ * @returns Locale resolver that ignores empty, invalid, and unsupported cookie values.
227
+ */
228
+ export function createCookieLocaleResolver(options) {
229
+ const source = options.source ?? 'cookie';
230
+ return ({
231
+ context,
232
+ supportedLocales
233
+ }) => {
234
+ const locale = options.getCookieValue(context);
235
+ if (locale === undefined || !isValidLocale(locale) || !isSupportedLocale(locale, supportedLocales)) {
236
+ return undefined;
237
+ }
238
+ return {
239
+ locale,
240
+ source
241
+ };
242
+ };
243
+ }
244
+
245
+ /**
246
+ * Creates a resolver that reads locale from storage, session, socket, call, request, or CLI configuration state.
247
+ *
248
+ * @param options Storage accessor and optional source label.
249
+ * @returns Locale resolver that ignores empty, invalid, and unsupported stored values.
250
+ */
251
+ export function createStorageLocaleResolver(options) {
252
+ const source = options.source ?? 'storage';
253
+ return ({
254
+ context,
255
+ supportedLocales
256
+ }) => {
257
+ const locale = options.getStoredLocale(context);
258
+ if (locale === undefined || !isValidLocale(locale) || !isSupportedLocale(locale, supportedLocales)) {
259
+ return undefined;
260
+ }
261
+ return {
262
+ locale,
263
+ source
264
+ };
265
+ };
266
+ }
@@ -0,0 +1,17 @@
1
+ import { FluoError } from '@fluojs/core';
2
+ import type { I18nErrorCode } from './types.js';
3
+ /**
4
+ * Base error type for caller-visible i18n package failures.
5
+ */
6
+ export declare class I18nError extends FluoError {
7
+ /** Stable i18n error code. */
8
+ readonly code: I18nErrorCode;
9
+ /**
10
+ * Creates an i18n package error with a stable code.
11
+ *
12
+ * @param message Human-readable error message.
13
+ * @param code Stable error code for programmatic handling.
14
+ */
15
+ constructor(message: string, code?: I18nErrorCode);
16
+ }
17
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,qBAAa,SAAU,SAAQ,SAAS;IACtC,8BAA8B;IAC9B,SAAiB,IAAI,EAAE,aAAa,CAAC;IAErC;;;;;OAKG;gBACS,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,aAA4B;CAGhE"}
package/dist/errors.js ADDED
@@ -0,0 +1,19 @@
1
+ import { FluoError } from '@fluojs/core';
2
+ /**
3
+ * Base error type for caller-visible i18n package failures.
4
+ */
5
+ export class I18nError extends FluoError {
6
+ /** Stable i18n error code. */
7
+
8
+ /**
9
+ * Creates an i18n package error with a stable code.
10
+ *
11
+ * @param message Human-readable error message.
12
+ * @param code Stable error code for programmatic handling.
13
+ */
14
+ constructor(message, code = 'I18N_ERROR') {
15
+ super(message, {
16
+ code
17
+ });
18
+ }
19
+ }
package/dist/http.d.ts ADDED
@@ -0,0 +1,120 @@
1
+ import { type RequestContext } from '@fluojs/http';
2
+ import { type AcceptLanguageLocalePolicyOptions } from './locale-resolution.js';
3
+ import type { I18nLocale } from './types.js';
4
+ /**
5
+ * Locale metadata stored on a fluo HTTP request context.
6
+ */
7
+ export interface HttpLocaleContext {
8
+ /** Locale selected for the active request. */
9
+ readonly locale: I18nLocale;
10
+ /** Optional resolver name or application-defined source that selected the locale. */
11
+ readonly source?: string;
12
+ }
13
+ /**
14
+ * Parsed `Accept-Language` preference ordered by caller priority.
15
+ */
16
+ export interface AcceptLanguagePreference {
17
+ /** Locale range from the header, such as `ko-KR`, `en`, or `*`. */
18
+ readonly locale: I18nLocale;
19
+ /** Normalized q-value between 0 and 1. */
20
+ readonly quality: number;
21
+ }
22
+ /**
23
+ * Input shared by explicit HTTP locale resolvers.
24
+ */
25
+ export interface HttpLocaleResolverInput {
26
+ /** Current request context being resolved. */
27
+ readonly context: RequestContext;
28
+ /** Supported locale allow-list. Empty or omitted lists allow any syntactically valid locale. */
29
+ readonly supportedLocales?: readonly I18nLocale[];
30
+ /** Default locale used when no resolver selects a supported locale. */
31
+ readonly defaultLocale: I18nLocale;
32
+ }
33
+ /**
34
+ * Result returned by one HTTP locale resolver.
35
+ */
36
+ export interface HttpLocaleResolverResult {
37
+ /** Locale selected by the resolver. */
38
+ readonly locale: I18nLocale;
39
+ /** Resolver name or application-defined source that selected the locale. */
40
+ readonly source?: string;
41
+ }
42
+ /**
43
+ * Explicit locale resolver used by `resolveHttpLocale(...)` in application-defined order.
44
+ */
45
+ export type HttpLocaleResolver = (input: HttpLocaleResolverInput) => unknown;
46
+ /**
47
+ * Options for resolving a request locale from an ordered resolver chain.
48
+ */
49
+ export interface ResolveHttpLocaleOptions {
50
+ /** Supported locale allow-list. Empty or omitted lists allow any syntactically valid locale. */
51
+ readonly supportedLocales?: readonly I18nLocale[];
52
+ /** Default locale returned when no resolver selects a supported locale. */
53
+ readonly defaultLocale: I18nLocale;
54
+ /** Resolver chain executed in array order. */
55
+ readonly resolvers?: readonly HttpLocaleResolver[];
56
+ }
57
+ /**
58
+ * Options for creating an `Accept-Language` resolver.
59
+ */
60
+ export interface AcceptLanguageLocaleResolverOptions {
61
+ /** Header name to inspect. Defaults to `accept-language`. */
62
+ readonly headerName?: string;
63
+ /** Resolver source label returned with matches. Defaults to `accept-language`. */
64
+ readonly source?: string;
65
+ }
66
+ /**
67
+ * Options for the opt-in `Accept-Language` policy resolver.
68
+ */
69
+ export interface AcceptLanguageLocalePolicyResolverOptions extends AcceptLanguageLocaleResolverOptions, AcceptLanguageLocalePolicyOptions {
70
+ }
71
+ /**
72
+ * Request-context key used by `setHttpLocale(...)` and `getHttpLocale(...)`.
73
+ */
74
+ export declare const HTTP_LOCALE_CONTEXT_KEY: import("@fluojs/http").ContextKey<HttpLocaleContext>;
75
+ /**
76
+ * Stores locale metadata on a fluo HTTP request context.
77
+ *
78
+ * @param context Request context to update.
79
+ * @param locale Locale selected for the request.
80
+ * @param metadata Additional locale metadata such as a resolver source.
81
+ */
82
+ export declare function setHttpLocale(context: RequestContext, locale: I18nLocale, metadata?: Omit<HttpLocaleContext, 'locale'>): void;
83
+ /**
84
+ * Reads locale metadata from a fluo HTTP request context.
85
+ *
86
+ * @param context Request context to inspect.
87
+ * @returns Stored locale metadata, or `undefined` when the request has no locale.
88
+ */
89
+ export declare function getHttpLocale(context: RequestContext): HttpLocaleContext | undefined;
90
+ /**
91
+ * Parses an `Accept-Language` header into quality-sorted locale preferences.
92
+ *
93
+ * @param header Raw header value or adapter-provided repeated header values.
94
+ * @returns Valid language ranges ordered by descending q-value and original header order for ties.
95
+ */
96
+ export declare function parseAcceptLanguage(header: string | readonly string[] | undefined): readonly AcceptLanguagePreference[];
97
+ /**
98
+ * Creates a resolver that selects the first supported `Accept-Language` locale.
99
+ *
100
+ * @param options Header name and source label options.
101
+ * @returns Locale resolver that inspects the current request headers.
102
+ */
103
+ export declare function createAcceptLanguageLocaleResolver(options?: AcceptLanguageLocaleResolverOptions): HttpLocaleResolver;
104
+ /**
105
+ * Creates an opt-in resolver that normalizes supported `Accept-Language` ranges and can select a wildcard fallback.
106
+ *
107
+ * @param options Header, source, normalization, and wildcard policy options.
108
+ * @returns Locale resolver that treats `*` as fallback-only and preserves explicit locale preferences first.
109
+ */
110
+ export declare function createAcceptLanguageLocalePolicyResolver(options?: AcceptLanguageLocalePolicyResolverOptions): HttpLocaleResolver;
111
+ /**
112
+ * Runs an explicit resolver chain and stores the selected request locale.
113
+ *
114
+ * @param context Request context to resolve and update.
115
+ * @param options Default locale, supported locales, and ordered resolvers.
116
+ * @returns Stored locale metadata selected by the first valid resolver or the configured default locale.
117
+ * @throws {TypeError} When the configured default locale is invalid or unsupported.
118
+ */
119
+ export declare function resolveHttpLocale(context: RequestContext, options: ResolveHttpLocaleOptions): HttpLocaleContext;
120
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,iCAAiC,EAMvC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,gGAAgG;IAChG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACpD;AAED;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAClD,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,yCAA0C,SAAQ,mCAAmC,EAAE,iCAAiC;CAAG;AAE5I;;GAEG;AACH,eAAO,MAAM,uBAAuB,sDAA+D,CAAC;AAepG;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAM,GAC/C,IAAI,CAEN;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB,GAAG,SAAS,CAEpF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,SAAS,wBAAwB,EAAE,CAEvH;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,mCAAwC,GAChD,kBAAkB,CAoBpB;AAED;;;;;GAKG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,GAAE,yCAA8C,GACtD,kBAAkB,CAkBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAwB/G"}