@_linked/translation 0.7.0 → 0.8.1
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 +15 -16
- package/lib/esm/archive.d.ts +2 -2
- package/lib/esm/archive.js +2 -2
- package/lib/esm/archive.js.map +1 -1
- package/lib/esm/authorization.d.ts +1 -1
- package/lib/esm/authorization.js +1 -1
- package/lib/esm/authorization.js.map +1 -1
- package/lib/esm/cdn-loader.d.ts +1 -1
- package/lib/esm/cdn-loader.js.map +1 -1
- package/lib/esm/core/messages.d.ts +14 -1
- package/lib/esm/core/messages.js +33 -2
- package/lib/esm/core/messages.js.map +1 -1
- package/lib/esm/exchange.d.ts +1 -1
- package/lib/esm/exchange.js +1 -1
- package/lib/esm/exchange.js.map +1 -1
- package/lib/esm/export.js +4 -1
- package/lib/esm/export.js.map +1 -1
- package/lib/esm/formats/xliff.js +1 -1
- package/lib/esm/formats/xliff.js.map +1 -1
- package/lib/esm/key-sync.d.ts +12 -0
- package/lib/esm/key-sync.js +32 -7
- package/lib/esm/key-sync.js.map +1 -1
- package/lib/esm/mt.js +1 -1
- package/lib/esm/mt.js.map +1 -1
- package/lib/esm/ontologies/translation.d.ts +193 -191
- package/lib/esm/ontologies/translation.js +4 -2
- package/lib/esm/ontologies/translation.js.map +1 -1
- package/lib/esm/package.d.ts +3 -3
- package/lib/esm/react.d.ts +38 -2
- package/lib/esm/react.js +98 -15
- package/lib/esm/react.js.map +1 -1
- package/lib/esm/records.d.ts +2 -1
- package/lib/esm/records.js.map +1 -1
- package/lib/esm/release.d.ts +3 -1
- package/lib/esm/release.js +21 -4
- package/lib/esm/release.js.map +1 -1
- package/lib/esm/shape-catalog.d.ts +1 -1
- package/lib/esm/shape-catalog.js.map +1 -1
- package/lib/esm/shapes/GlossaryTerm.d.ts +1 -1
- package/lib/esm/shapes/TranslationInventoryOrigin.d.ts +1 -1
- package/lib/esm/shapes/TranslationKey.d.ts +11 -6
- package/lib/esm/shapes/TranslationKey.js +16 -5
- package/lib/esm/shapes/TranslationKey.js.map +1 -1
- package/lib/esm/shapes/TranslationKeyVersion.d.ts +1 -1
- package/lib/esm/shapes/TranslationLanguage.d.ts +1 -1
- package/lib/esm/shapes/TranslationProvider.d.ts +25 -8
- package/lib/esm/shapes/TranslationProvider.js +69 -38
- package/lib/esm/shapes/TranslationProvider.js.map +1 -1
- package/lib/esm/shapes/TranslationRelease.d.ts +1 -1
- package/lib/esm/shapes/TranslationRevision.d.ts +1 -1
- package/lib/esm/shapes/TranslationUnit.d.ts +1 -1
- package/package.json +7 -7
- package/src/archive.ts +2 -2
- package/src/authorization.ts +1 -1
- package/src/cdn-loader.ts +1 -1
- package/src/core/messages.ts +35 -2
- package/src/exchange.ts +1 -1
- package/src/export.ts +4 -1
- package/src/formats/xliff.ts +1 -1
- package/src/key-sync.ts +46 -6
- package/src/mt.ts +1 -1
- package/src/ontologies/translation.ts +4 -2
- package/src/react.tsx +158 -35
- package/src/records.ts +2 -1
- package/src/release.ts +31 -3
- package/src/shape-catalog.ts +1 -1
- package/src/shapes/TranslationKey.ts +14 -5
- package/src/shapes/TranslationProvider.ts +92 -32
|
@@ -82,6 +82,12 @@ export class TranslationKey extends Shape {
|
|
|
82
82
|
return '';
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/** Arbitrary declared semantic resource, such as an action or condition. */
|
|
86
|
+
@objectProperty({ path: tr.ofResource, maxCount: 1 })
|
|
87
|
+
get ofResource(): string {
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
/** Reusable package that supplied the seed value. */
|
|
86
92
|
@literalProperty({ path: tr.fromPackage, maxCount: 1 })
|
|
87
93
|
get fromPackage(): string {
|
|
@@ -89,10 +95,11 @@ export class TranslationKey extends Shape {
|
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
/**
|
|
92
|
-
* True when this app copy of a
|
|
93
|
-
*
|
|
98
|
+
* True when this app copy of a declaration-owned key has been edited locally
|
|
99
|
+
* (shape, property or named package resource, including help) and should NOT
|
|
100
|
+
* be overwritten by declaration refresh or shape-route propagation (AD-N: "never
|
|
94
101
|
* overwrites an app's own override"). Set when the per-app editor changes the
|
|
95
|
-
* source of a key
|
|
102
|
+
* source of a key with declared ownership.
|
|
96
103
|
*/
|
|
97
104
|
@literalProperty({ path: tr.overridden, maxCount: 1 })
|
|
98
105
|
get overridden(): boolean {
|
|
@@ -100,9 +107,10 @@ export class TranslationKey extends Shape {
|
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
/**
|
|
103
|
-
* The
|
|
110
|
+
* The declaration's canonical source captured when this app first overrode the
|
|
104
111
|
* key — what "clear override" reverts to when no non-overridden sibling copy is
|
|
105
|
-
* available to read the current canonical from (AD-N).
|
|
112
|
+
* available to read the current canonical from (AD-N). The historic predicate
|
|
113
|
+
* name stays compatible; resource-owned help does not invent a second carrier.
|
|
106
114
|
*/
|
|
107
115
|
@literalProperty({ path: tr.shapeSource, maxCount: 1 })
|
|
108
116
|
get shapeSource(): string {
|
|
@@ -151,6 +159,7 @@ export class TranslationKey extends Shape {
|
|
|
151
159
|
ofField?: string;
|
|
152
160
|
ofShape?: string;
|
|
153
161
|
ofProperty?: string;
|
|
162
|
+
ofResource?: string;
|
|
154
163
|
fromPackage?: string;
|
|
155
164
|
format?: 'simple' | 'icu';
|
|
156
165
|
}): Promise<{ id: string }> {
|
|
@@ -44,6 +44,7 @@ export interface TranslationKeyInput {
|
|
|
44
44
|
ofField?: string;
|
|
45
45
|
ofShape?: string;
|
|
46
46
|
ofProperty?: string;
|
|
47
|
+
ofResource?: string;
|
|
47
48
|
fromPackage?: string;
|
|
48
49
|
/** Force the override flag; when omitted it is derived (see upsertTranslationKey). */
|
|
49
50
|
overridden?: boolean;
|
|
@@ -51,6 +52,25 @@ export interface TranslationKeyInput {
|
|
|
51
52
|
sourceLanguage?: string;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
/** Trusted caller context, not a client payload flag. Package discovery and
|
|
56
|
+
* explicit app authoring have different ownership semantics. */
|
|
57
|
+
export interface TranslationKeyWriteContext {
|
|
58
|
+
createdBy?: string;
|
|
59
|
+
/**
|
|
60
|
+
* `'declaration-sync'` is a refresh from code/package declarations: it never
|
|
61
|
+
* marks a key overridden, and it leaves an existing app override untouched
|
|
62
|
+
* (answering `preservedOverride: true`). Anything else is an app edit.
|
|
63
|
+
*/
|
|
64
|
+
source?: 'app-edit' | 'declaration-sync';
|
|
65
|
+
}
|
|
66
|
+
export interface TranslationKeyWriteResult {
|
|
67
|
+
id: string;
|
|
68
|
+
versionId: string;
|
|
69
|
+
versionCreated: boolean;
|
|
70
|
+
/** Present when a declaration refresh kept the app's override and wrote nothing. */
|
|
71
|
+
preservedOverride?: true;
|
|
72
|
+
}
|
|
73
|
+
|
|
54
74
|
export interface TranslationUnitInput {
|
|
55
75
|
appId: string;
|
|
56
76
|
key: string;
|
|
@@ -313,6 +333,7 @@ export function groupTranslationEntries(
|
|
|
313
333
|
format: row.format === 'icu' ? 'icu' : 'simple',
|
|
314
334
|
ofShape: iri(row.ofShape),
|
|
315
335
|
ofProperty: iri(row.ofProperty),
|
|
336
|
+
ofResource: iri(row.ofResource),
|
|
316
337
|
fromPackage: row.fromPackage || undefined,
|
|
317
338
|
overridden:
|
|
318
339
|
(row as any).overridden === true || (row as any).overridden === 'true'
|
|
@@ -397,6 +418,7 @@ export async function listTranslationKeys(data: { appId: string }) {
|
|
|
397
418
|
k.ofField,
|
|
398
419
|
k.ofShape,
|
|
399
420
|
k.ofProperty,
|
|
421
|
+
k.ofResource,
|
|
400
422
|
k.fromPackage,
|
|
401
423
|
k.overridden,
|
|
402
424
|
k.format,
|
|
@@ -423,6 +445,7 @@ export async function listTranslationEntries(data: {
|
|
|
423
445
|
k.format,
|
|
424
446
|
k.ofShape,
|
|
425
447
|
k.ofProperty,
|
|
448
|
+
k.ofResource,
|
|
426
449
|
k.fromPackage,
|
|
427
450
|
k.overridden,
|
|
428
451
|
k.currentVersion,
|
|
@@ -1061,8 +1084,8 @@ export async function decideTranslationProposal(
|
|
|
1061
1084
|
*/
|
|
1062
1085
|
export async function upsertTranslationKey(
|
|
1063
1086
|
data: TranslationKeyInput,
|
|
1064
|
-
authorship:
|
|
1065
|
-
): Promise<
|
|
1087
|
+
authorship: TranslationKeyWriteContext = {},
|
|
1088
|
+
): Promise<TranslationKeyWriteResult> {
|
|
1066
1089
|
const appId = requireText(data.appId, 'appId');
|
|
1067
1090
|
const key = requireText(data.key, 'key');
|
|
1068
1091
|
requireText(data.sourceText, 'sourceText');
|
|
@@ -1078,29 +1101,59 @@ export async function upsertTranslationKey(
|
|
|
1078
1101
|
ofField: data.ofField,
|
|
1079
1102
|
ofShape: data.ofShape ? { id: data.ofShape } : undefined,
|
|
1080
1103
|
ofProperty: data.ofProperty ? { id: data.ofProperty } : undefined,
|
|
1104
|
+
ofResource: data.ofResource ? { id: data.ofResource } : undefined,
|
|
1081
1105
|
fromPackage: data.fromPackage,
|
|
1082
|
-
overridden: data.overridden
|
|
1106
|
+
overridden: data.overridden,
|
|
1083
1107
|
format: data.format ?? 'simple',
|
|
1084
1108
|
} as any;
|
|
1109
|
+
// No catch: a failed read is not permission to create or overwrite the key.
|
|
1085
1110
|
const existing = await TranslationKey.select((k) => [
|
|
1086
1111
|
k.sourceText,
|
|
1087
1112
|
k.format,
|
|
1088
1113
|
k.ofShape,
|
|
1114
|
+
k.ofProperty,
|
|
1115
|
+
k.ofResource,
|
|
1116
|
+
k.fromPackage,
|
|
1089
1117
|
k.overridden,
|
|
1090
1118
|
k.currentVersion,
|
|
1091
1119
|
])
|
|
1092
1120
|
.where((k) => k.equals({ id } as any))
|
|
1093
|
-
.one()
|
|
1094
|
-
.catch(() => null);
|
|
1121
|
+
.one();
|
|
1095
1122
|
if (existing) {
|
|
1096
1123
|
const sourceChanged = (existing as any).sourceText !== data.sourceText;
|
|
1124
|
+
const formatChanged =
|
|
1125
|
+
((existing as any).format ?? 'simple') !== (data.format ?? 'simple');
|
|
1097
1126
|
const wasOverridden = (existing as any).overridden === true;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1127
|
+
if (authorship.source === 'declaration-sync' && wasOverridden) {
|
|
1128
|
+
const versionId = iri((existing as any).currentVersion);
|
|
1129
|
+
if (!versionId)
|
|
1130
|
+
throw new Error(
|
|
1131
|
+
`Translation override ${id} has no current version; refresh refused without changing its source.`
|
|
1132
|
+
);
|
|
1133
|
+
// No key write, version creation or unit invalidation. The declaration
|
|
1134
|
+
// inventory still records the package's current source independently.
|
|
1135
|
+
return { id, versionId, versionCreated: false, preservedOverride: true };
|
|
1136
|
+
}
|
|
1137
|
+
// AD-N ownership also covers property/resource/package declarations (help,
|
|
1138
|
+
// actions, groups), not only shapes. App edits preserve the first canonical
|
|
1139
|
+
// wording in the existing shapeSource carrier. Only an explicit app edit
|
|
1140
|
+
// may clear the override; automatic discovery cannot clear it by payload.
|
|
1141
|
+
const isDeclaredKey = !!(
|
|
1142
|
+
(existing as any).ofShape ||
|
|
1143
|
+
(existing as any).ofProperty ||
|
|
1144
|
+
(existing as any).ofResource ||
|
|
1145
|
+
(existing as any).fromPackage ||
|
|
1146
|
+
data.ofShape ||
|
|
1147
|
+
data.ofProperty ||
|
|
1148
|
+
data.ofResource ||
|
|
1149
|
+
data.fromPackage
|
|
1150
|
+
);
|
|
1151
|
+
if (
|
|
1152
|
+
authorship.source !== 'declaration-sync' &&
|
|
1153
|
+
data.overridden === undefined &&
|
|
1154
|
+
isDeclaredKey &&
|
|
1155
|
+
(sourceChanged || formatChanged)
|
|
1156
|
+
) {
|
|
1104
1157
|
values.overridden = true;
|
|
1105
1158
|
// Snapshot the canonical at FIRST divergence so "clear override" has a
|
|
1106
1159
|
// value to revert to even for a single-app project. Later edits keep the
|
|
@@ -1134,7 +1187,14 @@ export async function upsertTranslationKey(
|
|
|
1134
1187
|
})
|
|
1135
1188
|
: currentVersion;
|
|
1136
1189
|
values.currentVersion = { id: nextVersion.id };
|
|
1137
|
-
|
|
1190
|
+
// In the Linked mutation DSL an explicitly present `undefined` removes
|
|
1191
|
+
// that predicate. A partial source edit has not requested removal of the
|
|
1192
|
+
// declaration owner, help description, or existing override flag. Omit
|
|
1193
|
+
// untouched fields; an explicit false (reset) remains a real write.
|
|
1194
|
+
const patch = Object.fromEntries(
|
|
1195
|
+
Object.entries(values).filter(([, value]) => value !== undefined)
|
|
1196
|
+
);
|
|
1197
|
+
await TranslationKey.update(patch as any).for({ id } as any);
|
|
1138
1198
|
if (decision.action === 'create-version') {
|
|
1139
1199
|
await TranslationUnit.update({ state: 'stale' } as any).where((u) =>
|
|
1140
1200
|
u.ofKey.equals({ id } as any),
|
|
@@ -1491,7 +1551,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1491
1551
|
|
|
1492
1552
|
/**
|
|
1493
1553
|
* Authoring gate. Reads `linkedAuth` off the request the LINKED server already
|
|
1494
|
-
* populates, so this stays portable (no
|
|
1554
|
+
* populates, so this stays portable (no host-application import, AD-G).
|
|
1495
1555
|
*
|
|
1496
1556
|
* Every method except `getMessages` resolves the caller once, synchronously,
|
|
1497
1557
|
* before its first `await`, and uses that value for both the permission check
|
|
@@ -1542,21 +1602,21 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1542
1602
|
}
|
|
1543
1603
|
}
|
|
1544
1604
|
|
|
1545
|
-
@callable('
|
|
1605
|
+
@callable('signed-in')
|
|
1546
1606
|
async listKeys(data: { appId: string }) {
|
|
1547
1607
|
const actor = this.requireActor();
|
|
1548
1608
|
await this.requireAccess(actor, { appId: data?.appId }, 'read');
|
|
1549
1609
|
return listTranslationKeys(data);
|
|
1550
1610
|
}
|
|
1551
1611
|
|
|
1552
|
-
@callable('
|
|
1612
|
+
@callable('signed-in')
|
|
1553
1613
|
async listEntries(data: { appId: string }): Promise<TranslationEntryRecord[]> {
|
|
1554
1614
|
const actor = this.requireActor();
|
|
1555
1615
|
await this.requireAccess(actor, { appId: data?.appId }, 'read');
|
|
1556
1616
|
return listTranslationEntries(data);
|
|
1557
1617
|
}
|
|
1558
1618
|
|
|
1559
|
-
@callable('
|
|
1619
|
+
@callable('signed-in')
|
|
1560
1620
|
async listKeyVersions(data: {
|
|
1561
1621
|
appId: string;
|
|
1562
1622
|
key?: string;
|
|
@@ -1566,7 +1626,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1566
1626
|
return listTranslationKeyVersions(data);
|
|
1567
1627
|
}
|
|
1568
1628
|
|
|
1569
|
-
@callable('
|
|
1629
|
+
@callable('signed-in')
|
|
1570
1630
|
async listMemoryMatches(data: {
|
|
1571
1631
|
appId: string;
|
|
1572
1632
|
key: string;
|
|
@@ -1577,7 +1637,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1577
1637
|
return listTranslationMemoryMatches(data);
|
|
1578
1638
|
}
|
|
1579
1639
|
|
|
1580
|
-
@callable('
|
|
1640
|
+
@callable('signed-in')
|
|
1581
1641
|
async proposeRevision(data: {
|
|
1582
1642
|
appId: string;
|
|
1583
1643
|
key: string;
|
|
@@ -1601,7 +1661,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1601
1661
|
});
|
|
1602
1662
|
}
|
|
1603
1663
|
|
|
1604
|
-
@callable('
|
|
1664
|
+
@callable('signed-in')
|
|
1605
1665
|
async listProposals(data: {
|
|
1606
1666
|
appId: string;
|
|
1607
1667
|
language?: string;
|
|
@@ -1622,7 +1682,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1622
1682
|
return proposals.filter((_, index) => allowed[index]);
|
|
1623
1683
|
}
|
|
1624
1684
|
|
|
1625
|
-
@callable('
|
|
1685
|
+
@callable('signed-in')
|
|
1626
1686
|
async decideProposal(data: {
|
|
1627
1687
|
appId: string;
|
|
1628
1688
|
revisionId: string;
|
|
@@ -1646,7 +1706,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1646
1706
|
return decideTranslationProposal(data, actor);
|
|
1647
1707
|
}
|
|
1648
1708
|
|
|
1649
|
-
@callable('
|
|
1709
|
+
@callable('signed-in')
|
|
1650
1710
|
async listMemory(data: {
|
|
1651
1711
|
appId: string;
|
|
1652
1712
|
}): Promise<TranslationMemoryRecord[]> {
|
|
@@ -1655,7 +1715,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1655
1715
|
return listTranslationMemory(data);
|
|
1656
1716
|
}
|
|
1657
1717
|
|
|
1658
|
-
@callable('
|
|
1718
|
+
@callable('signed-in')
|
|
1659
1719
|
async pretranslateMemory(data: {
|
|
1660
1720
|
appId: string;
|
|
1661
1721
|
language: string;
|
|
@@ -1666,7 +1726,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1666
1726
|
return pretranslateFromMemory(data, { author: actor });
|
|
1667
1727
|
}
|
|
1668
1728
|
|
|
1669
|
-
@callable('
|
|
1729
|
+
@callable('signed-in')
|
|
1670
1730
|
async applyMemoryMatch(data: {
|
|
1671
1731
|
appId: string;
|
|
1672
1732
|
key: string;
|
|
@@ -1678,7 +1738,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1678
1738
|
return applyTranslationMemoryMatch(data, { author: actor });
|
|
1679
1739
|
}
|
|
1680
1740
|
|
|
1681
|
-
@callable('
|
|
1741
|
+
@callable('signed-in')
|
|
1682
1742
|
async listReleases(data: {
|
|
1683
1743
|
appId: string;
|
|
1684
1744
|
}): Promise<TranslationReleaseRecord[]> {
|
|
@@ -1687,7 +1747,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1687
1747
|
return listTranslationReleases(data);
|
|
1688
1748
|
}
|
|
1689
1749
|
|
|
1690
|
-
@callable('
|
|
1750
|
+
@callable('signed-in')
|
|
1691
1751
|
async createRelease(
|
|
1692
1752
|
data: Omit<TranslationReleaseRecord, 'id' | 'createdAt'> & {
|
|
1693
1753
|
createdAt?: string;
|
|
@@ -1698,7 +1758,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1698
1758
|
return createTranslationRelease(data);
|
|
1699
1759
|
}
|
|
1700
1760
|
|
|
1701
|
-
@callable('
|
|
1761
|
+
@callable('signed-in')
|
|
1702
1762
|
async advanceReleaseHotfix(data: {
|
|
1703
1763
|
id: string;
|
|
1704
1764
|
expectedSequence: number;
|
|
@@ -1712,14 +1772,14 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1712
1772
|
return advanceTranslationReleaseHotfix({ ...data, appId });
|
|
1713
1773
|
}
|
|
1714
1774
|
|
|
1715
|
-
@callable('
|
|
1775
|
+
@callable('signed-in')
|
|
1716
1776
|
async upsertKey(data: TranslationKeyInput): Promise<{ id: string }> {
|
|
1717
1777
|
const actor = this.requireActor();
|
|
1718
1778
|
await this.requireAccess(actor, data, 'manage');
|
|
1719
1779
|
return upsertTranslationKey(data, { createdBy: actor });
|
|
1720
1780
|
}
|
|
1721
1781
|
|
|
1722
|
-
@callable('
|
|
1782
|
+
@callable('signed-in')
|
|
1723
1783
|
async upsertUnit(data: TranslationUnitInput): Promise<{ id: string }> {
|
|
1724
1784
|
const actor = this.requireActor();
|
|
1725
1785
|
await this.requireAccess(actor, data, 'review');
|
|
@@ -1735,14 +1795,14 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1735
1795
|
* anchors the IRIs. Uniqueness = (term, language) — upsert is
|
|
1736
1796
|
* delete-then-create on that identity.
|
|
1737
1797
|
*/
|
|
1738
|
-
@callable('
|
|
1798
|
+
@callable('signed-in')
|
|
1739
1799
|
async listGlossary(data: { appId: string }): Promise<GlossaryTermRecord[]> {
|
|
1740
1800
|
const actor = this.requireActor();
|
|
1741
1801
|
await this.requireAccess(actor, { appId: data?.appId }, 'read');
|
|
1742
1802
|
return listGlossaryTerms(data);
|
|
1743
1803
|
}
|
|
1744
1804
|
|
|
1745
|
-
@callable('
|
|
1805
|
+
@callable('signed-in')
|
|
1746
1806
|
async upsertGlossaryTerm(data: {
|
|
1747
1807
|
appId: string;
|
|
1748
1808
|
term: string;
|
|
@@ -1785,7 +1845,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1785
1845
|
return { id };
|
|
1786
1846
|
}
|
|
1787
1847
|
|
|
1788
|
-
@callable('
|
|
1848
|
+
@callable('signed-in')
|
|
1789
1849
|
async deleteGlossaryTerm(data: { appId: string; id: string }): Promise<{ deleted: boolean }> {
|
|
1790
1850
|
const actor = this.requireActor();
|
|
1791
1851
|
await this.requireAccess(actor, data, 'manage');
|
|
@@ -1800,7 +1860,7 @@ export class TranslationProvider extends ShapeProvider {
|
|
|
1800
1860
|
}
|
|
1801
1861
|
|
|
1802
1862
|
/** History for one (key, language) cell — newest first (Plan 017 AD-P). */
|
|
1803
|
-
@callable('
|
|
1863
|
+
@callable('signed-in')
|
|
1804
1864
|
async listRevisions(data: {
|
|
1805
1865
|
appId: string;
|
|
1806
1866
|
key: string;
|