@_linked/translation 0.8.1 → 0.9.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/lib/esm/authorization.js +8 -2
- package/lib/esm/authorization.js.map +1 -1
- package/lib/esm/data/translation.ttl +489 -0
- package/lib/esm/exchange.js +12 -2
- package/lib/esm/exchange.js.map +1 -1
- package/lib/esm/mt.js +6 -1
- package/lib/esm/mt.js.map +1 -1
- package/lib/esm/ontologies/translation.d.ts +4 -9
- package/lib/esm/ontologies/translation.js +5 -5
- package/lib/esm/ontologies/translation.js.map +1 -1
- package/lib/esm/ontologies/translation.register.js +2 -2
- package/lib/esm/ontologies/translation.register.js.map +1 -1
- package/lib/esm/package.d.ts +1 -1
- package/lib/esm/react.js +6 -1
- package/lib/esm/react.js.map +1 -1
- package/package.json +4 -4
- package/src/authorization.ts +9 -2
- package/src/data/translation.ttl +489 -0
- package/src/exchange.ts +11 -2
- package/src/mt.ts +6 -1
- package/src/ontologies/translation.register.ts +2 -2
- package/src/ontologies/translation.ts +6 -7
- package/src/react.tsx +6 -1
- package/lib/esm/data/translation.json +0 -8
- package/src/data/translation.json +0 -8
package/lib/esm/authorization.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { sharedState } from '@_linked/core/utils/sharedState';
|
|
2
|
+
// On globalThis so a second copy of this module sees the resolver the host configured on the
|
|
3
|
+
// first; a copy that cannot see it would deny every author.
|
|
4
|
+
const state = sharedState('@_linked/translation', 'authorization', () => ({
|
|
5
|
+
resolver: undefined,
|
|
6
|
+
}));
|
|
2
7
|
/**
|
|
3
8
|
* Host hook: the host decides who may read and author an app's translations
|
|
4
9
|
* (for example by evaluating its own translator assignments and project roles).
|
|
@@ -8,13 +13,14 @@ let resolver;
|
|
|
8
13
|
* public runtime fetch (`getMessages`) keeps working.
|
|
9
14
|
*/
|
|
10
15
|
export function configureTranslationAuthorization(next) {
|
|
11
|
-
resolver = next;
|
|
16
|
+
state.resolver = next;
|
|
12
17
|
}
|
|
13
18
|
/**
|
|
14
19
|
* Whether the host's resolver grants `request`. Denies when no resolver is
|
|
15
20
|
* configured, and when the resolver throws or answers anything but `true`.
|
|
16
21
|
*/
|
|
17
22
|
export async function canAuthorTranslation(request) {
|
|
23
|
+
const resolver = state.resolver;
|
|
18
24
|
if (!resolver)
|
|
19
25
|
return false;
|
|
20
26
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/authorization.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAoB9D,6FAA6F;AAC7F,4DAA4D;AAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,sBAAsB,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IACxE,QAAQ,EAAE,SAAyD;CACpE,CAAC,CAAC,CAAC;AAEJ;;;;;;;GAOG;AACH,MAAM,UAAU,iCAAiC,CAC/C,IAAuC;IAEvC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAwC;IAExC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,uDAAuD,EAAE,KAAK,CAAC,CAAC;QAC7E,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["import { sharedState } from '@_linked/core/utils/sharedState';\n\nexport type TranslationAuthoringAction =\n | 'manage'\n | 'review'\n | 'propose'\n | 'run-mt'\n | 'read';\n\nexport interface TranslationAuthorizationRequest {\n appId: string;\n actorWebId: string;\n action: TranslationAuthoringAction;\n language?: string;\n}\n\nexport type TranslationAuthorizationResolver = (\n request: TranslationAuthorizationRequest,\n) => Promise<boolean>;\n\n// On globalThis so a second copy of this module sees the resolver the host configured on the\n// first; a copy that cannot see it would deny every author.\nconst state = sharedState('@_linked/translation', 'authorization', () => ({\n resolver: undefined as TranslationAuthorizationResolver | undefined,\n}));\n\n/**\n * Host hook: the host decides who may read and author an app's translations\n * (for example by evaluating its own translator assignments and project roles).\n *\n * The resolver is the only source of a \"yes\". A host that does not configure\n * one gets no authoring or read access over the translation provider; only the\n * public runtime fetch (`getMessages`) keeps working.\n */\nexport function configureTranslationAuthorization(\n next?: TranslationAuthorizationResolver,\n): void {\n state.resolver = next;\n}\n\n/**\n * Whether the host's resolver grants `request`. Denies when no resolver is\n * configured, and when the resolver throws or answers anything but `true`.\n */\nexport async function canAuthorTranslation(\n request: TranslationAuthorizationRequest,\n): Promise<boolean> {\n const resolver = state.resolver;\n if (!resolver) return false;\n try {\n return (await resolver(request)) === true;\n } catch (error) {\n console.warn('[translation] authorization resolver failed; denying.', error);\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
@prefix translation: <https://linked.cm/ont/translation/> .
|
|
2
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
3
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
4
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
5
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
6
|
+
@prefix dcterms: <http://purl.org/dc/terms/> .
|
|
7
|
+
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
|
|
8
|
+
@prefix schema: <http://schema.org/> .
|
|
9
|
+
|
|
10
|
+
translation:
|
|
11
|
+
a owl:Ontology ;
|
|
12
|
+
dcterms:description "Terms of translation keys, their versions, per-language units, revisions, releases, glossary and inventory."@en ;
|
|
13
|
+
dcterms:title "Linked translation"@en ;
|
|
14
|
+
owl:versionInfo "0.9.0" .
|
|
15
|
+
|
|
16
|
+
translation:GlossaryTerm
|
|
17
|
+
a owl:Class ;
|
|
18
|
+
rdfs:comment "A glossary entry that steers machine translation, such as a brand name to keep or a spelling to forbid."@en ;
|
|
19
|
+
rdfs:label "glossary term"@en .
|
|
20
|
+
|
|
21
|
+
translation:TranslationInventoryOrigin
|
|
22
|
+
a owl:Class ;
|
|
23
|
+
rdfs:comment "One place a branch's translation inventory observed a key, such as a source file line or a shape property."@en ;
|
|
24
|
+
rdfs:label "translation inventory origin"@en .
|
|
25
|
+
|
|
26
|
+
translation:TranslationKey
|
|
27
|
+
a owl:Class ;
|
|
28
|
+
rdfs:comment "A translatable key, either a UI string (kind ui) or a field of a graph node (kind content), with its canonical English source text."@en ;
|
|
29
|
+
rdfs:label "translation key"@en .
|
|
30
|
+
|
|
31
|
+
translation:TranslationKeyVersion
|
|
32
|
+
a owl:Class ;
|
|
33
|
+
rdfs:comment "An immutable version of a key's source text and runtime argument contract."@en ;
|
|
34
|
+
rdfs:label "translation key version"@en .
|
|
35
|
+
|
|
36
|
+
translation:TranslationLanguage
|
|
37
|
+
a owl:Class ;
|
|
38
|
+
rdfs:comment "A language an app is configured for, identified by its BCP-47 tag."@en ;
|
|
39
|
+
rdfs:label "translation language"@en .
|
|
40
|
+
|
|
41
|
+
translation:TranslationRelease
|
|
42
|
+
a owl:Class ;
|
|
43
|
+
rdfs:comment "Graph metadata of an immutable translation release, whose key and language selection lives in a content-addressed manifest."@en ;
|
|
44
|
+
rdfs:label "translation release"@en .
|
|
45
|
+
|
|
46
|
+
translation:TranslationRevision
|
|
47
|
+
a owl:Class ;
|
|
48
|
+
rdfs:comment "One append-only authored value for a key and language: a change in its history, a translator's proposal or a machine suggestion."@en ;
|
|
49
|
+
rdfs:label "translation revision"@en .
|
|
50
|
+
|
|
51
|
+
translation:TranslationUnit
|
|
52
|
+
a owl:Class ;
|
|
53
|
+
rdfs:comment "One language's current value for a translation key, with its review state and provenance."@en ;
|
|
54
|
+
rdfs:label "translation unit"@en .
|
|
55
|
+
|
|
56
|
+
translation:argumentSignature
|
|
57
|
+
a owl:DatatypeProperty ;
|
|
58
|
+
rdfs:comment "The runtime arguments a key version's message takes."@en ;
|
|
59
|
+
rdfs:label "argument signature"@en .
|
|
60
|
+
|
|
61
|
+
translation:author
|
|
62
|
+
a owl:ObjectProperty ;
|
|
63
|
+
rdfs:comment "The WebID or machine translation provider that wrote a revision."@en ;
|
|
64
|
+
rdfs:label "author"@en .
|
|
65
|
+
|
|
66
|
+
translation:authorKind
|
|
67
|
+
a owl:DatatypeProperty ;
|
|
68
|
+
rdfs:comment "Whether a revision was written by a human or a machine."@en ;
|
|
69
|
+
rdfs:label "author kind"@en .
|
|
70
|
+
|
|
71
|
+
translation:autoPublish
|
|
72
|
+
a owl:DatatypeProperty ;
|
|
73
|
+
rdfs:comment "Whether an edit publishes translations automatically (off by default)."@en ;
|
|
74
|
+
rdfs:label "auto publish"@en .
|
|
75
|
+
|
|
76
|
+
translation:basedOnText
|
|
77
|
+
a owl:DatatypeProperty ;
|
|
78
|
+
rdfs:comment "The unit's text when a revision was written, to detect conflicts."@en ;
|
|
79
|
+
rdfs:label "based on text"@en .
|
|
80
|
+
|
|
81
|
+
translation:branch
|
|
82
|
+
a owl:ObjectProperty ;
|
|
83
|
+
rdfs:comment "The branch a translation release was built from."@en ;
|
|
84
|
+
rdfs:label "branch"@en .
|
|
85
|
+
|
|
86
|
+
translation:buildId
|
|
87
|
+
a owl:DatatypeProperty ;
|
|
88
|
+
rdfs:comment "The identifier of the build a translation release was cut for."@en ;
|
|
89
|
+
rdfs:label "build id"@en .
|
|
90
|
+
|
|
91
|
+
translation:caseSensitive
|
|
92
|
+
a owl:DatatypeProperty ;
|
|
93
|
+
rdfs:comment "Whether a glossary term matches only with its exact casing."@en ;
|
|
94
|
+
rdfs:label "case sensitive"@en .
|
|
95
|
+
|
|
96
|
+
translation:cdnTarget
|
|
97
|
+
a owl:DatatypeProperty ;
|
|
98
|
+
rdfs:comment "The base URL or bucket prefix translations are delivered to."@en ;
|
|
99
|
+
rdfs:label "CDN target"@en .
|
|
100
|
+
|
|
101
|
+
translation:channel
|
|
102
|
+
a owl:DatatypeProperty ;
|
|
103
|
+
rdfs:comment "The delivery channel of a translation release, preview or production."@en ;
|
|
104
|
+
rdfs:label "channel"@en .
|
|
105
|
+
|
|
106
|
+
translation:contractHash
|
|
107
|
+
a owl:DatatypeProperty ;
|
|
108
|
+
rdfs:comment "The hash of a key version's source text and argument contract."@en ;
|
|
109
|
+
rdfs:label "contract hash"@en .
|
|
110
|
+
|
|
111
|
+
translation:contractSetHash
|
|
112
|
+
a owl:DatatypeProperty ;
|
|
113
|
+
rdfs:comment "The hash of every key contract a release covers."@en ;
|
|
114
|
+
rdfs:label "contract set hash"@en .
|
|
115
|
+
|
|
116
|
+
translation:createdAt
|
|
117
|
+
a owl:DatatypeProperty ;
|
|
118
|
+
rdfs:comment "When a key version, release or revision was created."@en ;
|
|
119
|
+
rdfs:label "created at"@en .
|
|
120
|
+
|
|
121
|
+
translation:createdBy
|
|
122
|
+
a owl:ObjectProperty ;
|
|
123
|
+
rdfs:comment "The WebID that created a key version."@en ;
|
|
124
|
+
rdfs:label "created by"@en .
|
|
125
|
+
|
|
126
|
+
translation:currentVersion
|
|
127
|
+
a owl:ObjectProperty ;
|
|
128
|
+
rdfs:comment "The key version that is a translation key's current source."@en ;
|
|
129
|
+
rdfs:label "current version"@en .
|
|
130
|
+
|
|
131
|
+
translation:decidedAt
|
|
132
|
+
a owl:DatatypeProperty ;
|
|
133
|
+
rdfs:comment "When a proposed or suggested revision was accepted or rejected."@en ;
|
|
134
|
+
rdfs:label "decided at"@en .
|
|
135
|
+
|
|
136
|
+
translation:decidedBy
|
|
137
|
+
a owl:ObjectProperty ;
|
|
138
|
+
rdfs:comment "The WebID of the reviewer who decided a revision."@en ;
|
|
139
|
+
rdfs:label "decided by"@en .
|
|
140
|
+
|
|
141
|
+
translation:defaultLanguage
|
|
142
|
+
a owl:DatatypeProperty ;
|
|
143
|
+
rdfs:comment "The BCP-47 tag of the app's authored source language."@en ;
|
|
144
|
+
rdfs:label "default language"@en .
|
|
145
|
+
|
|
146
|
+
translation:description
|
|
147
|
+
a owl:DatatypeProperty ;
|
|
148
|
+
rdfs:comment "A note that tells translators what a key or glossary term means and where it appears."@en ;
|
|
149
|
+
rdfs:label "description"@en .
|
|
150
|
+
|
|
151
|
+
translation:englishName
|
|
152
|
+
a owl:DatatypeProperty ;
|
|
153
|
+
rdfs:comment "A language's name in English."@en ;
|
|
154
|
+
rdfs:label "English name"@en .
|
|
155
|
+
|
|
156
|
+
translation:fallbackLanguage
|
|
157
|
+
a owl:ObjectProperty ;
|
|
158
|
+
rdfs:comment "The language whose text is shown when a value is missing in this one."@en ;
|
|
159
|
+
rdfs:label "fallback language"@en .
|
|
160
|
+
|
|
161
|
+
translation:format
|
|
162
|
+
a owl:DatatypeProperty ;
|
|
163
|
+
rdfs:comment "The message syntax of a key's text, simple or icu."@en ;
|
|
164
|
+
rdfs:label "format"@en .
|
|
165
|
+
|
|
166
|
+
translation:fromPackage
|
|
167
|
+
a owl:DatatypeProperty ;
|
|
168
|
+
rdfs:comment "The package whose seed catalog supplied a key."@en ;
|
|
169
|
+
rdfs:label "from package"@en .
|
|
170
|
+
|
|
171
|
+
translation:glossaryLanguage
|
|
172
|
+
a owl:DatatypeProperty ;
|
|
173
|
+
rdfs:comment "The BCP-47 tag of the language a glossary translation is for."@en ;
|
|
174
|
+
rdfs:label "glossary language"@en .
|
|
175
|
+
|
|
176
|
+
translation:glossaryTranslation
|
|
177
|
+
a owl:DatatypeProperty ;
|
|
178
|
+
rdfs:comment "The required translation of a glossary term."@en ;
|
|
179
|
+
rdfs:label "glossary translation"@en .
|
|
180
|
+
|
|
181
|
+
translation:hotfixSequence
|
|
182
|
+
a owl:DatatypeProperty ;
|
|
183
|
+
rdfs:comment "The hotfix number of a release on top of its base release."@en ;
|
|
184
|
+
rdfs:label "hotfix sequence"@en .
|
|
185
|
+
|
|
186
|
+
translation:inventoryAuthoritative
|
|
187
|
+
a owl:DatatypeProperty ;
|
|
188
|
+
rdfs:comment "Whether an inventory origin is the authoritative one for its key."@en ;
|
|
189
|
+
rdfs:label "inventory authoritative"@en .
|
|
190
|
+
|
|
191
|
+
translation:inventoryBranch
|
|
192
|
+
a owl:ObjectProperty ;
|
|
193
|
+
rdfs:comment "The branch an inventory origin was observed on."@en ;
|
|
194
|
+
rdfs:label "inventory branch"@en .
|
|
195
|
+
|
|
196
|
+
translation:inventoryFile
|
|
197
|
+
a owl:DatatypeProperty ;
|
|
198
|
+
rdfs:comment "The source file an inventory origin was found in."@en ;
|
|
199
|
+
rdfs:label "inventory file"@en .
|
|
200
|
+
|
|
201
|
+
translation:inventoryIdentity
|
|
202
|
+
a owl:DatatypeProperty ;
|
|
203
|
+
rdfs:comment "The stable identity of an inventory item across observations."@en ;
|
|
204
|
+
rdfs:label "inventory identity"@en .
|
|
205
|
+
|
|
206
|
+
translation:inventoryLine
|
|
207
|
+
a owl:DatatypeProperty ;
|
|
208
|
+
rdfs:comment "The line of the source file an inventory origin was found on."@en ;
|
|
209
|
+
rdfs:label "inventory line"@en .
|
|
210
|
+
|
|
211
|
+
translation:inventoryNode
|
|
212
|
+
a owl:ObjectProperty ;
|
|
213
|
+
rdfs:comment "The IRI of the graph node an inventory origin was found on."@en ;
|
|
214
|
+
rdfs:label "inventory node"@en .
|
|
215
|
+
|
|
216
|
+
translation:inventoryObservedAt
|
|
217
|
+
a owl:DatatypeProperty ;
|
|
218
|
+
rdfs:comment "When an inventory origin was last observed."@en ;
|
|
219
|
+
rdfs:label "inventory observed at"@en .
|
|
220
|
+
|
|
221
|
+
translation:inventoryOwner
|
|
222
|
+
a owl:ObjectProperty ;
|
|
223
|
+
rdfs:comment "The IRI of the node that owns an inventory origin."@en ;
|
|
224
|
+
rdfs:label "inventory owner"@en .
|
|
225
|
+
|
|
226
|
+
translation:inventoryProperty
|
|
227
|
+
a owl:ObjectProperty ;
|
|
228
|
+
rdfs:comment "The IRI of the property an inventory origin was found on."@en ;
|
|
229
|
+
rdfs:label "inventory property"@en .
|
|
230
|
+
|
|
231
|
+
translation:inventoryShape
|
|
232
|
+
a owl:ObjectProperty ;
|
|
233
|
+
rdfs:comment "The IRI of the shape an inventory origin was found on."@en ;
|
|
234
|
+
rdfs:label "inventory shape"@en .
|
|
235
|
+
|
|
236
|
+
translation:inventorySource
|
|
237
|
+
a owl:DatatypeProperty ;
|
|
238
|
+
rdfs:comment "The kind of source an inventory origin was found in."@en ;
|
|
239
|
+
rdfs:label "inventory source"@en .
|
|
240
|
+
|
|
241
|
+
translation:inventorySourceId
|
|
242
|
+
a owl:DatatypeProperty ;
|
|
243
|
+
rdfs:comment "The identifier of the source an inventory origin was found in."@en ;
|
|
244
|
+
rdfs:label "inventory source id"@en .
|
|
245
|
+
|
|
246
|
+
translation:inventoryStatus
|
|
247
|
+
a owl:DatatypeProperty ;
|
|
248
|
+
rdfs:comment "The status of an inventory origin: confirmed, pending, conflict or orphaned."@en ;
|
|
249
|
+
rdfs:label "inventory status"@en .
|
|
250
|
+
|
|
251
|
+
translation:inventoryTargetClass
|
|
252
|
+
a owl:DatatypeProperty ;
|
|
253
|
+
rdfs:comment "The target class of the shape an inventory origin was found on, as a literal."@en ;
|
|
254
|
+
rdfs:label "inventory target class"@en .
|
|
255
|
+
|
|
256
|
+
translation:key
|
|
257
|
+
a owl:DatatypeProperty ;
|
|
258
|
+
rdfs:comment "A translation key's name within its namespace."@en ;
|
|
259
|
+
rdfs:label "key"@en .
|
|
260
|
+
|
|
261
|
+
translation:kind
|
|
262
|
+
a owl:DatatypeProperty ;
|
|
263
|
+
rdfs:comment "Whether a translation key is a UI string (ui) or a field of a graph node (content)."@en ;
|
|
264
|
+
rdfs:label "kind"@en .
|
|
265
|
+
|
|
266
|
+
translation:language
|
|
267
|
+
a owl:DatatypeProperty ;
|
|
268
|
+
rdfs:comment "The BCP-47 tag of a unit's or revision's language."@en ;
|
|
269
|
+
rdfs:label "language"@en .
|
|
270
|
+
|
|
271
|
+
translation:languageCode
|
|
272
|
+
a owl:DatatypeProperty ;
|
|
273
|
+
rdfs:comment "The BCP-47 tag of a configured language."@en ;
|
|
274
|
+
rdfs:label "language code"@en .
|
|
275
|
+
|
|
276
|
+
translation:languageEnabled
|
|
277
|
+
a owl:DatatypeProperty ;
|
|
278
|
+
rdfs:comment "Whether a configured language is switched on for the app."@en ;
|
|
279
|
+
rdfs:label "language enabled"@en .
|
|
280
|
+
|
|
281
|
+
translation:languageIdentifier
|
|
282
|
+
a owl:ObjectProperty ;
|
|
283
|
+
rdfs:comment "The IRI that identifies a configured language."@en ;
|
|
284
|
+
rdfs:label "language identifier"@en .
|
|
285
|
+
|
|
286
|
+
translation:languageSupported
|
|
287
|
+
a owl:DatatypeProperty ;
|
|
288
|
+
rdfs:comment "Whether a language is supported by the app."@en ;
|
|
289
|
+
rdfs:label "language supported"@en .
|
|
290
|
+
|
|
291
|
+
translation:languages
|
|
292
|
+
a owl:DatatypeProperty ;
|
|
293
|
+
rdfs:comment "A BCP-47 tag the app's translation is active for, the source language included; multi-valued."@en ;
|
|
294
|
+
rdfs:label "languages"@en .
|
|
295
|
+
|
|
296
|
+
translation:manifestHash
|
|
297
|
+
a owl:DatatypeProperty ;
|
|
298
|
+
rdfs:comment "The hash of a release's content-addressed manifest."@en ;
|
|
299
|
+
rdfs:label "manifest hash"@en .
|
|
300
|
+
|
|
301
|
+
translation:mtDefault
|
|
302
|
+
a owl:DatatypeProperty ;
|
|
303
|
+
rdfs:comment "The key of the app's default machine translation provider."@en ;
|
|
304
|
+
rdfs:label "default MT provider"@en .
|
|
305
|
+
|
|
306
|
+
translation:mtFormality
|
|
307
|
+
a owl:DatatypeProperty ;
|
|
308
|
+
rdfs:comment "The formality machine translation uses, for the app (formal) or per language (de:informal); multi-valued."@en ;
|
|
309
|
+
rdfs:label "MT formality"@en .
|
|
310
|
+
|
|
311
|
+
translation:mtProvider
|
|
312
|
+
a owl:DatatypeProperty ;
|
|
313
|
+
rdfs:comment "The key of the machine translation provider that wrote a revision."@en ;
|
|
314
|
+
rdfs:label "MT provider"@en .
|
|
315
|
+
|
|
316
|
+
translation:mtStyleNote
|
|
317
|
+
a owl:DatatypeProperty ;
|
|
318
|
+
rdfs:comment "Free-text tone guidance given to LLM machine translation providers."@en ;
|
|
319
|
+
rdfs:label "MT style note"@en .
|
|
320
|
+
|
|
321
|
+
translation:namespace
|
|
322
|
+
a owl:DatatypeProperty ;
|
|
323
|
+
rdfs:comment "The namespace a translation key belongs to."@en ;
|
|
324
|
+
rdfs:label "namespace"@en .
|
|
325
|
+
|
|
326
|
+
translation:nativeName
|
|
327
|
+
a owl:DatatypeProperty ;
|
|
328
|
+
rdfs:comment "A language's name in that language."@en ;
|
|
329
|
+
rdfs:label "native name"@en .
|
|
330
|
+
|
|
331
|
+
translation:note
|
|
332
|
+
a owl:DatatypeProperty ;
|
|
333
|
+
rdfs:comment "A translator's or reviewer's comment on a revision."@en ;
|
|
334
|
+
rdfs:label "note"@en .
|
|
335
|
+
|
|
336
|
+
translation:ofApplication
|
|
337
|
+
a owl:ObjectProperty ;
|
|
338
|
+
rdfs:comment "The app a translation key, unit, revision, release or inventory record belongs to."@en ;
|
|
339
|
+
rdfs:label "of application"@en .
|
|
340
|
+
|
|
341
|
+
translation:ofField
|
|
342
|
+
a owl:DatatypeProperty ;
|
|
343
|
+
rdfs:comment "The field (property) of the node a content translation key translates."@en ;
|
|
344
|
+
rdfs:label "of field"@en .
|
|
345
|
+
|
|
346
|
+
translation:ofKey
|
|
347
|
+
a owl:ObjectProperty ;
|
|
348
|
+
rdfs:comment "The translation key a unit, revision or key version belongs to."@en ;
|
|
349
|
+
rdfs:label "of key"@en .
|
|
350
|
+
|
|
351
|
+
translation:ofKeyVersion
|
|
352
|
+
a owl:ObjectProperty ;
|
|
353
|
+
rdfs:comment "The key version a unit or revision was written against."@en ;
|
|
354
|
+
rdfs:label "of key version"@en .
|
|
355
|
+
|
|
356
|
+
translation:ofNode
|
|
357
|
+
a owl:ObjectProperty ;
|
|
358
|
+
rdfs:comment "The graph node whose field a content translation key translates."@en ;
|
|
359
|
+
rdfs:label "of node"@en .
|
|
360
|
+
|
|
361
|
+
translation:ofProperty
|
|
362
|
+
a owl:ObjectProperty ;
|
|
363
|
+
rdfs:comment "The predicate a package-supplied key is about."@en ;
|
|
364
|
+
rdfs:label "of property"@en .
|
|
365
|
+
|
|
366
|
+
translation:ofResource
|
|
367
|
+
a owl:ObjectProperty ;
|
|
368
|
+
rdfs:comment "Any other semantic resource a key is about, such as an action, group, condition or port."@en ;
|
|
369
|
+
rdfs:label "of resource"@en .
|
|
370
|
+
|
|
371
|
+
translation:ofShape
|
|
372
|
+
a owl:ObjectProperty ;
|
|
373
|
+
rdfs:comment "The SHACL shape a package-supplied key is about."@en ;
|
|
374
|
+
rdfs:label "of shape"@en .
|
|
375
|
+
|
|
376
|
+
translation:origin
|
|
377
|
+
a owl:DatatypeProperty ;
|
|
378
|
+
rdfs:comment "Where a unit's current value came from, such as translation memory (tm)."@en ;
|
|
379
|
+
rdfs:label "origin"@en .
|
|
380
|
+
|
|
381
|
+
translation:overridden
|
|
382
|
+
a owl:DatatypeProperty ;
|
|
383
|
+
rdfs:comment "Marks a shape key the app changed from its canonical text, so shape propagation leaves it alone."@en ;
|
|
384
|
+
rdfs:label "overridden"@en .
|
|
385
|
+
|
|
386
|
+
translation:parentLanguage
|
|
387
|
+
a owl:ObjectProperty ;
|
|
388
|
+
rdfs:comment "The broader language a regional language belongs to (de for de-CH)."@en ;
|
|
389
|
+
rdfs:label "parent language"@en .
|
|
390
|
+
|
|
391
|
+
translation:publishedAt
|
|
392
|
+
a owl:DatatypeProperty ;
|
|
393
|
+
rdfs:comment "When a translation release was published."@en ;
|
|
394
|
+
rdfs:label "published at"@en .
|
|
395
|
+
|
|
396
|
+
translation:qualitySummary
|
|
397
|
+
a owl:DatatypeProperty ;
|
|
398
|
+
rdfs:comment "A summary of the review state of the values in a release."@en ;
|
|
399
|
+
rdfs:label "quality summary"@en .
|
|
400
|
+
|
|
401
|
+
translation:releaseId
|
|
402
|
+
a owl:DatatypeProperty ;
|
|
403
|
+
rdfs:comment "The identifier of a translation release."@en ;
|
|
404
|
+
rdfs:label "release id"@en .
|
|
405
|
+
|
|
406
|
+
translation:reviewedOnlyLanguage
|
|
407
|
+
a owl:DatatypeProperty ;
|
|
408
|
+
rdfs:comment "A BCP-47 tag whose translations are published only once reviewed; multi-valued."@en ;
|
|
409
|
+
rdfs:label "reviewed-only language"@en .
|
|
410
|
+
|
|
411
|
+
translation:shapeSource
|
|
412
|
+
a owl:DatatypeProperty ;
|
|
413
|
+
rdfs:comment "The canonical source text at the moment a shape key was overridden, which clearing the override restores."@en ;
|
|
414
|
+
rdfs:label "shape source"@en .
|
|
415
|
+
|
|
416
|
+
translation:sourceHash
|
|
417
|
+
a owl:DatatypeProperty ;
|
|
418
|
+
rdfs:comment "The hash of a key version's source text."@en ;
|
|
419
|
+
rdfs:label "source hash"@en .
|
|
420
|
+
|
|
421
|
+
translation:sourceLanguage
|
|
422
|
+
a owl:DatatypeProperty ;
|
|
423
|
+
rdfs:comment "The BCP-47 tag of the language a key version's source text is in."@en ;
|
|
424
|
+
rdfs:label "source language"@en .
|
|
425
|
+
|
|
426
|
+
translation:sourceText
|
|
427
|
+
a owl:DatatypeProperty ;
|
|
428
|
+
rdfs:comment "The canonical English text of a translation key or key version."@en ;
|
|
429
|
+
rdfs:label "source text"@en .
|
|
430
|
+
|
|
431
|
+
translation:state
|
|
432
|
+
a owl:DatatypeProperty ;
|
|
433
|
+
rdfs:comment "The review state of a translation unit: untranslated, machine, reviewed or stale."@en ;
|
|
434
|
+
rdfs:label "state"@en .
|
|
435
|
+
|
|
436
|
+
translation:status
|
|
437
|
+
a owl:DatatypeProperty ;
|
|
438
|
+
rdfs:comment "The state of a release (draft, published, superseded, retired) or of a revision (applied, proposed, suggested, accepted, rejected, superseded)."@en ;
|
|
439
|
+
rdfs:label "status"@en .
|
|
440
|
+
|
|
441
|
+
translation:supersedes
|
|
442
|
+
a owl:ObjectProperty ;
|
|
443
|
+
rdfs:comment "The key version or release this one replaces."@en ;
|
|
444
|
+
rdfs:label "supersedes"@en .
|
|
445
|
+
|
|
446
|
+
translation:supportedUntil
|
|
447
|
+
a owl:DatatypeProperty ;
|
|
448
|
+
rdfs:comment "Until when a translation release is supported."@en ;
|
|
449
|
+
rdfs:label "supported until"@en .
|
|
450
|
+
|
|
451
|
+
translation:term
|
|
452
|
+
a owl:DatatypeProperty ;
|
|
453
|
+
rdfs:comment "The source-language term a glossary entry is about."@en ;
|
|
454
|
+
rdfs:label "term"@en .
|
|
455
|
+
|
|
456
|
+
translation:termType
|
|
457
|
+
a owl:DatatypeProperty ;
|
|
458
|
+
rdfs:comment "How machine translation treats a glossary term: prefer, require, keep or forbid."@en ;
|
|
459
|
+
rdfs:label "term type"@en .
|
|
460
|
+
|
|
461
|
+
translation:text
|
|
462
|
+
a owl:DatatypeProperty ;
|
|
463
|
+
rdfs:comment "The translated text of a unit or revision."@en ;
|
|
464
|
+
rdfs:label "text"@en .
|
|
465
|
+
|
|
466
|
+
translation:textDirection
|
|
467
|
+
a owl:DatatypeProperty ;
|
|
468
|
+
rdfs:comment "Whether a language is written left-to-right or right-to-left."@en ;
|
|
469
|
+
rdfs:label "text direction"@en .
|
|
470
|
+
|
|
471
|
+
translation:updatedAt
|
|
472
|
+
a owl:DatatypeProperty ;
|
|
473
|
+
rdfs:comment "When a translation unit last changed."@en ;
|
|
474
|
+
rdfs:label "updated at"@en .
|
|
475
|
+
|
|
476
|
+
translation:updatedBy
|
|
477
|
+
a owl:ObjectProperty ;
|
|
478
|
+
rdfs:comment "The WebID that last changed a translation unit."@en ;
|
|
479
|
+
rdfs:label "updated by"@en .
|
|
480
|
+
|
|
481
|
+
translation:useInstead
|
|
482
|
+
a owl:DatatypeProperty ;
|
|
483
|
+
rdfs:comment "The replacement for a forbidden glossary term or spelling."@en ;
|
|
484
|
+
rdfs:label "use instead"@en .
|
|
485
|
+
|
|
486
|
+
translation:versionId
|
|
487
|
+
a owl:DatatypeProperty ;
|
|
488
|
+
rdfs:comment "The identifier of a translation key version."@en ;
|
|
489
|
+
rdfs:label "version id"@en .
|
package/lib/esm/exchange.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sharedState } from '@_linked/core/utils/sharedState';
|
|
1
2
|
import { canonicalLanguageTag } from './key-version.js';
|
|
2
3
|
const EXCHANGE_STATES = new Set([
|
|
3
4
|
'untranslated',
|
|
@@ -5,7 +6,11 @@ const EXCHANGE_STATES = new Set([
|
|
|
5
6
|
'reviewed',
|
|
6
7
|
'stale',
|
|
7
8
|
]);
|
|
8
|
-
|
|
9
|
+
// On globalThis so an adapter the host registers on one copy of this module is found by
|
|
10
|
+
// another copy.
|
|
11
|
+
const { adapters } = sharedState('@_linked/translation', 'exchange', () => ({
|
|
12
|
+
adapters: new Map(),
|
|
13
|
+
}));
|
|
9
14
|
function record(value, label) {
|
|
10
15
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
11
16
|
throw new Error(`${label} must be an object.`);
|
|
@@ -205,7 +210,12 @@ export function isConfirmedBuildDeclaration(declaration) {
|
|
|
205
210
|
declaration.authoritative !== false);
|
|
206
211
|
}
|
|
207
212
|
export function registerTranslationFormatAdapter(adapter) {
|
|
208
|
-
|
|
213
|
+
const registered = adapters.get(adapter.format);
|
|
214
|
+
// The registry is process-wide, so the same adapter registered again (by a second copy of
|
|
215
|
+
// the host module that registers it) is not a conflict; a different adapter for the format is.
|
|
216
|
+
if (registered === adapter)
|
|
217
|
+
return;
|
|
218
|
+
if (registered) {
|
|
209
219
|
throw new Error(`Translation format adapter "${adapter.format}" is already registered.`);
|
|
210
220
|
}
|
|
211
221
|
adapters.set(adapter.format, adapter);
|
package/lib/esm/exchange.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MessageFormat } from './core/messages.js';\nimport { canonicalLanguageTag } from './key-version.js';\nimport type { TranslationState } from './records.js';\n\nexport type TranslationExchangeKind = 'ui' | 'semantic';\nexport type TranslationDeclarationKind =\n | TranslationExchangeKind\n | 'content';\nexport type TranslationDeclarationStatus = 'confirmed' | 'pending';\n\n/**\n * The build-facing subset of the later multi-source discovery contract.\n * Static extraction omits the optional fields and retains its existing\n * confirmed/simple behavior.\n */\nexport interface TranslationBuildDeclaration {\n key: string;\n sourceText: string;\n format?: MessageFormat;\n kind?: TranslationDeclarationKind;\n status?: TranslationDeclarationStatus;\n authoritative?: boolean;\n namespace?: string;\n file?: string;\n line?: number;\n}\n\nexport interface TranslationExchangeValue {\n text: string;\n state?: TranslationState;\n note?: string;\n}\n\nexport interface TranslationExchangeEntry {\n key: string;\n namespace?: string;\n kind: TranslationExchangeKind;\n sourceText: string;\n keyVersionId: string;\n sourceHash: string;\n contractHash: string;\n argumentSignature: string;\n description?: string;\n format: MessageFormat;\n translations: Record<string, TranslationExchangeValue>;\n}\n\nexport interface TranslationExchangeDocument {\n schemaVersion: 1;\n appId?: string;\n branchId?: string;\n sourceLanguage: string;\n targetLanguages: string[];\n exportedAt?: string;\n revisionWatermark?: string;\n contractSetHash?: string;\n entries: TranslationExchangeEntry[];\n}\n\nexport type ParsedTranslationExchangeEntry = Omit<\n TranslationExchangeEntry,\n | 'sourceText'\n | 'keyVersionId'\n | 'sourceHash'\n | 'contractHash'\n | 'argumentSignature'\n> & {\n sourceText?: string;\n keyVersionId?: string;\n sourceHash?: string;\n contractHash?: string;\n argumentSignature?: string;\n};\n\nexport interface ParsedTranslationExchangeDocument\n extends Omit<TranslationExchangeDocument, 'entries'> {\n entries: ParsedTranslationExchangeEntry[];\n}\n\nexport type TranslationFormat =\n | 'xliff-1.2'\n | 'xliff-2.0'\n | 'csv'\n | 'json';\n\nexport interface SerializedTranslationDocument {\n fileName: string;\n mediaType: string;\n body: Uint8Array;\n}\n\nexport interface TranslationFormatAdapter {\n readonly format: TranslationFormat;\n sniff(input: Uint8Array, fileName?: string): boolean;\n parse(\n input: Uint8Array,\n options?: unknown,\n ): Promise<ParsedTranslationExchangeDocument>;\n serialize(\n document: TranslationExchangeDocument,\n options?: unknown,\n ): Promise<SerializedTranslationDocument>;\n}\n\nexport type TranslationImportDisposition =\n | 'import'\n | 'carry-forward'\n | 'unverified-source'\n | 'conflict'\n | 'skip';\n\nexport interface TranslationImportDryRunEntry {\n key: string;\n language: string;\n disposition: TranslationImportDisposition;\n expectedKeyVersionId?: string;\n expectedUnitContentHash?: string;\n}\n\nexport interface TranslationImportDryRun {\n sessionId: string;\n documentHash: string;\n revisionWatermark: string;\n expiresAt: string;\n entries: TranslationImportDryRunEntry[];\n}\n\nconst EXCHANGE_STATES = new Set<TranslationState>([\n 'untranslated',\n 'machine',\n 'reviewed',\n 'stale',\n]);\nconst adapters = new Map<TranslationFormat, TranslationFormatAdapter>();\n\nfunction record(value: unknown, label: string): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`${label} is required.`);\n }\n return value.trim();\n}\n\nfunction optionalString(value: unknown, label: string): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`${label} must be a non-empty string when supplied.`);\n }\n return value.trim();\n}\n\nfunction messageFormat(value: unknown, label: string): MessageFormat {\n if (value !== 'simple' && value !== 'icu') {\n throw new Error(`${label} must be \"simple\" or \"icu\".`);\n }\n return value;\n}\n\nfunction exchangeKind(value: unknown, label: string): TranslationExchangeKind {\n if (value !== 'ui' && value !== 'semantic') {\n throw new Error(`${label} must be \"ui\" or \"semantic\".`);\n }\n return value;\n}\n\nfunction canonicalLanguages(value: unknown, label: string): string[] {\n if (!Array.isArray(value)) throw new Error(`${label} must be an array.`);\n const canonical: string[] = [];\n const seen = new Set<string>();\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new Error(`${label} must contain only BCP-47 strings.`);\n }\n const language = canonicalLanguageTag(item);\n if (!seen.has(language)) {\n seen.add(language);\n canonical.push(language);\n }\n }\n return canonical;\n}\n\nfunction normalizeTranslations(\n value: unknown,\n label: string,\n): Record<string, TranslationExchangeValue> {\n const input = record(value, label);\n const translations: Record<string, TranslationExchangeValue> = {};\n for (const [rawLanguage, rawValue] of Object.entries(input)) {\n const language = canonicalLanguageTag(rawLanguage);\n if (translations[language]) {\n throw new Error(\n `${label} contains duplicate canonical language \"${language}\".`,\n );\n }\n const item = record(rawValue, `${label}.${rawLanguage}`);\n if (typeof item.text !== 'string') {\n throw new Error(`${label}.${rawLanguage}.text must be a string.`);\n }\n const state = item.state;\n if (state !== undefined && !EXCHANGE_STATES.has(state as TranslationState)) {\n throw new Error(`${label}.${rawLanguage}.state is invalid.`);\n }\n translations[language] = {\n text: item.text,\n ...(state ? { state: state as TranslationState } : {}),\n ...(item.note === undefined\n ? {}\n : {\n note: requiredString(\n item.note,\n `${label}.${rawLanguage}.note`,\n ),\n }),\n };\n }\n return translations;\n}\n\nfunction normalizeEntry(\n value: unknown,\n index: number,\n): ParsedTranslationExchangeEntry {\n const item = record(value, `entries[${index}]`);\n const key = requiredString(item.key, `entries[${index}].key`);\n return {\n key,\n ...(item.namespace === undefined\n ? {}\n : {\n namespace: requiredString(\n item.namespace,\n `entries[${index}].namespace`,\n ),\n }),\n kind: exchangeKind(item.kind, `entries[${index}].kind`),\n format: messageFormat(item.format, `entries[${index}].format`),\n ...(item.sourceText === undefined\n ? {}\n : {\n sourceText:\n typeof item.sourceText === 'string'\n ? item.sourceText\n : requiredString(item.sourceText, `entries[${index}].sourceText`),\n }),\n ...(item.keyVersionId === undefined\n ? {}\n : {\n keyVersionId: requiredString(\n item.keyVersionId,\n `entries[${index}].keyVersionId`,\n ),\n }),\n ...(item.sourceHash === undefined\n ? {}\n : {\n sourceHash: requiredString(\n item.sourceHash,\n `entries[${index}].sourceHash`,\n ),\n }),\n ...(item.contractHash === undefined\n ? {}\n : {\n contractHash: requiredString(\n item.contractHash,\n `entries[${index}].contractHash`,\n ),\n }),\n ...(item.argumentSignature === undefined\n ? {}\n : {\n argumentSignature: requiredString(\n item.argumentSignature,\n `entries[${index}].argumentSignature`,\n ),\n }),\n ...(item.description === undefined\n ? {}\n : {\n description: requiredString(\n item.description,\n `entries[${index}].description`,\n ),\n }),\n translations: normalizeTranslations(\n item.translations,\n `entries[${index}].translations`,\n ),\n };\n}\n\n/**\n * Normalize adapter output without inventing evidence missing from a foreign\n * file. Import disposition handles those entries as unverified later.\n */\nexport function normalizeParsedTranslationExchangeDocument(\n value: unknown,\n): ParsedTranslationExchangeDocument {\n const input = record(value, 'Translation exchange document');\n if (input.schemaVersion !== 1) {\n throw new Error('Translation exchange schemaVersion must be 1.');\n }\n const sourceLanguage = canonicalLanguageTag(\n requiredString(input.sourceLanguage, 'sourceLanguage'),\n );\n const targetLanguages = canonicalLanguages(\n input.targetLanguages,\n 'targetLanguages',\n );\n if (!Array.isArray(input.entries)) {\n throw new Error('entries must be an array.');\n }\n const entries = input.entries.map(normalizeEntry);\n const identities = new Set<string>();\n for (const entry of entries) {\n for (const language of Object.keys(entry.translations)) {\n const identity = `${entry.namespace ?? ''}\\u0000${entry.key}\\u0000${language}`;\n if (identities.has(identity)) {\n throw new Error(\n `Duplicate translation entry for \"${entry.key}\" in ${language}.`,\n );\n }\n identities.add(identity);\n }\n }\n return {\n schemaVersion: 1,\n ...(input.appId === undefined\n ? {}\n : { appId: requiredString(input.appId, 'appId') }),\n ...(input.branchId === undefined\n ? {}\n : { branchId: requiredString(input.branchId, 'branchId') }),\n sourceLanguage,\n targetLanguages,\n ...(input.exportedAt === undefined\n ? {}\n : { exportedAt: requiredString(input.exportedAt, 'exportedAt') }),\n ...(input.revisionWatermark === undefined\n ? {}\n : {\n revisionWatermark: requiredString(\n input.revisionWatermark,\n 'revisionWatermark',\n ),\n }),\n ...(input.contractSetHash === undefined\n ? {}\n : {\n contractSetHash: requiredString(\n input.contractSetHash,\n 'contractSetHash',\n ),\n }),\n entries,\n };\n}\n\n/** Validate the stronger, version-evidenced document this package's own exports carry. */\nexport function validateTranslationExchangeDocument(\n value: unknown,\n): TranslationExchangeDocument {\n const parsed = normalizeParsedTranslationExchangeDocument(value);\n const entries = parsed.entries.map((entry, index): TranslationExchangeEntry => ({\n ...entry,\n sourceText:\n entry.sourceText ??\n requiredString(undefined, `entries[${index}].sourceText`),\n keyVersionId:\n entry.keyVersionId ??\n requiredString(undefined, `entries[${index}].keyVersionId`),\n sourceHash:\n entry.sourceHash ??\n requiredString(undefined, `entries[${index}].sourceHash`),\n contractHash:\n entry.contractHash ??\n requiredString(undefined, `entries[${index}].contractHash`),\n argumentSignature:\n entry.argumentSignature ??\n requiredString(undefined, `entries[${index}].argumentSignature`),\n }));\n return { ...parsed, entries };\n}\n\nexport function isConfirmedBuildDeclaration(\n declaration: TranslationBuildDeclaration,\n): boolean {\n return (\n (declaration.kind ?? 'ui') !== 'content' &&\n (declaration.status ?? 'confirmed') === 'confirmed' &&\n declaration.authoritative !== false\n );\n}\n\nexport function registerTranslationFormatAdapter(\n adapter: TranslationFormatAdapter,\n): void {\n if (adapters.has(adapter.format)) {\n throw new Error(\n `Translation format adapter \"${adapter.format}\" is already registered.`,\n );\n }\n adapters.set(adapter.format, adapter);\n}\n\nexport function getTranslationFormatAdapter(\n format: TranslationFormat,\n): TranslationFormatAdapter | undefined {\n return adapters.get(format);\n}\n\nexport function listTranslationFormatAdapters(): TranslationFormatAdapter[] {\n return [...adapters.values()].sort((left, right) =>\n left.format.localeCompare(right.format),\n );\n}\n\n/** Test/host reset hook; adapters are registered explicitly by the host. */\nexport function clearTranslationFormatAdapters(): void {\n adapters.clear();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import { sharedState } from '@_linked/core/utils/sharedState';\nimport type { MessageFormat } from './core/messages.js';\nimport { canonicalLanguageTag } from './key-version.js';\nimport type { TranslationState } from './records.js';\n\nexport type TranslationExchangeKind = 'ui' | 'semantic';\nexport type TranslationDeclarationKind =\n | TranslationExchangeKind\n | 'content';\nexport type TranslationDeclarationStatus = 'confirmed' | 'pending';\n\n/**\n * The build-facing subset of the later multi-source discovery contract.\n * Static extraction omits the optional fields and retains its existing\n * confirmed/simple behavior.\n */\nexport interface TranslationBuildDeclaration {\n key: string;\n sourceText: string;\n format?: MessageFormat;\n kind?: TranslationDeclarationKind;\n status?: TranslationDeclarationStatus;\n authoritative?: boolean;\n namespace?: string;\n file?: string;\n line?: number;\n}\n\nexport interface TranslationExchangeValue {\n text: string;\n state?: TranslationState;\n note?: string;\n}\n\nexport interface TranslationExchangeEntry {\n key: string;\n namespace?: string;\n kind: TranslationExchangeKind;\n sourceText: string;\n keyVersionId: string;\n sourceHash: string;\n contractHash: string;\n argumentSignature: string;\n description?: string;\n format: MessageFormat;\n translations: Record<string, TranslationExchangeValue>;\n}\n\nexport interface TranslationExchangeDocument {\n schemaVersion: 1;\n appId?: string;\n branchId?: string;\n sourceLanguage: string;\n targetLanguages: string[];\n exportedAt?: string;\n revisionWatermark?: string;\n contractSetHash?: string;\n entries: TranslationExchangeEntry[];\n}\n\nexport type ParsedTranslationExchangeEntry = Omit<\n TranslationExchangeEntry,\n | 'sourceText'\n | 'keyVersionId'\n | 'sourceHash'\n | 'contractHash'\n | 'argumentSignature'\n> & {\n sourceText?: string;\n keyVersionId?: string;\n sourceHash?: string;\n contractHash?: string;\n argumentSignature?: string;\n};\n\nexport interface ParsedTranslationExchangeDocument\n extends Omit<TranslationExchangeDocument, 'entries'> {\n entries: ParsedTranslationExchangeEntry[];\n}\n\nexport type TranslationFormat =\n | 'xliff-1.2'\n | 'xliff-2.0'\n | 'csv'\n | 'json';\n\nexport interface SerializedTranslationDocument {\n fileName: string;\n mediaType: string;\n body: Uint8Array;\n}\n\nexport interface TranslationFormatAdapter {\n readonly format: TranslationFormat;\n sniff(input: Uint8Array, fileName?: string): boolean;\n parse(\n input: Uint8Array,\n options?: unknown,\n ): Promise<ParsedTranslationExchangeDocument>;\n serialize(\n document: TranslationExchangeDocument,\n options?: unknown,\n ): Promise<SerializedTranslationDocument>;\n}\n\nexport type TranslationImportDisposition =\n | 'import'\n | 'carry-forward'\n | 'unverified-source'\n | 'conflict'\n | 'skip';\n\nexport interface TranslationImportDryRunEntry {\n key: string;\n language: string;\n disposition: TranslationImportDisposition;\n expectedKeyVersionId?: string;\n expectedUnitContentHash?: string;\n}\n\nexport interface TranslationImportDryRun {\n sessionId: string;\n documentHash: string;\n revisionWatermark: string;\n expiresAt: string;\n entries: TranslationImportDryRunEntry[];\n}\n\nconst EXCHANGE_STATES = new Set<TranslationState>([\n 'untranslated',\n 'machine',\n 'reviewed',\n 'stale',\n]);\n// On globalThis so an adapter the host registers on one copy of this module is found by\n// another copy.\nconst { adapters } = sharedState('@_linked/translation', 'exchange', () => ({\n adapters: new Map<TranslationFormat, TranslationFormatAdapter>(),\n}));\n\nfunction record(value: unknown, label: string): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`${label} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`${label} is required.`);\n }\n return value.trim();\n}\n\nfunction optionalString(value: unknown, label: string): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`${label} must be a non-empty string when supplied.`);\n }\n return value.trim();\n}\n\nfunction messageFormat(value: unknown, label: string): MessageFormat {\n if (value !== 'simple' && value !== 'icu') {\n throw new Error(`${label} must be \"simple\" or \"icu\".`);\n }\n return value;\n}\n\nfunction exchangeKind(value: unknown, label: string): TranslationExchangeKind {\n if (value !== 'ui' && value !== 'semantic') {\n throw new Error(`${label} must be \"ui\" or \"semantic\".`);\n }\n return value;\n}\n\nfunction canonicalLanguages(value: unknown, label: string): string[] {\n if (!Array.isArray(value)) throw new Error(`${label} must be an array.`);\n const canonical: string[] = [];\n const seen = new Set<string>();\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new Error(`${label} must contain only BCP-47 strings.`);\n }\n const language = canonicalLanguageTag(item);\n if (!seen.has(language)) {\n seen.add(language);\n canonical.push(language);\n }\n }\n return canonical;\n}\n\nfunction normalizeTranslations(\n value: unknown,\n label: string,\n): Record<string, TranslationExchangeValue> {\n const input = record(value, label);\n const translations: Record<string, TranslationExchangeValue> = {};\n for (const [rawLanguage, rawValue] of Object.entries(input)) {\n const language = canonicalLanguageTag(rawLanguage);\n if (translations[language]) {\n throw new Error(\n `${label} contains duplicate canonical language \"${language}\".`,\n );\n }\n const item = record(rawValue, `${label}.${rawLanguage}`);\n if (typeof item.text !== 'string') {\n throw new Error(`${label}.${rawLanguage}.text must be a string.`);\n }\n const state = item.state;\n if (state !== undefined && !EXCHANGE_STATES.has(state as TranslationState)) {\n throw new Error(`${label}.${rawLanguage}.state is invalid.`);\n }\n translations[language] = {\n text: item.text,\n ...(state ? { state: state as TranslationState } : {}),\n ...(item.note === undefined\n ? {}\n : {\n note: requiredString(\n item.note,\n `${label}.${rawLanguage}.note`,\n ),\n }),\n };\n }\n return translations;\n}\n\nfunction normalizeEntry(\n value: unknown,\n index: number,\n): ParsedTranslationExchangeEntry {\n const item = record(value, `entries[${index}]`);\n const key = requiredString(item.key, `entries[${index}].key`);\n return {\n key,\n ...(item.namespace === undefined\n ? {}\n : {\n namespace: requiredString(\n item.namespace,\n `entries[${index}].namespace`,\n ),\n }),\n kind: exchangeKind(item.kind, `entries[${index}].kind`),\n format: messageFormat(item.format, `entries[${index}].format`),\n ...(item.sourceText === undefined\n ? {}\n : {\n sourceText:\n typeof item.sourceText === 'string'\n ? item.sourceText\n : requiredString(item.sourceText, `entries[${index}].sourceText`),\n }),\n ...(item.keyVersionId === undefined\n ? {}\n : {\n keyVersionId: requiredString(\n item.keyVersionId,\n `entries[${index}].keyVersionId`,\n ),\n }),\n ...(item.sourceHash === undefined\n ? {}\n : {\n sourceHash: requiredString(\n item.sourceHash,\n `entries[${index}].sourceHash`,\n ),\n }),\n ...(item.contractHash === undefined\n ? {}\n : {\n contractHash: requiredString(\n item.contractHash,\n `entries[${index}].contractHash`,\n ),\n }),\n ...(item.argumentSignature === undefined\n ? {}\n : {\n argumentSignature: requiredString(\n item.argumentSignature,\n `entries[${index}].argumentSignature`,\n ),\n }),\n ...(item.description === undefined\n ? {}\n : {\n description: requiredString(\n item.description,\n `entries[${index}].description`,\n ),\n }),\n translations: normalizeTranslations(\n item.translations,\n `entries[${index}].translations`,\n ),\n };\n}\n\n/**\n * Normalize adapter output without inventing evidence missing from a foreign\n * file. Import disposition handles those entries as unverified later.\n */\nexport function normalizeParsedTranslationExchangeDocument(\n value: unknown,\n): ParsedTranslationExchangeDocument {\n const input = record(value, 'Translation exchange document');\n if (input.schemaVersion !== 1) {\n throw new Error('Translation exchange schemaVersion must be 1.');\n }\n const sourceLanguage = canonicalLanguageTag(\n requiredString(input.sourceLanguage, 'sourceLanguage'),\n );\n const targetLanguages = canonicalLanguages(\n input.targetLanguages,\n 'targetLanguages',\n );\n if (!Array.isArray(input.entries)) {\n throw new Error('entries must be an array.');\n }\n const entries = input.entries.map(normalizeEntry);\n const identities = new Set<string>();\n for (const entry of entries) {\n for (const language of Object.keys(entry.translations)) {\n const identity = `${entry.namespace ?? ''}\\u0000${entry.key}\\u0000${language}`;\n if (identities.has(identity)) {\n throw new Error(\n `Duplicate translation entry for \"${entry.key}\" in ${language}.`,\n );\n }\n identities.add(identity);\n }\n }\n return {\n schemaVersion: 1,\n ...(input.appId === undefined\n ? {}\n : { appId: requiredString(input.appId, 'appId') }),\n ...(input.branchId === undefined\n ? {}\n : { branchId: requiredString(input.branchId, 'branchId') }),\n sourceLanguage,\n targetLanguages,\n ...(input.exportedAt === undefined\n ? {}\n : { exportedAt: requiredString(input.exportedAt, 'exportedAt') }),\n ...(input.revisionWatermark === undefined\n ? {}\n : {\n revisionWatermark: requiredString(\n input.revisionWatermark,\n 'revisionWatermark',\n ),\n }),\n ...(input.contractSetHash === undefined\n ? {}\n : {\n contractSetHash: requiredString(\n input.contractSetHash,\n 'contractSetHash',\n ),\n }),\n entries,\n };\n}\n\n/** Validate the stronger, version-evidenced document this package's own exports carry. */\nexport function validateTranslationExchangeDocument(\n value: unknown,\n): TranslationExchangeDocument {\n const parsed = normalizeParsedTranslationExchangeDocument(value);\n const entries = parsed.entries.map((entry, index): TranslationExchangeEntry => ({\n ...entry,\n sourceText:\n entry.sourceText ??\n requiredString(undefined, `entries[${index}].sourceText`),\n keyVersionId:\n entry.keyVersionId ??\n requiredString(undefined, `entries[${index}].keyVersionId`),\n sourceHash:\n entry.sourceHash ??\n requiredString(undefined, `entries[${index}].sourceHash`),\n contractHash:\n entry.contractHash ??\n requiredString(undefined, `entries[${index}].contractHash`),\n argumentSignature:\n entry.argumentSignature ??\n requiredString(undefined, `entries[${index}].argumentSignature`),\n }));\n return { ...parsed, entries };\n}\n\nexport function isConfirmedBuildDeclaration(\n declaration: TranslationBuildDeclaration,\n): boolean {\n return (\n (declaration.kind ?? 'ui') !== 'content' &&\n (declaration.status ?? 'confirmed') === 'confirmed' &&\n declaration.authoritative !== false\n );\n}\n\nexport function registerTranslationFormatAdapter(\n adapter: TranslationFormatAdapter,\n): void {\n const registered = adapters.get(adapter.format);\n // The registry is process-wide, so the same adapter registered again (by a second copy of\n // the host module that registers it) is not a conflict; a different adapter for the format is.\n if (registered === adapter) return;\n if (registered) {\n throw new Error(\n `Translation format adapter \"${adapter.format}\" is already registered.`,\n );\n }\n adapters.set(adapter.format, adapter);\n}\n\nexport function getTranslationFormatAdapter(\n format: TranslationFormat,\n): TranslationFormatAdapter | undefined {\n return adapters.get(format);\n}\n\nexport function listTranslationFormatAdapters(): TranslationFormatAdapter[] {\n return [...adapters.values()].sort((left, right) =>\n left.format.localeCompare(right.format),\n );\n}\n\n/** Test/host reset hook; adapters are registered explicitly by the host. */\nexport function clearTranslationFormatAdapters(): void {\n adapters.clear();\n}\n"]}
|