@astroscope/i18n 0.1.0

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 (194) hide show
  1. package/README.md +262 -0
  2. package/dist/babel-plugin-FUTQRKLT.js +121 -0
  3. package/dist/babel-plugin-K2K4ZPM5.js +118 -0
  4. package/dist/chunk-22ZZFFC2.js +159 -0
  5. package/dist/chunk-2PSXD3JJ.js +144 -0
  6. package/dist/chunk-3VI62RLT.js +176 -0
  7. package/dist/chunk-4A5BKHFN.js +16 -0
  8. package/dist/chunk-4DAQPWXI.js +36 -0
  9. package/dist/chunk-4OGX6AF5.js +10 -0
  10. package/dist/chunk-4PHYKXO3.js +227 -0
  11. package/dist/chunk-4UBFISFY.js +376 -0
  12. package/dist/chunk-5DERF6DV.js +266 -0
  13. package/dist/chunk-5KGNHFTC.js +344 -0
  14. package/dist/chunk-5PP4D2VK.js +23 -0
  15. package/dist/chunk-6BW3PN23.js +14 -0
  16. package/dist/chunk-6ESQ4JQI.js +263 -0
  17. package/dist/chunk-A7MPXMOP.js +202 -0
  18. package/dist/chunk-AWZ2SQDW.js +149 -0
  19. package/dist/chunk-AYY2YIBQ.js +52 -0
  20. package/dist/chunk-BMNEJFTD.js +56 -0
  21. package/dist/chunk-BSXQGEUK.js +16 -0
  22. package/dist/chunk-BSYTJFGF.js +21 -0
  23. package/dist/chunk-BVPXEGTT.js +12 -0
  24. package/dist/chunk-C4DJYWF6.js +193 -0
  25. package/dist/chunk-C5EJYE2P.js +245 -0
  26. package/dist/chunk-CLNOQHMS.js +254 -0
  27. package/dist/chunk-E5MCIRSU.js +144 -0
  28. package/dist/chunk-E7ZJS7WX.js +162 -0
  29. package/dist/chunk-EMM6LRO2.js +8 -0
  30. package/dist/chunk-ESFGCYYH.js +24 -0
  31. package/dist/chunk-FAKBSLNW.js +24 -0
  32. package/dist/chunk-FHBVI3TL.js +372 -0
  33. package/dist/chunk-FI5KZ5IO.js +17 -0
  34. package/dist/chunk-H5R6YMOL.js +233 -0
  35. package/dist/chunk-H62K3FGA.js +236 -0
  36. package/dist/chunk-HDG2R6XT.js +211 -0
  37. package/dist/chunk-HGXU5QAK.js +344 -0
  38. package/dist/chunk-HHRMR3TM.js +17 -0
  39. package/dist/chunk-HS4HVBAD.js +127 -0
  40. package/dist/chunk-IPJWKKHJ.js +324 -0
  41. package/dist/chunk-ITTL4V7J.js +24 -0
  42. package/dist/chunk-IWUBCMOK.js +128 -0
  43. package/dist/chunk-JJBBY2GR.js +14 -0
  44. package/dist/chunk-JJEDOJBR.js +193 -0
  45. package/dist/chunk-JTUKXNIJ.js +23 -0
  46. package/dist/chunk-K7YULG4A.js +14 -0
  47. package/dist/chunk-KNDYKTHE.js +31 -0
  48. package/dist/chunk-KNONI6DP.js +89 -0
  49. package/dist/chunk-LMTEO22Y.js +17 -0
  50. package/dist/chunk-LRLZEX4D.js +147 -0
  51. package/dist/chunk-MFKPLUAN.js +241 -0
  52. package/dist/chunk-MIWXQOO3.js +316 -0
  53. package/dist/chunk-MJRTAWPR.js +261 -0
  54. package/dist/chunk-MZEPQCXX.js +249 -0
  55. package/dist/chunk-NHHTSFA7.js +237 -0
  56. package/dist/chunk-NTTXM7AG.js +23 -0
  57. package/dist/chunk-NZFAVJXR.js +192 -0
  58. package/dist/chunk-OFNFSDW3.js +13 -0
  59. package/dist/chunk-PG3XDNGF.js +227 -0
  60. package/dist/chunk-PVEVTPNK.js +139 -0
  61. package/dist/chunk-QAO4BXS4.js +244 -0
  62. package/dist/chunk-QCTULQQK.js +34 -0
  63. package/dist/chunk-QFAAGCP5.js +177 -0
  64. package/dist/chunk-QKND2KCA.js +163 -0
  65. package/dist/chunk-QZEGY6RJ.js +151 -0
  66. package/dist/chunk-RAE2L6FT.js +193 -0
  67. package/dist/chunk-S3ABJBU3.js +255 -0
  68. package/dist/chunk-SVDVCPCV.js +236 -0
  69. package/dist/chunk-T35ZUWTL.js +153 -0
  70. package/dist/chunk-T6WV5DW6.js +156 -0
  71. package/dist/chunk-TGUXVDA3.js +82 -0
  72. package/dist/chunk-TYMO7K3A.js +173 -0
  73. package/dist/chunk-V4RBFLQL.js +23 -0
  74. package/dist/chunk-V4XWJXXZ.js +23 -0
  75. package/dist/chunk-VQCY3OKK.js +258 -0
  76. package/dist/chunk-WLGOJPDJ.js +15 -0
  77. package/dist/chunk-WUEPDJIL.js +259 -0
  78. package/dist/chunk-X3L7WZLY.js +254 -0
  79. package/dist/chunk-XDD62ZM3.js +255 -0
  80. package/dist/chunk-XFXXEDRD.js +36 -0
  81. package/dist/chunk-XKYOR5UK.js +8 -0
  82. package/dist/chunk-Y26535SI.js +239 -0
  83. package/dist/chunk-Y3PQX5TX.js +152 -0
  84. package/dist/chunk-Y4BE2V6F.js +347 -0
  85. package/dist/chunk-Z4IZYDIA.js +24 -0
  86. package/dist/chunk-Z52G4CYY.js +14 -0
  87. package/dist/chunk-ZGLUYWVM.js +128 -0
  88. package/dist/client/directives/idle.d.ts +9 -0
  89. package/dist/client/directives/idle.js +15 -0
  90. package/dist/client/directives/load.d.ts +9 -0
  91. package/dist/client/directives/load.js +15 -0
  92. package/dist/client/directives/media.d.ts +9 -0
  93. package/dist/client/directives/media.js +15 -0
  94. package/dist/client/directives/only.d.ts +9 -0
  95. package/dist/client/directives/only.js +15 -0
  96. package/dist/client/directives/utils.d.ts +10 -0
  97. package/dist/client/directives/utils.js +7 -0
  98. package/dist/client/directives/visible.d.ts +9 -0
  99. package/dist/client/directives/visible.js +15 -0
  100. package/dist/client/import-with-i18n.d.ts +16 -0
  101. package/dist/client/import-with-i18n.js +8 -0
  102. package/dist/client/t.d.ts +20 -0
  103. package/dist/client/t.js +37 -0
  104. package/dist/client-directives/idle.d.ts +9 -0
  105. package/dist/client-directives/idle.js +15 -0
  106. package/dist/client-directives/load.d.ts +9 -0
  107. package/dist/client-directives/load.js +15 -0
  108. package/dist/client-directives/media.d.ts +9 -0
  109. package/dist/client-directives/media.js +15 -0
  110. package/dist/client-directives/only.d.ts +9 -0
  111. package/dist/client-directives/only.js +15 -0
  112. package/dist/client-directives/utils.d.ts +9 -0
  113. package/dist/client-directives/utils.js +7 -0
  114. package/dist/client-directives/visible.d.ts +9 -0
  115. package/dist/client-directives/visible.js +15 -0
  116. package/dist/extraction/index.d.ts +34 -0
  117. package/dist/extraction/index.js +9 -0
  118. package/dist/i18n-3cZHoHwP.d.ts +86 -0
  119. package/dist/i18n-BGfrSNM8.d.ts +56 -0
  120. package/dist/i18n-BHU81LMA.d.ts +55 -0
  121. package/dist/i18n-BagoeH4_.d.ts +62 -0
  122. package/dist/i18n-BeL84090.d.ts +77 -0
  123. package/dist/i18n-BeRWDfHi.d.ts +55 -0
  124. package/dist/i18n-Bfs2PVcf.d.ts +79 -0
  125. package/dist/i18n-BrL7p3aN.d.ts +99 -0
  126. package/dist/i18n-CNQNCFU0.d.ts +55 -0
  127. package/dist/i18n-CX_uU8V2.d.ts +80 -0
  128. package/dist/i18n-Cr1QZCwe.d.ts +64 -0
  129. package/dist/i18n-CzTRxGeX.d.ts +80 -0
  130. package/dist/i18n-DUOFiC7g.d.ts +77 -0
  131. package/dist/i18n-DcF47BHS.d.ts +77 -0
  132. package/dist/i18n-DifWvtaO.d.ts +60 -0
  133. package/dist/i18n-DumSqX1t.d.ts +55 -0
  134. package/dist/i18n-fWTJw12h.d.ts +80 -0
  135. package/dist/import-with-i18n.d.ts +23 -0
  136. package/dist/import-with-i18n.js +7 -0
  137. package/dist/index.d.ts +68 -0
  138. package/dist/index.js +151 -0
  139. package/dist/init.d.ts +2 -0
  140. package/dist/init.js +8 -0
  141. package/dist/internal.d.ts +11 -0
  142. package/dist/internal.js +9 -0
  143. package/dist/middleware-entrypoint-C0Drh9E_.d.ts +29 -0
  144. package/dist/middleware-entrypoint-mEl66IUy.d.ts +29 -0
  145. package/dist/middleware-entrypoint.d.ts +5 -0
  146. package/dist/middleware-entrypoint.js +30 -0
  147. package/dist/server/middleware-entrypoint.d.ts +2 -0
  148. package/dist/server/middleware-entrypoint.js +28 -0
  149. package/dist/server/t.d.ts +17 -0
  150. package/dist/server/t.js +59 -0
  151. package/dist/t-BY_C9lZ1.d.ts +30 -0
  152. package/dist/t-CG3yDiEa.d.ts +30 -0
  153. package/dist/t-CHsBfrPr.d.ts +30 -0
  154. package/dist/t-DQpXaDhP.d.ts +30 -0
  155. package/dist/t.client.d.ts +11 -0
  156. package/dist/t.client.js +35 -0
  157. package/dist/t.server.d.ts +22 -0
  158. package/dist/t.server.js +12 -0
  159. package/dist/types-8uKCwFda.d.ts +24 -0
  160. package/dist/types-BC6K-pID.d.ts +110 -0
  161. package/dist/types-BUV7BZML.d.ts +55 -0
  162. package/dist/types-BWGB322F.d.ts +46 -0
  163. package/dist/types-B_-RxW4A.d.ts +7 -0
  164. package/dist/types-BaaSiz9n.d.ts +7 -0
  165. package/dist/types-Bgl2V5xo.d.ts +102 -0
  166. package/dist/types-BwhB6IT4.d.ts +111 -0
  167. package/dist/types-Bzp6KxsI.d.ts +50 -0
  168. package/dist/types-C6rOJFY2.d.ts +24 -0
  169. package/dist/types-C7lD-Woj.d.ts +50 -0
  170. package/dist/types-CLWZeQhD.d.ts +54 -0
  171. package/dist/types-COXt613w.d.ts +19 -0
  172. package/dist/types-CUlkbl9-.d.ts +50 -0
  173. package/dist/types-CVv7GGPj.d.ts +46 -0
  174. package/dist/types-CiIDN2sW.d.ts +64 -0
  175. package/dist/types-Cr86qjYl.d.ts +58 -0
  176. package/dist/types-CxnObiEO.d.ts +7 -0
  177. package/dist/types-D44mFUjA.d.ts +97 -0
  178. package/dist/types-D85m9UTC.d.ts +137 -0
  179. package/dist/types-DWhsmSPP.d.ts +102 -0
  180. package/dist/types-DdprXGJ1.d.ts +46 -0
  181. package/dist/types-DhVJ2ZIo.d.ts +43 -0
  182. package/dist/types-DnbOuM1L.d.ts +7 -0
  183. package/dist/types-DsNK_9sI.d.ts +24 -0
  184. package/dist/types-DvWBr9Xp.d.ts +17 -0
  185. package/dist/types-DwkIalh6.d.ts +24 -0
  186. package/dist/types-OYRgjtE_.d.ts +110 -0
  187. package/dist/types-SV8S05GX.d.ts +7 -0
  188. package/dist/types-TYn9WnxY.d.ts +46 -0
  189. package/dist/types-aXCBbdhq.d.ts +55 -0
  190. package/dist/types-gn4aNKGx.d.ts +54 -0
  191. package/dist/types-nippsMkm.d.ts +54 -0
  192. package/package.json +105 -0
  193. package/src/components/I18nScript.astro +37 -0
  194. package/src/components/index.ts +2 -0
