@_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/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# `@_linked/translation`
|
|
2
|
+
|
|
3
|
+
Graph-native translation management for LINKED applications. It provides:
|
|
4
|
+
|
|
5
|
+
- `TranslationKey`, `TranslationUnit`, and `GlossaryTerm` shapes;
|
|
6
|
+
- a server provider for app-scoped keys and language messages;
|
|
7
|
+
- framework-light message formatting;
|
|
8
|
+
- React bindings compatible with Tolgee-style `useTranslate()` calls;
|
|
9
|
+
- a static key-sync tool that reports source drift, conflicts, and orphans.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @_linked/translation
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Entry points
|
|
18
|
+
|
|
19
|
+
- `@_linked/translation` — shapes and message model
|
|
20
|
+
- `@_linked/translation/backend` — LINKED server provider registration
|
|
21
|
+
- `@_linked/translation/react` — provider, hooks, and `<T>`
|
|
22
|
+
- `@_linked/translation/key-sync` — development-time source extraction and sync
|
|
23
|
+
- `@_linked/translation/key-sync/node` — recursive source-tree scan + dry-run/apply orchestration
|
|
24
|
+
- `@_linked/translation/shape-catalog` — package-owned translations attached to stable shape/property IRIs
|
|
25
|
+
- `@_linked/translation/discovery` — portable declarations and deterministic inventory merging
|
|
26
|
+
- `@_linked/translation/linked-discovery` — serialized LINKED package catalogs
|
|
27
|
+
- `@_linked/translation/archive` — full-fidelity backup and pure restore planning
|
|
28
|
+
|
|
29
|
+
## Code-canonical discovery
|
|
30
|
+
|
|
31
|
+
Create Now's Host Agent can inventory a managed app without running its
|
|
32
|
+
packages:
|
|
33
|
+
|
|
34
|
+
- literal `t()` and `<T>` calls are extracted from `src/`;
|
|
35
|
+
- finite dynamic key families are declared in a root
|
|
36
|
+
`translation.discovery.json`;
|
|
37
|
+
- a reusable package points to serialized catalog JSON with
|
|
38
|
+
`"linkedTranslationCatalog": "./translation.catalog.json"` in its
|
|
39
|
+
`package.json`.
|
|
40
|
+
|
|
41
|
+
The Host Agent walks installed `dependencies` and `optionalDependencies`,
|
|
42
|
+
parses only JSON, and never imports package JavaScript. A package catalog path
|
|
43
|
+
must remain inside that package. Inventory is branch-local because discovery
|
|
44
|
+
always runs against the exact managed branch clone and persists into that
|
|
45
|
+
branch's metadata dataset.
|
|
46
|
+
|
|
47
|
+
## Full-fidelity archives
|
|
48
|
+
|
|
49
|
+
The archive contract complements lossy XLIFF/CSV/JSON interchange. It stores
|
|
50
|
+
translation configuration, keys and versions, units, glossary/style,
|
|
51
|
+
revision history, provenance, content translations, and historical
|
|
52
|
+
release/build references in a deterministic hash-inventoried ZIP. Catalog
|
|
53
|
+
objects may be included for offline recovery or retained as references.
|
|
54
|
+
|
|
55
|
+
Restore planning is explicit:
|
|
56
|
+
|
|
57
|
+
- same-app recovery preserves stable IDs and blocks same-ID/different-content
|
|
58
|
+
collisions;
|
|
59
|
+
- cross-app migration deterministically rebases only app-scoped IRIs and
|
|
60
|
+
requires explicit node/field mappings for graph content;
|
|
61
|
+
- authors remain inert provenance, and releases always restore as retired
|
|
62
|
+
history pending a normal target-side publish.
|
|
63
|
+
|
|
64
|
+
Secrets, sessions, collaborators/invites, entitlements, and identity records
|
|
65
|
+
are rejected at the portable archive boundary.
|
|
66
|
+
|
|
67
|
+
## Translations shipped with a shape
|
|
68
|
+
|
|
69
|
+
Reusable asset packages can include a schema-versioned shape translation
|
|
70
|
+
catalog. The catalog is code-canonical package content; installation copies
|
|
71
|
+
only missing keys and active-language units into the consuming app's graph.
|
|
72
|
+
Existing app-authored translations are never overwritten. Packages may export
|
|
73
|
+
the TypeScript object or ship the same contract as JSON for Create Now's Host
|
|
74
|
+
Agent to discover without executing application code.
|
|
75
|
+
|
|
76
|
+
Create Now's editor, menu contribution, entitlement, and capability activation
|
|
77
|
+
are deliberately not part of this package. They live in Create Now's
|
|
78
|
+
`translation-studio` feature so applications can use this runtime without
|
|
79
|
+
depending on Create Now.
|
|
80
|
+
|
|
81
|
+
The package targets `@_linked/core` 2.14.4 and uses the permanent identifier
|
|
82
|
+
namespace `https://id.linked.cm/translation/`.
|
|
83
|
+
|
|
84
|
+
## Open language configuration
|
|
85
|
+
|
|
86
|
+
Language codes are BCP-47 strings. `TranslationLanguage` stores app-scoped RDF
|
|
87
|
+
resources for the code, stable language identifier, native and English names,
|
|
88
|
+
text direction, parent/fallback links, and enabled/supported flags. Hosts choose
|
|
89
|
+
an explicit configuration store; the portable package does not assume a CN
|
|
90
|
+
control plane. `defineLanguage` supplies editable defaults from the platform's
|
|
91
|
+
Unicode locale data. Validate relationship cycles before saving.
|
|
92
|
+
|
|
93
|
+
Publish the resource list as `languages.json` alongside the catalogs. Wire
|
|
94
|
+
`createCdnLanguageLoader({base})` to the React provider's `loadLanguages` prop
|
|
95
|
+
and `createCdnLoader({base})` to `loadMessages`. The language menu can then grow
|
|
96
|
+
without an app release. The CDN base remains caller-owned. Complete compiled
|
|
97
|
+
catalogs follow the configured fallback chain before the source language;
|
|
98
|
+
regional variants are separate tags, with no automatic Chinese-script conversion.
|
|
99
|
+
|
|
100
|
+
Core 2.18.1 compatibility: call `TranslationKey.upsertKey` for translation
|
|
101
|
+
creation. The inherited generic `Shape.upsert` API is preserved. Date-valued
|
|
102
|
+
shape mutations use `Date`; serialized translation records keep ISO strings.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { type TranslationJsonArchiveLimits } from './formats/json.js';
|
|
2
|
+
/** Full backups include every language and its revision history. CAT-file
|
|
3
|
+
* imports retain their smaller defaults; native backups remain bounded too. */
|
|
4
|
+
export declare const DEFAULT_TRANSLATION_ARCHIVE_LIMITS: TranslationJsonArchiveLimits;
|
|
5
|
+
export declare const TRANSLATION_ARCHIVE_MANIFEST_PATH = "create-now.translation-archive.json";
|
|
6
|
+
export type TranslationArchiveCollection = 'configuration' | 'keys' | 'keyVersions' | 'units' | 'glossary' | 'style' | 'revisions' | 'provenance' | 'content' | 'releases' | 'buildPins';
|
|
7
|
+
export declare const TRANSLATION_ARCHIVE_COLLECTIONS: readonly TranslationArchiveCollection[];
|
|
8
|
+
export declare const TRANSLATION_ARCHIVE_EXCLUSIONS: readonly string[];
|
|
9
|
+
export type TranslationArchiveJson = null | boolean | number | string | TranslationArchiveJson[] | {
|
|
10
|
+
[key: string]: TranslationArchiveJson;
|
|
11
|
+
};
|
|
12
|
+
export interface TranslationArchiveEntityInput {
|
|
13
|
+
id: string;
|
|
14
|
+
data: Record<string, TranslationArchiveJson>;
|
|
15
|
+
}
|
|
16
|
+
export interface TranslationArchiveEntity extends TranslationArchiveEntityInput {
|
|
17
|
+
contentHash: string;
|
|
18
|
+
}
|
|
19
|
+
export interface TranslationArchiveObjectInput {
|
|
20
|
+
hash: string;
|
|
21
|
+
body?: Uint8Array;
|
|
22
|
+
mediaType?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface TranslationArchiveSnapshot {
|
|
25
|
+
appId: string;
|
|
26
|
+
branchId: string;
|
|
27
|
+
revisionWatermark: string;
|
|
28
|
+
createdAt?: string;
|
|
29
|
+
collections: Partial<Record<TranslationArchiveCollection, TranslationArchiveEntityInput[]>>;
|
|
30
|
+
/** Immutable release catalog objects; omitted bodies remain references only. */
|
|
31
|
+
objects?: TranslationArchiveObjectInput[];
|
|
32
|
+
}
|
|
33
|
+
export interface TranslationArchiveFileInventory {
|
|
34
|
+
path: string;
|
|
35
|
+
collection: TranslationArchiveCollection;
|
|
36
|
+
hash: string;
|
|
37
|
+
bytes: number;
|
|
38
|
+
records: number;
|
|
39
|
+
}
|
|
40
|
+
export interface TranslationArchiveObjectInventory {
|
|
41
|
+
path: string;
|
|
42
|
+
hash: string;
|
|
43
|
+
bytes?: number;
|
|
44
|
+
mediaType?: string;
|
|
45
|
+
included: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface TranslationArchiveManifest {
|
|
48
|
+
schemaVersion: 1;
|
|
49
|
+
format: 'create-now-translation-archive';
|
|
50
|
+
appId: string;
|
|
51
|
+
branchId: string;
|
|
52
|
+
revisionWatermark: string;
|
|
53
|
+
createdAt?: string;
|
|
54
|
+
files: TranslationArchiveFileInventory[];
|
|
55
|
+
objects: TranslationArchiveObjectInventory[];
|
|
56
|
+
exclusions: string[];
|
|
57
|
+
archiveContentHash: string;
|
|
58
|
+
}
|
|
59
|
+
export interface SerializedTranslationArchive {
|
|
60
|
+
fileName: string;
|
|
61
|
+
mediaType: 'application/zip';
|
|
62
|
+
body: Uint8Array;
|
|
63
|
+
manifest: TranslationArchiveManifest;
|
|
64
|
+
}
|
|
65
|
+
export interface ParsedTranslationArchive {
|
|
66
|
+
manifest: TranslationArchiveManifest;
|
|
67
|
+
collections: Record<TranslationArchiveCollection, TranslationArchiveEntity[]>;
|
|
68
|
+
objects: Array<{
|
|
69
|
+
hash: string;
|
|
70
|
+
body?: Uint8Array;
|
|
71
|
+
mediaType?: string;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
export interface TranslationArchiveTargetRecord {
|
|
75
|
+
id: string;
|
|
76
|
+
contentHash: string;
|
|
77
|
+
}
|
|
78
|
+
export interface TranslationArchiveContentMapping {
|
|
79
|
+
sourceNodeIri: string;
|
|
80
|
+
sourceFieldIri: string;
|
|
81
|
+
targetNodeIri: string;
|
|
82
|
+
targetFieldIri: string;
|
|
83
|
+
}
|
|
84
|
+
export interface PlanTranslationArchiveRestoreOptions {
|
|
85
|
+
mode: 'same-app' | 'cross-app';
|
|
86
|
+
targetAppId: string;
|
|
87
|
+
targetRecords?: TranslationArchiveTargetRecord[];
|
|
88
|
+
contentMappings?: TranslationArchiveContentMapping[];
|
|
89
|
+
targetRevisionWatermark?: string;
|
|
90
|
+
}
|
|
91
|
+
export interface TranslationArchiveRestoreDecision {
|
|
92
|
+
collection: TranslationArchiveCollection;
|
|
93
|
+
sourceId: string;
|
|
94
|
+
targetId: string;
|
|
95
|
+
action: 'create' | 'skip' | 'collision' | 'unmapped';
|
|
96
|
+
expectedTargetContentHash?: string;
|
|
97
|
+
record?: TranslationArchiveEntity;
|
|
98
|
+
reason?: string;
|
|
99
|
+
retryKey: string;
|
|
100
|
+
}
|
|
101
|
+
export interface TranslationArchiveRestorePlan {
|
|
102
|
+
schemaVersion: 1;
|
|
103
|
+
mode: 'same-app' | 'cross-app';
|
|
104
|
+
sourceAppId: string;
|
|
105
|
+
targetAppId: string;
|
|
106
|
+
sourceBranchId: string;
|
|
107
|
+
archiveContentHash: string;
|
|
108
|
+
archiveRevisionWatermark: string;
|
|
109
|
+
expectedTargetRevisionWatermark?: string;
|
|
110
|
+
blocked: boolean;
|
|
111
|
+
decisions: TranslationArchiveRestoreDecision[];
|
|
112
|
+
iriMappings: Record<string, string>;
|
|
113
|
+
creates: number;
|
|
114
|
+
skips: number;
|
|
115
|
+
collisions: number;
|
|
116
|
+
unresolvedContent: number;
|
|
117
|
+
historicalReleases: number;
|
|
118
|
+
identityWrites: 0;
|
|
119
|
+
assignmentWrites: 0;
|
|
120
|
+
}
|
|
121
|
+
/** Create a deterministic, full-fidelity Create Now translation archive. */
|
|
122
|
+
export declare function createTranslationArchive(snapshot: TranslationArchiveSnapshot, options?: {
|
|
123
|
+
limits?: Partial<TranslationJsonArchiveLimits>;
|
|
124
|
+
}): Promise<SerializedTranslationArchive>;
|
|
125
|
+
/** Parse and verify every declared content file and optional catalog object. */
|
|
126
|
+
export declare function parseTranslationArchive(input: Uint8Array, options?: {
|
|
127
|
+
limits?: Partial<TranslationJsonArchiveLimits>;
|
|
128
|
+
}): Promise<ParsedTranslationArchive>;
|
|
129
|
+
/**
|
|
130
|
+
* Build a pure, conditional restore plan. A blocked plan is never executable:
|
|
131
|
+
* collisions and unresolved cross-app content mappings must be resolved first.
|
|
132
|
+
*/
|
|
133
|
+
export declare function planTranslationArchiveRestore(archive: ParsedTranslationArchive, options: PlanTranslationArchiveRestoreOptions): Promise<TranslationArchiveRestorePlan>;
|