@translation-cms/sync 1.2.28 → 1.2.30
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/dist/api.d.ts +105 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +208 -0
- package/dist/api.js.map +1 -0
- package/dist/bin.d.ts +25 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +208 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +107 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +10 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +35 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +15 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +62 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +131 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/watch.d.ts +18 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +71 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/config-internals/args.d.ts +11 -0
- package/dist/config/config-internals/args.d.ts.map +1 -0
- package/dist/config/config-internals/args.js +22 -0
- package/dist/config/config-internals/args.js.map +1 -0
- package/dist/config/config-internals/env.d.ts +10 -0
- package/dist/config/config-internals/env.d.ts.map +1 -0
- package/dist/config/config-internals/env.js +35 -0
- package/dist/config/config-internals/env.js.map +1 -0
- package/dist/config/config-internals/file.d.ts +11 -0
- package/dist/config/config-internals/file.d.ts.map +1 -0
- package/dist/config/config-internals/file.js +28 -0
- package/dist/config/config-internals/file.js.map +1 -0
- package/dist/config/config-internals/resolve.d.ts +21 -0
- package/dist/config/config-internals/resolve.d.ts.map +1 -0
- package/dist/config/config-internals/resolve.js +73 -0
- package/dist/config/config-internals/resolve.js.map +1 -0
- package/dist/config/config-internals/root.d.ts +9 -0
- package/dist/config/config-internals/root.d.ts.map +1 -0
- package/dist/config/config-internals/root.js +22 -0
- package/dist/config/config-internals/root.js.map +1 -0
- package/dist/config/config-internals/types.d.ts +91 -0
- package/dist/config/config-internals/types.d.ts.map +1 -0
- package/dist/config/config-internals/types.js +9 -0
- package/dist/config/config-internals/types.js.map +1 -0
- package/dist/config/resolve-config.d.ts +11 -0
- package/dist/config/resolve-config.d.ts.map +1 -0
- package/dist/config/resolve-config.js +10 -0
- package/dist/config/resolve-config.js.map +1 -0
- package/dist/core/api-internals/helpers.d.ts +9 -0
- package/dist/core/api-internals/helpers.d.ts.map +1 -0
- package/dist/core/api-internals/helpers.js +14 -0
- package/dist/core/api-internals/helpers.js.map +1 -0
- package/dist/core/api-internals/pull.d.ts +19 -0
- package/dist/core/api-internals/pull.d.ts.map +1 -0
- package/dist/core/api-internals/pull.js +269 -0
- package/dist/core/api-internals/pull.js.map +1 -0
- package/dist/core/api-internals/route-config.d.ts +13 -0
- package/dist/core/api-internals/route-config.d.ts.map +1 -0
- package/dist/core/api-internals/route-config.js +34 -0
- package/dist/core/api-internals/route-config.js.map +1 -0
- package/dist/core/api-internals/sync.d.ts +19 -0
- package/dist/core/api-internals/sync.d.ts.map +1 -0
- package/dist/core/api-internals/sync.js +139 -0
- package/dist/core/api-internals/sync.js.map +1 -0
- package/dist/core/api-internals/types.d.ts +33 -0
- package/dist/core/api-internals/types.d.ts.map +1 -0
- package/dist/core/api-internals/types.js +5 -0
- package/dist/core/api-internals/types.js.map +1 -0
- package/dist/core/api.d.ts +11 -0
- package/dist/core/api.d.ts.map +1 -0
- package/dist/core/api.js +11 -0
- package/dist/core/api.js.map +1 -0
- package/dist/core/cache-internals/format.d.ts +20 -0
- package/dist/core/cache-internals/format.d.ts.map +1 -0
- package/dist/core/cache-internals/format.js +33 -0
- package/dist/core/cache-internals/format.js.map +1 -0
- package/dist/core/cache-internals/params.d.ts +33 -0
- package/dist/core/cache-internals/params.d.ts.map +1 -0
- package/dist/core/cache-internals/params.js +155 -0
- package/dist/core/cache-internals/params.js.map +1 -0
- package/dist/core/cache-internals/pull.d.ts +17 -0
- package/dist/core/cache-internals/pull.d.ts.map +1 -0
- package/dist/core/cache-internals/pull.js +34 -0
- package/dist/core/cache-internals/pull.js.map +1 -0
- package/dist/core/cache-internals/sync.d.ts +29 -0
- package/dist/core/cache-internals/sync.d.ts.map +1 -0
- package/dist/core/cache-internals/sync.js +104 -0
- package/dist/core/cache-internals/sync.js.map +1 -0
- package/dist/core/cache-internals/types.d.ts +48 -0
- package/dist/core/cache-internals/types.d.ts.map +1 -0
- package/dist/core/cache-internals/types.js +2 -0
- package/dist/core/cache-internals/types.js.map +1 -0
- package/dist/core/cache.d.ts +13 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +33 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/scanner-internals/ast.d.ts +40 -0
- package/dist/core/scanner-internals/ast.d.ts.map +1 -0
- package/dist/core/scanner-internals/ast.js +100 -0
- package/dist/core/scanner-internals/ast.js.map +1 -0
- package/dist/core/scanner-internals/file-walker.d.ts +10 -0
- package/dist/core/scanner-internals/file-walker.d.ts.map +1 -0
- package/dist/core/scanner-internals/file-walker.js +23 -0
- package/dist/core/scanner-internals/file-walker.js.map +1 -0
- package/dist/core/scanner-internals/import-resolver.d.ts +21 -0
- package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -0
- package/dist/core/scanner-internals/import-resolver.js +119 -0
- package/dist/core/scanner-internals/import-resolver.js.map +1 -0
- package/dist/core/scanner-internals/key-extractor.d.ts +20 -0
- package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -0
- package/dist/core/scanner-internals/key-extractor.js +274 -0
- package/dist/core/scanner-internals/key-extractor.js.map +1 -0
- package/dist/core/scanner-internals/nav-config-scanner.d.ts +30 -0
- package/dist/core/scanner-internals/nav-config-scanner.d.ts.map +1 -0
- package/dist/core/scanner-internals/nav-config-scanner.js +170 -0
- package/dist/core/scanner-internals/nav-config-scanner.js.map +1 -0
- package/dist/core/scanner-internals/route-detector.d.ts +27 -0
- package/dist/core/scanner-internals/route-detector.d.ts.map +1 -0
- package/dist/core/scanner-internals/route-detector.js +78 -0
- package/dist/core/scanner-internals/route-detector.js.map +1 -0
- package/dist/core/scanner-internals/types.d.ts +60 -0
- package/dist/core/scanner-internals/types.d.ts.map +1 -0
- package/dist/core/scanner-internals/types.js +29 -0
- package/dist/core/scanner-internals/types.js.map +1 -0
- package/dist/core/scanner.d.ts +21 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +162 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/next.d.ts +33 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +110 -0
- package/dist/next.js.map +1 -0
- package/dist/preview/index.d.ts +39 -0
- package/dist/preview/index.d.ts.map +1 -0
- package/dist/preview/index.js +123 -0
- package/dist/preview/index.js.map +1 -0
- package/dist/preview/internals/highlight.d.ts +31 -0
- package/dist/preview/internals/highlight.d.ts.map +1 -0
- package/dist/preview/internals/highlight.js +184 -0
- package/dist/preview/internals/highlight.js.map +1 -0
- package/dist/preview/internals/interactions.d.ts +15 -0
- package/dist/preview/internals/interactions.d.ts.map +1 -0
- package/dist/preview/internals/interactions.js +38 -0
- package/dist/preview/internals/interactions.js.map +1 -0
- package/dist/preview/internals/interactive.d.ts +14 -0
- package/dist/preview/internals/interactive.d.ts.map +1 -0
- package/dist/preview/internals/interactive.js +122 -0
- package/dist/preview/internals/interactive.js.map +1 -0
- package/dist/preview/internals/locales.d.ts +9 -0
- package/dist/preview/internals/locales.d.ts.map +1 -0
- package/dist/preview/internals/locales.js +24 -0
- package/dist/preview/internals/locales.js.map +1 -0
- package/dist/preview/internals/state.d.ts +37 -0
- package/dist/preview/internals/state.d.ts.map +1 -0
- package/dist/preview/internals/state.js +74 -0
- package/dist/preview/internals/state.js.map +1 -0
- package/dist/preview/internals/styles.d.ts +8 -0
- package/dist/preview/internals/styles.d.ts.map +1 -0
- package/dist/preview/internals/styles.js +28 -0
- package/dist/preview/internals/styles.js.map +1 -0
- package/dist/preview/internals/types.d.ts +74 -0
- package/dist/preview/internals/types.d.ts.map +1 -0
- package/dist/preview/internals/types.js +5 -0
- package/dist/preview/internals/types.js.map +1 -0
- package/dist/preview/internals/ui-indicators.d.ts +15 -0
- package/dist/preview/internals/ui-indicators.d.ts.map +1 -0
- package/dist/preview/internals/ui-indicators.js +92 -0
- package/dist/preview/internals/ui-indicators.js.map +1 -0
- package/dist/scaffold/index.d.ts +3 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +3 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/intenrals/scaffold.d.ts +24 -0
- package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -0
- package/dist/scaffold/intenrals/scaffold.js +53 -0
- package/dist/scaffold/intenrals/scaffold.js.map +1 -0
- package/dist/scaffold/intenrals/templates.d.ts +10 -0
- package/dist/scaffold/intenrals/templates.d.ts.map +1 -0
- package/dist/scaffold/intenrals/templates.js +344 -0
- package/dist/scaffold/intenrals/templates.js.map +1 -0
- package/dist/scaffold/intenrals/types.d.ts +14 -0
- package/dist/scaffold/intenrals/types.d.ts.map +1 -0
- package/dist/scaffold/intenrals/types.js +5 -0
- package/dist/scaffold/intenrals/types.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull (fetch) published translations from CMS to local JSON files.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getLastPulledTime, saveLastPulledTime, PULL_META_FILE, DEFAULT_PULL_TTL_MS, } from '../../core/cache.js';
|
|
7
|
+
/**
|
|
8
|
+
* Returns an error message string if any required config field is missing,
|
|
9
|
+
* or null when all fields are present.
|
|
10
|
+
*/
|
|
11
|
+
function validateConfig(config) {
|
|
12
|
+
if (!config.cmsUrl?.trim())
|
|
13
|
+
return 'cmsUrl is required';
|
|
14
|
+
if (!config.apiKey?.trim())
|
|
15
|
+
return 'apiKey is required';
|
|
16
|
+
if (!config.projectId?.trim())
|
|
17
|
+
return 'projectId is required';
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the API URL for fetching translations.
|
|
22
|
+
* Uses the URL constructor to correctly handle base URLs with path prefixes.
|
|
23
|
+
* Appends ?env=<env> when a specific environment is requested.
|
|
24
|
+
*/
|
|
25
|
+
function buildFetchUrl(config, opts) {
|
|
26
|
+
try {
|
|
27
|
+
const baseUrl = new URL(config.cmsUrl);
|
|
28
|
+
baseUrl.pathname = `/api/translations/${encodeURIComponent(config.projectId)}`;
|
|
29
|
+
if (opts.env) {
|
|
30
|
+
baseUrl.searchParams.set('env', opts.env);
|
|
31
|
+
}
|
|
32
|
+
return baseUrl.toString();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`Invalid CMS URL: ${config.cmsUrl} — ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Fetch the URL with up to `maxRetries` attempts.
|
|
40
|
+
* Uses exponential backoff capped at 5 s: 0 ms, 1 s, 2 s, 4 s, 5 s, …
|
|
41
|
+
* Each attempt has a 30 s abort timeout to prevent hanging indefinitely.
|
|
42
|
+
*/
|
|
43
|
+
async function fetchWithRetry(url, apiKey, maxRetries = 3) {
|
|
44
|
+
let lastError = null;
|
|
45
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
46
|
+
try {
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
|
49
|
+
const response = await fetch(url, {
|
|
50
|
+
headers: { 'x-api-key': apiKey },
|
|
51
|
+
signal: controller.signal,
|
|
52
|
+
});
|
|
53
|
+
clearTimeout(timeoutId);
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
const body = await response.text().catch(() => '');
|
|
56
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}${body ? ` — ${body}` : ''}`);
|
|
57
|
+
}
|
|
58
|
+
return response;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
62
|
+
if (attempt < maxRetries) {
|
|
63
|
+
// Exponential backoff: 1 s, 2 s, 4 s, … capped at 5 s
|
|
64
|
+
const backoff = Math.min(1000 * Math.pow(2, attempt - 1), 5000);
|
|
65
|
+
console.log(`[CMS] ⟳ Retry ${attempt}/${maxRetries} after ${backoff}ms...`);
|
|
66
|
+
await new Promise(resolve => setTimeout(resolve, backoff));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
throw lastError || new Error('Unknown fetch error');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Converts a flat `{ "namespace:key": value }` object into
|
|
74
|
+
* `{ namespace: { key: value } }`, with dot-notation key support.
|
|
75
|
+
*
|
|
76
|
+
* Keys that don't contain a colon, or have an empty namespace/key segment,
|
|
77
|
+
* are skipped to avoid creating malformed output.
|
|
78
|
+
*/
|
|
79
|
+
function nestTranslationKeys(flat) {
|
|
80
|
+
const nested = {};
|
|
81
|
+
for (const [key, value] of Object.entries(flat)) {
|
|
82
|
+
const colonIdx = key.indexOf(':');
|
|
83
|
+
// Skip invalid keys: no colon, empty namespace, or empty key after colon
|
|
84
|
+
if (colonIdx === -1 || colonIdx === 0 || colonIdx === key.length - 1) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const namespace = key.slice(0, colonIdx);
|
|
88
|
+
const keyPath = key.slice(colonIdx + 1);
|
|
89
|
+
if (!nested[namespace]) {
|
|
90
|
+
nested[namespace] = {};
|
|
91
|
+
}
|
|
92
|
+
// Walk the dot-notation segments, creating intermediate objects as needed
|
|
93
|
+
const parts = keyPath.split('.');
|
|
94
|
+
const obj = nested[namespace];
|
|
95
|
+
const lastPart = parts[parts.length - 1];
|
|
96
|
+
let current = obj;
|
|
97
|
+
for (const part of parts.slice(0, -1)) {
|
|
98
|
+
if (!(part in current)) {
|
|
99
|
+
current[part] = {};
|
|
100
|
+
}
|
|
101
|
+
current = current[part];
|
|
102
|
+
}
|
|
103
|
+
current[lastPart] = value;
|
|
104
|
+
}
|
|
105
|
+
return nested;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Fetch published translations from the CMS and write them to local JSON files.
|
|
109
|
+
*
|
|
110
|
+
* Output format per locale: `{outputDir}/{locale}.json`
|
|
111
|
+
* Structure: `{ namespace: { key: value } }` — compatible with i18next-resources-to-backend.
|
|
112
|
+
*
|
|
113
|
+
* TTL cache: skips the network request if translations were pulled recently
|
|
114
|
+
* (configurable via opts.ttlMs). Bypassed when opts.force is true.
|
|
115
|
+
*
|
|
116
|
+
* Stale files: locale files that no longer exist in the CMS are emptied to `{}`
|
|
117
|
+
* rather than deleted, so static imports in the consuming app don't break.
|
|
118
|
+
*/
|
|
119
|
+
export async function pullTranslations(config, opts) {
|
|
120
|
+
const validationError = validateConfig(config);
|
|
121
|
+
if (validationError) {
|
|
122
|
+
console.error(`[CMS] ✗ Validation error: ${validationError}`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
const ttl = opts.ttlMs ?? DEFAULT_PULL_TTL_MS;
|
|
126
|
+
console.log(`[CMS] Checking for ${PULL_META_FILE}...`);
|
|
127
|
+
// TTL cache check — skip fetch if translations are still fresh
|
|
128
|
+
if (opts.force) {
|
|
129
|
+
console.log(`[CMS] --force flag detected, refreshing...`);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const lastPulled = getLastPulledTime(opts.outputDir);
|
|
133
|
+
if (lastPulled === null) {
|
|
134
|
+
console.log(`[CMS] ${PULL_META_FILE} not found, will refresh`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const age = Date.now() - lastPulled;
|
|
138
|
+
const ageS = Math.round(age / 1000);
|
|
139
|
+
const ttlS = Math.round(ttl / 1000);
|
|
140
|
+
console.log(`[CMS] ${PULL_META_FILE} found: ${new Date(lastPulled).toISOString()}`);
|
|
141
|
+
if (age < ttl) {
|
|
142
|
+
console.log(`[CMS] ✓ Translations fresh (age: ${ageS}s < TTL: ${ttlS}s) — using local files`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
console.log(`[CMS] ⟳ Translations stale (age: ${ageS}s ≥ TTL: ${ttlS}s) — refreshing...`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
let url;
|
|
149
|
+
try {
|
|
150
|
+
url = buildFetchUrl(config, opts);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
console.error(`[CMS] ✗ Failed to build URL: ${err instanceof Error ? err.message : String(err)}`);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
if (opts.env) {
|
|
157
|
+
console.log(`[CMS] Environment: ${opts.env}`);
|
|
158
|
+
}
|
|
159
|
+
console.log(`[CMS] Fetching from: ${url}`);
|
|
160
|
+
let response;
|
|
161
|
+
try {
|
|
162
|
+
response = await fetchWithRetry(url, config.apiKey);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
console.error(`[CMS] ✗ Pull failed after retries: ${err instanceof Error ? err.message : String(err)}`);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
let data;
|
|
169
|
+
try {
|
|
170
|
+
data = (await response.json());
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
console.error(`[CMS] ✗ Invalid JSON response: ${err instanceof Error ? err.message : String(err)}`);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
console.log(`[CMS] API returned ${Object.keys(data).length} locale keys`);
|
|
177
|
+
// Normalise each locale's payload to `{ namespace: { key: value } }`.
|
|
178
|
+
// The API may return either the nested form directly, or a flat
|
|
179
|
+
// `{ "namespace:key": value }` form — detect by inspecting the first value.
|
|
180
|
+
const processed = {};
|
|
181
|
+
for (const [locale, content] of Object.entries(data)) {
|
|
182
|
+
if (typeof content !== 'object' || content === null) {
|
|
183
|
+
console.warn(`[CMS] ⚠ Skipping invalid locale "${locale}"`);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const obj = content;
|
|
187
|
+
if (Object.keys(obj).length === 0) {
|
|
188
|
+
console.warn(`[CMS] ⚠ Locale "${locale}" is empty`);
|
|
189
|
+
processed[locale] = {};
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
// If the first value is a string, the payload is flat and needs nesting
|
|
193
|
+
const firstVal = Object.values(obj)[0];
|
|
194
|
+
processed[locale] =
|
|
195
|
+
typeof firstVal === 'string'
|
|
196
|
+
? nestTranslationKeys(obj)
|
|
197
|
+
: obj;
|
|
198
|
+
}
|
|
199
|
+
if (Object.keys(processed).length === 0) {
|
|
200
|
+
console.error(`[CMS] ✗ No valid locales received from API`);
|
|
201
|
+
console.error(`[CMS] This can happen when:\n` +
|
|
202
|
+
` • Your sync just uploaded keys and no translations exist yet\n` +
|
|
203
|
+
` • Your CMS project has no locales configured\n` +
|
|
204
|
+
` • API credentials are incorrect\n\n` +
|
|
205
|
+
`Next steps:\n` +
|
|
206
|
+
` 1. Go to your CMS and add translations for the uploaded keys\n` +
|
|
207
|
+
` 2. Or verify your project ID/API key in .env.local\n` +
|
|
208
|
+
` 3. Then run: pnpm sync-translations pull`);
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
fs.mkdirSync(opts.outputDir, { recursive: true });
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
console.error(`[CMS] ✗ Failed to create output directory: ${err instanceof Error ? err.message : String(err)}`);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
// Write one JSON file per locale
|
|
219
|
+
const writtenFiles = new Set();
|
|
220
|
+
let fileCount = 0;
|
|
221
|
+
for (const [locale, namespaces] of Object.entries(processed)) {
|
|
222
|
+
const filePath = path.join(opts.outputDir, `${locale}.json`);
|
|
223
|
+
try {
|
|
224
|
+
fs.writeFileSync(filePath, JSON.stringify(namespaces, null, 2), 'utf-8');
|
|
225
|
+
writtenFiles.add(filePath);
|
|
226
|
+
fileCount++;
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
console.error(`[CMS] ✗ Failed to write ${locale}.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Empty locale files that are no longer returned by the CMS.
|
|
233
|
+
// We write `{}` instead of deleting so static imports in the consuming app
|
|
234
|
+
// don't break at build time.
|
|
235
|
+
let emptied = 0;
|
|
236
|
+
try {
|
|
237
|
+
for (const entry of fs.readdirSync(opts.outputDir, {
|
|
238
|
+
withFileTypes: true,
|
|
239
|
+
})) {
|
|
240
|
+
if (entry.name === PULL_META_FILE)
|
|
241
|
+
continue;
|
|
242
|
+
if (!entry.isFile() || !entry.name.endsWith('.json'))
|
|
243
|
+
continue;
|
|
244
|
+
const filePath = path.join(opts.outputDir, entry.name);
|
|
245
|
+
if (!writtenFiles.has(filePath)) {
|
|
246
|
+
fs.writeFileSync(filePath, '{}\n', 'utf-8');
|
|
247
|
+
console.log(`[CMS] ○ Emptied: ${entry.name} (no data in CMS)`);
|
|
248
|
+
emptied++;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
console.warn(`[CMS] ⚠ Failed to clean up stale files: ${err instanceof Error ? err.message : String(err)}`);
|
|
254
|
+
}
|
|
255
|
+
// Update the pull timestamp so the TTL cache is valid on next run
|
|
256
|
+
try {
|
|
257
|
+
saveLastPulledTime(opts.outputDir);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
console.warn(`[CMS] ⚠ Failed to save cache metadata: ${err instanceof Error ? err.message : String(err)}`);
|
|
261
|
+
}
|
|
262
|
+
if (emptied > 0) {
|
|
263
|
+
console.log(`[CMS] ✓ Refresh complete: wrote ${fileCount} files, emptied ${emptied} stale files`);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.log(`[CMS] ✓ Refresh complete: wrote ${fileCount} JSON files, updated ${PULL_META_FILE}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../src/core/api-internals/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch preview route configuration from CMS.
|
|
3
|
+
*/
|
|
4
|
+
import type { Config } from '../../config/resolve-config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fetches the project's preview route config from the CMS and returns it as
|
|
7
|
+
* a routeParams Record (route pattern → params), ready to pass to scanProject.
|
|
8
|
+
*
|
|
9
|
+
* Returns an empty object when the CMS doesn't have any routes configured or
|
|
10
|
+
* when the request fails (non-fatal — a warning is printed instead).
|
|
11
|
+
*/
|
|
12
|
+
export declare function fetchRouteParams(config: Config): Promise<Record<string, Record<string, string>>>;
|
|
13
|
+
//# sourceMappingURL=route-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-config.d.ts","sourceRoot":"","sources":["../../../src/core/api-internals/route-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAClC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CA8BjD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch preview route configuration from CMS.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Fetches the project's preview route config from the CMS and returns it as
|
|
6
|
+
* a routeParams Record (route pattern → params), ready to pass to scanProject.
|
|
7
|
+
*
|
|
8
|
+
* Returns an empty object when the CMS doesn't have any routes configured or
|
|
9
|
+
* when the request fails (non-fatal — a warning is printed instead).
|
|
10
|
+
*/
|
|
11
|
+
export async function fetchRouteParams(config) {
|
|
12
|
+
const url = `${config.cmsUrl.replace(/\/$/, '')}/api/sync/${config.projectId}`;
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
headers: { 'x-api-key': config.apiKey },
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
console.warn(`[CMS] Could not fetch route config (${response.status}) — using local routeParams only`);
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
const data = (await response.json());
|
|
22
|
+
const routeParams = data.routeParams ?? {};
|
|
23
|
+
const count = Object.keys(routeParams).length;
|
|
24
|
+
if (count > 0) {
|
|
25
|
+
console.log(`[CMS] Loaded ${count} preview route(s) from CMS config`);
|
|
26
|
+
}
|
|
27
|
+
return routeParams;
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.warn(`[CMS] Could not fetch route config — using local routeParams only:`, err instanceof Error ? err.message : String(err));
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=route-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-config.js","sourceRoot":"","sources":["../../../src/core/api-internals/route-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAClC,MAAc;IAEd,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,MAAM,CAAC,SAAS,EAAE,CAAC;IAC/E,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACR,uCAAuC,QAAQ,CAAC,MAAM,kCAAkC,CAC3F,CAAC;YACF,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;QAC9C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CACP,gBAAgB,KAAK,mCAAmC,CAC3D,CAAC;QACN,CAAC;QACD,OAAO,WAAW,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CACR,oEAAoE,EACpE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACnD,CAAC;QACF,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync (push) translation keys to CMS.
|
|
3
|
+
*/
|
|
4
|
+
import type { Config } from '../../config/resolve-config.js';
|
|
5
|
+
import type { NamespaceMap } from '../../core/scanner.js';
|
|
6
|
+
import type { PostToSyncOptions } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Push discovered translation keys to the CMS sync endpoint.
|
|
9
|
+
*
|
|
10
|
+
* Three possible outcomes:
|
|
11
|
+
* 1. **Dry-run** (`opts.dryRun`) — prints a diff against the last cache and
|
|
12
|
+
* optionally writes a report, but never POSTs to the CMS.
|
|
13
|
+
* 2. **No changes** — skips the POST when the serialized keys are identical
|
|
14
|
+
* to the last cache and `--force` was not passed.
|
|
15
|
+
* 3. **Sync** — POSTs the full namespace map; on success saves the new cache
|
|
16
|
+
* and optionally writes a report.
|
|
17
|
+
*/
|
|
18
|
+
export declare function postToSync(config: Config, namespaces: NamespaceMap, opts?: PostToSyncOptions): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/core/api-internals/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,YAAY,CAAC;AAYlE;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,YAAY,EACxB,IAAI,GAAE,iBAA2C,GAClD,OAAO,CAAC,IAAI,CAAC,CAoJf"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync (push) translation keys to CMS.
|
|
3
|
+
*/
|
|
4
|
+
import { loadSyncCache, saveSyncCache, isSyncNeeded, computeDiff, writeReport, serializeNamespaces, formatPreviewRoutes, } from '../../core/cache.js';
|
|
5
|
+
import { resolveReportPath } from './helpers.js';
|
|
6
|
+
/**
|
|
7
|
+
* Push discovered translation keys to the CMS sync endpoint.
|
|
8
|
+
*
|
|
9
|
+
* Three possible outcomes:
|
|
10
|
+
* 1. **Dry-run** (`opts.dryRun`) — prints a diff against the last cache and
|
|
11
|
+
* optionally writes a report, but never POSTs to the CMS.
|
|
12
|
+
* 2. **No changes** — skips the POST when the serialized keys are identical
|
|
13
|
+
* to the last cache and `--force` was not passed.
|
|
14
|
+
* 3. **Sync** — POSTs the full namespace map; on success saves the new cache
|
|
15
|
+
* and optionally writes a report.
|
|
16
|
+
*/
|
|
17
|
+
export async function postToSync(config, namespaces, opts = { root: process.cwd() }) {
|
|
18
|
+
// Flatten NamespaceMap → plain serializable object for the API payload and cache
|
|
19
|
+
const { serialized, totalKeys } = serializeNamespaces(namespaces);
|
|
20
|
+
const namespaceCount = Object.keys(serialized).length;
|
|
21
|
+
console.log(`Found ${totalKeys} key(s) across ${namespaceCount} namespace(s): ${Object.keys(serialized).join(', ')}`);
|
|
22
|
+
if (totalKeys === 0) {
|
|
23
|
+
console.log('Nothing to sync.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Load the baseline from the last successful sync to diff against
|
|
27
|
+
const cached = loadSyncCache(opts.root);
|
|
28
|
+
// ---- Dry-run: print diff and return without posting --------------------
|
|
29
|
+
if (opts.dryRun) {
|
|
30
|
+
const diff = computeDiff(serialized, cached);
|
|
31
|
+
console.log('\n[dry-run] Would sync to CMS (not actually posting):');
|
|
32
|
+
console.log(` + ${diff.added.length} new key(s)`);
|
|
33
|
+
console.log(` - ${diff.removed.length} removed key(s)`);
|
|
34
|
+
console.log(` ~ ${diff.routesChanged.length} route update(s)`);
|
|
35
|
+
console.log(` = ${diff.unchanged} unchanged`);
|
|
36
|
+
if (diff.added.length > 0) {
|
|
37
|
+
console.log('\nNew keys:');
|
|
38
|
+
for (const { namespace, key, routes } of diff.added) {
|
|
39
|
+
console.log(` + ${namespace}:${key} (${formatPreviewRoutes(routes)})`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (diff.removed.length > 0) {
|
|
43
|
+
console.log('\nRemoved keys:');
|
|
44
|
+
for (const { namespace, key } of diff.removed) {
|
|
45
|
+
console.log(` - ${namespace}:${key}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (diff.routesChanged.length > 0) {
|
|
49
|
+
console.log('\nRoute updates:');
|
|
50
|
+
for (const { namespace, key, before, after, } of diff.routesChanged) {
|
|
51
|
+
console.log(` ~ ${namespace}:${key} [${formatPreviewRoutes(before)}] -> [${formatPreviewRoutes(after)}]`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (opts.reportPath) {
|
|
55
|
+
writeReport(resolveReportPath(opts.root, opts.reportPath), serialized, diff);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// ---- Skip if no changes ------------------------------------------------
|
|
60
|
+
// isSyncNeeded compares serialized keys against the cache — if identical,
|
|
61
|
+
// there's nothing new for the CMS to process.
|
|
62
|
+
if (!opts.force && !isSyncNeeded(serialized, cached)) {
|
|
63
|
+
console.log('No changes detected — skipping sync. Use --force to override.');
|
|
64
|
+
if (opts.reportPath) {
|
|
65
|
+
// Write a report even when skipping so CI artefacts stay up-to-date
|
|
66
|
+
writeReport(resolveReportPath(opts.root, opts.reportPath), serialized);
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// ---- Post to CMS -------------------------------------------------------
|
|
71
|
+
// Strip trailing slash to avoid double slashes in the URL
|
|
72
|
+
const url = `${config.cmsUrl.replace(/\/$/, '')}/api/sync/${config.projectId}`;
|
|
73
|
+
console.log(`Posting to ${url}...`);
|
|
74
|
+
// Build the API payload — same as serialized but with optional values merged
|
|
75
|
+
// in per key. Values are excluded from the cache so key-change detection is
|
|
76
|
+
// not affected by local translation edits.
|
|
77
|
+
const apiPayload = opts.localValues && Object.keys(opts.localValues).length > 0
|
|
78
|
+
? buildPayloadWithValues(serialized, opts.localValues)
|
|
79
|
+
: serialized;
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: {
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
'x-api-key': config.apiKey,
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify({ namespaces: apiPayload }),
|
|
87
|
+
});
|
|
88
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
89
|
+
const isJson = contentType.includes('application/json');
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
console.error(`Sync failed: ${response.status} ${response.statusText}`);
|
|
92
|
+
// HTML response usually means the endpoint doesn't exist (wrong URL / not deployed)
|
|
93
|
+
if (!isJson) {
|
|
94
|
+
console.error(`The CMS returned HTML instead of JSON. Is the sync endpoint available at ${url}?`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.error(JSON.stringify(await response.json()));
|
|
98
|
+
}
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
// A 2xx with an HTML body is also invalid — guard against misconfigured proxies
|
|
102
|
+
if (!isJson) {
|
|
103
|
+
console.error(`The CMS returned HTML instead of JSON. Is the sync endpoint available at ${url}?`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
const data = (await response.json());
|
|
107
|
+
const valuesPart = data.valuesUploaded != null && data.valuesUploaded > 0
|
|
108
|
+
? `, ${data.valuesUploaded} draft value(s) bootstrapped`
|
|
109
|
+
: '';
|
|
110
|
+
console.log(`Synced: ${data.created} created, ${data.updated ?? 0} routes updated, ${data.existing} existing${valuesPart}`);
|
|
111
|
+
if (data.message)
|
|
112
|
+
console.log(data.message);
|
|
113
|
+
// Persist the new baseline so subsequent runs can detect changes correctly
|
|
114
|
+
saveSyncCache(opts.root, serialized);
|
|
115
|
+
if (opts.reportPath) {
|
|
116
|
+
const diff = computeDiff(serialized, cached);
|
|
117
|
+
writeReport(resolveReportPath(opts.root, opts.reportPath), serialized, diff);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Merge local translation values into the serialized namespace payload.
|
|
122
|
+
* Values are attached per key but never included in the sync cache — this
|
|
123
|
+
* keeps key-change detection independent of translation edits.
|
|
124
|
+
*/
|
|
125
|
+
function buildPayloadWithValues(serialized, localValues) {
|
|
126
|
+
const payload = {};
|
|
127
|
+
for (const [ns, entries] of Object.entries(serialized)) {
|
|
128
|
+
const nsValues = localValues[ns] ?? {};
|
|
129
|
+
payload[ns] = entries.map(entry => {
|
|
130
|
+
const values = nsValues[entry.key];
|
|
131
|
+
if (values && Object.keys(values).length > 0) {
|
|
132
|
+
return { ...entry, values };
|
|
133
|
+
}
|
|
134
|
+
return entry;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return payload;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/core/api-internals/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for sync API.
|
|
3
|
+
*/
|
|
4
|
+
export interface SyncResponse {
|
|
5
|
+
created: number;
|
|
6
|
+
updated?: number;
|
|
7
|
+
existing: number;
|
|
8
|
+
valuesUploaded?: number;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PostToSyncOptions {
|
|
12
|
+
root: string;
|
|
13
|
+
force?: boolean;
|
|
14
|
+
/** Preview what would be synced without posting to the CMS. */
|
|
15
|
+
dryRun?: boolean;
|
|
16
|
+
/** Write a JSON scan report to this file path. */
|
|
17
|
+
reportPath?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Translation values read from local JSON files, keyed by
|
|
20
|
+
* namespace → translationKey → locale → value.
|
|
21
|
+
* When provided, values are included in the sync payload so the CMS can
|
|
22
|
+
* store them as drafts (only where no draft exists yet).
|
|
23
|
+
*/
|
|
24
|
+
localValues?: Record<string, Record<string, Record<string, string>>>;
|
|
25
|
+
}
|
|
26
|
+
export interface PullOptions {
|
|
27
|
+
outputDir: string;
|
|
28
|
+
force?: boolean;
|
|
29
|
+
ttlMs?: number;
|
|
30
|
+
/** Pull from a specific environment (e.g. "staging"). */
|
|
31
|
+
env?: string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/api-internals/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/api-internals/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMS Sync API — Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Coordinates pushing translation keys to the CMS and pulling published
|
|
5
|
+
* translations back to local JSON files.
|
|
6
|
+
*/
|
|
7
|
+
export type { SyncResponse, PostToSyncOptions, PullOptions, } from './api-internals/types.js';
|
|
8
|
+
export { fetchRouteParams } from './api-internals/route-config.js';
|
|
9
|
+
export { postToSync } from './api-internals/sync.js';
|
|
10
|
+
export { pullTranslations } from './api-internals/pull.js';
|
|
11
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/core/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACR,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/core/api.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMS Sync API — Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Coordinates pushing translation keys to the CMS and pulling published
|
|
5
|
+
* translations back to local JSON files.
|
|
6
|
+
*/
|
|
7
|
+
// Re-export public functions
|
|
8
|
+
export { fetchRouteParams } from './api-internals/route-config.js';
|
|
9
|
+
export { postToSync } from './api-internals/sync.js';
|
|
10
|
+
export { pullTranslations } from './api-internals/pull.js';
|
|
11
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/core/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,6BAA6B;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PreviewRoute } from '../../core/scanner.js';
|
|
2
|
+
/**
|
|
3
|
+
* Format a single PreviewRoute for human-readable output.
|
|
4
|
+
*
|
|
5
|
+
* Plain string routes are returned as-is.
|
|
6
|
+
* Object routes (with params) are rendered as `/path (key=value, …)`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* formatPreviewRoute('/dashboard') // → "/dashboard"
|
|
10
|
+
* formatPreviewRoute({ route: '/blog/[slug]', params: { slug: 'hello' } })
|
|
11
|
+
* // → "/blog/[slug] (slug=hello)"
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatPreviewRoute(route: PreviewRoute): string;
|
|
14
|
+
/**
|
|
15
|
+
* Format an array of PreviewRoutes as a comma-separated string.
|
|
16
|
+
* Returns `"no route"` for keys that have no associated preview routes
|
|
17
|
+
* (e.g. keys inside dialogs or overlays).
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatPreviewRoutes(routes: PreviewRoute[]): string;
|
|
20
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/core/cache-internals/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAS9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAGlE"}
|