intor 2.3.31 → 2.3.32
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/dist/core/export/index.js +1 -1
- package/dist/core/export/server/index.js +1 -1
- package/dist/core/src/config/resolvers/resolve-fallback-locales.js +1 -0
- package/dist/core/src/config/resolvers/resolve-routing-options.js +1 -0
- package/dist/core/src/config/validators/validate-default-locale.js +1 -0
- package/dist/core/src/config/validators/validate-id.js +1 -0
- package/dist/core/src/config/validators/validate-supported-locales.js +1 -0
- package/dist/{svelte/src/client/svelte/render/create-svelte-renderer.js → core/src/core/render/create-html-renderer.js} +6 -7
- package/dist/{svelte/src/client/svelte → core/src/core}/render/utils/render-attributes.js +7 -5
- package/dist/core/src/core/translator/create-t-rich.js +22 -0
- package/dist/core/src/routing/pathname/canonicalize-pathname.js +1 -0
- package/dist/core/src/routing/pathname/materialize-pathname.js +1 -0
- package/dist/core/src/routing/pathname/standardize-pathname.js +1 -0
- package/dist/core/src/server/helpers/get-translator.js +12 -3
- package/dist/core/src/server/intor/intor.js +1 -0
- package/dist/core/src/server/messages/load-local-messages/load-local-messages.js +1 -0
- package/dist/core/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
- package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
- package/dist/core/src/server/messages/load-messages.js +1 -0
- package/dist/core/src/server/translator/create-translator.js +5 -15
- package/dist/core/src/server/translator/init-translator.js +6 -12
- package/dist/express/src/adapters/express/helpers/get-translator.js +1 -1
- package/dist/express/src/adapters/express/middleware/create-intor-middleware.js +3 -3
- package/dist/express/src/core/render/create-html-renderer.js +44 -0
- package/dist/express/src/core/render/utils/escape-html.js +10 -0
- package/dist/express/src/core/render/utils/render-attributes.js +17 -0
- package/dist/express/src/core/translator/create-t-rich.js +22 -0
- package/dist/express/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
- package/dist/express/src/routing/locale/get-locale-from-pathname.js +1 -0
- package/dist/express/src/routing/pathname/canonicalize-pathname.js +1 -0
- package/dist/express/src/routing/pathname/materialize-pathname.js +1 -0
- package/dist/express/src/routing/pathname/standardize-pathname.js +1 -0
- package/dist/express/src/server/helpers/get-translator.js +12 -3
- package/dist/express/src/server/messages/load-local-messages/load-local-messages.js +1 -0
- package/dist/express/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
- package/dist/express/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
- package/dist/express/src/server/messages/load-messages.js +1 -0
- package/dist/express/src/server/translator/create-translator.js +5 -15
- package/dist/express/src/server/translator/init-translator.js +6 -12
- package/dist/next/src/adapters/next/navigation/link.js +1 -0
- package/dist/next/src/adapters/next/navigation/redirect.js +1 -0
- package/dist/next/src/adapters/next/navigation/use-router.js +1 -0
- package/dist/next/src/adapters/next/proxy/intor-proxy.js +1 -0
- package/dist/next/src/adapters/next/server/get-locale.js +1 -0
- package/dist/next/src/adapters/next/server/get-translator.js +1 -1
- package/dist/next/src/adapters/next/server/intor.js +1 -1
- package/dist/next/src/client/shared/navigation/execute-navigation.js +1 -0
- package/dist/next/src/core/render/create-html-renderer.js +44 -0
- package/dist/next/src/core/render/utils/escape-html.js +10 -0
- package/dist/next/src/core/render/utils/render-attributes.js +17 -0
- package/dist/next/src/core/translator/create-t-rich.js +22 -0
- package/dist/next/src/policies/shoud-full-reload.js +1 -0
- package/dist/next/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
- package/dist/next/src/routing/locale/get-locale-from-pathname.js +1 -0
- package/dist/next/src/routing/pathname/canonicalize-pathname.js +1 -0
- package/dist/next/src/routing/pathname/materialize-pathname.js +1 -0
- package/dist/next/src/routing/pathname/standardize-pathname.js +1 -0
- package/dist/next/src/server/helpers/get-translator.js +12 -3
- package/dist/next/src/server/intor/intor.js +1 -0
- package/dist/next/src/server/messages/load-local-messages/load-local-messages.js +1 -0
- package/dist/next/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
- package/dist/next/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
- package/dist/next/src/server/messages/load-messages.js +1 -0
- package/dist/next/src/server/translator/create-translator.js +5 -15
- package/dist/next/src/server/translator/init-translator.js +6 -12
- package/dist/react/src/client/react/helpers/use-intor.js +1 -0
- package/dist/react/src/client/react/provider/effects/use-locale-effects.js +1 -0
- package/dist/react/src/client/react/render/create-react-renderer.js +0 -1
- package/dist/react/src/client/react/translator/create-t-rich.js +7 -4
- package/dist/react/src/client/react/translator/use-translator.js +3 -3
- package/dist/react/src/client/shared/helpers/get-client-locale.js +1 -0
- package/dist/react/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/svelte/src/client/shared/helpers/get-client-locale.js +1 -0
- package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/svelte/src/client/svelte/provider/effects/locale-effects.js +1 -0
- package/dist/svelte/src/client/svelte/provider/intor-provider.svelte +7 -2
- package/dist/svelte/src/client/svelte/translator/use-translator.js +5 -7
- package/dist/svelte/src/core/render/create-html-renderer.js +44 -0
- package/dist/svelte/src/core/render/utils/escape-html.js +10 -0
- package/dist/svelte/src/core/render/utils/render-attributes.js +17 -0
- package/dist/svelte/src/core/translator/create-t-rich.js +22 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/navigation/use-navigation.js +1 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/server/create-intor-handle.js +1 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/server/intor.js +1 -1
- package/dist/svelte-kit/src/client/shared/navigation/execute-navigation.js +1 -0
- package/dist/svelte-kit/src/policies/shoud-full-reload.js +1 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
- package/dist/svelte-kit/src/routing/locale/get-locale-from-pathname.js +1 -0
- package/dist/svelte-kit/src/routing/pathname/canonicalize-pathname.js +1 -0
- package/dist/svelte-kit/src/routing/pathname/materialize-pathname.js +1 -0
- package/dist/svelte-kit/src/routing/pathname/standardize-pathname.js +1 -0
- package/dist/svelte-kit/src/server/intor/intor.js +1 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/load-local-messages.js +1 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
- package/dist/svelte-kit/src/server/messages/load-messages.js +1 -0
- package/dist/svelte-kit/src/server/translator/create-translator.js +5 -15
- package/dist/svelte-kit/src/server/translator/init-translator.js +6 -12
- package/dist/types/export/internal/index.d.ts +1 -1
- package/dist/types/export/svelte/index.d.ts +1 -1
- package/dist/types/src/client/react/render/index.d.ts +1 -1
- package/dist/types/src/client/react/render/types.d.ts +2 -6
- package/dist/types/src/client/react/translator/create-t-rich.d.ts +2 -2
- package/dist/types/src/client/react/translator/translator-instance.d.ts +1 -1
- package/dist/types/src/client/svelte/index.d.ts +1 -1
- package/dist/types/src/client/svelte/provider/index.d.ts +1 -0
- package/dist/types/src/client/svelte/provider/types.d.ts +4 -0
- package/dist/types/src/client/svelte/translator/translator-instance.d.ts +3 -4
- package/dist/types/src/client/vue/render/index.d.ts +1 -1
- package/dist/types/src/client/vue/render/types.d.ts +2 -6
- package/dist/types/src/client/vue/translator/create-t-rich.d.ts +2 -3
- package/dist/types/src/client/vue/translator/translator-instance.d.ts +1 -1
- package/dist/types/src/core/index.d.ts +2 -0
- package/dist/types/src/core/render/create-html-renderer.d.ts +11 -0
- package/dist/types/src/core/render/index.d.ts +2 -0
- package/dist/types/src/core/render/types.d.ts +10 -0
- package/dist/types/src/core/translator/create-t-rich.d.ts +12 -0
- package/dist/types/src/core/translator/index.d.ts +1 -0
- package/dist/types/src/server/helpers/get-translator.d.ts +4 -4
- package/dist/types/src/server/translator/create-translator.d.ts +5 -13
- package/dist/types/src/server/translator/init-translator.d.ts +6 -7
- package/dist/types/src/server/translator/translator-instance.d.ts +5 -3
- package/dist/vue/src/client/shared/helpers/get-client-locale.js +1 -0
- package/dist/vue/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/vue/src/client/vue/helpers/use-intor.js +1 -0
- package/dist/vue/src/client/vue/provider/effects/use-locale-effects.js +1 -0
- package/dist/vue/src/client/vue/render/create-vue-renderer.js +0 -1
- package/dist/vue/src/client/vue/translator/create-t-rich.js +6 -8
- package/dist/vue/src/client/vue/translator/use-translator.js +4 -6
- package/package.json +15 -15
- package/dist/react/src/client/react/render/render-rich-message-react.js +0 -22
- package/dist/svelte/src/client/svelte/render/render-rich-message-svelte.js +0 -20
- package/dist/svelte/src/client/svelte/translator/create-t-rich.js +0 -23
- package/dist/types/src/client/react/render/render-rich-message-react.d.ts +0 -14
- package/dist/types/src/client/svelte/render/create-svelte-renderer.d.ts +0 -14
- package/dist/types/src/client/svelte/render/index.d.ts +0 -2
- package/dist/types/src/client/svelte/render/render-rich-message-svelte.d.ts +0 -12
- package/dist/types/src/client/svelte/render/types.d.ts +0 -8
- package/dist/types/src/client/svelte/translator/create-t-rich.d.ts +0 -15
- package/dist/types/src/client/vue/render/render-rich-message-vue.d.ts +0 -14
- package/dist/vue/src/client/vue/render/render-rich-message-vue.js +0 -19
- /package/dist/{svelte/src/client/svelte → core/src/core}/render/utils/escape-html.js +0 -0
- /package/dist/types/src/{client/svelte → core}/render/utils/escape-html.d.ts +0 -0
- /package/dist/types/src/{client/svelte → core}/render/utils/render-attributes.d.ts +0 -0
|
@@ -2,19 +2,20 @@ import '../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { loadMessages } from '../messages/load-messages.js';
|
|
6
7
|
import 'node:path';
|
|
7
8
|
import 'node:fs/promises';
|
|
8
9
|
import { createTranslator } from './create-translator.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Initialize a locale-bound Translator snapshot.
|
|
12
13
|
*
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
14
|
+
* - Resolves loader options and loads messages if configured
|
|
15
|
+
* - Creates an immutable Translator instance for server usage
|
|
15
16
|
*/
|
|
16
17
|
async function initTranslator(config, locale, options) {
|
|
17
|
-
const { readers, allowCacheWrite = false, fetch,
|
|
18
|
+
const { readers, allowCacheWrite = false, fetch, handlers, plugins, } = options;
|
|
18
19
|
const loader = resolveLoaderOptions(config);
|
|
19
20
|
// Load messages
|
|
20
21
|
let messages = {};
|
|
@@ -29,14 +30,7 @@ async function initTranslator(config, locale, options) {
|
|
|
29
30
|
messages = loaded || {};
|
|
30
31
|
}
|
|
31
32
|
// Create immutable translator snapshot
|
|
32
|
-
return createTranslator({
|
|
33
|
-
config,
|
|
34
|
-
locale,
|
|
35
|
-
messages,
|
|
36
|
-
preKey,
|
|
37
|
-
handlers,
|
|
38
|
-
plugins,
|
|
39
|
-
});
|
|
33
|
+
return createTranslator({ config, locale, messages, handlers, plugins });
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
export { initTranslator };
|
|
@@ -2,6 +2,7 @@ import { redirect as redirect$1 } from 'next/navigation';
|
|
|
2
2
|
import '../../../core/error/intor-error.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { resolveNavigation } from '../../../routing/navigation/resolve-navigation.js';
|
|
6
7
|
import { getLocale } from '../server/get-locale.js';
|
|
7
8
|
|
|
@@ -4,6 +4,7 @@ import '../../../core/error/intor-error.js';
|
|
|
4
4
|
import { normalizeQuery } from '../../../core/utils/normalizers/normalize-query.js';
|
|
5
5
|
import 'logry';
|
|
6
6
|
import 'p-limit';
|
|
7
|
+
import 'intor-translator';
|
|
7
8
|
import { resolveInbound } from '../../../routing/inbound/resolve-inbound.js';
|
|
8
9
|
import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-from-accept-language.js';
|
|
9
10
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import '../../../core/error/intor-error.js';
|
|
2
2
|
import 'logry';
|
|
3
3
|
import 'p-limit';
|
|
4
|
+
import 'intor-translator';
|
|
4
5
|
import 'node:path';
|
|
5
6
|
import 'node:fs/promises';
|
|
6
|
-
import 'intor-translator';
|
|
7
7
|
import { getTranslator as getTranslator$1 } from '../../../server/helpers/get-translator.js';
|
|
8
8
|
import { getLocale } from './get-locale.js';
|
|
9
9
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import '../../../core/error/intor-error.js';
|
|
2
2
|
import 'logry';
|
|
3
3
|
import 'p-limit';
|
|
4
|
+
import 'intor-translator';
|
|
4
5
|
import { intor as intor$1 } from '../../../server/intor/intor.js';
|
|
5
6
|
import 'node:path';
|
|
6
7
|
import 'node:fs/promises';
|
|
7
|
-
import 'intor-translator';
|
|
8
8
|
import { getLocale } from './get-locale.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { escapeHtml } from './utils/escape-html.js';
|
|
2
|
+
import { renderAttributes } from './utils/render-attributes.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create an HTML string renderer for semantic rich messages.
|
|
6
|
+
*
|
|
7
|
+
* - Transforms semantic rich AST nodes into escaped HTML strings.
|
|
8
|
+
* - Can be used in any HTML-based environment.
|
|
9
|
+
*
|
|
10
|
+
* This renderer is intentionally minimal and stateless.
|
|
11
|
+
*/
|
|
12
|
+
const createHtmlRenderer = (tagRenderers) => {
|
|
13
|
+
return {
|
|
14
|
+
/** Render plain text nodes */
|
|
15
|
+
text(value) {
|
|
16
|
+
return escapeHtml(value);
|
|
17
|
+
},
|
|
18
|
+
/** Render semantic tag nodes */
|
|
19
|
+
tag(name, attributes, children) {
|
|
20
|
+
const tagRenderer = tagRenderers?.[name];
|
|
21
|
+
if (tagRenderer) {
|
|
22
|
+
return typeof tagRenderer === "function"
|
|
23
|
+
? tagRenderer(children)
|
|
24
|
+
: tagRenderer;
|
|
25
|
+
}
|
|
26
|
+
// Default behavior: render as native HTML tag
|
|
27
|
+
return `<${name}${renderAttributes(attributes)}>${children.join("")}</${name}>`;
|
|
28
|
+
},
|
|
29
|
+
/** Render raw (non-tokenized) message values as escaped HTML strings */
|
|
30
|
+
raw(value) {
|
|
31
|
+
if (value == null)
|
|
32
|
+
return "";
|
|
33
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
34
|
+
return escapeHtml(String(value));
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
return value.map((v) => escapeHtml(String(v))).join("");
|
|
38
|
+
}
|
|
39
|
+
throw new Error("[intor] HTML renderer cannot render raw non-primitive values.");
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { createHtmlRenderer };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { escapeHtml } from './escape-html.js';
|
|
2
|
+
|
|
3
|
+
function renderAttributes(attributes) {
|
|
4
|
+
if (!attributes)
|
|
5
|
+
return "";
|
|
6
|
+
return Object.entries(attributes)
|
|
7
|
+
.map(([key, value]) => {
|
|
8
|
+
if (value === true)
|
|
9
|
+
return ` ${key}`;
|
|
10
|
+
if (value == null)
|
|
11
|
+
return "";
|
|
12
|
+
return ` ${key}="${escapeHtml(String(value))}"`;
|
|
13
|
+
})
|
|
14
|
+
.join("");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { renderAttributes };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { renderRichMessage } from 'intor-translator';
|
|
2
|
+
import { createHtmlRenderer } from '../render/create-html-renderer.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create an HTML-string rich translation function.
|
|
6
|
+
*
|
|
7
|
+
* - Resolves translated messages via `translator.t`
|
|
8
|
+
* - Renders semantic rich tags into escaped HTML strings
|
|
9
|
+
* - Supports optional scoped keys via `preKey`
|
|
10
|
+
*
|
|
11
|
+
* Can be used in any HTML-based environment (Astro, Svelte, SSR, etc.).
|
|
12
|
+
*/
|
|
13
|
+
const createTRich = (t) => {
|
|
14
|
+
return (key, tagRenderers, replacements) => {
|
|
15
|
+
const message = t(key, replacements);
|
|
16
|
+
const renderer = createHtmlRenderer(tagRenderers);
|
|
17
|
+
const nodes = renderRichMessage(message, renderer);
|
|
18
|
+
return nodes.join("");
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { createTRich };
|
|
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
|
|
|
2
2
|
import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Resolve the active locale from inbound routing configuration.
|
|
@@ -3,6 +3,7 @@ import '../../core/error/intor-error.js';
|
|
|
3
3
|
import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
|
|
4
4
|
import 'logry';
|
|
5
5
|
import 'p-limit';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Standardizes a canonical pathname into an internal routing template
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import '../../core/error/intor-error.js';
|
|
2
|
+
import 'logry';
|
|
3
|
+
import 'p-limit';
|
|
4
|
+
import { createTRich } from '../../core/translator/create-t-rich.js';
|
|
1
5
|
import { initTranslator } from '../translator/init-translator.js';
|
|
2
6
|
|
|
3
7
|
// Implementation
|
|
@@ -8,15 +12,20 @@ async function getTranslator(config, params) {
|
|
|
8
12
|
readers,
|
|
9
13
|
allowCacheWrite,
|
|
10
14
|
fetch: fetch || globalThis.fetch,
|
|
11
|
-
preKey,
|
|
12
15
|
plugins,
|
|
13
16
|
handlers,
|
|
14
17
|
});
|
|
18
|
+
const scoped = translator.scoped(preKey);
|
|
15
19
|
return {
|
|
16
20
|
messages: translator.messages,
|
|
17
21
|
locale: translator.locale,
|
|
18
|
-
hasKey:
|
|
19
|
-
t:
|
|
22
|
+
hasKey: scoped.hasKey,
|
|
23
|
+
t: scoped.t,
|
|
24
|
+
tRich: createTRich(scoped.t),
|
|
25
|
+
// NOTE:
|
|
26
|
+
// The runtime implementation is intentionally erased.
|
|
27
|
+
// Type safety is guaranteed by public type contracts.
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
29
|
};
|
|
21
30
|
}
|
|
22
31
|
|
|
@@ -3,6 +3,7 @@ import pLimit from 'p-limit';
|
|
|
3
3
|
import '../../../core/error/intor-error.js';
|
|
4
4
|
import { normalizeCacheKey } from '../../../core/utils/normalizers/normalize-cache-key.js';
|
|
5
5
|
import { getLogger } from '../../../core/logger/get-logger.js';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
import { getMessagesPool } from './cache/messages-pool.js';
|
|
7
8
|
import { readLocaleMessages } from './read-locale-messages/read-locale-messages.js';
|
|
8
9
|
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import '../../../../../core/error/intor-error.js';
|
|
4
4
|
import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
5
5
|
import 'p-limit';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Recursively collects message file metadata under a given locale root.
|
|
@@ -5,6 +5,7 @@ import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
|
5
5
|
import 'p-limit';
|
|
6
6
|
import { isValidMessages } from '../../../../../core/messages/utils/is-valid-messages.js';
|
|
7
7
|
import { nestObjectFromPath } from '../../../../../core/messages/utils/nest-object-from-path.js';
|
|
8
|
+
import 'intor-translator';
|
|
8
9
|
import { jsonReader } from './utils/json-reader.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -2,6 +2,7 @@ import '../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import { getLogger } from '../../core/logger/get-logger.js';
|
|
4
4
|
import { loadRemoteMessages } from '../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { loadLocalMessages } from './load-local-messages/load-local-messages.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -2,17 +2,14 @@ import { Translator } from 'intor-translator';
|
|
|
2
2
|
import { mergeMessages } from '../../core/messages/merge-messages.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Create a server-side
|
|
5
|
+
* Create a server-side Translator instance for a fixed locale.
|
|
6
6
|
*
|
|
7
7
|
* - Merges static config messages with runtime-loaded messages
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
* The returned object is a read-only translation view
|
|
12
|
-
* and does not expose the underlying Translator instance.
|
|
8
|
+
* - Initializes a Translator bound to a specific locale
|
|
9
|
+
* - Injects fallback rules, handlers, and plugins from config
|
|
13
10
|
*/
|
|
14
11
|
function createTranslator(params) {
|
|
15
|
-
const { config, locale, messages,
|
|
12
|
+
const { config, locale, messages, handlers, plugins } = params;
|
|
16
13
|
// Merge static config messages with runtime-loaded messages
|
|
17
14
|
const finalMessages = mergeMessages(config.messages, messages, {
|
|
18
15
|
config,
|
|
@@ -27,14 +24,7 @@ function createTranslator(params) {
|
|
|
27
24
|
handlers,
|
|
28
25
|
plugins,
|
|
29
26
|
});
|
|
30
|
-
|
|
31
|
-
const scoped = preKey ? translator.scoped(preKey) : null;
|
|
32
|
-
return {
|
|
33
|
-
messages: finalMessages,
|
|
34
|
-
locale,
|
|
35
|
-
hasKey: scoped ? scoped.hasKey : translator.hasKey,
|
|
36
|
-
t: scoped ? scoped.t : translator.t,
|
|
37
|
-
};
|
|
27
|
+
return translator;
|
|
38
28
|
}
|
|
39
29
|
|
|
40
30
|
export { createTranslator };
|
|
@@ -2,19 +2,20 @@ import '../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { loadMessages } from '../messages/load-messages.js';
|
|
6
7
|
import 'node:path';
|
|
7
8
|
import 'node:fs/promises';
|
|
8
9
|
import { createTranslator } from './create-translator.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Initialize a locale-bound Translator snapshot.
|
|
12
13
|
*
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
14
|
+
* - Resolves loader options and loads messages if configured
|
|
15
|
+
* - Creates an immutable Translator instance for server usage
|
|
15
16
|
*/
|
|
16
17
|
async function initTranslator(config, locale, options) {
|
|
17
|
-
const { readers, allowCacheWrite = false, fetch,
|
|
18
|
+
const { readers, allowCacheWrite = false, fetch, handlers, plugins, } = options;
|
|
18
19
|
const loader = resolveLoaderOptions(config, "server");
|
|
19
20
|
// Load messages
|
|
20
21
|
let messages = {};
|
|
@@ -29,14 +30,7 @@ async function initTranslator(config, locale, options) {
|
|
|
29
30
|
messages = loaded || {};
|
|
30
31
|
}
|
|
31
32
|
// Create immutable translator snapshot
|
|
32
|
-
return createTranslator({
|
|
33
|
-
config,
|
|
34
|
-
locale,
|
|
35
|
-
messages,
|
|
36
|
-
preKey,
|
|
37
|
-
handlers,
|
|
38
|
-
plugins,
|
|
39
|
-
});
|
|
33
|
+
return createTranslator({ config, locale, messages, handlers, plugins });
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
export { initTranslator };
|
|
@@ -3,6 +3,7 @@ import '../../../core/error/intor-error.js';
|
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
5
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
import { getClientLocale } from '../../shared/helpers/get-client-locale.js';
|
|
7
8
|
|
|
8
9
|
function useIntor(config, loader) {
|
|
@@ -4,6 +4,7 @@ import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-o
|
|
|
4
4
|
import '../../../../core/error/intor-error.js';
|
|
5
5
|
import 'logry';
|
|
6
6
|
import 'p-limit';
|
|
7
|
+
import 'intor-translator';
|
|
7
8
|
import { getLocaleFromCookie } from '../../../shared/utils/locale/get-locale-from-cookie.js';
|
|
8
9
|
import { setLocaleCookie } from '../../../shared/utils/locale/set-locale-cookie.js';
|
|
9
10
|
import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
|
|
@@ -11,7 +11,6 @@ const createReactRenderer = (tagRenderers) => {
|
|
|
11
11
|
},
|
|
12
12
|
/** Render semantic tag nodes */
|
|
13
13
|
tag(name, _attributes, children) {
|
|
14
|
-
// Custom tag renderers override
|
|
15
14
|
const tagRenderer = tagRenderers?.[name];
|
|
16
15
|
if (tagRenderer) {
|
|
17
16
|
return typeof tagRenderer === "function"
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { renderRichMessage } from 'intor-translator';
|
|
3
|
+
import { createReactRenderer } from '../render/create-react-renderer.js';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Create a React-specific rich translation function.
|
|
@@ -12,11 +14,12 @@ import { renderRichMessageReact } from '../render/render-rich-message-react.js';
|
|
|
12
14
|
*
|
|
13
15
|
* Intended for React client usage only.
|
|
14
16
|
*/
|
|
15
|
-
const createTRich = (
|
|
16
|
-
const t = preKey ? translator.scoped(preKey).t : translator.t;
|
|
17
|
+
const createTRich = (t) => {
|
|
17
18
|
return (key, tagRenderers, replacements) => {
|
|
18
19
|
const message = t(key, replacements);
|
|
19
|
-
|
|
20
|
+
const reactRenderer = createReactRenderer(tagRenderers);
|
|
21
|
+
const nodes = renderRichMessage(message, reactRenderer);
|
|
22
|
+
return nodes.map((node, index) => jsx(Fragment, { children: node }, index));
|
|
20
23
|
};
|
|
21
24
|
};
|
|
22
25
|
|
|
@@ -11,9 +11,9 @@ function useTranslator(preKey) {
|
|
|
11
11
|
locale: translator.locale,
|
|
12
12
|
isLoading: translator.isLoading,
|
|
13
13
|
setLocale,
|
|
14
|
-
hasKey:
|
|
15
|
-
t:
|
|
16
|
-
tRich: createTRich(
|
|
14
|
+
hasKey: scoped.hasKey,
|
|
15
|
+
t: scoped.t,
|
|
16
|
+
tRich: createTRich(scoped.t),
|
|
17
17
|
// NOTE:
|
|
18
18
|
// The runtime implementation is intentionally erased.
|
|
19
19
|
// Type safety is guaranteed by public type contracts.
|
|
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
|
|
|
2
2
|
import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { detectBrowserLocale } from '../utils/locale/detect-browser-locale.js';
|
|
6
7
|
import { getLocaleFromCookie } from '../utils/locale/get-locale-from-cookie.js';
|
|
7
8
|
|
|
@@ -3,6 +3,7 @@ import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options
|
|
|
3
3
|
import 'logry';
|
|
4
4
|
import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
5
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Creates a framework-agnostic message refetcher.
|
|
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
|
|
|
2
2
|
import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { detectBrowserLocale } from '../utils/locale/detect-browser-locale.js';
|
|
6
7
|
import { getLocaleFromCookie } from '../utils/locale/get-locale-from-cookie.js';
|
|
7
8
|
|
|
@@ -3,6 +3,7 @@ import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options
|
|
|
3
3
|
import 'logry';
|
|
4
4
|
import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
5
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
6
|
+
import 'intor-translator';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Creates a framework-agnostic message refetcher.
|
|
@@ -2,6 +2,7 @@ import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-o
|
|
|
2
2
|
import '../../../../core/error/intor-error.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { getLocaleFromCookie } from '../../../shared/utils/locale/get-locale-from-cookie.js';
|
|
6
7
|
import { setLocaleCookie } from '../../../shared/utils/locale/set-locale-cookie.js';
|
|
7
8
|
import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { IntorProviderProps } from "./types";
|
|
2
3
|
import { createIntorStore } from "./create-intor-store";
|
|
3
|
-
|
|
4
|
+
const { value, children } = $props<{
|
|
5
|
+
value: IntorProviderProps["value"];
|
|
6
|
+
children: IntorProviderProps["children"];
|
|
7
|
+
}>();
|
|
8
|
+
// svelte-ignore state_referenced_locally
|
|
4
9
|
createIntorStore(value);
|
|
5
10
|
</script>
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
{@render children()}
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { derived } from 'svelte/store';
|
|
2
|
-
import 'intor-translator';
|
|
3
|
-
import 'svelte';
|
|
4
2
|
import '../../../core/error/intor-error.js';
|
|
5
3
|
import 'logry';
|
|
6
4
|
import 'p-limit';
|
|
5
|
+
import { createTRich } from '../../../core/translator/create-t-rich.js';
|
|
6
|
+
import 'intor-translator';
|
|
7
|
+
import 'svelte';
|
|
7
8
|
import '../provider/intor-provider.svelte';
|
|
8
9
|
import { useIntorContext } from '../provider/use-intor-context.js';
|
|
9
|
-
import { createTRich } from './create-t-rich.js';
|
|
10
10
|
|
|
11
11
|
// Implementation
|
|
12
12
|
function useTranslator(preKey) {
|
|
13
13
|
const { translator, locale, setLocale } = useIntorContext();
|
|
14
|
-
const scoped = preKey
|
|
15
|
-
? derived(translator, ($t) => $t.scoped(preKey))
|
|
16
|
-
: translator;
|
|
14
|
+
const scoped = derived(translator, ($t) => $t.scoped(preKey));
|
|
17
15
|
return {
|
|
18
16
|
messages: derived(translator, ($t) => $t.messages),
|
|
19
17
|
locale,
|
|
@@ -21,7 +19,7 @@ function useTranslator(preKey) {
|
|
|
21
19
|
setLocale,
|
|
22
20
|
hasKey: derived(scoped, ($t) => $t.hasKey),
|
|
23
21
|
t: derived(scoped, ($t) => $t.t),
|
|
24
|
-
tRich: derived(
|
|
22
|
+
tRich: derived(scoped, ($t) => createTRich($t.t)),
|
|
25
23
|
// NOTE:
|
|
26
24
|
// The runtime implementation is intentionally erased.
|
|
27
25
|
// Type safety is guaranteed by public type contracts.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { escapeHtml } from './utils/escape-html.js';
|
|
2
|
+
import { renderAttributes } from './utils/render-attributes.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create an HTML string renderer for semantic rich messages.
|
|
6
|
+
*
|
|
7
|
+
* - Transforms semantic rich AST nodes into escaped HTML strings.
|
|
8
|
+
* - Can be used in any HTML-based environment.
|
|
9
|
+
*
|
|
10
|
+
* This renderer is intentionally minimal and stateless.
|
|
11
|
+
*/
|
|
12
|
+
const createHtmlRenderer = (tagRenderers) => {
|
|
13
|
+
return {
|
|
14
|
+
/** Render plain text nodes */
|
|
15
|
+
text(value) {
|
|
16
|
+
return escapeHtml(value);
|
|
17
|
+
},
|
|
18
|
+
/** Render semantic tag nodes */
|
|
19
|
+
tag(name, attributes, children) {
|
|
20
|
+
const tagRenderer = tagRenderers?.[name];
|
|
21
|
+
if (tagRenderer) {
|
|
22
|
+
return typeof tagRenderer === "function"
|
|
23
|
+
? tagRenderer(children)
|
|
24
|
+
: tagRenderer;
|
|
25
|
+
}
|
|
26
|
+
// Default behavior: render as native HTML tag
|
|
27
|
+
return `<${name}${renderAttributes(attributes)}>${children.join("")}</${name}>`;
|
|
28
|
+
},
|
|
29
|
+
/** Render raw (non-tokenized) message values as escaped HTML strings */
|
|
30
|
+
raw(value) {
|
|
31
|
+
if (value == null)
|
|
32
|
+
return "";
|
|
33
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
34
|
+
return escapeHtml(String(value));
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
return value.map((v) => escapeHtml(String(v))).join("");
|
|
38
|
+
}
|
|
39
|
+
throw new Error("[intor] HTML renderer cannot render raw non-primitive values.");
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { createHtmlRenderer };
|