@i18n-micro/types 1.2.0 → 1.2.2

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.
@@ -0,0 +1,467 @@
1
+ /** BCP-47 locale code string (e.g. `'en'`, `'de-DE'`, `'zh-Hans'`). */
2
+ export type LocaleCode = string;
3
+ /**
4
+ * Key registry for typed translation keys.
5
+ * Users (via `@i18n-micro/types-generator`) extend this interface through
6
+ * TypeScript module augmentation to get autocompletion for `$t()` calls.
7
+ */
8
+ export interface DefineLocaleMessage {
9
+ readonly __augmentation?: never;
10
+ }
11
+ /**
12
+ * Resolved translation key type.
13
+ * - When `DefineLocaleMessage` is empty (generator not connected) — resolves to `string`.
14
+ * - When `DefineLocaleMessage` has keys — resolves to a union of those keys **and** `string`,
15
+ * providing autocompletion while still allowing dynamic keys.
16
+ */
17
+ export type TranslationKey = keyof DefineLocaleMessage extends never ? string : keyof DefineLocaleMessage | string;
18
+ /**
19
+ * Helper for creating typed prefixes.
20
+ * Allows safe usage of dynamic keys.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Assuming keys: 'errors.404', 'errors.500', 'btn.save'
25
+ * function getErrorText(code: string) {
26
+ * return t(`errors.${code}` as ScopedKey<'errors'>)
27
+ * }
28
+ * ```
29
+ */
30
+ export type ScopedKey<Scope extends string> = Extract<TranslationKey, `${Scope}.${string}`>;
31
+ /**
32
+ * Locale configuration object.
33
+ *
34
+ * Supports arbitrary custom properties via the index signature `[key: string]: unknown`.
35
+ * To get full TypeScript support for your custom properties, use module augmentation:
36
+ *
37
+ * ```typescript
38
+ * // app/i18n.d.ts (or any .d.ts file included in your tsconfig)
39
+ * declare module '@i18n-micro/types' {
40
+ * interface Locale {
41
+ * flag?: string
42
+ * currency?: string
43
+ * }
44
+ * }
45
+ * ```
46
+ *
47
+ * Then access them with full typing:
48
+ * ```typescript
49
+ * const locales = $getLocales()
50
+ * locales[0].flag // string | undefined (typed!)
51
+ * locales[0].currency // string | undefined (typed!)
52
+ * ```
53
+ */
54
+ export interface Locale {
55
+ /** BCP-47 locale code (e.g. `'en'`, `'de-DE'`, `'zh-Hans'`). Used in URLs and as file/key identifier. */
56
+ code: LocaleCode;
57
+ /** When `true`, this locale is excluded from route generation and language switching. */
58
+ disabled?: boolean;
59
+ /** ISO 639-1 / BCP-47 tag for `<html lang>` and `hreflang` SEO attributes (e.g. `'en-US'`). */
60
+ iso?: string;
61
+ /**
62
+ * Open Graph locale for `og:locale` / `og:locale:alternate` meta `content` (e.g. `ar_AE`).
63
+ * If omitted or empty, `iso` is used (then `code`).
64
+ */
65
+ og?: string;
66
+ /**
67
+ * When `false`, this locale is omitted from cross-locale SEO tags (`hreflang`,
68
+ * `og:locale:alternate`). If the configured default locale has `seo: false`, the
69
+ * `x-default` hreflang link is not emitted. Routing and translations are unchanged.
70
+ * @default true when omitted.
71
+ */
72
+ seo?: boolean;
73
+ /** Text direction. Reflected in `<html dir>` when the locale is active. */
74
+ dir?: 'ltr' | 'rtl' | 'auto';
75
+ /** Human-readable name shown in language switchers (e.g. `'English'`, `'Deutsch'`). */
76
+ displayName?: string;
77
+ /**
78
+ * Per-locale base URL for SEO meta tags.
79
+ * Useful for multi-domain setups where each locale lives on its own domain
80
+ * (e.g. `'https://en.example.com'`).
81
+ */
82
+ baseUrl?: string;
83
+ /**
84
+ * When `true`, this locale is treated as the "base default" for the domain
85
+ * specified in `baseUrl`. Affects canonical URL generation in multi-domain setups.
86
+ */
87
+ baseDefault?: boolean;
88
+ /**
89
+ * Locale code to fall back to when a translation key is missing in this locale.
90
+ * Overrides the global `fallbackLocale` for this specific locale.
91
+ */
92
+ fallbackLocale?: string;
93
+ /** Allows arbitrary extra properties for user-defined locale metadata. */
94
+ [key: string]: unknown;
95
+ }
96
+ /**
97
+ * Per-page i18n configuration declared via `defineI18nRoute()` in page components.
98
+ */
99
+ export interface DefineI18nRouteConfig {
100
+ /**
101
+ * Restrict which locales this page is available in.
102
+ * - `string[]` — list of allowed locale codes.
103
+ * - `Record<LocaleCode, Translations>` — allowed locales with inline translation overrides.
104
+ */
105
+ locales?: string[] | Record<LocaleCode, Translations>;
106
+ /** Per-locale custom route paths (e.g. `{ en: '/about', de: '/ueber-uns' }`). */
107
+ localeRoutes?: Record<LocaleCode, string>;
108
+ /**
109
+ * Disable SEO meta tag generation for this page.
110
+ * - `true` — disable all meta tags.
111
+ * - `string[]` — disable only for the listed locale codes.
112
+ */
113
+ disableMeta?: boolean | string[];
114
+ }
115
+ /** Locale-specific route params for `$switchLocalePath` and `<i18n-link>`. */
116
+ export type I18nRouteParams = Record<LocaleCode, Record<string, string>> | null;
117
+ /** Interpolation parameters passed to the `t()` function. */
118
+ export type Params = Record<string, string | number | boolean>;
119
+ /** Getter function signature used by pluralization to resolve nested keys. */
120
+ export type Getter = (key: TranslationKey, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown;
121
+ /**
122
+ * Custom pluralization function.
123
+ * Called when `tc()` / `$tc()` is used. Receives the key, count, params, locale,
124
+ * and a getter to fetch the singular/plural forms from translations.
125
+ */
126
+ export type PluralFunc = (key: TranslationKey, count: number, params: Params, locale: string, getter: Getter) => string | null;
127
+ /**
128
+ * Global per-route locale configuration.
129
+ * - `Record<string, string>` — custom paths per locale for the route.
130
+ * - `false` — exclude the route from localization entirely.
131
+ * - `true` — include with default behavior.
132
+ */
133
+ export type GlobalLocaleRoutes = Record<string, Record<LocaleCode, string> | false | boolean> | null | undefined;
134
+ /** URL routing strategy for locale handling. */
135
+ export type Strategies = 'no_prefix' | 'prefix_except_default' | 'prefix' | 'prefix_and_default';
136
+ /**
137
+ * Callback invoked when a translation key is missing.
138
+ * Useful for logging, reporting, or providing dynamic fallbacks.
139
+ */
140
+ export type MissingHandler = (locale: string, key: TranslationKey, routeName: string, instance?: unknown, type?: string) => void;
141
+ export interface ModuleOptions {
142
+ /**
143
+ * List of supported locales.
144
+ * Each entry defines a locale code plus optional metadata (ISO, direction, display name, etc.).
145
+ * @default []
146
+ */
147
+ locales?: Locale[];
148
+ /**
149
+ * Generate SEO meta tags (`hreflang`, `canonical`, `og:url`, `og:locale`) automatically.
150
+ * @default true
151
+ */
152
+ meta?: boolean;
153
+ /**
154
+ * URL routing strategy for locale prefixes.
155
+ * - `'no_prefix'` — no locale in URL; locale stored in cookie.
156
+ * - `'prefix_except_default'` — prefix all locales except the default.
157
+ * - `'prefix'` — always prefix, including the default locale.
158
+ * - `'prefix_and_default'` — like `prefix`, but the default locale is also accessible without prefix.
159
+ * @default 'prefix_except_default'
160
+ */
161
+ strategy?: Strategies;
162
+ /**
163
+ * Base URL for SEO meta tags (canonical, og:url, hreflang).
164
+ * - `undefined` — dynamically resolved from the current request URL
165
+ * (`useRequestURL().origin` on server, `window.location.origin` on client).
166
+ * Best for multi-domain deployments.
167
+ * - A concrete URL string (e.g. `'https://example.com'`) — used as-is.
168
+ * @default undefined
169
+ */
170
+ metaBaseUrl?: string;
171
+ /**
172
+ * Trust the `X-Forwarded-Host` header when resolving the base URL for meta tags.
173
+ * Enable when the app runs behind a reverse proxy (nginx, Cloudflare, AWS ALB, etc.)
174
+ * that sets this header to the real client-facing hostname.
175
+ * @default true
176
+ */
177
+ metaTrustForwardedHost?: boolean;
178
+ /**
179
+ * Trust the `X-Forwarded-Proto` header when resolving the protocol for meta tags.
180
+ * Enable when the app runs behind a TLS-terminating proxy so that
181
+ * canonical URLs use `https://` even though the app itself listens on HTTP.
182
+ * @default true
183
+ */
184
+ metaTrustForwardedProto?: boolean;
185
+ /**
186
+ * Register the `defineI18nRoute()` macro plugin, enabling per-page `defineI18nRoute()` calls.
187
+ * @default true
188
+ */
189
+ define?: boolean;
190
+ /**
191
+ * Enable automatic locale-based redirects.
192
+ * When `true`, visitors are redirected to their preferred locale (detected from cookie,
193
+ * `Accept-Language` header, or the default) on the first visit.
194
+ * @default true
195
+ */
196
+ redirects?: boolean;
197
+ /**
198
+ * Register the core i18n plugin that provides `$t()`, `$tc()`, `$getLocale()`,
199
+ * `$switchLocale()`, and other runtime helpers.
200
+ * @default true
201
+ */
202
+ plugin?: boolean;
203
+ /**
204
+ * Register the i18n hooks plugin that provides `i18n:register` and `i18n:beforeLocaleSwitch`
205
+ * / `i18n:afterLocaleSwitch` app-level hooks.
206
+ * @default true
207
+ */
208
+ hooks?: boolean;
209
+ /**
210
+ * Register built-in i18n components (`<i18n-link>`, `<i18n-switcher>`, `<i18n-t>`, `<i18n-group>`).
211
+ * Set to `false` to disable automatic component registration (e.g. if you don't use them
212
+ * and want to reduce the module footprint).
213
+ * @default true
214
+ */
215
+ components?: boolean;
216
+ /**
217
+ * The locale to use when no locale can be determined from URL or user preferences.
218
+ * Also used as the fallback locale for missing translations when `fallbackLocale` is not set.
219
+ * @default 'en'
220
+ */
221
+ defaultLocale?: string;
222
+ /**
223
+ * Base URL path segment for the translations API route (used in SSR/SSG data fetching).
224
+ * Can also be set via `NUXT_I18N_APP_BASE_URL` environment variable.
225
+ * @default '_locales'
226
+ */
227
+ apiBaseUrl?: string;
228
+ /**
229
+ * Override the host used for client-side translation fetch requests.
230
+ * Useful when the client reaches the server via a different hostname than the one Nuxt sees.
231
+ * Can also be set via `NUXT_I18N_APP_BASE_CLIENT_HOST` environment variable.
232
+ * @default undefined
233
+ */
234
+ apiBaseClientHost?: string;
235
+ /**
236
+ * Override the host used for server-side translation fetch requests.
237
+ * Useful in container/microservice setups where the server reaches itself via an internal hostname.
238
+ * Can also be set via `NUXT_I18N_APP_BASE_SERVER_HOST` environment variable.
239
+ * @default undefined
240
+ */
241
+ apiBaseServerHost?: string;
242
+ /**
243
+ * Path to the directory containing translation JSON files, relative to the project root.
244
+ * @default 'locales'
245
+ */
246
+ translationDir?: string;
247
+ /**
248
+ * Automatically detect the user's preferred language from the `Accept-Language` HTTP header.
249
+ * Used in combination with `autoDetectPath` to decide when detection occurs.
250
+ * @default true
251
+ */
252
+ autoDetectLanguage?: boolean;
253
+ /**
254
+ * URL path on which automatic language detection and redirect occur.
255
+ * - `'/'` — detect only on the root path.
256
+ * - `'*'` — detect and redirect on every path (including locale-prefixed ones).
257
+ * @default '/'
258
+ */
259
+ autoDetectPath?: string;
260
+ /**
261
+ * Disable the file watcher that auto-creates missing translation files in development mode.
262
+ * @default false
263
+ */
264
+ disableWatcher?: boolean;
265
+ /**
266
+ * Generate TypeScript type declarations for `useI18n`, `$t`, and related helpers
267
+ * based on the translation keys in your default locale files.
268
+ * @default true
269
+ */
270
+ types?: boolean;
271
+ /**
272
+ * Map route names to other route names to share the same translation files.
273
+ * For example, `{ 'about-us': 'about' }` means the `about-us` page will use
274
+ * translations from the `about` page instead of its own.
275
+ * @default {}
276
+ */
277
+ routesLocaleLinks?: {
278
+ [key: string]: string;
279
+ };
280
+ /**
281
+ * Custom pluralization function or a path to a file exporting one.
282
+ * When a string path is provided, the file is imported at build time.
283
+ * The function receives `(key, count, params, locale, getter)` and should return
284
+ * the correct plural form as a string, or `null` to fall back to the built-in logic.
285
+ * @default built-in pluralization (singular/plural by count)
286
+ */
287
+ plural?: string | PluralFunc;
288
+ /**
289
+ * Disable per-page translation files.
290
+ * When `true`, only global translations (`{locale}.json`) are loaded;
291
+ * page-specific files (`pages/{page}/{locale}.json`) are not generated or loaded.
292
+ * @default false
293
+ */
294
+ disablePageLocales?: boolean;
295
+ /**
296
+ * Global fallback locale code.
297
+ * When a translation key is missing in the active locale, the module looks it up
298
+ * in this locale before returning the key itself.
299
+ * @default undefined (no fallback; returns the raw key)
300
+ */
301
+ fallbackLocale?: string;
302
+ /**
303
+ * Cookie name for persisting the user's locale preference across sessions.
304
+ * Set to `null` to disable cookie-based persistence.
305
+ * Automatically set to `'user-locale'` for the `no_prefix` strategy if not provided.
306
+ * @default null
307
+ */
308
+ localeCookie?: string | null;
309
+ /**
310
+ * Enable verbose debug logging for locale detection, route generation, and translation loading.
311
+ * @default false
312
+ */
313
+ debug?: boolean;
314
+ /**
315
+ * Global route-level locale configuration.
316
+ * Allows restricting or customizing locale routes for specific pages without
317
+ * modifying their components.
318
+ * - `false` — exclude the route from localization.
319
+ * - `Record<LocaleCode, string>` — custom per-locale paths.
320
+ * @default {}
321
+ */
322
+ globalLocaleRoutes?: GlobalLocaleRoutes;
323
+ /**
324
+ * Custom regular expression (or its string source) for matching locale codes in URL segments.
325
+ * All locale codes defined in `locales` must match this pattern, or a warning is emitted.
326
+ * @default undefined (uses built-in pattern based on locale codes)
327
+ */
328
+ customRegexMatcher?: string | RegExp;
329
+ /**
330
+ * For `no_prefix` strategy: enable redirect from a locale-prefixed URL
331
+ * (e.g. `/en/about`) to the unprefixed version (`/about`).
332
+ * @default false
333
+ */
334
+ noPrefixRedirect?: boolean;
335
+ /**
336
+ * List of query parameter names preserved in canonical and `og:url` meta tags.
337
+ * Parameters not in this list are stripped from the canonical URL.
338
+ * @default ['page', 'sort', 'filter', 'search', 'q', 'query', 'tag']
339
+ */
340
+ canonicalQueryWhitelist?: string[];
341
+ /**
342
+ * URL patterns (strings or RegExp) to exclude from i18n processing entirely.
343
+ * Matching routes won't get locale prefixes, redirects, or translation loading.
344
+ * Internal Nuxt paths (`/__nuxt_error`, etc.) are always excluded automatically.
345
+ * @default undefined
346
+ */
347
+ excludePatterns?: (string | RegExp)[];
348
+ /**
349
+ * Prefix prepended to localized route names (e.g. `'localized-index'`).
350
+ * Used internally to distinguish original routes from generated locale variants.
351
+ * @default 'localized-'
352
+ */
353
+ localizedRouteNamePrefix?: string;
354
+ /**
355
+ * Per-route locale restrictions, extracted from `defineI18nRoute()` calls.
356
+ * Maps a route path (e.g. `'/about'`) to an array of allowed locale codes.
357
+ * Routes not listed have no restrictions (all locales allowed).
358
+ */
359
+ routeLocales?: Record<string, string[]>;
360
+ /**
361
+ * Per-route meta tag disabling, extracted from `defineI18nRoute()` calls.
362
+ * Maps a route path to `true` (disable all meta) or an array of locale codes
363
+ * for which meta should be disabled.
364
+ */
365
+ routeDisableMeta?: Record<string, boolean | string[]>;
366
+ /**
367
+ * Show console warnings when a translation key is missing.
368
+ * @default true
369
+ */
370
+ missingWarn?: boolean;
371
+ /**
372
+ * Enable Hot Module Replacement for translation files in development.
373
+ * When `true`, changes to JSON translation files trigger an automatic reload
374
+ * without a full page refresh.
375
+ * @default true
376
+ */
377
+ hmr?: boolean;
378
+ /**
379
+ * Maximum number of entries in the in-memory translation cache.
380
+ * `0` means no limit.
381
+ * @default 0
382
+ */
383
+ cacheMaxSize?: number;
384
+ /**
385
+ * Time-to-live (in seconds) for cached translation entries.
386
+ * `0` means entries never expire.
387
+ * @default 0
388
+ */
389
+ cacheTtl?: number;
390
+ /**
391
+ * Value used for cache-busting translation requests (`?v=...`).
392
+ *
393
+ * When not provided, the module falls back to `Date.now()` (non-deterministic).
394
+ * For reproducible/rolling deployments, set this to a stable value
395
+ * (e.g. a git SHA or build number).
396
+ *
397
+ * @example
398
+ * i18n: { dateBuild: 'e3b0c442' }
399
+ */
400
+ dateBuild?: string | number;
401
+ /**
402
+ * Bucket for experimental/unstable options.
403
+ * Contents may change or be removed without notice between minor versions.
404
+ */
405
+ experimental?: Record<string, unknown>;
406
+ }
407
+ /**
408
+ * Extended module options injected into the Nuxt runtime config.
409
+ * Includes resolved values and build-time metadata.
410
+ */
411
+ export interface ModuleOptionsExtend extends ModuleOptions {
412
+ /** Value used for cache-busting translation requests (`?v=...`). */
413
+ dateBuild: string | number;
414
+ /** Whether the Nuxt app uses hash-based routing (`router.options.hashMode`). */
415
+ hashMode: boolean;
416
+ /** Whether the current build is a static site generation (SSG / `nuxi generate`). */
417
+ isSSG: boolean;
418
+ /** Resolved translations API base URL (after env variable / config merging). */
419
+ apiBaseUrl: string;
420
+ /** Resolved flag: whether per-page translations are disabled. */
421
+ disablePageLocales: boolean;
422
+ /** Resolved flag: whether locale-based redirects are enabled. */
423
+ redirects?: boolean;
424
+ }
425
+ /**
426
+ * Private (server-only) module options passed to Nitro plugins and server middleware.
427
+ * Extends `ModuleOptions` with resolved root paths and directory info.
428
+ */
429
+ export interface ModulePrivateOptionsExtend extends ModuleOptions {
430
+ /** Absolute path to the Nuxt project root directory. */
431
+ rootDir: string;
432
+ /** Resolved debug flag. */
433
+ debug: boolean;
434
+ /** Resolved path to the translations directory. */
435
+ translationDir: string;
436
+ /** Resolved fallback locale code. */
437
+ fallbackLocale: string;
438
+ /** Resolved translations API base URL. */
439
+ apiBaseUrl: string;
440
+ /** Resolved client-side host override. */
441
+ apiBaseClientHost?: string;
442
+ /** Resolved server-side host override. */
443
+ apiBaseServerHost?: string;
444
+ /** Resolved custom regex matcher (RegExp is serialized to its `.source` string). */
445
+ customRegexMatcher?: string | RegExp;
446
+ /** Resolved route-to-route translation sharing map. */
447
+ routesLocaleLinks?: {
448
+ [key: string]: string;
449
+ };
450
+ }
451
+ /** Object shape for a translation value that contains singular/plural forms. */
452
+ export interface PluralTranslations {
453
+ /** Singular form of the translation (count === 1). */
454
+ singular: string;
455
+ /** Plural form of the translation (count !== 1). */
456
+ plural: string;
457
+ }
458
+ /** A translation value without the `unknown` escape hatch. */
459
+ export type CleanTranslation = string | number | boolean | Translations | PluralTranslations | null;
460
+ /** A single translation value — can be a primitive, nested object, plural pair, or `unknown`. */
461
+ export type Translation = CleanTranslation | unknown;
462
+ /** A flat or nested dictionary of translation key-value pairs. */
463
+ export interface Translations {
464
+ [key: string]: Translation;
465
+ }
466
+ declare const init: () => void;
467
+ export { init };
package/dist/index.d.ts CHANGED
@@ -63,6 +63,13 @@ export interface Locale {
63
63
  * If omitted or empty, `iso` is used (then `code`).
64
64
  */
65
65
  og?: string;
66
+ /**
67
+ * When `false`, this locale is omitted from cross-locale SEO tags (`hreflang`,
68
+ * `og:locale:alternate`). If the configured default locale has `seo: false`, the
69
+ * `x-default` hreflang link is not emitted. Routing and translations are unchanged.
70
+ * @default true when omitted.
71
+ */
72
+ seo?: boolean;
66
73
  /** Text direction. Reflected in `<html dir>` when the locale is active. */
67
74
  dir?: 'ltr' | 'rtl' | 'auto';
68
75
  /** Human-readable name shown in language switchers (e.g. `'English'`, `'Deutsch'`). */
package/package.json CHANGED
@@ -1,31 +1,64 @@
1
1
  {
2
2
  "name": "@i18n-micro/types",
3
- "version": "1.2.0",
4
- "description": "",
5
- "repository": "s00d/nuxt-i18n-micro",
3
+ "version": "1.2.2",
4
+ "description": "TypeScript definitions for the Nuxt I18n Micro ecosystem.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/s00d/nuxt-i18n-micro.git",
8
+ "directory": "packages/types"
9
+ },
6
10
  "license": "MIT",
7
11
  "type": "module",
12
+ "sideEffects": false,
8
13
  "author": {
9
14
  "name": "s00d",
10
15
  "email": "Virus191288@gmail.com",
11
16
  "url": "https://s00d.github.io/"
12
17
  },
13
- "homepage": "https://github.com/s00d/nuxt-i18n-micro",
18
+ "homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/types#readme",
14
19
  "bugs": {
15
20
  "url": "https://github.com/s00d/nuxt-i18n-micro/issues"
16
21
  },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
17
25
  "main": "dist/index.cjs",
18
- "module": "dist/index.mjs",
19
26
  "types": "dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "import": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.mjs"
32
+ },
33
+ "require": {
34
+ "types": "./dist/index.d.cts",
35
+ "default": "./dist/index.cjs"
36
+ },
37
+ "default": "./dist/index.mjs"
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
20
46
  "publishConfig": {
21
47
  "access": "public"
22
48
  },
23
- "keywords": [],
49
+ "keywords": [
50
+ "nuxt",
51
+ "i18n",
52
+ "typescript",
53
+ "types"
54
+ ],
24
55
  "devDependencies": {
56
+ "publint": "^0.3.17",
57
+ "vite": "^7.3.1",
25
58
  "vite-plugin-dts": "^4.5.4"
26
59
  },
27
60
  "scripts": {
28
61
  "build": "vite build",
29
- "test": "echo \"Error: no test specified\""
62
+ "check:package": "publint"
30
63
  }
31
64
  }
