@_linked/translation 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/lib/cjs/data/translation.json +8 -0
- package/lib/esm/archive.d.ts +133 -0
- package/lib/esm/archive.js +567 -0
- package/lib/esm/archive.js.map +1 -0
- package/lib/esm/authorization.d.ts +12 -0
- package/lib/esm/authorization.js +10 -0
- package/lib/esm/authorization.js.map +1 -0
- package/lib/esm/backend.d.ts +1 -0
- package/lib/esm/backend.js +3 -0
- package/lib/esm/backend.js.map +1 -0
- package/lib/esm/cdn-loader.d.ts +40 -0
- package/lib/esm/cdn-loader.js +200 -0
- package/lib/esm/cdn-loader.js.map +1 -0
- package/lib/esm/checks.d.ts +56 -0
- package/lib/esm/checks.js +288 -0
- package/lib/esm/checks.js.map +1 -0
- package/lib/esm/compile.d.ts +64 -0
- package/lib/esm/compile.js +99 -0
- package/lib/esm/compile.js.map +1 -0
- package/lib/esm/core/messages.d.ts +25 -0
- package/lib/esm/core/messages.js +76 -0
- package/lib/esm/core/messages.js.map +1 -0
- package/lib/esm/data/translation.json +8 -0
- package/lib/esm/discovery.d.ts +97 -0
- package/lib/esm/discovery.js +365 -0
- package/lib/esm/discovery.js.map +1 -0
- package/lib/esm/exchange.d.ts +100 -0
- package/lib/esm/exchange.js +223 -0
- package/lib/esm/exchange.js.map +1 -0
- package/lib/esm/export.d.ts +28 -0
- package/lib/esm/export.js +92 -0
- package/lib/esm/export.js.map +1 -0
- package/lib/esm/formats/csv.d.ts +8 -0
- package/lib/esm/formats/csv.js +397 -0
- package/lib/esm/formats/csv.js.map +1 -0
- package/lib/esm/formats/json.d.ts +30 -0
- package/lib/esm/formats/json.js +459 -0
- package/lib/esm/formats/json.js.map +1 -0
- package/lib/esm/formats/xliff.d.ts +12 -0
- package/lib/esm/formats/xliff.js +577 -0
- package/lib/esm/formats/xliff.js.map +1 -0
- package/lib/esm/import.d.ts +197 -0
- package/lib/esm/import.js +391 -0
- package/lib/esm/import.js.map +1 -0
- package/lib/esm/index.d.ts +42 -0
- package/lib/esm/index.js +34 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/key-sync-node.d.ts +29 -0
- package/lib/esm/key-sync-node.js +174 -0
- package/lib/esm/key-sync-node.js.map +1 -0
- package/lib/esm/key-sync.d.ts +46 -0
- package/lib/esm/key-sync.js +114 -0
- package/lib/esm/key-sync.js.map +1 -0
- package/lib/esm/key-version.d.ts +50 -0
- package/lib/esm/key-version.js +134 -0
- package/lib/esm/key-version.js.map +1 -0
- package/lib/esm/languages.d.ts +18 -0
- package/lib/esm/languages.js +74 -0
- package/lib/esm/languages.js.map +1 -0
- package/lib/esm/linked-discovery.d.ts +44 -0
- package/lib/esm/linked-discovery.js +267 -0
- package/lib/esm/linked-discovery.js.map +1 -0
- package/lib/esm/message-format.d.ts +41 -0
- package/lib/esm/message-format.js +133 -0
- package/lib/esm/message-format.js.map +1 -0
- package/lib/esm/mt.d.ts +111 -0
- package/lib/esm/mt.js +142 -0
- package/lib/esm/mt.js.map +1 -0
- package/lib/esm/ontologies/translation.d.ts +203 -0
- package/lib/esm/ontologies/translation.js +219 -0
- package/lib/esm/ontologies/translation.js.map +1 -0
- package/lib/esm/package.d.ts +4 -0
- package/lib/esm/package.js +11 -0
- package/lib/esm/package.js.map +1 -0
- package/lib/esm/react.d.ts +55 -0
- package/lib/esm/react.js +127 -0
- package/lib/esm/react.js.map +1 -0
- package/lib/esm/records.d.ts +151 -0
- package/lib/esm/records.js +2 -0
- package/lib/esm/records.js.map +1 -0
- package/lib/esm/release.d.ts +198 -0
- package/lib/esm/release.js +435 -0
- package/lib/esm/release.js.map +1 -0
- package/lib/esm/shape-catalog.d.ts +79 -0
- package/lib/esm/shape-catalog.js +118 -0
- package/lib/esm/shape-catalog.js.map +1 -0
- package/lib/esm/shapes/GlossaryTerm.d.ts +28 -0
- package/lib/esm/shapes/GlossaryTerm.js +94 -0
- package/lib/esm/shapes/GlossaryTerm.js.map +1 -0
- package/lib/esm/shapes/TranslationInventoryOrigin.d.ts +33 -0
- package/lib/esm/shapes/TranslationInventoryOrigin.js +209 -0
- package/lib/esm/shapes/TranslationInventoryOrigin.js.map +1 -0
- package/lib/esm/shapes/TranslationKey.d.ts +92 -0
- package/lib/esm/shapes/TranslationKey.js +194 -0
- package/lib/esm/shapes/TranslationKey.js.map +1 -0
- package/lib/esm/shapes/TranslationKeyVersion.d.ts +19 -0
- package/lib/esm/shapes/TranslationKeyVersion.js +125 -0
- package/lib/esm/shapes/TranslationKeyVersion.js.map +1 -0
- package/lib/esm/shapes/TranslationLanguage.d.ts +15 -0
- package/lib/esm/shapes/TranslationLanguage.js +102 -0
- package/lib/esm/shapes/TranslationLanguage.js.map +1 -0
- package/lib/esm/shapes/TranslationProvider.d.ts +409 -0
- package/lib/esm/shapes/TranslationProvider.js +1376 -0
- package/lib/esm/shapes/TranslationProvider.js.map +1 -0
- package/lib/esm/shapes/TranslationRelease.d.ts +36 -0
- package/lib/esm/shapes/TranslationRelease.js +149 -0
- package/lib/esm/shapes/TranslationRelease.js.map +1 -0
- package/lib/esm/shapes/TranslationRevision.d.ts +39 -0
- package/lib/esm/shapes/TranslationRevision.js +159 -0
- package/lib/esm/shapes/TranslationRevision.js.map +1 -0
- package/lib/esm/shapes/TranslationUnit.d.ts +26 -0
- package/lib/esm/shapes/TranslationUnit.js +111 -0
- package/lib/esm/shapes/TranslationUnit.js.map +1 -0
- package/package.json +134 -0
- package/src/archive.ts +894 -0
- package/src/authorization.ts +33 -0
- package/src/backend.ts +2 -0
- package/src/cdn-loader.ts +264 -0
- package/src/checks.ts +413 -0
- package/src/compile.ts +168 -0
- package/src/core/messages.ts +106 -0
- package/src/data/translation.json +8 -0
- package/src/discovery.ts +594 -0
- package/src/exchange.ts +428 -0
- package/src/export.ts +135 -0
- package/src/formats/csv.ts +459 -0
- package/src/formats/json.ts +587 -0
- package/src/formats/xliff.ts +708 -0
- package/src/import.ts +648 -0
- package/src/index.ts +207 -0
- package/src/key-sync-node.ts +269 -0
- package/src/key-sync.ts +168 -0
- package/src/key-version.ts +206 -0
- package/src/languages.ts +102 -0
- package/src/linked-discovery.ts +385 -0
- package/src/message-format.ts +214 -0
- package/src/mt.ts +248 -0
- package/src/ontologies/translation.ts +234 -0
- package/src/package.ts +19 -0
- package/src/react.tsx +250 -0
- package/src/records.ts +180 -0
- package/src/release.ts +726 -0
- package/src/shape-catalog.ts +198 -0
- package/src/shapes/GlossaryTerm.ts +61 -0
- package/src/shapes/TranslationInventoryOrigin.ts +131 -0
- package/src/shapes/TranslationKey.ts +174 -0
- package/src/shapes/TranslationKeyVersion.ts +77 -0
- package/src/shapes/TranslationLanguage.ts +51 -0
- package/src/shapes/TranslationProvider.ts +1755 -0
- package/src/shapes/TranslationRelease.ts +114 -0
- package/src/shapes/TranslationRevision.ts +105 -0
- package/src/shapes/TranslationUnit.ts +72 -0
package/src/package.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { linkedPackage } from '@_linked/core/utils/Package';
|
|
2
|
+
|
|
3
|
+
// Reusable LINKED translation package. Uses a HOST-NEUTRAL identifier root
|
|
4
|
+
// (NOT CN's id.create.now), so the shape/ontology IRIs baked into every app's
|
|
5
|
+
// dataset stay stable when this package is later extracted to its own repo
|
|
6
|
+
// (`@_linked/translation` / `@semantu/translation`) — a move, not a rewrite
|
|
7
|
+
// (Plan 014 AD-G). R14: confirm ownership of `id.linked.cm` before seeding real
|
|
8
|
+
// data under these IRIs; changing the baseUri afterwards means re-materializing.
|
|
9
|
+
export const {
|
|
10
|
+
linkedShape,
|
|
11
|
+
linkedUtil,
|
|
12
|
+
linkedOntology,
|
|
13
|
+
registerPackageExport,
|
|
14
|
+
packageExports,
|
|
15
|
+
packageName,
|
|
16
|
+
getPackageShape,
|
|
17
|
+
} = linkedPackage('@_linked/translation', {
|
|
18
|
+
baseUri: 'https://id.linked.cm/translation/',
|
|
19
|
+
});
|
package/src/react.tsx
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
languageFallbacks,
|
|
3
|
+
type TranslationLanguageDefinition,
|
|
4
|
+
} from './languages.js';
|
|
5
|
+
import React, {
|
|
6
|
+
createContext,
|
|
7
|
+
useCallback,
|
|
8
|
+
useContext,
|
|
9
|
+
useEffect,
|
|
10
|
+
useMemo,
|
|
11
|
+
useState,
|
|
12
|
+
} from 'react';
|
|
13
|
+
import {
|
|
14
|
+
directionFor,
|
|
15
|
+
type MessageFormat,
|
|
16
|
+
translate,
|
|
17
|
+
type TranslationMessages,
|
|
18
|
+
} from './core/messages.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* React binding for the translation core (Plan 014 P1.5). Kept in a `/react`
|
|
22
|
+
* subpath so non-React consumers use `./core/messages` without pulling React.
|
|
23
|
+
* Message LOADING is caller-injected (`loadMessages`) so this stays transport-
|
|
24
|
+
* agnostic: dev wires it to CN's API, prod to the bundled `{lang}.json` with a
|
|
25
|
+
* CDN overlay (AD-J/AD-K) — the provider doesn't care which.
|
|
26
|
+
*
|
|
27
|
+
* The hook shape mirrors Tolgee (`useTranslate().t(key, default, params)`,
|
|
28
|
+
* `useLanguage()`), so swapping serve's provider touches only its i18n file.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export interface TranslationLanguage {
|
|
32
|
+
tag: string; // BCP-47
|
|
33
|
+
label: string;
|
|
34
|
+
direction?: 'ltr' | 'rtl';
|
|
35
|
+
fallback?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface TranslationCallOptions {
|
|
39
|
+
/** Explicit syntax for an inline default before per-key catalog metadata loads. */
|
|
40
|
+
format?: MessageFormat;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface TranslationContextValue {
|
|
44
|
+
t: (
|
|
45
|
+
key: string,
|
|
46
|
+
defaultValue?: string,
|
|
47
|
+
params?: Record<string, unknown>,
|
|
48
|
+
options?: TranslationCallOptions
|
|
49
|
+
) => string;
|
|
50
|
+
language: string;
|
|
51
|
+
setLanguage: (tag: string) => void;
|
|
52
|
+
languages: TranslationLanguage[];
|
|
53
|
+
dir: 'ltr' | 'rtl';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const TranslationContext = createContext<TranslationContextValue | null>(null);
|
|
57
|
+
|
|
58
|
+
export interface TranslationProviderProps {
|
|
59
|
+
children: React.ReactNode;
|
|
60
|
+
languages: TranslationLanguage[];
|
|
61
|
+
/** Optional live catalog metadata, refreshed independently of an app build. */
|
|
62
|
+
loadLanguages?: () => Promise<TranslationLanguageDefinition[]>;
|
|
63
|
+
defaultLanguage?: string;
|
|
64
|
+
/** Global message format. 'simple' = FormatSimple (Tolgee-compatible default). */
|
|
65
|
+
format?: MessageFormat;
|
|
66
|
+
/** Caller-injected loader: dev→API, prod→bundled file then CDN overlay. */
|
|
67
|
+
loadMessages: (language: string) => Promise<TranslationMessages>;
|
|
68
|
+
/** localStorage key persisting the selected language. */
|
|
69
|
+
storageKey?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function TranslationProvider({
|
|
73
|
+
children,
|
|
74
|
+
languages: initialLanguages,
|
|
75
|
+
loadLanguages,
|
|
76
|
+
defaultLanguage = 'en',
|
|
77
|
+
format = 'simple',
|
|
78
|
+
loadMessages,
|
|
79
|
+
storageKey = 'linked.lang',
|
|
80
|
+
}: TranslationProviderProps) {
|
|
81
|
+
const [remoteLanguages, setRemoteLanguages] =
|
|
82
|
+
useState<TranslationLanguageDefinition[]>();
|
|
83
|
+
const languages = remoteLanguages
|
|
84
|
+
? remoteLanguages
|
|
85
|
+
.filter((item) => item.enabled && item.supported)
|
|
86
|
+
.map((item) => ({
|
|
87
|
+
tag: item.code,
|
|
88
|
+
label: item.nativeName,
|
|
89
|
+
direction: item.direction,
|
|
90
|
+
fallback: item.fallback,
|
|
91
|
+
}))
|
|
92
|
+
: initialLanguages;
|
|
93
|
+
const [language, setLanguageState] = useState<string>(() => {
|
|
94
|
+
if (typeof window !== 'undefined') {
|
|
95
|
+
const stored = window.localStorage?.getItem(storageKey);
|
|
96
|
+
if (stored && languages.some((l) => l.tag === stored)) return stored;
|
|
97
|
+
}
|
|
98
|
+
return defaultLanguage;
|
|
99
|
+
});
|
|
100
|
+
const dir =
|
|
101
|
+
languages.find((item) => item.tag === language)?.direction ??
|
|
102
|
+
directionFor(language);
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (!loadLanguages) return;
|
|
105
|
+
let cancelled = false;
|
|
106
|
+
loadLanguages()
|
|
107
|
+
.then((items) => {
|
|
108
|
+
if (!cancelled) {
|
|
109
|
+
setRemoteLanguages(items);
|
|
110
|
+
setMessagesByLang({});
|
|
111
|
+
const stored =
|
|
112
|
+
typeof window !== 'undefined'
|
|
113
|
+
? window.localStorage?.getItem(storageKey)
|
|
114
|
+
: null;
|
|
115
|
+
if (
|
|
116
|
+
stored &&
|
|
117
|
+
items.some(
|
|
118
|
+
(item) => item.code === stored && item.enabled && item.supported
|
|
119
|
+
)
|
|
120
|
+
)
|
|
121
|
+
setLanguageState(stored);
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
.catch(() => {});
|
|
125
|
+
return () => {
|
|
126
|
+
cancelled = true;
|
|
127
|
+
};
|
|
128
|
+
}, [loadLanguages, storageKey]);
|
|
129
|
+
const [messagesByLang, setMessagesByLang] = useState<
|
|
130
|
+
Record<string, TranslationMessages>
|
|
131
|
+
>({});
|
|
132
|
+
|
|
133
|
+
// Load the active language's messages once. English renders from inline
|
|
134
|
+
// defaults until (and if) a payload arrives, so the app is never blank.
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (messagesByLang[language]) return;
|
|
137
|
+
let cancelled = false;
|
|
138
|
+
const chain = languageFallbacks(
|
|
139
|
+
language,
|
|
140
|
+
defaultLanguage,
|
|
141
|
+
remoteLanguages
|
|
142
|
+
).reverse();
|
|
143
|
+
Promise.all(chain.map((code) => loadMessages(code).catch(() => ({}))))
|
|
144
|
+
.then((maps) => Object.assign({}, ...maps) as TranslationMessages)
|
|
145
|
+
.then((msgs) => {
|
|
146
|
+
if (!cancelled) {
|
|
147
|
+
setMessagesByLang((prev) => ({ ...prev, [language]: msgs }));
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
.catch(() => {
|
|
151
|
+
/* offline / missing → keep inline defaults */
|
|
152
|
+
});
|
|
153
|
+
return () => {
|
|
154
|
+
cancelled = true;
|
|
155
|
+
};
|
|
156
|
+
}, [
|
|
157
|
+
language,
|
|
158
|
+
loadMessages,
|
|
159
|
+
messagesByLang,
|
|
160
|
+
defaultLanguage,
|
|
161
|
+
remoteLanguages,
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
// Reflect the configured language and text direction on <html>.
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (typeof document !== 'undefined') {
|
|
167
|
+
document.documentElement.dir = dir;
|
|
168
|
+
document.documentElement.lang = language;
|
|
169
|
+
}
|
|
170
|
+
}, [language, dir]);
|
|
171
|
+
|
|
172
|
+
const setLanguage = useCallback(
|
|
173
|
+
(tag: string) => {
|
|
174
|
+
setLanguageState(tag);
|
|
175
|
+
if (typeof window !== 'undefined') {
|
|
176
|
+
window.localStorage?.setItem(storageKey, tag);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
[storageKey]
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
const t = useCallback(
|
|
183
|
+
(
|
|
184
|
+
key: string,
|
|
185
|
+
defaultValue?: string,
|
|
186
|
+
params?: Record<string, unknown>,
|
|
187
|
+
options?: TranslationCallOptions
|
|
188
|
+
) =>
|
|
189
|
+
translate(
|
|
190
|
+
messagesByLang[language] ?? {},
|
|
191
|
+
key,
|
|
192
|
+
defaultValue,
|
|
193
|
+
params,
|
|
194
|
+
options?.format ?? format,
|
|
195
|
+
language
|
|
196
|
+
),
|
|
197
|
+
[messagesByLang, language, format]
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const value = useMemo<TranslationContextValue>(
|
|
201
|
+
() => ({ t, language, setLanguage, languages, dir }),
|
|
202
|
+
[t, language, setLanguage, languages, dir]
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<TranslationContext.Provider value={value}>
|
|
207
|
+
{children}
|
|
208
|
+
</TranslationContext.Provider>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function useTranslationContext(hook: string): TranslationContextValue {
|
|
213
|
+
const ctx = useContext(TranslationContext);
|
|
214
|
+
if (!ctx)
|
|
215
|
+
throw new Error(`${hook} must be used within a <TranslationProvider>`);
|
|
216
|
+
return ctx;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Tolgee-compatible: `const { t } = useTranslate()`. */
|
|
220
|
+
export function useTranslate() {
|
|
221
|
+
const ctx = useTranslationContext('useTranslate');
|
|
222
|
+
return { t: ctx.t };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Active language + switcher + direction + the available languages. */
|
|
226
|
+
export function useLanguage() {
|
|
227
|
+
const ctx = useTranslationContext('useLanguage');
|
|
228
|
+
return {
|
|
229
|
+
language: ctx.language,
|
|
230
|
+
setLanguage: ctx.setLanguage,
|
|
231
|
+
languages: ctx.languages,
|
|
232
|
+
dir: ctx.dir,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** JSX convenience (Tolgee `<T keyName=… />`). */
|
|
237
|
+
export function T({
|
|
238
|
+
keyName,
|
|
239
|
+
defaultValue,
|
|
240
|
+
params,
|
|
241
|
+
format,
|
|
242
|
+
}: {
|
|
243
|
+
keyName: string;
|
|
244
|
+
defaultValue?: string;
|
|
245
|
+
params?: Record<string, unknown>;
|
|
246
|
+
format?: MessageFormat;
|
|
247
|
+
}) {
|
|
248
|
+
const { t } = useTranslate();
|
|
249
|
+
return <>{t(keyName, defaultValue, params, { format })}</>;
|
|
250
|
+
}
|
package/src/records.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/** Review lifecycle shared by the portable runtime and authoring clients. */
|
|
2
|
+
export type TranslationState =
|
|
3
|
+
| 'untranslated'
|
|
4
|
+
| 'machine'
|
|
5
|
+
| 'reviewed'
|
|
6
|
+
| 'stale';
|
|
7
|
+
|
|
8
|
+
/** Plain RPC-safe value for one language. Never contains a live Shape. */
|
|
9
|
+
export interface TranslationUnitRecord {
|
|
10
|
+
language: string;
|
|
11
|
+
text: string;
|
|
12
|
+
state: TranslationState;
|
|
13
|
+
/** Machine-provider provenance for the current value (`tm` for memory). */
|
|
14
|
+
origin?: string;
|
|
15
|
+
updatedAt?: string;
|
|
16
|
+
keyVersionId?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Plain immutable source/argument-contract record for Studio and RPC. */
|
|
20
|
+
export interface TranslationKeyVersionRecord {
|
|
21
|
+
id: string;
|
|
22
|
+
versionId: string;
|
|
23
|
+
sourceLanguage: string;
|
|
24
|
+
sourceText: string;
|
|
25
|
+
format: 'simple' | 'icu';
|
|
26
|
+
argumentSignature: string;
|
|
27
|
+
contractHash: string;
|
|
28
|
+
sourceHash: string;
|
|
29
|
+
supersedes?: string;
|
|
30
|
+
createdAt?: string;
|
|
31
|
+
createdBy?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type TranslationReleaseChannel = 'preview' | 'production';
|
|
35
|
+
export type TranslationReleaseStatus =
|
|
36
|
+
| 'draft'
|
|
37
|
+
| 'published'
|
|
38
|
+
| 'superseded'
|
|
39
|
+
| 'retired';
|
|
40
|
+
|
|
41
|
+
/** Plain graph metadata for a schema-v2 translation release. */
|
|
42
|
+
export interface TranslationReleaseRecord {
|
|
43
|
+
id: string;
|
|
44
|
+
releaseId: string;
|
|
45
|
+
appId: string;
|
|
46
|
+
branchId: string;
|
|
47
|
+
buildId?: string;
|
|
48
|
+
channel: TranslationReleaseChannel;
|
|
49
|
+
status: TranslationReleaseStatus;
|
|
50
|
+
contractSetHash: string;
|
|
51
|
+
manifestHash: string;
|
|
52
|
+
hotfixSequence: number;
|
|
53
|
+
qualitySummary?: string;
|
|
54
|
+
createdAt: string;
|
|
55
|
+
publishedAt?: string;
|
|
56
|
+
supportedUntil?: string;
|
|
57
|
+
supersedes?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Lifecycle of one authored value (Plan 017 AD-P). */
|
|
61
|
+
export type TranslationRevisionStatus =
|
|
62
|
+
| 'applied' // a direct edit, recorded as history
|
|
63
|
+
| 'proposed' // awaiting a reviewer (human author)
|
|
64
|
+
| 'suggested' // awaiting a reviewer (machine author)
|
|
65
|
+
| 'accepted'
|
|
66
|
+
| 'rejected'
|
|
67
|
+
| 'superseded';
|
|
68
|
+
|
|
69
|
+
/** Plain RPC-safe view of one revision (history entry / pending value). */
|
|
70
|
+
export interface TranslationRevisionRecord {
|
|
71
|
+
id: string;
|
|
72
|
+
key: string;
|
|
73
|
+
language: string;
|
|
74
|
+
text: string;
|
|
75
|
+
status: TranslationRevisionStatus;
|
|
76
|
+
author?: string;
|
|
77
|
+
authorKind: 'human' | 'machine';
|
|
78
|
+
mtProvider?: string;
|
|
79
|
+
basedOnText?: string;
|
|
80
|
+
note?: string;
|
|
81
|
+
createdAt?: string;
|
|
82
|
+
decidedAt?: string;
|
|
83
|
+
decidedBy?: string;
|
|
84
|
+
keyVersionId?: string;
|
|
85
|
+
/** Current unit diverged after this proposal was authored. */
|
|
86
|
+
conflicted?: boolean;
|
|
87
|
+
currentText?: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface TranslationProposalDecision {
|
|
91
|
+
revision: TranslationRevisionRecord;
|
|
92
|
+
unit?: TranslationUnitRecord;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type TranslationMemoryMatchKind = 'exact' | 'carry-forward';
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* One reviewed unit that can seed the current key version. Exact source
|
|
99
|
+
* matches may pretranslate as machine/TM; changed source text is an explicit
|
|
100
|
+
* same-key carry-forward review.
|
|
101
|
+
*/
|
|
102
|
+
export interface TranslationMemoryMatchRecord {
|
|
103
|
+
unitId: string;
|
|
104
|
+
key: string;
|
|
105
|
+
language: string;
|
|
106
|
+
text: string;
|
|
107
|
+
keyVersionId: string;
|
|
108
|
+
sourceText: string;
|
|
109
|
+
sourceHash: string;
|
|
110
|
+
contractHash: string;
|
|
111
|
+
kind: TranslationMemoryMatchKind;
|
|
112
|
+
updatedAt?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Searchable reviewed unit exposed by the explicit Translation Memory browser. */
|
|
116
|
+
export interface TranslationMemoryRecord {
|
|
117
|
+
unitId: string;
|
|
118
|
+
key: string;
|
|
119
|
+
language: string;
|
|
120
|
+
text: string;
|
|
121
|
+
keyVersionId: string;
|
|
122
|
+
sourceText: string;
|
|
123
|
+
sourceHash: string;
|
|
124
|
+
contractHash: string;
|
|
125
|
+
updatedAt?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface TranslationMemoryPretranslateCandidate {
|
|
129
|
+
key: string;
|
|
130
|
+
language: string;
|
|
131
|
+
unitId: string;
|
|
132
|
+
sourceKey: string;
|
|
133
|
+
text: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface TranslationMemoryPretranslateReport {
|
|
137
|
+
language: string;
|
|
138
|
+
eligible: number;
|
|
139
|
+
translated: number;
|
|
140
|
+
candidates: TranslationMemoryPretranslateCandidate[];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Termbase entry behavior (Plan 017 B2-1). */
|
|
144
|
+
export type GlossaryTermType = 'prefer' | 'require' | 'keep' | 'forbid';
|
|
145
|
+
|
|
146
|
+
/** Plain RPC-safe termbase entry (steers MT + checks; Plan 014 AD-L / 017 B2). */
|
|
147
|
+
export interface GlossaryTermRecord {
|
|
148
|
+
id: string;
|
|
149
|
+
term: string;
|
|
150
|
+
/** prefer = translate as `translation`; keep = do-not-translate; forbid = never use. */
|
|
151
|
+
termType: GlossaryTermType;
|
|
152
|
+
/** Preferred translation (prefer entries). */
|
|
153
|
+
translation?: string;
|
|
154
|
+
/** Replacement wording (forbid entries — alternative-spelling policing). */
|
|
155
|
+
useInstead?: string;
|
|
156
|
+
/** Target language this applies to; empty = all languages. */
|
|
157
|
+
language?: string;
|
|
158
|
+
/** Exact-casing match (proper nouns / all-caps styling). */
|
|
159
|
+
caseSensitive?: boolean;
|
|
160
|
+
description?: string;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Plain RPC-safe editor/runtime view of a key and its language values. */
|
|
164
|
+
export interface TranslationEntryRecord {
|
|
165
|
+
key: string;
|
|
166
|
+
namespace: string;
|
|
167
|
+
sourceText: string;
|
|
168
|
+
description?: string;
|
|
169
|
+
kind: 'ui' | 'content';
|
|
170
|
+
format: 'simple' | 'icu';
|
|
171
|
+
/** Optional semantic organization for translations supplied with LINKED shapes. */
|
|
172
|
+
ofShape?: string;
|
|
173
|
+
ofProperty?: string;
|
|
174
|
+
fromPackage?: string;
|
|
175
|
+
/** This app diverged a shape-owned key locally; shape propagation skips it (AD-N). */
|
|
176
|
+
overridden?: boolean;
|
|
177
|
+
currentVersion?: TranslationKeyVersionRecord;
|
|
178
|
+
versions?: TranslationKeyVersionRecord[];
|
|
179
|
+
units: Record<string, TranslationUnitRecord>;
|
|
180
|
+
}
|