intor 2.3.30 → 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 -10
- 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 +2 -1
- 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 +26 -17
- package/dist/svelte-kit/src/adapters/svelte-kit/server/intor.js +1 -1
- package/dist/svelte-kit/src/adapters/svelte-kit/server/utils/is-svelte-kit-ssg.js +15 -0
- 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/adapters/svelte-kit/server/utils/is-svelte-kit-ssg.d.ts +8 -0
- 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 +17 -17
- package/dist/express/src/core/constants/headers.js +0 -6
- 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/svelte-kit/src/core/constants/headers.js +0 -6
- 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
|
@@ -8,7 +8,7 @@ import 'p-limit';
|
|
|
8
8
|
export { isValidMessages } from '../src/core/messages/utils/is-valid-messages.js';
|
|
9
9
|
export { mergeMessages } from '../src/core/messages/merge-messages.js';
|
|
10
10
|
export { INTOR_MESSAGES_KIND, INTOR_MESSAGES_KIND_KEY, INTOR_PREFIX, getMessagesKind } from '../src/core/messages/internal-metadata.js';
|
|
11
|
+
export { Translator, tokenize } from 'intor-translator';
|
|
11
12
|
export { defineIntorConfig } from '../src/config/define-intor-config.js';
|
|
12
13
|
import '../src/config/constants/cookie.js';
|
|
13
14
|
export { localizePathname } from '../src/routing/pathname/localize-pathname.js';
|
|
14
|
-
export { Translator, tokenize } from 'intor-translator';
|
|
@@ -4,7 +4,7 @@ import 'node:path';
|
|
|
4
4
|
import 'p-limit';
|
|
5
5
|
import '../../src/core/error/intor-error.js';
|
|
6
6
|
import 'logry';
|
|
7
|
+
import 'intor-translator';
|
|
7
8
|
export { clearMessagesPool } from '../../src/server/messages/load-local-messages/cache/messages-pool.js';
|
|
8
9
|
import 'node:fs/promises';
|
|
9
|
-
import 'intor-translator';
|
|
10
10
|
export { getTranslator } from '../../src/server/helpers/get-translator.js';
|
|
@@ -2,6 +2,7 @@ import '../../core/error/intor-error.js';
|
|
|
2
2
|
import { deepMerge } from '../../core/utils/deep-merge.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
5
6
|
import { DEFAULT_ROUTING_OPTIONS } from '../constants/routing.js';
|
|
6
7
|
import '../constants/cookie.js';
|
|
7
8
|
|
|
@@ -2,15 +2,14 @@ import { escapeHtml } from './utils/escape-html.js';
|
|
|
2
2
|
import { renderAttributes } from './utils/render-attributes.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Create
|
|
5
|
+
* Create an HTML string renderer for semantic rich messages.
|
|
6
6
|
*
|
|
7
|
-
* - Transforms semantic AST nodes into HTML strings.
|
|
8
|
-
* -
|
|
7
|
+
* - Transforms semantic rich AST nodes into escaped HTML strings.
|
|
8
|
+
* - Can be used in any HTML-based environment.
|
|
9
9
|
*
|
|
10
10
|
* This renderer is intentionally minimal and stateless.
|
|
11
11
|
*/
|
|
12
|
-
const
|
|
13
|
-
const { tagRenderers } = options ?? {};
|
|
12
|
+
const createHtmlRenderer = (tagRenderers) => {
|
|
14
13
|
return {
|
|
15
14
|
/** Render plain text nodes */
|
|
16
15
|
text(value) {
|
|
@@ -37,9 +36,9 @@ const createSvelteRenderer = (options) => {
|
|
|
37
36
|
if (Array.isArray(value)) {
|
|
38
37
|
return value.map((v) => escapeHtml(String(v))).join("");
|
|
39
38
|
}
|
|
40
|
-
throw new Error("[intor]
|
|
39
|
+
throw new Error("[intor] HTML renderer cannot render raw non-primitive values.");
|
|
41
40
|
},
|
|
42
41
|
};
|
|
43
42
|
};
|
|
44
43
|
|
|
45
|
-
export {
|
|
44
|
+
export { createHtmlRenderer };
|
|
@@ -4,11 +4,13 @@ function renderAttributes(attributes) {
|
|
|
4
4
|
if (!attributes)
|
|
5
5
|
return "";
|
|
6
6
|
return Object.entries(attributes)
|
|
7
|
-
.map(([key, value]) =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
.map(([key, value]) => {
|
|
8
|
+
if (value === true)
|
|
9
|
+
return ` ${key}`;
|
|
10
|
+
if (value == null)
|
|
11
|
+
return "";
|
|
12
|
+
return ` ${key}="${escapeHtml(String(value))}"`;
|
|
13
|
+
})
|
|
12
14
|
.join("");
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -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 };
|
|
@@ -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 };
|
|
@@ -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
|
|
|
9
9
|
// Implementation
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { INTOR_HEADERS } from '../../../core/constants/headers.js';
|
|
2
1
|
import '../../../core/error/intor-error.js';
|
|
3
2
|
import { normalizeQuery } from '../../../core/utils/normalizers/normalize-query.js';
|
|
4
3
|
import 'logry';
|
|
5
4
|
import 'p-limit';
|
|
5
|
+
import 'intor-translator';
|
|
6
6
|
import { resolveInbound } from '../../../routing/inbound/resolve-inbound.js';
|
|
7
7
|
import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-from-accept-language.js';
|
|
8
8
|
import 'node:path';
|
|
9
9
|
import 'node:fs/promises';
|
|
10
|
-
import 'intor-translator';
|
|
11
10
|
import { getTranslator } from '../../../server/helpers/get-translator.js';
|
|
12
11
|
import { parseCookieHeader } from '../../../server/shared/utils/parse-cookie-header.js';
|
|
13
12
|
|
|
@@ -23,7 +22,7 @@ import { parseCookieHeader } from '../../../server/shared/utils/parse-cookie-hea
|
|
|
23
22
|
*/
|
|
24
23
|
function createIntorMiddleware(config, options) {
|
|
25
24
|
return async function intorMiddleware(req, _res, next) {
|
|
26
|
-
//
|
|
25
|
+
// Locale from Accept-Language header
|
|
27
26
|
const acceptLanguage = req.headers["accept-language"];
|
|
28
27
|
const localeFromAcceptLanguage = getLocaleFromAcceptLanguage(acceptLanguage, config.supportedLocales);
|
|
29
28
|
// ----------------------------------------------------------
|
|
@@ -36,14 +35,9 @@ function createIntorMiddleware(config, options) {
|
|
|
36
35
|
detected: localeFromAcceptLanguage || config.defaultLocale,
|
|
37
36
|
});
|
|
38
37
|
// --------------------------------------------------
|
|
39
|
-
// Attach routing metadata to response headers
|
|
40
|
-
// --------------------------------------------------
|
|
41
|
-
req.headers[INTOR_HEADERS.LOCALE] = locale;
|
|
42
|
-
req.headers[INTOR_HEADERS.LOCALE_SOURCE] = localeSource;
|
|
43
|
-
req.headers[INTOR_HEADERS.PATHNAME] = pathname;
|
|
44
|
-
// --------------------------------------------------
|
|
45
38
|
// Bind inbound routing context
|
|
46
39
|
// --------------------------------------------------
|
|
40
|
+
req.intor = { locale, localeSource, pathname };
|
|
47
41
|
const { hasKey, t } = (await getTranslator(config, {
|
|
48
42
|
locale,
|
|
49
43
|
handlers: options?.handlers,
|
|
@@ -51,7 +45,6 @@ function createIntorMiddleware(config, options) {
|
|
|
51
45
|
readers: options?.readers,
|
|
52
46
|
allowCacheWrite: true,
|
|
53
47
|
}));
|
|
54
|
-
req.intor = { locale, localeSource, pathname };
|
|
55
48
|
// DX shortcuts (optional)
|
|
56
49
|
req.locale = locale;
|
|
57
50
|
req.hasKey = hasKey;
|
|
@@ -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 };
|