package/fix.ts DELETED
@@ -1 +0,0 @@
1
- import '@types/jest'
package/jest.config.cjs DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- roots: ['<rootDir>/tests'],
3
- testMatch: ['**/?(*.)+(spec|test).[tj]s?(x)'],
4
- transform: {
5
- '^.+\\.ts$': 'ts-jest',
6
- },
7
- }
package/src/index.ts DELETED
@@ -1,517 +0,0 @@
1
- /** BCP-47 locale code string (e.g. `'en'`, `'de-DE'`, `'zh-Hans'`). */
2
- export type LocaleCode = string
3
-
4
- /**
5
- * Key registry for typed translation keys.
6
- * Users (via `@i18n-micro/types-generator`) extend this interface through
7
- * TypeScript module augmentation to get autocompletion for `$t()` calls.
8
- */
9
- export interface DefineLocaleMessage {
10
- // Module augmentation point - will be extended by @i18n-micro/types-generator
11
- readonly __augmentation?: never
12
- }
13
-
14
- /**
15
- * Resolved translation key type.
16
- * - When `DefineLocaleMessage` is empty (generator not connected) — resolves to `string`.
17
- * - When `DefineLocaleMessage` has keys — resolves to a union of those keys **and** `string`,
18
- * providing autocompletion while still allowing dynamic keys.
19
- */
20
- export type TranslationKey = keyof DefineLocaleMessage extends never ? string : keyof DefineLocaleMessage | string
21
-
22
- /**
23
- * Helper for creating typed prefixes.
24
- * Allows safe usage of dynamic keys.
25
- *
26
- * @example
27
- * ```typescript
28
- * // Assuming keys: 'errors.404', 'errors.500', 'btn.save'
29
- * function getErrorText(code: string) {
30
- * return t(`errors.${code}` as ScopedKey<'errors'>)
31
- * }
32
- * ```
33
- */
34
- export type ScopedKey<Scope extends string> = Extract<TranslationKey, `${Scope}.${string}`>
35
-
36
- /**
37
- * Locale configuration object.
38
- *
39
- * Supports arbitrary custom properties via the index signature `[key: string]: unknown`.
40
- * To get full TypeScript support for your custom properties, use module augmentation:
41
- *
42
- * ```typescript
43
- * // app/i18n.d.ts (or any .d.ts file included in your tsconfig)
44
- * declare module '@i18n-micro/types' {
45
- * interface Locale {
46
- * flag?: string
47
- * currency?: string
48
- * }
49
- * }
50
- * ```
51
- *
52
- * Then access them with full typing:
53
- * ```typescript
54
- * const locales = $getLocales()
55
- * locales[0].flag // string | undefined (typed!)
56
- * locales[0].currency // string | undefined (typed!)
57
- * ```
58
- */
59
- export interface Locale {
60
- /** BCP-47 locale code (e.g. `'en'`, `'de-DE'`, `'zh-Hans'`). Used in URLs and as file/key identifier. */
61
- code: LocaleCode
62
- /** When `true`, this locale is excluded from route generation and language switching. */
63
- disabled?: boolean
64
- /** ISO 639-1 / BCP-47 tag for `<html lang>` and `hreflang` SEO attributes (e.g. `'en-US'`). */
65
- iso?: string
66
- /**
67
- * Open Graph locale for `og:locale` / `og:locale:alternate` meta `content` (e.g. `ar_AE`).
68
- * If omitted or empty, `iso` is used (then `code`).
69
- */
70
- og?: string
71
- /** Text direction. Reflected in `<html dir>` when the locale is active. */
72
- dir?: 'ltr' | 'rtl' | 'auto'
73
- /** Human-readable name shown in language switchers (e.g. `'English'`, `'Deutsch'`). */
74
- displayName?: string
75
- /**
76
- * Per-locale base URL for SEO meta tags.
77
- * Useful for multi-domain setups where each locale lives on its own domain
78
- * (e.g. `'https://en.example.com'`).
79
- */
80
- baseUrl?: string
81
- /**
82
- * When `true`, this locale is treated as the "base default" for the domain
83
- * specified in `baseUrl`. Affects canonical URL generation in multi-domain setups.
84
- */
85
- baseDefault?: boolean
86
- /**
87
- * Locale code to fall back to when a translation key is missing in this locale.
88
- * Overrides the global `fallbackLocale` for this specific locale.
89
- */
90
- fallbackLocale?: string
91
- /** Allows arbitrary extra properties for user-defined locale metadata. */
92
- [key: string]: unknown
93
- }
94
-
95
- /**
96
- * Per-page i18n configuration declared via `defineI18nRoute()` in page components.
97
- */
98
- export interface DefineI18nRouteConfig {
99
- /**
100
- * Restrict which locales this page is available in.
101
- * - `string[]` — list of allowed locale codes.
102
- * - `Record<LocaleCode, Translations>` — allowed locales with inline translation overrides.
103
- */
104
- locales?: string[] | Record<LocaleCode, Translations>
105
- /** Per-locale custom route paths (e.g. `{ en: '/about', de: '/ueber-uns' }`). */
106
- localeRoutes?: Record<LocaleCode, string>
107
- /**
108
- * Disable SEO meta tag generation for this page.
109
- * - `true` — disable all meta tags.
110
- * - `string[]` — disable only for the listed locale codes.
111
- */
112
- disableMeta?: boolean | string[]
113
- }
114
-
115
- /** Locale-specific route params for `$switchLocalePath` and `<i18n-link>`. */
116
- export type I18nRouteParams = Record<LocaleCode, Record<string, string>> | null
117
-
118
- /** Interpolation parameters passed to the `t()` function. */
119
- export type Params = Record<string, string | number | boolean>
120
-
121
- /** Getter function signature used by pluralization to resolve nested keys. */
122
- export type Getter = (key: TranslationKey, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown
123
-
124
- /**
125
- * Custom pluralization function.
126
- * Called when `tc()` / `$tc()` is used. Receives the key, count, params, locale,
127
- * and a getter to fetch the singular/plural forms from translations.
128
- */
129
- export type PluralFunc = (key: TranslationKey, count: number, params: Params, locale: string, getter: Getter) => string | null
130
-
131
- /**
132
- * Global per-route locale configuration.
133
- * - `Record<string, string>` — custom paths per locale for the route.
134
- * - `false` — exclude the route from localization entirely.
135
- * - `true` — include with default behavior.
136
- */
137
- export type GlobalLocaleRoutes = Record<string, Record<LocaleCode, string> | false | boolean> | null | undefined
138
-
139
- /** URL routing strategy for locale handling. */
140
- export type Strategies = 'no_prefix' | 'prefix_except_default' | 'prefix' | 'prefix_and_default'
141
-
142
- /**
143
- * Callback invoked when a translation key is missing.
144
- * Useful for logging, reporting, or providing dynamic fallbacks.
145
- */
146
- export type MissingHandler = (locale: string, key: TranslationKey, routeName: string, instance?: unknown, type?: string) => void
147
-
148
- export interface ModuleOptions {
149
- /**
150
- * List of supported locales.
151
- * Each entry defines a locale code plus optional metadata (ISO, direction, display name, etc.).
152
- * @default []
153
- */
154
- locales?: Locale[]
155
-
156
- /**
157
- * Generate SEO meta tags (`hreflang`, `canonical`, `og:url`, `og:locale`) automatically.
158
- * @default true
159
- */
160
- meta?: boolean
161
-
162
- /**
163
- * URL routing strategy for locale prefixes.
164
- * - `'no_prefix'` — no locale in URL; locale stored in cookie.
165
- * - `'prefix_except_default'` — prefix all locales except the default.
166
- * - `'prefix'` — always prefix, including the default locale.
167
- * - `'prefix_and_default'` — like `prefix`, but the default locale is also accessible without prefix.
168
- * @default 'prefix_except_default'
169
- */
170
- strategy?: Strategies
171
-
172
- /**
173
- * Base URL for SEO meta tags (canonical, og:url, hreflang).
174
- * - `undefined` — dynamically resolved from the current request URL
175
- * (`useRequestURL().origin` on server, `window.location.origin` on client).
176
- * Best for multi-domain deployments.
177
- * - A concrete URL string (e.g. `'https://example.com'`) — used as-is.
178
- * @default undefined
179
- */
180
- metaBaseUrl?: string
181
-
182
- /**
183
- * Trust the `X-Forwarded-Host` header when resolving the base URL for meta tags.
184
- * Enable when the app runs behind a reverse proxy (nginx, Cloudflare, AWS ALB, etc.)
185
- * that sets this header to the real client-facing hostname.
186
- * @default true
187
- */
188
- metaTrustForwardedHost?: boolean
189
-
190
- /**
191
- * Trust the `X-Forwarded-Proto` header when resolving the protocol for meta tags.
192
- * Enable when the app runs behind a TLS-terminating proxy so that
193
- * canonical URLs use `https://` even though the app itself listens on HTTP.
194
- * @default true
195
- */
196
- metaTrustForwardedProto?: boolean
197
-
198
- /**
199
- * Register the `defineI18nRoute()` macro plugin, enabling per-page `defineI18nRoute()` calls.
200
- * @default true
201
- */
202
- define?: boolean
203
-
204
- /**
205
- * Enable automatic locale-based redirects.
206
- * When `true`, visitors are redirected to their preferred locale (detected from cookie,
207
- * `Accept-Language` header, or the default) on the first visit.
208
- * @default true
209
- */
210
- redirects?: boolean
211
-
212
- /**
213
- * Register the core i18n plugin that provides `$t()`, `$tc()`, `$getLocale()`,
214
- * `$switchLocale()`, and other runtime helpers.
215
- * @default true
216
- */
217
- plugin?: boolean
218
-
219
- /**
220
- * Register the i18n hooks plugin that provides `i18n:register` and `i18n:beforeLocaleSwitch`
221
- * / `i18n:afterLocaleSwitch` app-level hooks.
222
- * @default true
223
- */
224
- hooks?: boolean
225
-
226
- /**
227
- * Register built-in i18n components (`<i18n-link>`, `<i18n-switcher>`, `<i18n-t>`, `<i18n-group>`).
228
- * Set to `false` to disable automatic component registration (e.g. if you don't use them
229
- * and want to reduce the module footprint).
230
- * @default true
231
- */
232
- components?: boolean
233
-
234
- /**
235
- * The locale to use when no locale can be determined from URL or user preferences.
236
- * Also used as the fallback locale for missing translations when `fallbackLocale` is not set.
237
- * @default 'en'
238
- */
239
- defaultLocale?: string
240
-
241
- /**
242
- * Base URL path segment for the translations API route (used in SSR/SSG data fetching).
243
- * Can also be set via `NUXT_I18N_APP_BASE_URL` environment variable.
244
- * @default '_locales'
245
- */
246
- apiBaseUrl?: string
247
-
248
- /**
249
- * Override the host used for client-side translation fetch requests.
250
- * Useful when the client reaches the server via a different hostname than the one Nuxt sees.
251
- * Can also be set via `NUXT_I18N_APP_BASE_CLIENT_HOST` environment variable.
252
- * @default undefined
253
- */
254
- apiBaseClientHost?: string
255
-
256
- /**
257
- * Override the host used for server-side translation fetch requests.
258
- * Useful in container/microservice setups where the server reaches itself via an internal hostname.
259
- * Can also be set via `NUXT_I18N_APP_BASE_SERVER_HOST` environment variable.
260
- * @default undefined
261
- */
262
- apiBaseServerHost?: string
263
-
264
- /**
265
- * Path to the directory containing translation JSON files, relative to the project root.
266
- * @default 'locales'
267
- */
268
- translationDir?: string
269
-
270
- /**
271
- * Automatically detect the user's preferred language from the `Accept-Language` HTTP header.
272
- * Used in combination with `autoDetectPath` to decide when detection occurs.
273
- * @default true
274
- */
275
- autoDetectLanguage?: boolean
276
-
277
- /**
278
- * URL path on which automatic language detection and redirect occur.
279
- * - `'/'` — detect only on the root path.
280
- * - `'*'` — detect and redirect on every path (including locale-prefixed ones).
281
- * @default '/'
282
- */
283
- autoDetectPath?: string
284
-
285
- /**
286
- * Disable the file watcher that auto-creates missing translation files in development mode.
287
- * @default false
288
- */
289
- disableWatcher?: boolean
290
-
291
- /**
292
- * Generate TypeScript type declarations for `useI18n`, `$t`, and related helpers
293
- * based on the translation keys in your default locale files.
294
- * @default true
295
- */
296
- types?: boolean
297
-
298
- /**
299
- * Map route names to other route names to share the same translation files.
300
- * For example, `{ 'about-us': 'about' }` means the `about-us` page will use
301
- * translations from the `about` page instead of its own.
302
- * @default {}
303
- */
304
- routesLocaleLinks?: { [key: string]: string }
305
-
306
- /**
307
- * Custom pluralization function or a path to a file exporting one.
308
- * When a string path is provided, the file is imported at build time.
309
- * The function receives `(key, count, params, locale, getter)` and should return
310
- * the correct plural form as a string, or `null` to fall back to the built-in logic.
311
- * @default built-in pluralization (singular/plural by count)
312
- */
313
- plural?: string | PluralFunc
314
-
315
- /**
316
- * Disable per-page translation files.
317
- * When `true`, only global translations (`{locale}.json`) are loaded;
318
- * page-specific files (`pages/{page}/{locale}.json`) are not generated or loaded.
319
- * @default false
320
- */
321
- disablePageLocales?: boolean
322
-
323
- /**
324
- * Global fallback locale code.
325
- * When a translation key is missing in the active locale, the module looks it up
326
- * in this locale before returning the key itself.
327
- * @default undefined (no fallback; returns the raw key)
328
- */
329
- fallbackLocale?: string
330
-
331
- /**
332
- * Cookie name for persisting the user's locale preference across sessions.
333
- * Set to `null` to disable cookie-based persistence.
334
- * Automatically set to `'user-locale'` for the `no_prefix` strategy if not provided.
335
- * @default null
336
- */
337
- localeCookie?: string | null
338
-
339
- /**
340
- * Enable verbose debug logging for locale detection, route generation, and translation loading.
341
- * @default false
342
- */
343
- debug?: boolean
344
-
345
- /**
346
- * Global route-level locale configuration.
347
- * Allows restricting or customizing locale routes for specific pages without
348
- * modifying their components.
349
- * - `false` — exclude the route from localization.
350
- * - `Record<LocaleCode, string>` — custom per-locale paths.
351
- * @default {}
352
- */
353
- globalLocaleRoutes?: GlobalLocaleRoutes
354
-
355
- /**
356
- * Custom regular expression (or its string source) for matching locale codes in URL segments.
357
- * All locale codes defined in `locales` must match this pattern, or a warning is emitted.
358
- * @default undefined (uses built-in pattern based on locale codes)
359
- */
360
- customRegexMatcher?: string | RegExp
361
-
362
- /**
363
- * For `no_prefix` strategy: enable redirect from a locale-prefixed URL
364
- * (e.g. `/en/about`) to the unprefixed version (`/about`).
365
- * @default false
366
- */
367
- noPrefixRedirect?: boolean
368
-
369
- /**
370
- * List of query parameter names preserved in canonical and `og:url` meta tags.
371
- * Parameters not in this list are stripped from the canonical URL.
372
- * @default ['page', 'sort', 'filter', 'search', 'q', 'query', 'tag']
373
- */
374
- canonicalQueryWhitelist?: string[]
375
-
376
- /**
377
- * URL patterns (strings or RegExp) to exclude from i18n processing entirely.
378
- * Matching routes won't get locale prefixes, redirects, or translation loading.
379
- * Internal Nuxt paths (`/__nuxt_error`, etc.) are always excluded automatically.
380
- * @default undefined
381
- */
382
- excludePatterns?: (string | RegExp)[]
383
-
384
- /**
385
- * Prefix prepended to localized route names (e.g. `'localized-index'`).
386
- * Used internally to distinguish original routes from generated locale variants.
387
- * @default 'localized-'
388
- */
389
- localizedRouteNamePrefix?: string
390
-
391
- /**
392
- * Per-route locale restrictions, extracted from `defineI18nRoute()` calls.
393
- * Maps a route path (e.g. `'/about'`) to an array of allowed locale codes.
394
- * Routes not listed have no restrictions (all locales allowed).
395
- */
396
- routeLocales?: Record<string, string[]>
397
-
398
- /**
399
- * Per-route meta tag disabling, extracted from `defineI18nRoute()` calls.
400
- * Maps a route path to `true` (disable all meta) or an array of locale codes
401
- * for which meta should be disabled.
402
- */
403
- routeDisableMeta?: Record<string, boolean | string[]>
404
-
405
- /**
406
- * Show console warnings when a translation key is missing.
407
- * @default true
408
- */
409
- missingWarn?: boolean
410
-
411
- /**
412
- * Enable Hot Module Replacement for translation files in development.
413
- * When `true`, changes to JSON translation files trigger an automatic reload
414
- * without a full page refresh.
415
- * @default true
416
- */
417
- hmr?: boolean
418
-
419
- /**
420
- * Maximum number of entries in the in-memory translation cache.
421
- * `0` means no limit.
422
- * @default 0
423
- */
424
- cacheMaxSize?: number
425
-
426
- /**
427
- * Time-to-live (in seconds) for cached translation entries.
428
- * `0` means entries never expire.
429
- * @default 0
430
- */
431
- cacheTtl?: number
432
-
433
- /**
434
- * Value used for cache-busting translation requests (`?v=...`).
435
- *
436
- * When not provided, the module falls back to `Date.now()` (non-deterministic).
437
- * For reproducible/rolling deployments, set this to a stable value
438
- * (e.g. a git SHA or build number).
439
- *
440
- * @example
441
- * i18n: { dateBuild: 'e3b0c442' }
442
- */
443
- dateBuild?: string | number
444
-
445
- /**
446
- * Bucket for experimental/unstable options.
447
- * Contents may change or be removed without notice between minor versions.
448
- */
449
- experimental?: Record<string, unknown>
450
- }
451
-
452
- /**
453
- * Extended module options injected into the Nuxt runtime config.
454
- * Includes resolved values and build-time metadata.
455
- */
456
- export interface ModuleOptionsExtend extends ModuleOptions {
457
- /** Value used for cache-busting translation requests (`?v=...`). */
458
- dateBuild: string | number
459
- /** Whether the Nuxt app uses hash-based routing (`router.options.hashMode`). */
460
- hashMode: boolean
461
- /** Whether the current build is a static site generation (SSG / `nuxi generate`). */
462
- isSSG: boolean
463
- /** Resolved translations API base URL (after env variable / config merging). */
464
- apiBaseUrl: string
465
- /** Resolved flag: whether per-page translations are disabled. */
466
- disablePageLocales: boolean
467
- /** Resolved flag: whether locale-based redirects are enabled. */
468
- redirects?: boolean
469
- }
470
-
471
- /**
472
- * Private (server-only) module options passed to Nitro plugins and server middleware.
473
- * Extends `ModuleOptions` with resolved root paths and directory info.
474
- */
475
- export interface ModulePrivateOptionsExtend extends ModuleOptions {
476
- /** Absolute path to the Nuxt project root directory. */
477
- rootDir: string
478
- /** Resolved debug flag. */
479
- debug: boolean
480
- /** Resolved path to the translations directory. */
481
- translationDir: string
482
- /** Resolved fallback locale code. */
483
- fallbackLocale: string
484
- /** Resolved translations API base URL. */
485
- apiBaseUrl: string
486
- /** Resolved client-side host override. */
487
- apiBaseClientHost?: string
488
- /** Resolved server-side host override. */
489
- apiBaseServerHost?: string
490
- /** Resolved custom regex matcher (RegExp is serialized to its `.source` string). */
491
- customRegexMatcher?: string | RegExp
492
- /** Resolved route-to-route translation sharing map. */
493
- routesLocaleLinks?: { [key: string]: string }
494
- }
495
-
496
- /** Object shape for a translation value that contains singular/plural forms. */
497
- export interface PluralTranslations {
498
- /** Singular form of the translation (count === 1). */
499
- singular: string
500
- /** Plural form of the translation (count !== 1). */
501
- plural: string
502
- }
503
-
504
- /** A translation value without the `unknown` escape hatch. */
505
- export type CleanTranslation = string | number | boolean | Translations | PluralTranslations | null
506
-
507
- /** A single translation value — can be a primitive, nested object, plural pair, or `unknown`. */
508
- export type Translation = CleanTranslation | unknown
509
-
510
- /** A flat or nested dictionary of translation key-value pairs. */
511
- export interface Translations {
512
- [key: string]: Translation
513
- }
514
-
515
- const init = () => {}
516
-
517
- export { init }
package/tsconfig.json DELETED
@@ -1,24 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2018",
4
- "module": "esnext",
5
- "moduleResolution": "node",
6
-
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "outDir": "./dist",
12
- "declaration": true,
13
- "declarationDir": "./dist",
14
- "sourceMap": true,
15
- "rootDir": "./src",
16
- "baseUrl": "./",
17
- "paths": {
18
- "*": ["node_modules/*", "src/types/*"]
19
- },
20
- "types": ["jest", "node"]
21
- },
22
- "include": ["src/**/*"],
23
- "exclude": ["node_modules", "dist", "tests"]
24
- }
package/vite.config.mts DELETED
@@ -1,22 +0,0 @@
1
- // @ts-nocheck
2
- import { resolve } from 'node:path'
3
- import { defineConfig } from 'vite'
4
- import dts from 'vite-plugin-dts'
5
-
6
- export default defineConfig({
7
- build: {
8
- lib: {
9
- entry: resolve(__dirname, 'src/index.ts'),
10
- name: '@i18n-micro/core',
11
- formats: ['cjs', 'es'],
12
- fileName: (format) => `index.${format === 'cjs' ? 'cjs' : 'mjs'}`,
13
- },
14
- rollupOptions: {
15
- external: ['vue'],
16
- output: {
17
- exports: 'named',
18
- },
19
- },
20
- },
21
- plugins: [dts()],
22
- })