@@ -0,0 +1,55 @@
1
+ import { a as ExtractionManifest } from './types-DwkIalh6.js';
2
+ import { T as TranslationMeta, C as CompiledTranslations, R as RawTranslations } from './types-gn4aNKGx.js';
3
+
4
+ /**
5
+ * Fallback behavior when translation is missing
6
+ */
7
+ type FallbackBehavior = 'key' | 'fallback' | 'throw' | ((key: string, meta?: TranslationMeta | undefined) => string);
8
+ /**
9
+ * Request-scoped i18n context
10
+ */
11
+ type I18nContext = {
12
+ locale: string;
13
+ translations: CompiledTranslations;
14
+ fallback: FallbackBehavior;
15
+ };
16
+
17
+ type I18nConfig = {
18
+ locales: string[];
19
+ defaultLocale?: string | undefined;
20
+ fallback?: FallbackBehavior | undefined;
21
+ };
22
+ type NormalizedConfig = {
23
+ locales: string[];
24
+ defaultLocale: string;
25
+ fallback: FallbackBehavior;
26
+ };
27
+ declare class I18nSingleton {
28
+ private config;
29
+ private rawCache;
30
+ private compiledCache;
31
+ private hashCache;
32
+ private manifestGetter;
33
+ configure(config: I18nConfig): void;
34
+ isConfigured(): boolean;
35
+ getConfig(): NormalizedConfig;
36
+ setTranslations(locale: string, raw: RawTranslations): void;
37
+ getTranslations(locale: string): RawTranslations;
38
+ getCompiledTranslations(locale: string): CompiledTranslations;
39
+ /**
40
+ * Get the extraction manifest (keys + chunks).
41
+ * - keys: translation keys extracted from codebase with metadata
42
+ * - chunks: mapping of chunk names to their translation keys
43
+ */
44
+ getManifest(): ExtractionManifest;
45
+ getHashes(locale: string): Record<string, string>;
46
+ /**
47
+ * Clear translations for specified locale(s).
48
+ * @param locales - Locale(s) to clear, or all if not specified
49
+ */
50
+ clear(locales?: string | string[] | undefined): void;
51
+ private resolveLocales;
52
+ }
53
+ declare const i18n: I18nSingleton;
54
+
55
+ export { type FallbackBehavior as F, type I18nConfig as I, type I18nContext as a, i18n as i };
@@ -0,0 +1,80 @@
1
+ import { T as TranslationMeta, C as CompiledTranslations, R as RawTranslations } from './types-nippsMkm.js';
2
+
3
+ /**
4
+ * Extracted metadata for a single translation key
5
+ */
6
+ type ExtractedKey = {
7
+ key: string;
8
+ meta: TranslationMeta;
9
+ file: string;
10
+ line: number;
11
+ };
12
+ /**
13
+ * Chunk-to-keys mapping produced by Vite plugin
14
+ */
15
+ type ChunkManifest = Record<string, string[]>;
16
+ /**
17
+ * Full extraction manifest
18
+ */
19
+ type ExtractionManifest = {
20
+ keys: ExtractedKey[];
21
+ chunks: ChunkManifest;
22
+ };
23
+
24
+ /**
25
+ * Fallback behavior when translation is missing
26
+ */
27
+ type FallbackBehavior = 'key' | 'fallback' | 'throw' | ((key: string, meta?: TranslationMeta | undefined) => string);
28
+ /**
29
+ * Request-scoped i18n context
30
+ */
31
+ type I18nContext = {
32
+ locale: string;
33
+ translations: CompiledTranslations;
34
+ fallback: FallbackBehavior;
35
+ };
36
+
37
+ type I18nConfig = {
38
+ locales: string[];
39
+ defaultLocale?: string | undefined;
40
+ fallback?: FallbackBehavior | undefined;
41
+ };
42
+ type NormalizedConfig = {
43
+ locales: string[];
44
+ defaultLocale: string;
45
+ fallback: FallbackBehavior;
46
+ };
47
+ declare class I18nSingleton {
48
+ private config;
49
+ private rawCache;
50
+ private compiledCache;
51
+ private extractionManifest;
52
+ private hashCache;
53
+ configure(config: I18nConfig): void;
54
+ isConfigured(): boolean;
55
+ getConfig(): NormalizedConfig;
56
+ setTranslations(locale: string, raw: RawTranslations): void;
57
+ getTranslations(locale: string): RawTranslations;
58
+ getCompiledTranslations(locale: string): CompiledTranslations;
59
+ getChunkManifest(): ChunkManifest;
60
+ /**
61
+ * Get extracted translation keys with metadata.
62
+ * Use this to populate your CMS with keys extracted from the codebase.
63
+ */
64
+ getExtractedKeys(): ExtractedKey[] | null;
65
+ /**
66
+ * Get the full extraction manifest (keys + chunks).
67
+ * Returns null in dev mode (manifest doesn't exist).
68
+ */
69
+ getExtractionManifest(): ExtractionManifest | null;
70
+ getHashes(locale: string): Record<string, string>;
71
+ /**
72
+ * Clear translations for specified locale(s).
73
+ * @param locales - Locale(s) to clear, or all if not specified
74
+ */
75
+ clear(locales?: string | string[] | undefined): void;
76
+ private resolveLocales;
77
+ }
78
+ declare const i18n: I18nSingleton;
79
+
80
+ export { type ExtractedKey as E, type FallbackBehavior as F, type I18nConfig as I, type ExtractionManifest as a, type I18nContext as b, i18n as i };
@@ -0,0 +1,23 @@
1
+ import './types-DWhsmSPP.js';
2
+
3
+ /**
4
+ * Import a module with i18n translations loaded in parallel.
5
+ * Use this for dynamic imports inside React components that use translations.
6
+ *
7
+ * The Vite plugin will transform calls to inject the chunk ID at build time.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // The Vite plugin transforms this:
12
+ * const Module = await importWithI18n(() => import('./HeavyComponent'));
13
+ *
14
+ * // Into this at build time:
15
+ * const Module = await importWithI18n(() => import('./HeavyComponent'), '_astro/HeavyComponent.abc123');
16
+ * ```
17
+ *
18
+ * @param importFn - A function that returns the dynamic import promise
19
+ * @param chunkId - (Injected by Vite plugin) The chunk ID for loading translations
20
+ */
21
+ declare function importWithI18n<T>(importFn: () => Promise<T>, chunkId?: string): Promise<T>;
22
+
23
+ export { importWithI18n };
@@ -0,0 +1,7 @@
1
+ import {
2
+ importWithI18n
3
+ } from "./chunk-V4XWJXXZ.js";
4
+ import "./chunk-FI5KZ5IO.js";
5
+ export {
6
+ importWithI18n
7
+ };
@@ -0,0 +1,68 @@
1
+ import { AstroIntegration, MiddlewareHandler, APIContext } from 'astro';
2
+ export { F as FallbackBehavior, I as I18nConfig, i as i18n } from './i18n-BGfrSNM8.js';
3
+ export { R as RawTranslations, T as TranslationMeta } from './types-Bzp6KxsI.js';
4
+ export { E as ExtractedKey, a as ExtractionManifest } from './types-8uKCwFda.js';
5
+
6
+ interface I18nOptions {
7
+ }
8
+
9
+ /**
10
+ * Astro integration for i18n with automatic per-chunk translation loading.
11
+ *
12
+ * Registers:
13
+ * - Client directives (`client:load-x`, `client:idle-x`, `client:visible-x`, `client:media-x`, `client:only-x`)
14
+ * - Vite plugin for translation key extraction
15
+ */
16
+ declare function i18nIntegration(_options?: I18nOptions): AstroIntegration;
17
+
18
+ type I18nMiddlewareOptions = {
19
+ locale: (ctx: APIContext) => string;
20
+ };
21
+ /**
22
+ * Create the i18n chunk middleware that serves translation chunks at `/_i18n/` endpoints.
23
+ *
24
+ * Place this early in your middleware sequence (before session/auth)
25
+ * to avoid unnecessary overhead for static translation requests.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // src/middleware.ts
30
+ * import { sequence } from 'astro:middleware';
31
+ * import { createI18nChunkMiddleware, createI18nMiddleware } from '@astroscope/i18n';
32
+ *
33
+ * export const onRequest = sequence(
34
+ * createI18nChunkMiddleware(), // early: serves /_i18n/ chunks
35
+ * sessionMiddleware,
36
+ * createI18nMiddleware({ locale: (ctx) => ... }), // after session
37
+ * );
38
+ * ```
39
+ */
40
+ declare function createI18nChunkMiddleware(): MiddlewareHandler;
41
+ /**
42
+ * Create the i18n locale middleware.
43
+ *
44
+ * Sets up the request context with locale and translations for use by
45
+ * `t()` and `<I18nScript />`. Place this after session middleware if
46
+ * your locale detection depends on session/cookies.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * import { createI18nMiddleware, detectLocale, i18n } from '@astroscope/i18n';
51
+ *
52
+ * export const i18nMiddleware = createI18nMiddleware({
53
+ * locale: (ctx) =>
54
+ * ctx.cookies.get('locale')?.value ??
55
+ * detectLocale(ctx.request) ??
56
+ * i18n.getConfig().defaultLocale,
57
+ * });
58
+ * ```
59
+ */
60
+ declare function createI18nMiddleware(options: I18nMiddlewareOptions): MiddlewareHandler;
61
+
62
+ /**
63
+ * Detect locale from Accept-Language header.
64
+ * Returns best match from configured locales, or undefined if none match.
65
+ */
66
+ declare function detectLocale(request: Request): string | undefined;
67
+
68
+ export { type I18nMiddlewareOptions, createI18nChunkMiddleware, createI18nMiddleware, i18nIntegration as default, detectLocale };
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ import {
2
+ i18nVitePlugin
3
+ } from "./chunk-JJEDOJBR.js";
4
+ import {
5
+ i18n,
6
+ runWithContext
7
+ } from "./chunk-QFAAGCP5.js";
8
+ import "./chunk-KNDYKTHE.js";
9
+ import "./chunk-4A5BKHFN.js";
10
+
11
+ // src/integration/integration.ts
12
+ var CLIENT_DIRECTIVES = ["load-x", "idle-x", "visible-x", "media-x", "only-x"];
13
+ function i18nIntegration(_options = {}) {
14
+ return {
15
+ name: "@astroscope/i18n",
16
+ hooks: {
17
+ "astro:config:setup": ({ addClientDirective, updateConfig, logger }) => {
18
+ for (const directive of CLIENT_DIRECTIVES) {
19
+ const base = directive.replace("-x", "");
20
+ addClientDirective({
21
+ name: directive,
22
+ entrypoint: `@astroscope/i18n/client-directives/${base}.js`
23
+ });
24
+ }
25
+ updateConfig({
26
+ vite: {
27
+ plugins: [i18nVitePlugin({ logger })]
28
+ }
29
+ });
30
+ },
31
+ "astro:config:done": ({ injectTypes }) => {
32
+ const typeMap = {
33
+ load: "boolean",
34
+ idle: "boolean",
35
+ visible: "boolean | string",
36
+ media: "string",
37
+ only: "string"
38
+ };
39
+ const attributes = CLIENT_DIRECTIVES.map((d) => {
40
+ const base = d.replace("-x", "");
41
+ return ` 'client:${d}'?: ${typeMap[base]};`;
42
+ }).join("\n");
43
+ injectTypes({
44
+ filename: "client-directives.d.ts",
45
+ content: `// generated by @astroscope/i18n
46
+ declare namespace astroHTML.JSX {
47
+ interface AstroBuiltinAttributes {
48
+ ${attributes}
49
+ }
50
+ }`
51
+ });
52
+ }
53
+ }
54
+ };
55
+ }
56
+
57
+ // src/server/middleware.ts
58
+ var I18N_ENDPOINT_PREFIX = "/_i18n/";
59
+ function createI18nChunkMiddleware() {
60
+ return (ctx, next) => {
61
+ const { pathname } = ctx.url;
62
+ if (!pathname.startsWith(I18N_ENDPOINT_PREFIX)) {
63
+ return next();
64
+ }
65
+ const path = pathname.slice(I18N_ENDPOINT_PREFIX.length);
66
+ const slashIdx = path.indexOf("/");
67
+ if (slashIdx === -1) {
68
+ return next();
69
+ }
70
+ const locale = path.slice(0, slashIdx);
71
+ const rest = path.slice(slashIdx + 1);
72
+ if (!rest.endsWith(".js")) {
73
+ return next();
74
+ }
75
+ const withoutJs = rest.slice(0, -3);
76
+ const lastDotIdx = withoutJs.lastIndexOf(".");
77
+ if (lastDotIdx === -1) {
78
+ return next();
79
+ }
80
+ const chunkName = withoutJs.slice(0, lastDotIdx);
81
+ const keys = i18n.getManifest().chunks[chunkName];
82
+ if (!keys) {
83
+ return new Response(`/* chunk not found: ${chunkName} */`, {
84
+ status: 404,
85
+ headers: { "Content-Type": "application/javascript" }
86
+ });
87
+ }
88
+ const translations = i18n.getTranslations(locale);
89
+ const chunkTranslations = {};
90
+ for (const key of keys) {
91
+ if (translations[key]) {
92
+ chunkTranslations[key] = translations[key];
93
+ }
94
+ }
95
+ const js = `/* @astroscope/i18n chunk: ${chunkName} */
96
+ (function() {
97
+ var i = window.__i18n__;
98
+ if (i) Object.assign(i.translations, ${JSON.stringify(chunkTranslations)});
99
+ })();
100
+ `;
101
+ const body = new TextEncoder().encode(js);
102
+ return new Response(body, {
103
+ status: 200,
104
+ headers: {
105
+ "Content-Type": "text/javascript; charset=utf-8",
106
+ "Content-Length": String(body.byteLength),
107
+ "Cache-Control": "public, max-age=31536000, immutable"
108
+ }
109
+ });
110
+ };
111
+ }
112
+ function createI18nMiddleware(options) {
113
+ return (ctx, next) => {
114
+ const locale = options.locale(ctx);
115
+ const context = {
116
+ locale,
117
+ translations: i18n.getCompiledTranslations(locale),
118
+ fallback: i18n.getConfig().fallback
119
+ };
120
+ return runWithContext(context, () => next());
121
+ };
122
+ }
123
+
124
+ // src/server/locale.ts
125
+ function detectLocale(request) {
126
+ const config = i18n.getConfig();
127
+ if (!config) return void 0;
128
+ const { locales } = config;
129
+ const acceptLanguage = request.headers.get("accept-language");
130
+ if (!acceptLanguage) return void 0;
131
+ const preferred = acceptLanguage.split(",").map((part) => {
132
+ const [lang, q = "q=1"] = part.trim().split(";");
133
+ return {
134
+ lang: lang.split("-")[0].toLowerCase(),
135
+ q: parseFloat(q.replace("q=", ""))
136
+ };
137
+ }).sort((a, b) => b.q - a.q);
138
+ for (const { lang } of preferred) {
139
+ if (locales.includes(lang)) {
140
+ return lang;
141
+ }
142
+ }
143
+ return void 0;
144
+ }
145
+ export {
146
+ createI18nChunkMiddleware,
147
+ createI18nMiddleware,
148
+ i18nIntegration as default,
149
+ detectLocale,
150
+ i18n
151
+ };
package/dist/init.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/init.js ADDED
@@ -0,0 +1,8 @@
1
+ import {
2
+ i18n
3
+ } from "./chunk-2PSXD3JJ.js";
4
+ import "./chunk-KNDYKTHE.js";
5
+
6
+ // src/init.ts
7
+ import { getManifest } from "virtual:@astroscope/i18n/manifest";
8
+ i18n.setManifestGetter(getManifest);
@@ -0,0 +1,11 @@
1
+ import { a as I18nContext } from './i18n-BGfrSNM8.js';
2
+ export { i as i18n } from './i18n-BGfrSNM8.js';
3
+ export { I as I18nClientState } from './types-Bzp6KxsI.js';
4
+ import './types-8uKCwFda.js';
5
+
6
+ /**
7
+ * Get the current i18n context
8
+ */
9
+ declare function getContext(): I18nContext | null;
10
+
11
+ export { getContext };
@@ -0,0 +1,9 @@
1
+ import {
2
+ getContext,
3
+ i18n
4
+ } from "./chunk-QFAAGCP5.js";
5
+ import "./chunk-KNDYKTHE.js";
6
+ export {
7
+ getContext,
8
+ i18n
9
+ };
@@ -0,0 +1,29 @@
1
+ import { APIContext, MiddlewareHandler } from 'astro';
2
+
3
+ type I18nMiddlewareOptions = {
4
+ locale: (ctx: APIContext) => string;
5
+ };
6
+ /**
7
+ * Detect locale from Accept-Language header.
8
+ * Returns best match from configured locales, or undefined if none match.
9
+ */
10
+ declare function detectLocale(request: Request): string | undefined;
11
+ /**
12
+ * Create the i18n middleware.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createI18nMiddleware, detectLocale, i18n } from '@astroscope/i18n';
17
+ *
18
+ * export const i18nMiddleware = createI18nMiddleware({
19
+ * locale: (ctx) =>
20
+ * ctx.cookies.get('locale')?.value ??
21
+ * detectLocale(ctx.request) ??
22
+ * i18n.getDefaultLocale() ??
23
+ * 'en',
24
+ * });
25
+ * ```
26
+ */
27
+ declare function createI18nMiddleware(options: I18nMiddlewareOptions): MiddlewareHandler;
28
+
29
+ export { type I18nMiddlewareOptions as I, createI18nMiddleware as c, detectLocale as d };
@@ -0,0 +1,29 @@
1
+ import { APIContext, MiddlewareHandler } from 'astro';
2
+
3
+ type I18nMiddlewareOptions = {
4
+ locale: (ctx: APIContext) => string;
5
+ };
6
+ /**
7
+ * Detect locale from Accept-Language header.
8
+ * Returns best match from configured locales, or undefined if none match.
9
+ */
10
+ declare function detectLocale(request: Request): string | undefined;
11
+ /**
12
+ * Create the i18n middleware.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createI18nMiddleware, detectLocale, i18n } from '@astroscope/i18n';
17
+ *
18
+ * export const i18nMiddleware = createI18nMiddleware({
19
+ * locale: (ctx) =>
20
+ * ctx.cookies.get('locale')?.value ??
21
+ * detectLocale(ctx.request) ??
22
+ * i18n.getConfig()?.defaultLocale ??
23
+ * 'en',
24
+ * });
25
+ * ```
26
+ */
27
+ declare function createI18nMiddleware(options: I18nMiddlewareOptions): MiddlewareHandler;
28
+
29
+ export { type I18nMiddlewareOptions as I, createI18nMiddleware as c, detectLocale as d };
@@ -0,0 +1,5 @@
1
+ import * as astro from 'astro';
2
+
3
+ declare const onRequest: astro.MiddlewareHandler;
4
+
5
+ export { onRequest };
@@ -0,0 +1,30 @@
1
+ import {
2
+ createI18nMiddleware,
3
+ getI18nService
4
+ } from "./chunk-FHBVI3TL.js";
5
+ import "./chunk-KNONI6DP.js";
6
+
7
+ // src/middleware-entrypoint.ts
8
+ import fs from "fs";
9
+ function loadChunkManifest() {
10
+ try {
11
+ const manifestPath = new URL("./i18n-manifest.json", import.meta.url);
12
+ const content = fs.readFileSync(manifestPath, "utf-8");
13
+ const manifest = JSON.parse(content);
14
+ return manifest.chunks;
15
+ } catch {
16
+ return void 0;
17
+ }
18
+ }
19
+ var chunkManifest = loadChunkManifest();
20
+ var service = getI18nService();
21
+ var config = service.config;
22
+ var onRequest = createI18nMiddleware({
23
+ locales: config.locales,
24
+ defaultLocale: config.defaultLocale,
25
+ fallback: config.fallback,
26
+ chunkManifest
27
+ });
28
+ export {
29
+ onRequest
30
+ };
@@ -0,0 +1,2 @@
1
+ export { c as createI18nMiddleware, d as detectLocale } from '../middleware-entrypoint-C0Drh9E_.js';
2
+ import 'astro';
@@ -0,0 +1,28 @@
1
+ import {
2
+ createI18nMiddleware,
3
+ detectLocale,
4
+ i18n
5
+ } from "../chunk-NHHTSFA7.js";
6
+ import "../chunk-JJBBY2GR.js";
7
+ import "../chunk-KNDYKTHE.js";
8
+
9
+ // src/server/middleware-entrypoint.ts
10
+ import fs from "fs";
11
+ function loadChunkManifest() {
12
+ try {
13
+ const manifestPath = new URL("./i18n-manifest.json", import.meta.url);
14
+ const content = fs.readFileSync(manifestPath, "utf-8");
15
+ const manifest = JSON.parse(content);
16
+ return manifest.chunks;
17
+ } catch {
18
+ return void 0;
19
+ }
20
+ }
21
+ var chunkManifest = loadChunkManifest();
22
+ if (chunkManifest) {
23
+ i18n.setChunkManifest(chunkManifest);
24
+ }
25
+ export {
26
+ createI18nMiddleware,
27
+ detectLocale
28
+ };
@@ -0,0 +1,17 @@
1
+ import { a as TranslateFunction } from '../types-Bzp6KxsI.js';
2
+
3
+ /**
4
+ * Get the current locale from request context.
5
+ * Returns defaultLocale if called outside a request (e.g. during build).
6
+ */
7
+ declare function getLocale(): string;
8
+ /**
9
+ * Server-side translate function
10
+ *
11
+ * Call patterns:
12
+ * - Development: t('key', 'fallback') or t('key', 'fallback', values)
13
+ * - Production: t('key') or t('key', undefined, values)
14
+ */
15
+ declare const t: TranslateFunction;
16
+
17
+ export { getLocale, t };
@@ -0,0 +1,59 @@
1
+ import {
2
+ getContext,
3
+ i18n
4
+ } from "../chunk-QFAAGCP5.js";
5
+ import {
6
+ normalizeMeta
7
+ } from "../chunk-EMM6LRO2.js";
8
+ import {
9
+ compileMessage
10
+ } from "../chunk-KNDYKTHE.js";
11
+
12
+ // src/server/t.ts
13
+ var fallbackCache = /* @__PURE__ */ new Map();
14
+ function applyFallback(key, meta, fallback) {
15
+ if (typeof fallback === "function") {
16
+ return fallback(key, meta);
17
+ }
18
+ switch (fallback) {
19
+ case "key":
20
+ return key;
21
+ case "fallback":
22
+ return meta.fallback || key;
23
+ case "throw":
24
+ throw new Error(`Missing translation for key: ${key}`);
25
+ default:
26
+ return meta.fallback || key;
27
+ }
28
+ }
29
+ function getLocale() {
30
+ const ctx = getContext();
31
+ return ctx?.locale ?? i18n.getConfig().defaultLocale;
32
+ }
33
+ var t = ((key, meta, values) => {
34
+ const normalizedMeta = meta ? normalizeMeta(meta) : { fallback: "" };
35
+ const ctx = getContext();
36
+ if (!ctx) {
37
+ const defaultLocale = i18n.getConfig().defaultLocale;
38
+ const fallbackStr = normalizedMeta.fallback || key;
39
+ const cacheKey = `${defaultLocale}:${fallbackStr}`;
40
+ let compiled2 = fallbackCache.get(cacheKey);
41
+ if (!compiled2) {
42
+ compiled2 = compileMessage(defaultLocale, fallbackStr);
43
+ fallbackCache.set(cacheKey, compiled2);
44
+ }
45
+ return compiled2(values);
46
+ }
47
+ const compiled = ctx.translations[key];
48
+ if (!compiled) {
49
+ const fallbackValue = applyFallback(key, normalizedMeta, ctx.fallback);
50
+ const compiledFallback = compileMessage(ctx.locale, fallbackValue);
51
+ ctx.translations[key] = compiledFallback;
52
+ return compiledFallback(values);
53
+ }
54
+ return compiled(values);
55
+ });
56
+ export {
57
+ getLocale,
58
+ t
59
+ };
@@ -0,0 +1,30 @@
1
+ import { T as TranslationMeta } from './types-BwhB6IT4.js';
2
+
3
+ /**
4
+ * Translate function signature
5
+ *
6
+ * @param key - Translation key (e.g., 'checkout.title')
7
+ * @param meta - Metadata with example and variable definitions (extracted at build time)
8
+ * @param values - Runtime values for interpolation
9
+ * @returns Translated string
10
+ *
11
+ * @example
12
+ * // Simple
13
+ * t('checkout.title', { example: 'Bestellübersicht' })
14
+ *
15
+ * @example
16
+ * // With variables
17
+ * t('checkout.tax', {
18
+ * example: 'Enthält {name} MwSt.',
19
+ * variables: { name: { example: '19%' } }
20
+ * }, { name: taxRate })
21
+ *
22
+ * @example
23
+ * // Pluralization (ICU)
24
+ * t('cart.items', {
25
+ * example: '{count, plural, one {# item} other {# items}}'
26
+ * }, { count: itemCount })
27
+ */
28
+ type TranslateFunction = (key: string, meta: TranslationMeta, values?: Record<string, unknown>) => string;
29
+
30
+ export type { TranslateFunction as T };