@comvi/next 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.
- package/LICENSE +21 -0
- package/README.md +256 -0
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/client/I18nProvider.cjs +101 -0
- package/dist/client/I18nProvider.d.ts +84 -0
- package/dist/client/I18nProvider.d.ts.map +1 -0
- package/dist/client/I18nProvider.js +99 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client.cjs +31 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +5 -0
- package/dist/createNextI18n.cjs +153 -0
- package/dist/createNextI18n.d.ts +183 -0
- package/dist/createNextI18n.d.ts.map +1 -0
- package/dist/createNextI18n.js +152 -0
- package/dist/index.cjs +17 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/middleware/createMiddleware.cjs +185 -0
- package/dist/middleware/createMiddleware.d.ts +38 -0
- package/dist/middleware/createMiddleware.d.ts.map +1 -0
- package/dist/middleware/createMiddleware.js +184 -0
- package/dist/middleware/types.d.ts +87 -0
- package/dist/middleware/types.d.ts.map +1 -0
- package/dist/middleware.cjs +3 -0
- package/dist/middleware.d.ts +3 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +2 -0
- package/dist/navigation.cjs +8 -0
- package/dist/navigation.d.ts +5 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +5 -0
- package/dist/routing/Link.cjs +42 -0
- package/dist/routing/Link.d.ts +25 -0
- package/dist/routing/Link.d.ts.map +1 -0
- package/dist/routing/Link.js +39 -0
- package/dist/routing/context.cjs +21 -0
- package/dist/routing/context.d.ts +9 -0
- package/dist/routing/context.d.ts.map +1 -0
- package/dist/routing/context.js +18 -0
- package/dist/routing/defineRouting.cjs +141 -0
- package/dist/routing/defineRouting.d.ts +123 -0
- package/dist/routing/defineRouting.d.ts.map +1 -0
- package/dist/routing/defineRouting.js +139 -0
- package/dist/routing/hooks.cjs +104 -0
- package/dist/routing/hooks.d.ts +66 -0
- package/dist/routing/hooks.d.ts.map +1 -0
- package/dist/routing/hooks.js +102 -0
- package/dist/routing/types.d.ts +35 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/utils.cjs +94 -0
- package/dist/routing/utils.d.ts +8 -0
- package/dist/routing/utils.d.ts.map +1 -0
- package/dist/routing/utils.js +91 -0
- package/dist/routing.cjs +5 -0
- package/dist/routing.d.ts +4 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +2 -0
- package/dist/server/cache.cjs +69 -0
- package/dist/server/cache.d.ts +42 -0
- package/dist/server/cache.d.ts.map +1 -0
- package/dist/server/cache.js +66 -0
- package/dist/server/ensureInitialized.cjs +19 -0
- package/dist/server/ensureInitialized.d.ts +7 -0
- package/dist/server/ensureInitialized.d.ts.map +1 -0
- package/dist/server/ensureInitialized.js +19 -0
- package/dist/server/getI18n.cjs +115 -0
- package/dist/server/getI18n.d.ts +61 -0
- package/dist/server/getI18n.d.ts.map +1 -0
- package/dist/server/getI18n.js +114 -0
- package/dist/server/getLocale.cjs +37 -0
- package/dist/server/getLocale.d.ts +22 -0
- package/dist/server/getLocale.d.ts.map +1 -0
- package/dist/server/getLocale.js +36 -0
- package/dist/server/loadTranslations.cjs +54 -0
- package/dist/server/loadTranslations.d.ts +34 -0
- package/dist/server/loadTranslations.d.ts.map +1 -0
- package/dist/server/loadTranslations.js +54 -0
- package/dist/server/setRequestLocale.cjs +31 -0
- package/dist/server/setRequestLocale.d.ts +26 -0
- package/dist/server/setRequestLocale.d.ts.map +1 -0
- package/dist/server/setRequestLocale.js +31 -0
- package/dist/server/types.d.ts +43 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server.cjs +11 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +6 -0
- package/package.json +111 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_cache = require("./cache.cjs");
|
|
3
|
+
const require_ensureInitialized = require("./ensureInitialized.cjs");
|
|
4
|
+
const require_getLocale = require("./getLocale.cjs");
|
|
5
|
+
const require_loadTranslations = require("./loadTranslations.cjs");
|
|
6
|
+
let _comvi_core = require("@comvi/core");
|
|
7
|
+
//#region src/server/getI18n.ts
|
|
8
|
+
var virtualNodeToText = (node) => {
|
|
9
|
+
if (node.type === "text") return node.text;
|
|
10
|
+
let text = "";
|
|
11
|
+
for (const child of node.children) {
|
|
12
|
+
if (typeof child === "string") {
|
|
13
|
+
text += child;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
text += virtualNodeToText(child);
|
|
17
|
+
}
|
|
18
|
+
return text;
|
|
19
|
+
};
|
|
20
|
+
var translationResultToString = (result) => {
|
|
21
|
+
if (typeof result === "string") return result;
|
|
22
|
+
let text = "";
|
|
23
|
+
for (const part of result) text += typeof part === "string" ? part : virtualNodeToText(part);
|
|
24
|
+
return text;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Get i18n for use in Server Components, Server Actions, and Route Handlers
|
|
28
|
+
*
|
|
29
|
+
* This function uses the global i18n instance (configured via setI18n) and
|
|
30
|
+
* automatically reads the locale from the request context (set by setRequestLocale
|
|
31
|
+
* or middleware).
|
|
32
|
+
*
|
|
33
|
+
* @param options - Options object with locale and namespace
|
|
34
|
+
* @returns Object with t() function and hasTranslation() helper
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // Server Component - using keys from default namespace
|
|
39
|
+
* import { getI18n } from '@comvi/next/server';
|
|
40
|
+
*
|
|
41
|
+
* export default async function HomePage() {
|
|
42
|
+
* const { t } = await getI18n();
|
|
43
|
+
* return (
|
|
44
|
+
* <div>
|
|
45
|
+
* <h1>{t('home.title')}</h1>
|
|
46
|
+
* <p>{t('common.description')}</p>
|
|
47
|
+
* </div>
|
|
48
|
+
* );
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* // Using a different namespace
|
|
55
|
+
* const { t } = await getI18n();
|
|
56
|
+
* // Access admin namespace translations
|
|
57
|
+
* t('title', { ns: 'admin' }) // → "Admin Dashboard"
|
|
58
|
+
* t('roles.admin', { ns: 'admin' }) // → "Administrator"
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* // With explicit locale (for generateMetadata)
|
|
64
|
+
* export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
|
|
65
|
+
* const { locale } = await params;
|
|
66
|
+
* const { t } = await getI18n({ locale });
|
|
67
|
+
* return { title: t('common.title') };
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```tsx
|
|
73
|
+
* // Check if translation exists (with namespace support)
|
|
74
|
+
* const { t, hasTranslation } = await getI18n();
|
|
75
|
+
* hasTranslation('common.title') // true (default namespace)
|
|
76
|
+
* hasTranslation('title', { ns: 'admin' }) // true (admin namespace)
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* getI18n auto-loads only the default namespace (or the namespace passed via
|
|
81
|
+
* getI18n({ ns })). If you call t() with a different ns, ensure you preloaded it
|
|
82
|
+
* via loadTranslations(locale, { namespaces: [...] }) in your layout or metadata.
|
|
83
|
+
*/
|
|
84
|
+
async function getI18n(options) {
|
|
85
|
+
const i18n = require_cache.getI18nInstance();
|
|
86
|
+
await require_ensureInitialized.ensureInitialized(i18n);
|
|
87
|
+
let locale = options?.locale;
|
|
88
|
+
if (!locale) try {
|
|
89
|
+
locale = await require_getLocale.getLocale();
|
|
90
|
+
} catch (e) {
|
|
91
|
+
const err = /* @__PURE__ */ new Error("[comvi/next] Locale not set. Call setRequestLocale(locale) in your layout/page first, or configure middleware.");
|
|
92
|
+
err.cause = e;
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
const defaultNs = options?.ns ?? i18n.getDefaultNamespace();
|
|
96
|
+
if (!i18n.hasLocale(locale, defaultNs)) await require_loadTranslations.loadTranslations(locale, { namespaces: [defaultNs] });
|
|
97
|
+
const translate = (0, _comvi_core.createBoundTranslation)(i18n, defaultNs);
|
|
98
|
+
const t = ((key, params) => {
|
|
99
|
+
return translationResultToString(translate(key, {
|
|
100
|
+
...params,
|
|
101
|
+
locale
|
|
102
|
+
}));
|
|
103
|
+
});
|
|
104
|
+
const hasTranslation = (key, opts) => {
|
|
105
|
+
const checkLocale = opts?.locale ?? locale;
|
|
106
|
+
const checkNs = opts?.ns ?? defaultNs;
|
|
107
|
+
return i18n.hasTranslation(key, checkLocale, checkNs);
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
t,
|
|
111
|
+
hasTranslation
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
exports.getI18n = getI18n;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { GetI18nOptions, ServerI18n } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Get i18n for use in Server Components, Server Actions, and Route Handlers
|
|
4
|
+
*
|
|
5
|
+
* This function uses the global i18n instance (configured via setI18n) and
|
|
6
|
+
* automatically reads the locale from the request context (set by setRequestLocale
|
|
7
|
+
* or middleware).
|
|
8
|
+
*
|
|
9
|
+
* @param options - Options object with locale and namespace
|
|
10
|
+
* @returns Object with t() function and hasTranslation() helper
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // Server Component - using keys from default namespace
|
|
15
|
+
* import { getI18n } from '@comvi/next/server';
|
|
16
|
+
*
|
|
17
|
+
* export default async function HomePage() {
|
|
18
|
+
* const { t } = await getI18n();
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* <h1>{t('home.title')}</h1>
|
|
22
|
+
* <p>{t('common.description')}</p>
|
|
23
|
+
* </div>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* // Using a different namespace
|
|
31
|
+
* const { t } = await getI18n();
|
|
32
|
+
* // Access admin namespace translations
|
|
33
|
+
* t('title', { ns: 'admin' }) // → "Admin Dashboard"
|
|
34
|
+
* t('roles.admin', { ns: 'admin' }) // → "Administrator"
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* // With explicit locale (for generateMetadata)
|
|
40
|
+
* export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
|
|
41
|
+
* const { locale } = await params;
|
|
42
|
+
* const { t } = await getI18n({ locale });
|
|
43
|
+
* return { title: t('common.title') };
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* // Check if translation exists (with namespace support)
|
|
50
|
+
* const { t, hasTranslation } = await getI18n();
|
|
51
|
+
* hasTranslation('common.title') // true (default namespace)
|
|
52
|
+
* hasTranslation('title', { ns: 'admin' }) // true (admin namespace)
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @remarks
|
|
56
|
+
* getI18n auto-loads only the default namespace (or the namespace passed via
|
|
57
|
+
* getI18n({ ns })). If you call t() with a different ns, ensure you preloaded it
|
|
58
|
+
* via loadTranslations(locale, { namespaces: [...] }) in your layout or metadata.
|
|
59
|
+
*/
|
|
60
|
+
export declare function getI18n(options?: GetI18nOptions): Promise<ServerI18n>;
|
|
61
|
+
//# sourceMappingURL=getI18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getI18n.d.ts","sourceRoot":"","sources":["../../src/server/getI18n.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EAGX,MAAM,SAAS,CAAC;AA8BjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,wBAAsB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAiD3E"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { getI18nInstance } from "./cache.js";
|
|
2
|
+
import { ensureInitialized } from "./ensureInitialized.js";
|
|
3
|
+
import { getLocale } from "./getLocale.js";
|
|
4
|
+
import { loadTranslations } from "./loadTranslations.js";
|
|
5
|
+
import { createBoundTranslation } from "@comvi/core";
|
|
6
|
+
//#region src/server/getI18n.ts
|
|
7
|
+
var virtualNodeToText = (node) => {
|
|
8
|
+
if (node.type === "text") return node.text;
|
|
9
|
+
let text = "";
|
|
10
|
+
for (const child of node.children) {
|
|
11
|
+
if (typeof child === "string") {
|
|
12
|
+
text += child;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
text += virtualNodeToText(child);
|
|
16
|
+
}
|
|
17
|
+
return text;
|
|
18
|
+
};
|
|
19
|
+
var translationResultToString = (result) => {
|
|
20
|
+
if (typeof result === "string") return result;
|
|
21
|
+
let text = "";
|
|
22
|
+
for (const part of result) text += typeof part === "string" ? part : virtualNodeToText(part);
|
|
23
|
+
return text;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Get i18n for use in Server Components, Server Actions, and Route Handlers
|
|
27
|
+
*
|
|
28
|
+
* This function uses the global i18n instance (configured via setI18n) and
|
|
29
|
+
* automatically reads the locale from the request context (set by setRequestLocale
|
|
30
|
+
* or middleware).
|
|
31
|
+
*
|
|
32
|
+
* @param options - Options object with locale and namespace
|
|
33
|
+
* @returns Object with t() function and hasTranslation() helper
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // Server Component - using keys from default namespace
|
|
38
|
+
* import { getI18n } from '@comvi/next/server';
|
|
39
|
+
*
|
|
40
|
+
* export default async function HomePage() {
|
|
41
|
+
* const { t } = await getI18n();
|
|
42
|
+
* return (
|
|
43
|
+
* <div>
|
|
44
|
+
* <h1>{t('home.title')}</h1>
|
|
45
|
+
* <p>{t('common.description')}</p>
|
|
46
|
+
* </div>
|
|
47
|
+
* );
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* // Using a different namespace
|
|
54
|
+
* const { t } = await getI18n();
|
|
55
|
+
* // Access admin namespace translations
|
|
56
|
+
* t('title', { ns: 'admin' }) // → "Admin Dashboard"
|
|
57
|
+
* t('roles.admin', { ns: 'admin' }) // → "Administrator"
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* // With explicit locale (for generateMetadata)
|
|
63
|
+
* export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
|
|
64
|
+
* const { locale } = await params;
|
|
65
|
+
* const { t } = await getI18n({ locale });
|
|
66
|
+
* return { title: t('common.title') };
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* // Check if translation exists (with namespace support)
|
|
73
|
+
* const { t, hasTranslation } = await getI18n();
|
|
74
|
+
* hasTranslation('common.title') // true (default namespace)
|
|
75
|
+
* hasTranslation('title', { ns: 'admin' }) // true (admin namespace)
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* getI18n auto-loads only the default namespace (or the namespace passed via
|
|
80
|
+
* getI18n({ ns })). If you call t() with a different ns, ensure you preloaded it
|
|
81
|
+
* via loadTranslations(locale, { namespaces: [...] }) in your layout or metadata.
|
|
82
|
+
*/
|
|
83
|
+
async function getI18n(options) {
|
|
84
|
+
const i18n = getI18nInstance();
|
|
85
|
+
await ensureInitialized(i18n);
|
|
86
|
+
let locale = options?.locale;
|
|
87
|
+
if (!locale) try {
|
|
88
|
+
locale = await getLocale();
|
|
89
|
+
} catch (e) {
|
|
90
|
+
const err = /* @__PURE__ */ new Error("[comvi/next] Locale not set. Call setRequestLocale(locale) in your layout/page first, or configure middleware.");
|
|
91
|
+
err.cause = e;
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
const defaultNs = options?.ns ?? i18n.getDefaultNamespace();
|
|
95
|
+
if (!i18n.hasLocale(locale, defaultNs)) await loadTranslations(locale, { namespaces: [defaultNs] });
|
|
96
|
+
const translate = createBoundTranslation(i18n, defaultNs);
|
|
97
|
+
const t = ((key, params) => {
|
|
98
|
+
return translationResultToString(translate(key, {
|
|
99
|
+
...params,
|
|
100
|
+
locale
|
|
101
|
+
}));
|
|
102
|
+
});
|
|
103
|
+
const hasTranslation = (key, opts) => {
|
|
104
|
+
const checkLocale = opts?.locale ?? locale;
|
|
105
|
+
const checkNs = opts?.ns ?? defaultNs;
|
|
106
|
+
return i18n.hasTranslation(key, checkLocale, checkNs);
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
t,
|
|
110
|
+
hasTranslation
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { getI18n };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_cache = require("./cache.cjs");
|
|
3
|
+
let next_headers = require("next/headers");
|
|
4
|
+
//#region src/server/getLocale.ts
|
|
5
|
+
/**
|
|
6
|
+
* Header name set by middleware to pass locale to Server Components
|
|
7
|
+
*/
|
|
8
|
+
var LOCALE_HEADER = "x-comvi-locale";
|
|
9
|
+
/**
|
|
10
|
+
* Get the current request locale
|
|
11
|
+
*
|
|
12
|
+
* This function reads the locale from:
|
|
13
|
+
* 1. Request cache (set by setRequestLocale)
|
|
14
|
+
* 2. x-comvi-locale header (set by middleware)
|
|
15
|
+
*
|
|
16
|
+
* @returns The current locale
|
|
17
|
+
* @throws Error if locale cannot be determined
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* import { getLocale } from '@comvi/next/server';
|
|
22
|
+
*
|
|
23
|
+
* export default async function Page() {
|
|
24
|
+
* const locale = await getLocale();
|
|
25
|
+
* return <p>Current locale: {locale}</p>;
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
async function getLocale() {
|
|
30
|
+
const cachedLocale = require_cache.getRequestLocaleFromCache();
|
|
31
|
+
if (cachedLocale) return cachedLocale;
|
|
32
|
+
const localeFromHeader = (await (0, next_headers.headers)()).get(LOCALE_HEADER);
|
|
33
|
+
if (localeFromHeader) return localeFromHeader;
|
|
34
|
+
throw new Error("[comvi/next] Unable to determine locale. Make sure to call setRequestLocale() in your layout/page or configure middleware.");
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
exports.getLocale = getLocale;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the current request locale
|
|
3
|
+
*
|
|
4
|
+
* This function reads the locale from:
|
|
5
|
+
* 1. Request cache (set by setRequestLocale)
|
|
6
|
+
* 2. x-comvi-locale header (set by middleware)
|
|
7
|
+
*
|
|
8
|
+
* @returns The current locale
|
|
9
|
+
* @throws Error if locale cannot be determined
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { getLocale } from '@comvi/next/server';
|
|
14
|
+
*
|
|
15
|
+
* export default async function Page() {
|
|
16
|
+
* const locale = await getLocale();
|
|
17
|
+
* return <p>Current locale: {locale}</p>;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function getLocale(): Promise<string>;
|
|
22
|
+
//# sourceMappingURL=getLocale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getLocale.d.ts","sourceRoot":"","sources":["../../src/server/getLocale.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBjD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getRequestLocaleFromCache } from "./cache.js";
|
|
2
|
+
import { headers } from "next/headers";
|
|
3
|
+
//#region src/server/getLocale.ts
|
|
4
|
+
/**
|
|
5
|
+
* Header name set by middleware to pass locale to Server Components
|
|
6
|
+
*/
|
|
7
|
+
var LOCALE_HEADER = "x-comvi-locale";
|
|
8
|
+
/**
|
|
9
|
+
* Get the current request locale
|
|
10
|
+
*
|
|
11
|
+
* This function reads the locale from:
|
|
12
|
+
* 1. Request cache (set by setRequestLocale)
|
|
13
|
+
* 2. x-comvi-locale header (set by middleware)
|
|
14
|
+
*
|
|
15
|
+
* @returns The current locale
|
|
16
|
+
* @throws Error if locale cannot be determined
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { getLocale } from '@comvi/next/server';
|
|
21
|
+
*
|
|
22
|
+
* export default async function Page() {
|
|
23
|
+
* const locale = await getLocale();
|
|
24
|
+
* return <p>Current locale: {locale}</p>;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
async function getLocale() {
|
|
29
|
+
const cachedLocale = getRequestLocaleFromCache();
|
|
30
|
+
if (cachedLocale) return cachedLocale;
|
|
31
|
+
const localeFromHeader = (await headers()).get(LOCALE_HEADER);
|
|
32
|
+
if (localeFromHeader) return localeFromHeader;
|
|
33
|
+
throw new Error("[comvi/next] Unable to determine locale. Make sure to call setRequestLocale() in your layout/page or configure middleware.");
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { getLocale };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const require_cache = require("./cache.cjs");
|
|
2
|
+
const require_ensureInitialized = require("./ensureInitialized.cjs");
|
|
3
|
+
//#region src/server/loadTranslations.ts
|
|
4
|
+
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
5
|
+
var noLoaderWarnings = /* @__PURE__ */ new WeakSet();
|
|
6
|
+
var NO_LOADER_WARNING_MESSAGE = "[comvi/next] No loader configured. Register one via i18n.registerLoader(...) or createNextI18n(...).use(plugin).";
|
|
7
|
+
var toPlainObject = (value) => {
|
|
8
|
+
return Object.fromEntries(Object.entries(value));
|
|
9
|
+
};
|
|
10
|
+
var warnNoLoaderConfigured = (i18n) => {
|
|
11
|
+
if (noLoaderWarnings.has(i18n)) return;
|
|
12
|
+
noLoaderWarnings.add(i18n);
|
|
13
|
+
console.warn(NO_LOADER_WARNING_MESSAGE);
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Load translations for a locale using the configured i18n loader.
|
|
17
|
+
*
|
|
18
|
+
* If no loader is configured, this function returns already-cached translations
|
|
19
|
+
* for requested namespaces (if any) and logs a warning.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const messages = await loadTranslations(locale);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const messages = await loadTranslations(locale, {
|
|
29
|
+
* namespaces: ["common", "admin"],
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
async function loadTranslations(locale, options = {}) {
|
|
34
|
+
const i18n = require_cache.getI18nInstance();
|
|
35
|
+
await require_ensureInitialized.ensureInitialized(i18n);
|
|
36
|
+
const defaultNs = i18n.getDefaultNamespace();
|
|
37
|
+
const namespaces = options.namespaces ?? [defaultNs];
|
|
38
|
+
const hasLoader = Boolean(i18n.getLoader());
|
|
39
|
+
const result = {};
|
|
40
|
+
for (const namespace of namespaces) {
|
|
41
|
+
const cacheKey = `${locale}:${namespace}`;
|
|
42
|
+
if (!i18n.hasLocale(locale, namespace) && hasLoader) try {
|
|
43
|
+
await i18n.reloadTranslations(locale, namespace);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
const err = toError(error);
|
|
46
|
+
console.warn(`[comvi/next] Failed to load ${locale}:${namespace}:`, err.message);
|
|
47
|
+
}
|
|
48
|
+
if (i18n.hasLocale(locale, namespace)) result[cacheKey] = toPlainObject(i18n.getTranslations(locale, namespace));
|
|
49
|
+
}
|
|
50
|
+
if (!hasLoader && Object.keys(result).length === 0) warnNoLoaderConfigured(i18n);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
exports.loadTranslations = loadTranslations;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TranslationValue } from '@comvi/core';
|
|
2
|
+
/**
|
|
3
|
+
* Options for loadTranslations
|
|
4
|
+
*/
|
|
5
|
+
export interface LoadTranslationsOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Namespaces to load. Defaults to default namespace only.
|
|
8
|
+
*/
|
|
9
|
+
namespaces?: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Translations result keyed by "locale:namespace"
|
|
13
|
+
*/
|
|
14
|
+
export type TranslationsResult = Record<string, Record<string, TranslationValue>>;
|
|
15
|
+
/**
|
|
16
|
+
* Load translations for a locale using the configured i18n loader.
|
|
17
|
+
*
|
|
18
|
+
* If no loader is configured, this function returns already-cached translations
|
|
19
|
+
* for requested namespaces (if any) and logs a warning.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const messages = await loadTranslations(locale);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const messages = await loadTranslations(locale, {
|
|
29
|
+
* namespaces: ["common", "admin"],
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadTranslations(locale: string, options?: LoadTranslationsOptions): Promise<TranslationsResult>;
|
|
34
|
+
//# sourceMappingURL=loadTranslations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadTranslations.d.ts","sourceRoot":"","sources":["../../src/server/loadTranslations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI1D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAyBlF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAuC7B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getI18nInstance } from "./cache.js";
|
|
2
|
+
import { ensureInitialized } from "./ensureInitialized.js";
|
|
3
|
+
//#region src/server/loadTranslations.ts
|
|
4
|
+
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
5
|
+
var noLoaderWarnings = /* @__PURE__ */ new WeakSet();
|
|
6
|
+
var NO_LOADER_WARNING_MESSAGE = "[comvi/next] No loader configured. Register one via i18n.registerLoader(...) or createNextI18n(...).use(plugin).";
|
|
7
|
+
var toPlainObject = (value) => {
|
|
8
|
+
return Object.fromEntries(Object.entries(value));
|
|
9
|
+
};
|
|
10
|
+
var warnNoLoaderConfigured = (i18n) => {
|
|
11
|
+
if (noLoaderWarnings.has(i18n)) return;
|
|
12
|
+
noLoaderWarnings.add(i18n);
|
|
13
|
+
console.warn(NO_LOADER_WARNING_MESSAGE);
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Load translations for a locale using the configured i18n loader.
|
|
17
|
+
*
|
|
18
|
+
* If no loader is configured, this function returns already-cached translations
|
|
19
|
+
* for requested namespaces (if any) and logs a warning.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const messages = await loadTranslations(locale);
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const messages = await loadTranslations(locale, {
|
|
29
|
+
* namespaces: ["common", "admin"],
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
async function loadTranslations(locale, options = {}) {
|
|
34
|
+
const i18n = getI18nInstance();
|
|
35
|
+
await ensureInitialized(i18n);
|
|
36
|
+
const defaultNs = i18n.getDefaultNamespace();
|
|
37
|
+
const namespaces = options.namespaces ?? [defaultNs];
|
|
38
|
+
const hasLoader = Boolean(i18n.getLoader());
|
|
39
|
+
const result = {};
|
|
40
|
+
for (const namespace of namespaces) {
|
|
41
|
+
const cacheKey = `${locale}:${namespace}`;
|
|
42
|
+
if (!i18n.hasLocale(locale, namespace) && hasLoader) try {
|
|
43
|
+
await i18n.reloadTranslations(locale, namespace);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
const err = toError(error);
|
|
46
|
+
console.warn(`[comvi/next] Failed to load ${locale}:${namespace}:`, err.message);
|
|
47
|
+
}
|
|
48
|
+
if (i18n.hasLocale(locale, namespace)) result[cacheKey] = toPlainObject(i18n.getTranslations(locale, namespace));
|
|
49
|
+
}
|
|
50
|
+
if (!hasLoader && Object.keys(result).length === 0) warnNoLoaderConfigured(i18n);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { loadTranslations };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const require_cache = require("./cache.cjs");
|
|
2
|
+
//#region src/server/setRequestLocale.ts
|
|
3
|
+
/**
|
|
4
|
+
* Enable static rendering for internationalized pages
|
|
5
|
+
*
|
|
6
|
+
* Call this at the top of your layout and page components before
|
|
7
|
+
* using any translation functions. This is required for static
|
|
8
|
+
* rendering with generateStaticParams().
|
|
9
|
+
*
|
|
10
|
+
* @param locale - The locale for this request (typically from params.locale)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // app/[locale]/page.tsx
|
|
15
|
+
* import { setRequestLocale } from '@comvi/next/server';
|
|
16
|
+
*
|
|
17
|
+
* export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
|
|
18
|
+
* const { locale } = await params;
|
|
19
|
+
* setRequestLocale(locale);
|
|
20
|
+
*
|
|
21
|
+
* // Now you can use getTranslations()
|
|
22
|
+
* const t = await getTranslations('HomePage');
|
|
23
|
+
* return <h1>{t('title')}</h1>;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function setRequestLocale(locale) {
|
|
28
|
+
require_cache.setRequestLocaleInternal(locale);
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
exports.setRequestLocale = setRequestLocale;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enable static rendering for internationalized pages
|
|
3
|
+
*
|
|
4
|
+
* Call this at the top of your layout and page components before
|
|
5
|
+
* using any translation functions. This is required for static
|
|
6
|
+
* rendering with generateStaticParams().
|
|
7
|
+
*
|
|
8
|
+
* @param locale - The locale for this request (typically from params.locale)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // app/[locale]/page.tsx
|
|
13
|
+
* import { setRequestLocale } from '@comvi/next/server';
|
|
14
|
+
*
|
|
15
|
+
* export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
|
|
16
|
+
* const { locale } = await params;
|
|
17
|
+
* setRequestLocale(locale);
|
|
18
|
+
*
|
|
19
|
+
* // Now you can use getTranslations()
|
|
20
|
+
* const t = await getTranslations('HomePage');
|
|
21
|
+
* return <h1>{t('title')}</h1>;
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function setRequestLocale(locale: string): void;
|
|
26
|
+
//# sourceMappingURL=setRequestLocale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setRequestLocale.d.ts","sourceRoot":"","sources":["../../src/server/setRequestLocale.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAErD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { setRequestLocaleInternal } from "./cache.js";
|
|
2
|
+
//#region src/server/setRequestLocale.ts
|
|
3
|
+
/**
|
|
4
|
+
* Enable static rendering for internationalized pages
|
|
5
|
+
*
|
|
6
|
+
* Call this at the top of your layout and page components before
|
|
7
|
+
* using any translation functions. This is required for static
|
|
8
|
+
* rendering with generateStaticParams().
|
|
9
|
+
*
|
|
10
|
+
* @param locale - The locale for this request (typically from params.locale)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // app/[locale]/page.tsx
|
|
15
|
+
* import { setRequestLocale } from '@comvi/next/server';
|
|
16
|
+
*
|
|
17
|
+
* export default async function Page({ params }: { params: Promise<{ locale: string }> }) {
|
|
18
|
+
* const { locale } = await params;
|
|
19
|
+
* setRequestLocale(locale);
|
|
20
|
+
*
|
|
21
|
+
* // Now you can use getTranslations()
|
|
22
|
+
* const t = await getTranslations('HomePage');
|
|
23
|
+
* return <h1>{t('title')}</h1>;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function setRequestLocale(locale) {
|
|
28
|
+
setRequestLocaleInternal(locale);
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { setRequestLocale };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TranslationParams, NamespacedKeys, Namespaces, NamespacedParamsArg, ParamsArg, PermissiveKey } from '@comvi/core';
|
|
2
|
+
/**
|
|
3
|
+
* Options for getI18n function
|
|
4
|
+
*/
|
|
5
|
+
export interface GetI18nOptions {
|
|
6
|
+
/** Explicit locale (for generateMetadata, etc.) - defaults to request locale */
|
|
7
|
+
locale?: string;
|
|
8
|
+
/** Default namespace to use (overrides i18n.defaultNs) */
|
|
9
|
+
ns?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Translation function type for Server Components (returns string)
|
|
13
|
+
*/
|
|
14
|
+
export interface TranslationFunction {
|
|
15
|
+
<NS extends Namespaces, K extends NamespacedKeys<NS>>(key: K, ...params: NamespacedParamsArg<NS, K>): string;
|
|
16
|
+
<K extends import('@comvi/core').DefaultNsKeys>(key: K, ...params: ParamsArg<K>): string;
|
|
17
|
+
(key: PermissiveKey, params?: TranslationParams): string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for hasTranslation check
|
|
21
|
+
*/
|
|
22
|
+
export interface HasTranslationOptions {
|
|
23
|
+
/** Namespace to check (defaults to defaultNamespace) */
|
|
24
|
+
ns?: string;
|
|
25
|
+
/** Locale to check (defaults to current locale) */
|
|
26
|
+
locale?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Result returned by getI18n
|
|
30
|
+
*/
|
|
31
|
+
export interface ServerI18n {
|
|
32
|
+
/** Translation function */
|
|
33
|
+
t: TranslationFunction;
|
|
34
|
+
/** Check if a translation key exists */
|
|
35
|
+
hasTranslation: (key: string, options?: HasTranslationOptions) => boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Internal request store interface
|
|
39
|
+
*/
|
|
40
|
+
export interface RequestStore {
|
|
41
|
+
locale: string | undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|