@proveanything/smartlinks 1.9.3 → 1.9.5
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 +3 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/translations.d.ts +12 -0
- package/dist/api/translations.js +217 -0
- package/dist/docs/API_SUMMARY.md +313 -1
- package/dist/docs/overview.md +1 -0
- package/dist/docs/translations.md +335 -0
- package/dist/index.d.ts +1 -0
- package/dist/openapi.yaml +1797 -494
- package/dist/translationCache.d.ts +38 -0
- package/dist/translationCache.js +298 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/translations.d.ts +107 -0
- package/dist/types/translations.js +1 -0
- package/docs/API_SUMMARY.md +313 -1
- package/docs/overview.md +1 -0
- package/docs/translations.md +335 -0
- package/openapi.yaml +1797 -494
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ If you're new to the SDK, this is the easiest path:
|
|
|
22
22
|
|
|
23
23
|
- [docs/ai.md](docs/ai.md) — AI responses, chat, RAG, voice, streaming, and product assistants
|
|
24
24
|
- [docs/analytics.md](docs/analytics.md) — fire-and-forget web analytics, tag scan telemetry, and dashboard queries
|
|
25
|
+
- [docs/translations.md](docs/translations.md) — runtime translation lookup, browser-side caching, and translation admin flows
|
|
25
26
|
- [docs/widgets.md](docs/widgets.md) — embeddable React components
|
|
26
27
|
- [docs/realtime.md](docs/realtime.md) — subscriptions and live updates
|
|
27
28
|
- [docs/iframe-responder.md](docs/iframe-responder.md) — iframe integration and parent/child messaging
|
|
@@ -31,6 +32,7 @@ If you're new to the SDK, this is the easiest path:
|
|
|
31
32
|
|
|
32
33
|
- **Build an AI assistant** → start with [docs/ai.md](docs/ai.md)
|
|
33
34
|
- **Track page views, clicks, or tag scans** → start with [docs/analytics.md](docs/analytics.md)
|
|
35
|
+
- **Translate dynamic content with local browser caching** → start with [docs/translations.md](docs/translations.md)
|
|
34
36
|
- **Fetch collections/products** → see [Quick start](README.md#quick-start)
|
|
35
37
|
- **Authenticate admins or end users** → see [Authentication](README.md#authentication)
|
|
36
38
|
- **Upload and manage files** → see [Assets](README.md#assets)
|
|
@@ -42,6 +44,7 @@ For the full list of functions and types, see the API summary:
|
|
|
42
44
|
**Documentation:**
|
|
43
45
|
- [AI & Chat Completions](docs/ai.md) - Chat completions, RAG, voice integration
|
|
44
46
|
- [Analytics](docs/analytics.md) - Fire-and-forget analytics tracking, tag scans, and dashboard queries
|
|
47
|
+
- [Translations](docs/translations.md) - Runtime translation lookup, browser-side IndexedDB caching, and admin translation management
|
|
45
48
|
- [Widgets](docs/widgets.md) - Embeddable React components
|
|
46
49
|
- [Realtime](docs/realtime.md) - Realtime data updates
|
|
47
50
|
- [iframe Responder](docs/iframe-responder.md) - iframe integration
|
package/dist/api/index.d.ts
CHANGED
package/dist/api/index.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ResolvedTranslationResponse, TranslationHashOptions, TranslationListParams, TranslationListResponse, TranslationLookupRequest, TranslationLookupResponse, TranslationRecord, TranslationResolveOptions, TranslationUpdateRequest } from '../types/translations';
|
|
2
|
+
export declare namespace translations {
|
|
3
|
+
function hashText(text: string, options?: TranslationHashOptions): Promise<string>;
|
|
4
|
+
function hashTexts(texts: string[], options?: TranslationHashOptions): Promise<string[]>;
|
|
5
|
+
function normalizeText(text: string, options?: TranslationHashOptions): string;
|
|
6
|
+
function lookup(collectionId: string, body: TranslationLookupRequest): Promise<TranslationLookupResponse>;
|
|
7
|
+
function resolve(collectionId: string, body: TranslationLookupRequest, options?: TranslationResolveOptions): Promise<ResolvedTranslationResponse>;
|
|
8
|
+
function list(collectionId: string, params?: TranslationListParams): Promise<TranslationListResponse>;
|
|
9
|
+
function get(collectionId: string, translationId: string): Promise<TranslationRecord>;
|
|
10
|
+
function update(collectionId: string, translationId: string, body: TranslationUpdateRequest): Promise<TranslationRecord>;
|
|
11
|
+
function clearLocalCache(collectionId?: string): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { patch, post, request } from '../http';
|
|
2
|
+
import { clearCachedTranslations, deriveTranslationContextKey, getCachedTranslations, getDefaultTranslationCacheTtlMs, hashTranslationText, normalizeTranslationText, setCachedTranslations, } from '../translationCache';
|
|
3
|
+
function normalizeLookupRequest(body) {
|
|
4
|
+
var _a, _b, _c;
|
|
5
|
+
const texts = Array.isArray(body.texts)
|
|
6
|
+
? [...(body.texts)]
|
|
7
|
+
: typeof body.text === 'string'
|
|
8
|
+
? [body.text]
|
|
9
|
+
: [];
|
|
10
|
+
if (!body.targetLanguage) {
|
|
11
|
+
throw new Error('[smartlinks] translations.lookup requires targetLanguage');
|
|
12
|
+
}
|
|
13
|
+
if (texts.length === 0) {
|
|
14
|
+
throw new Error('[smartlinks] translations.lookup requires text or texts');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
targetLanguage: body.targetLanguage,
|
|
18
|
+
sourceLanguage: (_a = body.sourceLanguage) !== null && _a !== void 0 ? _a : 'en',
|
|
19
|
+
mode: (_b = body.mode) !== null && _b !== void 0 ? _b : 'cache-fill',
|
|
20
|
+
contentType: (_c = body.contentType) !== null && _c !== void 0 ? _c : 'text/plain',
|
|
21
|
+
contextKey: deriveTranslationContextKey(body.context),
|
|
22
|
+
requestBody: {
|
|
23
|
+
targetLanguage: body.targetLanguage,
|
|
24
|
+
sourceLanguage: body.sourceLanguage,
|
|
25
|
+
mode: body.mode,
|
|
26
|
+
contentType: body.contentType,
|
|
27
|
+
context: body.context,
|
|
28
|
+
returnMeta: body.returnMeta,
|
|
29
|
+
texts,
|
|
30
|
+
},
|
|
31
|
+
texts,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function buildTranslationListQuery(params = {}) {
|
|
35
|
+
const query = new URLSearchParams();
|
|
36
|
+
for (const [key, value] of Object.entries(params)) {
|
|
37
|
+
if (value === undefined || value === null)
|
|
38
|
+
continue;
|
|
39
|
+
query.append(key, String(value));
|
|
40
|
+
}
|
|
41
|
+
const queryString = query.toString();
|
|
42
|
+
return queryString ? `?${queryString}` : '';
|
|
43
|
+
}
|
|
44
|
+
function sameLanguage(left, right) {
|
|
45
|
+
return left.trim().toLowerCase() === right.trim().toLowerCase();
|
|
46
|
+
}
|
|
47
|
+
function toResolvedItem(item, index, cacheSource) {
|
|
48
|
+
return Object.assign(Object.assign({}, item), { index,
|
|
49
|
+
cacheSource });
|
|
50
|
+
}
|
|
51
|
+
export var translations;
|
|
52
|
+
(function (translations) {
|
|
53
|
+
async function hashText(text, options) {
|
|
54
|
+
return hashTranslationText(text, options);
|
|
55
|
+
}
|
|
56
|
+
translations.hashText = hashText;
|
|
57
|
+
async function hashTexts(texts, options) {
|
|
58
|
+
return Promise.all(texts.map((text) => hashTranslationText(text, options)));
|
|
59
|
+
}
|
|
60
|
+
translations.hashTexts = hashTexts;
|
|
61
|
+
function normalizeText(text, options) {
|
|
62
|
+
return normalizeTranslationText(text, options);
|
|
63
|
+
}
|
|
64
|
+
translations.normalizeText = normalizeText;
|
|
65
|
+
async function lookup(collectionId, body) {
|
|
66
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/translations/lookup`;
|
|
67
|
+
const normalized = normalizeLookupRequest(body);
|
|
68
|
+
return post(path, normalized.requestBody);
|
|
69
|
+
}
|
|
70
|
+
translations.lookup = lookup;
|
|
71
|
+
async function resolve(collectionId, body, options = {}) {
|
|
72
|
+
var _a, _b, _c;
|
|
73
|
+
const normalized = normalizeLookupRequest(body);
|
|
74
|
+
const { useLocalCache = true, refreshLocalCache = false, localCacheTtlMs = getDefaultTranslationCacheTtlMs(), hashOptions, } = options;
|
|
75
|
+
const hashes = await Promise.all(normalized.texts.map((text) => hashTranslationText(text, hashOptions)));
|
|
76
|
+
const results = new Array(normalized.texts.length);
|
|
77
|
+
if (sameLanguage(normalized.sourceLanguage, normalized.targetLanguage)) {
|
|
78
|
+
const passthroughItems = normalized.texts.map((text, index) => ({
|
|
79
|
+
index,
|
|
80
|
+
hash: hashes[index],
|
|
81
|
+
sourceText: text,
|
|
82
|
+
translatedText: text,
|
|
83
|
+
status: 'passthrough',
|
|
84
|
+
quality: 'passthrough',
|
|
85
|
+
cacheSource: 'local',
|
|
86
|
+
expiresAt: Date.now() + localCacheTtlMs,
|
|
87
|
+
}));
|
|
88
|
+
if (useLocalCache) {
|
|
89
|
+
await setCachedTranslations({
|
|
90
|
+
collectionId,
|
|
91
|
+
sourceLanguage: normalized.sourceLanguage,
|
|
92
|
+
targetLanguage: normalized.targetLanguage,
|
|
93
|
+
contentType: normalized.contentType,
|
|
94
|
+
contextKey: normalized.contextKey,
|
|
95
|
+
ttlMs: localCacheTtlMs,
|
|
96
|
+
items: passthroughItems.map((item) => ({ hash: item.hash, item })),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
targetLanguage: normalized.targetLanguage,
|
|
101
|
+
sourceLanguage: normalized.sourceLanguage,
|
|
102
|
+
mode: normalized.mode,
|
|
103
|
+
items: passthroughItems,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const cachedByHash = useLocalCache && !refreshLocalCache
|
|
107
|
+
? await getCachedTranslations({
|
|
108
|
+
collectionId,
|
|
109
|
+
sourceLanguage: normalized.sourceLanguage,
|
|
110
|
+
targetLanguage: normalized.targetLanguage,
|
|
111
|
+
contentType: normalized.contentType,
|
|
112
|
+
contextKey: normalized.contextKey,
|
|
113
|
+
hashes,
|
|
114
|
+
})
|
|
115
|
+
: new Map();
|
|
116
|
+
const missingIndexes = [];
|
|
117
|
+
for (let index = 0; index < normalized.texts.length; index += 1) {
|
|
118
|
+
const cached = cachedByHash.get(hashes[index]);
|
|
119
|
+
if ((_a = cached === null || cached === void 0 ? void 0 : cached.item) === null || _a === void 0 ? void 0 : _a.translatedText) {
|
|
120
|
+
results[index] = toResolvedItem(cached.item, index, 'local');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
missingIndexes.push(index);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (missingIndexes.length === 0) {
|
|
127
|
+
return {
|
|
128
|
+
targetLanguage: normalized.targetLanguage,
|
|
129
|
+
sourceLanguage: normalized.sourceLanguage,
|
|
130
|
+
mode: normalized.mode,
|
|
131
|
+
items: results,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const uniqueMisses = [];
|
|
135
|
+
const uniqueMissLookup = new Map();
|
|
136
|
+
for (const index of missingIndexes) {
|
|
137
|
+
const hash = hashes[index];
|
|
138
|
+
const existing = uniqueMissLookup.get(hash);
|
|
139
|
+
if (existing) {
|
|
140
|
+
existing.indexes.push(index);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
uniqueMissLookup.set(hash, { firstIndex: index, indexes: [index] });
|
|
144
|
+
uniqueMisses.push({ index, hash, text: normalized.texts[index] });
|
|
145
|
+
}
|
|
146
|
+
const remoteResponse = await lookup(collectionId, {
|
|
147
|
+
targetLanguage: normalized.targetLanguage,
|
|
148
|
+
sourceLanguage: body.sourceLanguage,
|
|
149
|
+
mode: body.mode,
|
|
150
|
+
contentType: body.contentType,
|
|
151
|
+
context: body.context,
|
|
152
|
+
returnMeta: body.returnMeta,
|
|
153
|
+
texts: uniqueMisses.map((item) => item.text),
|
|
154
|
+
});
|
|
155
|
+
const cacheableRemoteItems = [];
|
|
156
|
+
remoteResponse.items.forEach((remoteItem, remoteIndex) => {
|
|
157
|
+
var _a, _b;
|
|
158
|
+
const miss = uniqueMisses[remoteIndex];
|
|
159
|
+
if (!miss)
|
|
160
|
+
return;
|
|
161
|
+
const indexes = (_b = (_a = uniqueMissLookup.get(miss.hash)) === null || _a === void 0 ? void 0 : _a.indexes) !== null && _b !== void 0 ? _b : [miss.index];
|
|
162
|
+
for (const index of indexes) {
|
|
163
|
+
const resolvedItem = Object.assign(Object.assign({}, remoteItem), { index, hash: miss.hash, sourceText: normalized.texts[index], cacheSource: 'remote' });
|
|
164
|
+
results[index] = resolvedItem;
|
|
165
|
+
}
|
|
166
|
+
if (remoteItem.translatedText) {
|
|
167
|
+
cacheableRemoteItems.push({
|
|
168
|
+
hash: miss.hash,
|
|
169
|
+
item: Object.assign(Object.assign({}, remoteItem), { index: miss.index, hash: miss.hash, sourceText: miss.text, cacheSource: 'remote' }),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
if (useLocalCache && cacheableRemoteItems.length > 0) {
|
|
174
|
+
await setCachedTranslations({
|
|
175
|
+
collectionId,
|
|
176
|
+
sourceLanguage: normalized.sourceLanguage,
|
|
177
|
+
targetLanguage: normalized.targetLanguage,
|
|
178
|
+
contentType: normalized.contentType,
|
|
179
|
+
contextKey: normalized.contextKey,
|
|
180
|
+
ttlMs: localCacheTtlMs,
|
|
181
|
+
items: cacheableRemoteItems,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
targetLanguage: remoteResponse.targetLanguage,
|
|
186
|
+
sourceLanguage: (_b = remoteResponse.sourceLanguage) !== null && _b !== void 0 ? _b : normalized.sourceLanguage,
|
|
187
|
+
mode: (_c = remoteResponse.mode) !== null && _c !== void 0 ? _c : normalized.mode,
|
|
188
|
+
items: results.map((item, index) => item !== null && item !== void 0 ? item : {
|
|
189
|
+
index,
|
|
190
|
+
hash: hashes[index],
|
|
191
|
+
sourceText: normalized.texts[index],
|
|
192
|
+
cacheSource: 'remote',
|
|
193
|
+
}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
translations.resolve = resolve;
|
|
197
|
+
async function list(collectionId, params) {
|
|
198
|
+
const query = buildTranslationListQuery(params);
|
|
199
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/translations${query}`;
|
|
200
|
+
return request(path);
|
|
201
|
+
}
|
|
202
|
+
translations.list = list;
|
|
203
|
+
async function get(collectionId, translationId) {
|
|
204
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/translations/${encodeURIComponent(translationId)}`;
|
|
205
|
+
return request(path);
|
|
206
|
+
}
|
|
207
|
+
translations.get = get;
|
|
208
|
+
async function update(collectionId, translationId, body) {
|
|
209
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/translations/${encodeURIComponent(translationId)}`;
|
|
210
|
+
return patch(path, body);
|
|
211
|
+
}
|
|
212
|
+
translations.update = update;
|
|
213
|
+
async function clearLocalCache(collectionId) {
|
|
214
|
+
await clearCachedTranslations(collectionId);
|
|
215
|
+
}
|
|
216
|
+
translations.clearLocalCache = clearLocalCache;
|
|
217
|
+
})(translations || (translations = {}));
|
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.5 | Generated: 2026-03-23T20:19:00.201Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -10,13 +10,16 @@ For detailed guides on specific features:
|
|
|
10
10
|
|
|
11
11
|
- **[SmartLinks Microapp Overview](overview.md)** - Platform architecture, data model, auth patterns, storage, anti-patterns, and quick-reference for all SDK docs
|
|
12
12
|
- **[AI & Chat Completions](ai.md)** - Chat completions, RAG (document-grounded Q&A), voice integration, streaming, tool calling, podcast generation
|
|
13
|
+
- **[Translations](translations.md)** - Runtime translation lookup, browser-side IndexedDB caching, and admin translation management
|
|
13
14
|
- **[Widgets](widgets.md)** - Embeddable React components for parent applications
|
|
14
15
|
- **[Containers](containers.md)** - Building full-app embeddable containers (lazy-loaded)
|
|
16
|
+
- **[Scanner Containers](scanner-container.md)** - Building scanner microapps for the SmartLinks Scanner Android host (RFID, NFC, QR, key events)
|
|
15
17
|
- **[Multi-Page App Architecture](mpa.md)** - Vite MPA build pipeline: public/admin entry points, widget/container/executor bundles, content-hashed CDN assets
|
|
16
18
|
- **[App Configuration Files](app-manifest.md)** - `app.manifest.json` and `app.admin.json` reference — bundles, components, setup questions, import schemas, tunable fields, and metrics
|
|
17
19
|
- **[Executor Model](executor.md)** - Programmatic JS bundles for AI-driven setup, server-side SEO metadata generation, and LLM content for AI crawlers
|
|
18
20
|
- **[Realtime](realtime.md)** - Real-time data updates and WebSocket connections
|
|
19
21
|
- **[iframe Responder](iframe-responder.md)** - iframe integration and cross-origin communication
|
|
22
|
+
- **[Utilities](utils.md)** - Helper functions for building portal paths, URLs, and common tasks
|
|
20
23
|
- **[i18n](i18n.md)** - Internationalization and localization
|
|
21
24
|
- **[Liquid Templates](liquid-templates.md)** - Dynamic templating for content generation
|
|
22
25
|
- **[Theme System](theme.system.md)** - Theme configuration and customization
|
|
@@ -110,6 +113,7 @@ The Smartlinks SDK is organized into the following namespaces:
|
|
|
110
113
|
- **realtime** - Functions for realtime operations
|
|
111
114
|
- **tags** - Functions for tags operations
|
|
112
115
|
- **template** - Functions for template operations
|
|
116
|
+
- **translations** - Functions for translations operations
|
|
113
117
|
|
|
114
118
|
## HTTP Utilities
|
|
115
119
|
|
|
@@ -6343,6 +6347,153 @@ interface TemplateRenderSourceResponse {
|
|
|
6343
6347
|
|
|
6344
6348
|
**TemplatePublic** = `TemplateBase`
|
|
6345
6349
|
|
|
6350
|
+
### translations
|
|
6351
|
+
|
|
6352
|
+
**TranslationContext** (interface)
|
|
6353
|
+
```typescript
|
|
6354
|
+
interface TranslationContext {
|
|
6355
|
+
surface?: string
|
|
6356
|
+
field?: string
|
|
6357
|
+
[key: string]: TranslationContextValue | undefined
|
|
6358
|
+
}
|
|
6359
|
+
```
|
|
6360
|
+
|
|
6361
|
+
**TranslationLookupRequestBase** (interface)
|
|
6362
|
+
```typescript
|
|
6363
|
+
interface TranslationLookupRequestBase {
|
|
6364
|
+
targetLanguage: string
|
|
6365
|
+
sourceLanguage?: string
|
|
6366
|
+
mode?: TranslationLookupMode
|
|
6367
|
+
contentType?: TranslationContentType
|
|
6368
|
+
context?: TranslationContext
|
|
6369
|
+
returnMeta?: boolean
|
|
6370
|
+
}
|
|
6371
|
+
```
|
|
6372
|
+
|
|
6373
|
+
**TranslationLookupItem** (interface)
|
|
6374
|
+
```typescript
|
|
6375
|
+
interface TranslationLookupItem {
|
|
6376
|
+
index: number
|
|
6377
|
+
hash: string
|
|
6378
|
+
sourceText: string
|
|
6379
|
+
translatedText?: string
|
|
6380
|
+
status?: TranslationItemStatus
|
|
6381
|
+
provider?: string
|
|
6382
|
+
model?: string
|
|
6383
|
+
isOverride?: boolean
|
|
6384
|
+
quality?: TranslationQuality
|
|
6385
|
+
createdAt?: string
|
|
6386
|
+
updatedAt?: string
|
|
6387
|
+
}
|
|
6388
|
+
```
|
|
6389
|
+
|
|
6390
|
+
**TranslationLookupResponse** (interface)
|
|
6391
|
+
```typescript
|
|
6392
|
+
interface TranslationLookupResponse {
|
|
6393
|
+
targetLanguage: string
|
|
6394
|
+
sourceLanguage?: string
|
|
6395
|
+
mode?: TranslationLookupMode
|
|
6396
|
+
items: TranslationLookupItem[]
|
|
6397
|
+
}
|
|
6398
|
+
```
|
|
6399
|
+
|
|
6400
|
+
**ResolvedTranslationResponse** (interface)
|
|
6401
|
+
```typescript
|
|
6402
|
+
interface ResolvedTranslationResponse {
|
|
6403
|
+
targetLanguage: string
|
|
6404
|
+
sourceLanguage?: string
|
|
6405
|
+
mode?: TranslationLookupMode
|
|
6406
|
+
items: ResolvedTranslationItem[]
|
|
6407
|
+
}
|
|
6408
|
+
```
|
|
6409
|
+
|
|
6410
|
+
**TranslationHashOptions** (interface)
|
|
6411
|
+
```typescript
|
|
6412
|
+
interface TranslationHashOptions {
|
|
6413
|
+
trim?: boolean
|
|
6414
|
+
collapseWhitespace?: boolean
|
|
6415
|
+
unicodeNormalization?: 'NFC' | 'NFKC' | false
|
|
6416
|
+
}
|
|
6417
|
+
```
|
|
6418
|
+
|
|
6419
|
+
**TranslationResolveOptions** (interface)
|
|
6420
|
+
```typescript
|
|
6421
|
+
interface TranslationResolveOptions {
|
|
6422
|
+
useLocalCache?: boolean
|
|
6423
|
+
refreshLocalCache?: boolean
|
|
6424
|
+
localCacheTtlMs?: number
|
|
6425
|
+
hashOptions?: TranslationHashOptions
|
|
6426
|
+
}
|
|
6427
|
+
```
|
|
6428
|
+
|
|
6429
|
+
**TranslationRecord** (interface)
|
|
6430
|
+
```typescript
|
|
6431
|
+
interface TranslationRecord {
|
|
6432
|
+
id: string
|
|
6433
|
+
collectionId: string
|
|
6434
|
+
sourceHash: string
|
|
6435
|
+
sourceText: string
|
|
6436
|
+
sourceLanguage?: string
|
|
6437
|
+
targetLanguage: string
|
|
6438
|
+
contentType: string
|
|
6439
|
+
contextKey?: string | null
|
|
6440
|
+
translatedText: string
|
|
6441
|
+
provider?: string | null
|
|
6442
|
+
model?: string | null
|
|
6443
|
+
quality: TranslationQuality
|
|
6444
|
+
isOverride: boolean
|
|
6445
|
+
metadata?: Record<string, any>
|
|
6446
|
+
createdAt: string
|
|
6447
|
+
updatedAt: string
|
|
6448
|
+
}
|
|
6449
|
+
```
|
|
6450
|
+
|
|
6451
|
+
**TranslationListParams** (interface)
|
|
6452
|
+
```typescript
|
|
6453
|
+
interface TranslationListParams {
|
|
6454
|
+
targetLanguage?: string
|
|
6455
|
+
sourceLanguage?: string
|
|
6456
|
+
contentType?: string
|
|
6457
|
+
contextKey?: string
|
|
6458
|
+
q?: string
|
|
6459
|
+
isOverride?: boolean
|
|
6460
|
+
limit?: number
|
|
6461
|
+
offset?: number
|
|
6462
|
+
}
|
|
6463
|
+
```
|
|
6464
|
+
|
|
6465
|
+
**TranslationListResponse** (interface)
|
|
6466
|
+
```typescript
|
|
6467
|
+
interface TranslationListResponse {
|
|
6468
|
+
items: TranslationRecord[]
|
|
6469
|
+
total?: number
|
|
6470
|
+
limit?: number
|
|
6471
|
+
offset?: number
|
|
6472
|
+
}
|
|
6473
|
+
```
|
|
6474
|
+
|
|
6475
|
+
**TranslationUpdateRequest** (interface)
|
|
6476
|
+
```typescript
|
|
6477
|
+
interface TranslationUpdateRequest {
|
|
6478
|
+
translatedText?: string
|
|
6479
|
+
isOverride?: boolean
|
|
6480
|
+
quality?: TranslationQuality
|
|
6481
|
+
metadata?: Record<string, any>
|
|
6482
|
+
}
|
|
6483
|
+
```
|
|
6484
|
+
|
|
6485
|
+
**TranslationLookupMode** = `'cache-fill' | 'cache-only'`
|
|
6486
|
+
|
|
6487
|
+
**TranslationContentType** = `'text/plain' | 'text/html' | 'text/x-liquid' | (string & {})`
|
|
6488
|
+
|
|
6489
|
+
**TranslationQuality** = `'machine' | 'human' | 'passthrough' | (string & {})`
|
|
6490
|
+
|
|
6491
|
+
**TranslationItemStatus** = `'cached' | 'generated' | 'miss' | 'passthrough' | 'local-cache' | (string & {})`
|
|
6492
|
+
|
|
6493
|
+
**TranslationContextValue** = `string | number | boolean | null`
|
|
6494
|
+
|
|
6495
|
+
**TranslationLookupRequest** = `TranslationLookupSingleRequest | TranslationLookupBatchRequest`
|
|
6496
|
+
|
|
6346
6497
|
### variant
|
|
6347
6498
|
|
|
6348
6499
|
**VariantResponse** = `any`
|
|
@@ -6412,6 +6563,140 @@ type VerifyTokenResponse = {
|
|
|
6412
6563
|
}
|
|
6413
6564
|
```
|
|
6414
6565
|
|
|
6566
|
+
### conditions (utils)
|
|
6567
|
+
|
|
6568
|
+
**BaseCondition** (interface)
|
|
6569
|
+
```typescript
|
|
6570
|
+
interface BaseCondition {
|
|
6571
|
+
type: string
|
|
6572
|
+
contains?: boolean
|
|
6573
|
+
passes?: boolean
|
|
6574
|
+
}
|
|
6575
|
+
```
|
|
6576
|
+
|
|
6577
|
+
**ConditionSet** (interface)
|
|
6578
|
+
```typescript
|
|
6579
|
+
interface ConditionSet {
|
|
6580
|
+
id?: string
|
|
6581
|
+
type?: 'and' | 'or'
|
|
6582
|
+
conditions?: Condition[]
|
|
6583
|
+
}
|
|
6584
|
+
```
|
|
6585
|
+
|
|
6586
|
+
**UserLocation** (interface)
|
|
6587
|
+
```typescript
|
|
6588
|
+
interface UserLocation {
|
|
6589
|
+
country?: string
|
|
6590
|
+
latitude?: number
|
|
6591
|
+
longitude?: number
|
|
6592
|
+
}
|
|
6593
|
+
```
|
|
6594
|
+
|
|
6595
|
+
**PlatformInfo** (interface)
|
|
6596
|
+
```typescript
|
|
6597
|
+
interface PlatformInfo {
|
|
6598
|
+
android?: boolean
|
|
6599
|
+
ios?: boolean
|
|
6600
|
+
win?: boolean
|
|
6601
|
+
mac?: boolean
|
|
6602
|
+
}
|
|
6603
|
+
```
|
|
6604
|
+
|
|
6605
|
+
**StatsInfo** (interface)
|
|
6606
|
+
```typescript
|
|
6607
|
+
interface StatsInfo {
|
|
6608
|
+
version?: string | null
|
|
6609
|
+
platform?: PlatformInfo
|
|
6610
|
+
mobile?: boolean
|
|
6611
|
+
}
|
|
6612
|
+
```
|
|
6613
|
+
|
|
6614
|
+
**UserInfo** (interface)
|
|
6615
|
+
```typescript
|
|
6616
|
+
interface UserInfo {
|
|
6617
|
+
valid: boolean
|
|
6618
|
+
uid?: string
|
|
6619
|
+
location?: UserLocation
|
|
6620
|
+
groups?: string[]
|
|
6621
|
+
}
|
|
6622
|
+
```
|
|
6623
|
+
|
|
6624
|
+
**ProductInfo** (interface)
|
|
6625
|
+
```typescript
|
|
6626
|
+
interface ProductInfo {
|
|
6627
|
+
id: string
|
|
6628
|
+
tags?: Record<string, any>
|
|
6629
|
+
}
|
|
6630
|
+
```
|
|
6631
|
+
|
|
6632
|
+
**ProofInfo** (interface)
|
|
6633
|
+
```typescript
|
|
6634
|
+
interface ProofInfo {
|
|
6635
|
+
id?: string
|
|
6636
|
+
userId?: string
|
|
6637
|
+
claimable?: boolean
|
|
6638
|
+
virtual?: boolean
|
|
6639
|
+
}
|
|
6640
|
+
```
|
|
6641
|
+
|
|
6642
|
+
**CollectionInfo** (interface)
|
|
6643
|
+
```typescript
|
|
6644
|
+
interface CollectionInfo {
|
|
6645
|
+
id: string
|
|
6646
|
+
roles?: Record<string, any>
|
|
6647
|
+
}
|
|
6648
|
+
```
|
|
6649
|
+
|
|
6650
|
+
**ConditionParams** (interface)
|
|
6651
|
+
```typescript
|
|
6652
|
+
interface ConditionParams {
|
|
6653
|
+
condition?: ConditionSet
|
|
6654
|
+
conditionId?: string
|
|
6655
|
+
conditionStack?: string[]
|
|
6656
|
+
user?: UserInfo
|
|
6657
|
+
product?: ProductInfo
|
|
6658
|
+
proof?: ProofInfo
|
|
6659
|
+
collection?: CollectionInfo
|
|
6660
|
+
stats?: StatsInfo
|
|
6661
|
+
fetchCondition?: (collectionId: string, conditionId: string) => Promise<ConditionSet | null>
|
|
6662
|
+
getLocation?: () => Promise<{ latitude: number; longitude: number }>
|
|
6663
|
+
debugConditions?: boolean | ConditionDebugOptions
|
|
6664
|
+
[key: string]: any
|
|
6665
|
+
}
|
|
6666
|
+
```
|
|
6667
|
+
|
|
6668
|
+
**ConditionDebugOptions** (interface)
|
|
6669
|
+
```typescript
|
|
6670
|
+
interface ConditionDebugOptions {
|
|
6671
|
+
enabled?: boolean
|
|
6672
|
+
logger?: ConditionDebugLogger
|
|
6673
|
+
label?: string
|
|
6674
|
+
}
|
|
6675
|
+
```
|
|
6676
|
+
|
|
6677
|
+
**RegionKey** = `keyof typeof REGION_COUNTRIES`
|
|
6678
|
+
|
|
6679
|
+
**Condition** = ``
|
|
6680
|
+
|
|
6681
|
+
**ConditionDebugLogger** = `(...args: any[]) => void`
|
|
6682
|
+
|
|
6683
|
+
### paths (utils)
|
|
6684
|
+
|
|
6685
|
+
**PortalPathParams** (interface)
|
|
6686
|
+
```typescript
|
|
6687
|
+
interface PortalPathParams {
|
|
6688
|
+
collection: Collection | { shortId: string; portalUrl?: string }
|
|
6689
|
+
product?: Product
|
|
6690
|
+
productId?: string
|
|
6691
|
+
batch?: BatchResponse
|
|
6692
|
+
batchId?: string
|
|
6693
|
+
variant?: { id: string } | string
|
|
6694
|
+
proof?: Proof | string
|
|
6695
|
+
queryParams?: Record<string, string>
|
|
6696
|
+
pathOnly?: boolean
|
|
6697
|
+
}
|
|
6698
|
+
```
|
|
6699
|
+
|
|
6415
6700
|
## API Functions
|
|
6416
6701
|
|
|
6417
6702
|
### analytics.admin
|
|
@@ -8169,6 +8454,33 @@ Reverse lookup by ref via POST (public). `POST /public/collection/:collectionId/
|
|
|
8169
8454
|
**renderSource**(collectionId: string,
|
|
8170
8455
|
body: TemplateRenderSourceRequest) → `Promise<TemplateRenderSourceResponse>`
|
|
8171
8456
|
|
|
8457
|
+
### translations
|
|
8458
|
+
|
|
8459
|
+
**hashText**(text: string, options?: TranslationHashOptions) → `Promise<string>`
|
|
8460
|
+
|
|
8461
|
+
**hashTexts**(texts: string[], options?: TranslationHashOptions) → `Promise<string[]>`
|
|
8462
|
+
|
|
8463
|
+
**normalizeText**(text: string, options?: TranslationHashOptions) → `string`
|
|
8464
|
+
|
|
8465
|
+
**lookup**(collectionId: string,
|
|
8466
|
+
body: TranslationLookupRequest) → `Promise<TranslationLookupResponse>`
|
|
8467
|
+
|
|
8468
|
+
**resolve**(collectionId: string,
|
|
8469
|
+
body: TranslationLookupRequest,
|
|
8470
|
+
options: TranslationResolveOptions = {}) → `Promise<ResolvedTranslationResponse>`
|
|
8471
|
+
|
|
8472
|
+
**list**(collectionId: string,
|
|
8473
|
+
params?: TranslationListParams) → `Promise<TranslationListResponse>`
|
|
8474
|
+
|
|
8475
|
+
**get**(collectionId: string,
|
|
8476
|
+
translationId: string) → `Promise<TranslationRecord>`
|
|
8477
|
+
|
|
8478
|
+
**update**(collectionId: string,
|
|
8479
|
+
translationId: string,
|
|
8480
|
+
body: TranslationUpdateRequest) → `Promise<TranslationRecord>`
|
|
8481
|
+
|
|
8482
|
+
**clearLocalCache**(collectionId?: string) → `Promise<void>`
|
|
8483
|
+
|
|
8172
8484
|
### tts
|
|
8173
8485
|
|
|
8174
8486
|
**generate**(collectionId: string,
|
package/dist/docs/overview.md
CHANGED
|
@@ -49,6 +49,7 @@ The SmartLinks SDK (`@proveanything/smartlinks`) includes comprehensive document
|
|
|
49
49
|
| **Multi-Page Architecture** | `docs/mpa.md` | Build pipeline, entry points, multi-page setup, content hashing |
|
|
50
50
|
| **AI & Chat** | `docs/ai.md` | Chat completions, RAG, streaming, tool calling, voice, podcasts, TTS |
|
|
51
51
|
| **Analytics** | `docs/analytics.md` | Fire-and-forget page/click/tag analytics plus admin dashboard queries |
|
|
52
|
+
| **Translations** | `docs/translations.md` | Runtime translation lookup, local-first IndexedDB caching, and translation admin APIs |
|
|
52
53
|
| **Theming** | `docs/theme.system.md` | Implementing dynamic themes via URL params or postMessage |
|
|
53
54
|
| **Theme Defaults** | `docs/theme-defaults.md` | Default colour values for light/dark modes |
|
|
54
55
|
| **Internationalization** | `docs/i18n.md` | Adding multi-language support, translation patterns |
|