@translation-cms/sync 1.2.1 → 1.2.4

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.
Files changed (161) hide show
  1. package/dist/bin.d.ts +25 -0
  2. package/dist/bin.d.ts.map +1 -0
  3. package/dist/bin.js +173 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/commands/init.d.ts +2 -0
  6. package/dist/commands/init.d.ts.map +1 -0
  7. package/dist/commands/init.js +68 -0
  8. package/dist/commands/init.js.map +1 -0
  9. package/dist/commands/pull.d.ts +3 -0
  10. package/dist/commands/pull.d.ts.map +1 -0
  11. package/dist/commands/pull.js +22 -0
  12. package/dist/commands/pull.js.map +1 -0
  13. package/dist/commands/status.d.ts +3 -0
  14. package/dist/commands/status.d.ts.map +1 -0
  15. package/dist/commands/status.js +46 -0
  16. package/dist/commands/status.js.map +1 -0
  17. package/dist/commands/sync.d.ts +10 -0
  18. package/dist/commands/sync.d.ts.map +1 -0
  19. package/dist/commands/sync.js +20 -0
  20. package/dist/commands/sync.js.map +1 -0
  21. package/dist/commands/watch.d.ts +4 -0
  22. package/dist/commands/watch.d.ts.map +1 -0
  23. package/dist/commands/watch.js +51 -0
  24. package/dist/commands/watch.js.map +1 -0
  25. package/dist/{load-config.d.ts → config/resolve-config.d.ts} +13 -10
  26. package/dist/config/resolve-config.d.ts.map +1 -0
  27. package/dist/{resolve-config.js → config/resolve-config.js} +21 -0
  28. package/dist/config/resolve-config.js.map +1 -0
  29. package/dist/core/api-internals/helpers.d.ts +9 -0
  30. package/dist/core/api-internals/helpers.d.ts.map +1 -0
  31. package/dist/core/api-internals/helpers.js +14 -0
  32. package/dist/core/api-internals/helpers.js.map +1 -0
  33. package/dist/core/api-internals/pull.d.ts +11 -0
  34. package/dist/core/api-internals/pull.d.ts.map +1 -0
  35. package/dist/core/api-internals/pull.js +124 -0
  36. package/dist/core/api-internals/pull.js.map +1 -0
  37. package/dist/core/api-internals/route-config.d.ts +13 -0
  38. package/dist/core/api-internals/route-config.d.ts.map +1 -0
  39. package/dist/core/api-internals/route-config.js +34 -0
  40. package/dist/core/api-internals/route-config.js.map +1 -0
  41. package/dist/core/api-internals/sync.d.ts +12 -0
  42. package/dist/core/api-internals/sync.d.ts.map +1 -0
  43. package/dist/core/api-internals/sync.js +95 -0
  44. package/dist/core/api-internals/sync.js.map +1 -0
  45. package/dist/core/api-internals/types.d.ts +25 -0
  46. package/dist/core/api-internals/types.d.ts.map +1 -0
  47. package/dist/core/api-internals/types.js +5 -0
  48. package/dist/core/api-internals/types.js.map +1 -0
  49. package/dist/core/api.d.ts +11 -0
  50. package/dist/core/api.d.ts.map +1 -0
  51. package/dist/core/api.js +11 -0
  52. package/dist/core/api.js.map +1 -0
  53. package/dist/{sync.d.ts → core/cache.d.ts} +5 -33
  54. package/dist/core/cache.d.ts.map +1 -0
  55. package/dist/core/cache.js +143 -0
  56. package/dist/core/cache.js.map +1 -0
  57. package/dist/core/scanner-internals/ast.d.ts +22 -0
  58. package/dist/core/scanner-internals/ast.d.ts.map +1 -0
  59. package/dist/core/scanner-internals/ast.js +80 -0
  60. package/dist/core/scanner-internals/ast.js.map +1 -0
  61. package/dist/core/scanner-internals/file-walker.d.ts +9 -0
  62. package/dist/core/scanner-internals/file-walker.d.ts.map +1 -0
  63. package/dist/core/scanner-internals/file-walker.js +25 -0
  64. package/dist/core/scanner-internals/file-walker.js.map +1 -0
  65. package/dist/core/scanner-internals/import-resolver.d.ts +13 -0
  66. package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -0
  67. package/dist/core/scanner-internals/import-resolver.js +124 -0
  68. package/dist/core/scanner-internals/import-resolver.js.map +1 -0
  69. package/dist/core/scanner-internals/key-extractor.d.ts +16 -0
  70. package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -0
  71. package/dist/core/scanner-internals/key-extractor.js +172 -0
  72. package/dist/core/scanner-internals/key-extractor.js.map +1 -0
  73. package/dist/core/scanner-internals/route-detector.d.ts +19 -0
  74. package/dist/core/scanner-internals/route-detector.d.ts.map +1 -0
  75. package/dist/core/scanner-internals/route-detector.js +74 -0
  76. package/dist/core/scanner-internals/route-detector.js.map +1 -0
  77. package/dist/core/scanner-internals/types.d.ts +53 -0
  78. package/dist/core/scanner-internals/types.d.ts.map +1 -0
  79. package/dist/core/scanner-internals/types.js +29 -0
  80. package/dist/core/scanner-internals/types.js.map +1 -0
  81. package/dist/core/scanner.d.ts +20 -0
  82. package/dist/core/scanner.d.ts.map +1 -0
  83. package/dist/core/scanner.js +113 -0
  84. package/dist/core/scanner.js.map +1 -0
  85. package/dist/index.d.ts +2 -2
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/preview/index.d.ts +38 -0
  90. package/dist/preview/index.d.ts.map +1 -0
  91. package/dist/preview/index.js +114 -0
  92. package/dist/preview/index.js.map +1 -0
  93. package/dist/preview/internals/highlight.d.ts +22 -0
  94. package/dist/preview/internals/highlight.d.ts.map +1 -0
  95. package/dist/preview/internals/highlight.js +153 -0
  96. package/dist/preview/internals/highlight.js.map +1 -0
  97. package/dist/preview/internals/interactions.d.ts +15 -0
  98. package/dist/preview/internals/interactions.d.ts.map +1 -0
  99. package/dist/preview/internals/interactions.js +38 -0
  100. package/dist/preview/internals/interactions.js.map +1 -0
  101. package/dist/preview/internals/locales.d.ts +9 -0
  102. package/dist/preview/internals/locales.d.ts.map +1 -0
  103. package/dist/preview/internals/locales.js +24 -0
  104. package/dist/preview/internals/locales.js.map +1 -0
  105. package/dist/preview/internals/state.d.ts +35 -0
  106. package/dist/preview/internals/state.d.ts.map +1 -0
  107. package/dist/preview/internals/state.js +65 -0
  108. package/dist/preview/internals/state.js.map +1 -0
  109. package/dist/preview/internals/styles.d.ts +8 -0
  110. package/dist/preview/internals/styles.d.ts.map +1 -0
  111. package/dist/preview/internals/styles.js +28 -0
  112. package/dist/preview/internals/styles.js.map +1 -0
  113. package/dist/preview/internals/types.d.ts +49 -0
  114. package/dist/preview/internals/types.d.ts.map +1 -0
  115. package/dist/preview/internals/types.js +5 -0
  116. package/dist/preview/internals/types.js.map +1 -0
  117. package/dist/scaffold/index.d.ts +3 -0
  118. package/dist/scaffold/index.d.ts.map +1 -0
  119. package/dist/scaffold/index.js +3 -0
  120. package/dist/scaffold/index.js.map +1 -0
  121. package/dist/scaffold/intenrals/scaffold.d.ts +7 -0
  122. package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -0
  123. package/dist/scaffold/intenrals/scaffold.js +34 -0
  124. package/dist/scaffold/intenrals/scaffold.js.map +1 -0
  125. package/dist/scaffold/intenrals/templates.d.ts +10 -0
  126. package/dist/scaffold/intenrals/templates.d.ts.map +1 -0
  127. package/dist/{scaffold.js → scaffold/intenrals/templates.js} +10 -38
  128. package/dist/scaffold/intenrals/templates.js.map +1 -0
  129. package/dist/{scaffold.d.ts → scaffold/intenrals/types.d.ts} +4 -2
  130. package/dist/scaffold/intenrals/types.d.ts.map +1 -0
  131. package/dist/scaffold/intenrals/types.js +5 -0
  132. package/dist/scaffold/intenrals/types.js.map +1 -0
  133. package/package.json +7 -7
  134. package/schema.json +64 -0
  135. package/dist/cli-entry.d.ts +0 -3
  136. package/dist/cli-entry.d.ts.map +0 -1
  137. package/dist/cli-entry.js +0 -390
  138. package/dist/cli-entry.js.map +0 -1
  139. package/dist/cli.d.ts +0 -16
  140. package/dist/cli.d.ts.map +0 -1
  141. package/dist/cli.js +0 -16
  142. package/dist/cli.js.map +0 -1
  143. package/dist/load-config.d.ts.map +0 -1
  144. package/dist/load-config.js +0 -24
  145. package/dist/load-config.js.map +0 -1
  146. package/dist/preview.d.ts +0 -88
  147. package/dist/preview.d.ts.map +0 -1
  148. package/dist/preview.js +0 -461
  149. package/dist/preview.js.map +0 -1
  150. package/dist/resolve-config.d.ts +0 -15
  151. package/dist/resolve-config.d.ts.map +0 -1
  152. package/dist/resolve-config.js.map +0 -1
  153. package/dist/scaffold.d.ts.map +0 -1
  154. package/dist/scaffold.js.map +0 -1
  155. package/dist/scanner.d.ts +0 -77
  156. package/dist/scanner.d.ts.map +0 -1
  157. package/dist/scanner.js +0 -555
  158. package/dist/scanner.js.map +0 -1
  159. package/dist/sync.d.ts.map +0 -1
  160. package/dist/sync.js +0 -383
  161. package/dist/sync.js.map +0 -1
package/dist/bin.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * sync-translations CLI
4
+ *
5
+ * Subcommands:
6
+ * sync (default) Scan codebase and sync translation keys to the CMS.
7
+ * pull Fetch translations from CMS and write local JSON files.
8
+ * status Show what would change on next sync (no network calls).
9
+ * watch Watch for file changes and auto-sync on save.
10
+ * init Interactive setup — creates .translationsrc.json.
11
+ *
12
+ * Usage:
13
+ * sync-translations # sync keys + pull
14
+ * sync-translations sync --dry-run # preview changes only
15
+ * sync-translations sync --report scan.json # write JSON report
16
+ * sync-translations pull --output ./locales # custom output dir
17
+ * sync-translations pull --force # ignore TTL cache
18
+ * sync-translations pull --env staging # pull staging env
19
+ * sync-translations pull --ttl 600000 # custom TTL (ms)
20
+ * sync-translations status # diff vs last sync cache
21
+ * sync-translations watch # watch + auto-sync
22
+ * sync-translations init # interactive setup
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
package/dist/bin.js ADDED
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * sync-translations CLI
4
+ *
5
+ * Subcommands:
6
+ * sync (default) Scan codebase and sync translation keys to the CMS.
7
+ * pull Fetch translations from CMS and write local JSON files.
8
+ * status Show what would change on next sync (no network calls).
9
+ * watch Watch for file changes and auto-sync on save.
10
+ * init Interactive setup — creates .translationsrc.json.
11
+ *
12
+ * Usage:
13
+ * sync-translations # sync keys + pull
14
+ * sync-translations sync --dry-run # preview changes only
15
+ * sync-translations sync --report scan.json # write JSON report
16
+ * sync-translations pull --output ./locales # custom output dir
17
+ * sync-translations pull --force # ignore TTL cache
18
+ * sync-translations pull --env staging # pull staging env
19
+ * sync-translations pull --ttl 600000 # custom TTL (ms)
20
+ * sync-translations status # diff vs last sync cache
21
+ * sync-translations watch # watch + auto-sync
22
+ * sync-translations init # interactive setup
23
+ */
24
+ import path from 'path';
25
+ import fs from 'fs';
26
+ import { resolveConfig, findProjectRoot, loadConfigFile } from './config/resolve-config.js';
27
+ import { fetchRouteParams } from './core/api.js';
28
+ import { runStatus } from './commands/status.js';
29
+ import { runWatch } from './commands/watch.js';
30
+ import { runInit } from './commands/init.js';
31
+ import { runPull } from './commands/pull.js';
32
+ import { runSync } from './commands/sync.js';
33
+ // ---------------------------------------------------------------------------
34
+ // Helpers
35
+ // ---------------------------------------------------------------------------
36
+ /**
37
+ * Strip line and block comments from a JSONC string, skipping string literals
38
+ * to avoid false positives on patterns like "@/*" or "**\/*.ts".
39
+ */
40
+ function stripJsonComments(input) {
41
+ let result = '';
42
+ let i = 0;
43
+ while (i < input.length) {
44
+ if (input[i] === '"') {
45
+ result += '"';
46
+ i++;
47
+ while (i < input.length) {
48
+ const ch = input[i];
49
+ result += ch;
50
+ i++;
51
+ if (ch === '\\') {
52
+ if (i < input.length)
53
+ result += input[i++];
54
+ }
55
+ else if (ch === '"') {
56
+ break;
57
+ }
58
+ }
59
+ continue;
60
+ }
61
+ if (input[i] === '/' && input[i + 1] === '/') {
62
+ while (i < input.length && input[i] !== '\n')
63
+ i++;
64
+ continue;
65
+ }
66
+ if (input[i] === '/' && input[i + 1] === '*') {
67
+ i += 2;
68
+ while (i < input.length) {
69
+ if (input[i] === '*' && input[i + 1] === '/') {
70
+ i += 2;
71
+ break;
72
+ }
73
+ i++;
74
+ }
75
+ continue;
76
+ }
77
+ result += input[i++];
78
+ }
79
+ return result;
80
+ }
81
+ /** Load TypeScript path alias mappings from tsconfig.json. */
82
+ function loadTsConfigPathMappings(root) {
83
+ const tsconfigPath = path.join(root, 'tsconfig.json');
84
+ if (!fs.existsSync(tsconfigPath))
85
+ return null;
86
+ try {
87
+ const cleaned = stripJsonComments(fs.readFileSync(tsconfigPath, 'utf-8'));
88
+ const tsconfig = JSON.parse(cleaned);
89
+ if (typeof tsconfig === 'object' && tsconfig !== null && 'compilerOptions' in tsconfig) {
90
+ const opts = tsconfig.compilerOptions;
91
+ if (typeof opts === 'object' && opts !== null && 'paths' in opts) {
92
+ const paths = opts.paths;
93
+ if (typeof paths === 'object' && paths !== null) {
94
+ return paths;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ catch {
100
+ // Silently ignore tsconfig parse errors
101
+ }
102
+ return null;
103
+ }
104
+ function getFlag(args, flag) {
105
+ const idx = args.indexOf(flag);
106
+ return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined;
107
+ }
108
+ function hasFlag(args, ...flags) {
109
+ return flags.some(f => args.includes(f));
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Main
113
+ // ---------------------------------------------------------------------------
114
+ const SUBCOMMANDS = new Set(['sync', 'pull', 'status', 'watch', 'init']);
115
+ async function main() {
116
+ const args = process.argv.slice(2);
117
+ const subcommand = args.find(a => !a.startsWith('-')) ?? 'sync';
118
+ if (!SUBCOMMANDS.has(subcommand)) {
119
+ console.error(`Unknown subcommand: ${subcommand}`);
120
+ console.error(`Available: ${[...SUBCOMMANDS].join(', ')}`);
121
+ process.exit(1);
122
+ }
123
+ const root = findProjectRoot();
124
+ const fileConfig = loadConfigFile(root);
125
+ if (subcommand === 'init') {
126
+ await runInit(root);
127
+ return;
128
+ }
129
+ const config = resolveConfig(root, fileConfig);
130
+ const pathMappings = loadTsConfigPathMappings(root);
131
+ let cmsRouteParams = {};
132
+ if (subcommand !== 'pull') {
133
+ cmsRouteParams = await fetchRouteParams(config);
134
+ }
135
+ const scanOpts = {
136
+ excludedDirs: fileConfig.excludedDirs,
137
+ sourceExtensions: fileConfig.sourceExtensions,
138
+ routeParams: { ...cmsRouteParams, ...(fileConfig.routeParams ?? {}) },
139
+ pathMappings: pathMappings ?? undefined,
140
+ projectRoot: root,
141
+ };
142
+ if (subcommand === 'status') {
143
+ runStatus(root, scanOpts);
144
+ return;
145
+ }
146
+ if (subcommand === 'watch') {
147
+ const outputDir = fileConfig.outputDir ?? path.join(root, 'public', 'locales');
148
+ await runWatch(root, config, outputDir, scanOpts);
149
+ return;
150
+ }
151
+ if (subcommand === 'pull') {
152
+ await runPull(root, config, fileConfig, args);
153
+ return;
154
+ }
155
+ // sync (default)
156
+ const outputDir = fileConfig.outputDir ?? path.join(root, 'public', 'locales');
157
+ const reportArg = getFlag(args, '--report');
158
+ await runSync(root, config, scanOpts, {
159
+ outputDir,
160
+ dryRun: hasFlag(args, '--dry-run'),
161
+ force: hasFlag(args, '--force'),
162
+ reportPath: reportArg
163
+ ? path.isAbsolute(reportArg)
164
+ ? reportArg
165
+ : path.join(root, reportArg)
166
+ : undefined,
167
+ });
168
+ }
169
+ main().catch(err => {
170
+ process.stderr.write(`${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
171
+ process.exit(1);
172
+ });
173
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runInit(root: string): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFzD"}
@@ -0,0 +1,68 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import { scaffoldI18n } from '../scaffold/index.js';
4
+ export async function runInit(root) {
5
+ const { createInterface } = await import('readline');
6
+ const rl = createInterface({
7
+ input: process.stdin,
8
+ output: process.stdout,
9
+ });
10
+ const question = (prompt) => new Promise(resolve => rl.question(prompt, resolve));
11
+ console.log('sync-translations init\n');
12
+ console.log('This creates .translationsrc.json in your project root.');
13
+ console.log('Values here override env vars for the sync-translations CLI.\n');
14
+ const cmsUrl = await question('CMS URL (e.g. https://cms.example.com): ');
15
+ const projectId = await question('Project ID: ');
16
+ const apiKey = await question('API key: ');
17
+ const i18nDirInput = await question('i18n directory [./src/lib/i18n]: ');
18
+ const pullTtlInput = await question('Pull TTL in seconds [300]: ');
19
+ const scaffoldInput = await question('Scaffold i18n files (settings, client, server, provider)? [Y/n]: ');
20
+ rl.close();
21
+ const i18nDir = i18nDirInput.trim() || './src/lib/i18n';
22
+ const outputDir = `${i18nDir.replace(/\/$/, '')}/dictionaries`;
23
+ const config = {
24
+ $schema: './node_modules/@translation-cms/sync/schema.json',
25
+ };
26
+ if (cmsUrl.trim())
27
+ config['cmsUrl'] = cmsUrl.trim();
28
+ if (projectId.trim())
29
+ config['projectId'] = projectId.trim();
30
+ if (apiKey.trim())
31
+ config['apiKey'] = apiKey.trim();
32
+ config['outputDir'] = outputDir;
33
+ if (pullTtlInput.trim()) {
34
+ const ttlSec = parseInt(pullTtlInput.trim(), 10);
35
+ if (!isNaN(ttlSec))
36
+ config['pullTtlMs'] = ttlSec * 1000;
37
+ }
38
+ const configPath = path.join(root, '.translationsrc.json');
39
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
40
+ console.log(`\nCreated: ${configPath}`);
41
+ if (config['apiKey']) {
42
+ console.log('\nWarning: .translationsrc.json contains an API key. Consider adding it to .gitignore:');
43
+ console.log(' echo ".translationsrc.json" >> .gitignore');
44
+ console.log('Or move the API key to CMS_SYNC_API_KEY in .env.local instead.');
45
+ }
46
+ const doScaffold = scaffoldInput.trim().toLowerCase() !== 'n';
47
+ if (doScaffold) {
48
+ const absI18nDir = path.isAbsolute(i18nDir)
49
+ ? i18nDir
50
+ : path.resolve(root, i18nDir);
51
+ const { written, skipped } = scaffoldI18n({ i18nDir: absI18nDir });
52
+ if (written.length > 0) {
53
+ console.log('\nScaffolded i18n files:');
54
+ for (const f of written)
55
+ console.log(` + src/lib/i18n/${f}`);
56
+ }
57
+ if (skipped.length > 0) {
58
+ console.log('\nSkipped (already exist):');
59
+ for (const f of skipped)
60
+ console.log(` ~ src/lib/i18n/${f}`);
61
+ }
62
+ console.log('\nNext steps:');
63
+ console.log(' 1. Install peer deps: pnpm add i18next react-i18next i18next-resources-to-backend');
64
+ console.log(' 2. Pull translations: sync-translations pull');
65
+ console.log(' 3. Wrap your root layout with <TranslationProvider locale={locale}>');
66
+ }
67
+ }
68
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Config, TranslationsConfig } from '../config/resolve-config.js';
2
+ export declare function runPull(root: string, config: Config, fileConfig: TranslationsConfig, args: string[]): Promise<void>;
3
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAG9E,wBAAsB,OAAO,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,kBAAkB,EAC9B,IAAI,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,22 @@
1
+ import path from 'path';
2
+ import { pullTranslations } from '../core/api.js';
3
+ export async function runPull(root, config, fileConfig, args) {
4
+ const outputArg = getFlag(args, '--output');
5
+ const outputDir = outputArg
6
+ ? path.resolve(root, outputArg)
7
+ : fileConfig.outputDir
8
+ ? path.resolve(root, fileConfig.outputDir)
9
+ : path.join(root, 'public', 'locales');
10
+ const ttlArg = getFlag(args, '--ttl');
11
+ await pullTranslations(config, {
12
+ outputDir,
13
+ force: args.includes('--force'),
14
+ ttlMs: ttlArg ? parseInt(ttlArg, 10) : fileConfig.pullTtlMs,
15
+ env: getFlag(args, '--env'),
16
+ });
17
+ }
18
+ function getFlag(args, flag) {
19
+ const idx = args.indexOf(flag);
20
+ return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined;
21
+ }
22
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,OAAO,CACzB,IAAY,EACZ,MAAc,EACd,UAA8B,EAC9B,IAAc;IAEd,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS;QACvB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAC/B,CAAC,CAAC,UAAU,CAAC,SAAS;YACpB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;YAC1C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,gBAAgB,CAAC,MAAM,EAAE;QAC3B,SAAS;QACT,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS;QAC3D,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;KAC9B,CAAC,CAAC;AACP,CAAC;AAED,SAAS,OAAO,CAAC,IAAc,EAAE,IAAY;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACnE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ScanOptions } from '../core/scanner.js';
2
+ export declare function runStatus(root: string, scanOpts: ScanOptions): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQnE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,IAAI,CAyDnE"}
@@ -0,0 +1,46 @@
1
+ import { scanProject } from '../core/scanner.js';
2
+ import { serializeNamespaces, loadSyncCache, computeDiff, formatPreviewRoutes, } from '../core/cache.js';
3
+ export function runStatus(root, scanOpts) {
4
+ console.log(`Scanning project: ${root}`);
5
+ const namespaces = scanProject(root, scanOpts);
6
+ const { serialized, totalKeys } = serializeNamespaces(namespaces);
7
+ const namespaceCount = Object.keys(serialized).length;
8
+ console.log(`\nFound ${totalKeys} key(s) across ${namespaceCount} namespace(s): ${Object.keys(serialized).join(', ')}`);
9
+ const cached = loadSyncCache(root);
10
+ if (!cached) {
11
+ console.log('\nNo sync cache found (.cms-sync-cache.json). Run sync first to establish a baseline.');
12
+ return;
13
+ }
14
+ const diff = computeDiff(serialized, cached);
15
+ console.log('\nStatus vs last sync:');
16
+ console.log(` + ${diff.added.length} new key(s)`);
17
+ console.log(` - ${diff.removed.length} removed key(s)`);
18
+ console.log(` ~ ${diff.routesChanged.length} route update(s)`);
19
+ console.log(` = ${diff.unchanged} unchanged`);
20
+ if (diff.added.length > 0) {
21
+ console.log('\nNew keys:');
22
+ for (const { namespace, key, routes } of diff.added) {
23
+ console.log(` + ${namespace}:${key} (${formatPreviewRoutes(routes)})`);
24
+ }
25
+ }
26
+ if (diff.removed.length > 0) {
27
+ console.log('\nRemoved keys:');
28
+ for (const { namespace, key } of diff.removed) {
29
+ console.log(` - ${namespace}:${key}`);
30
+ }
31
+ }
32
+ if (diff.routesChanged.length > 0) {
33
+ console.log('\nRoute updates:');
34
+ for (const { namespace, key, before, after } of diff.routesChanged) {
35
+ console.log(` ~ ${namespace}:${key} [${formatPreviewRoutes(before)}] -> [${formatPreviewRoutes(after)}]`);
36
+ }
37
+ }
38
+ const total = diff.added.length + diff.removed.length + diff.routesChanged.length;
39
+ if (total > 0) {
40
+ console.log('\nRun "sync-translations sync" to push these changes.');
41
+ }
42
+ else {
43
+ console.log('\nEverything is in sync.');
44
+ }
45
+ }
46
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Config } from '../config/resolve-config.js';
2
+ import { type ScanOptions } from '../core/scanner.js';
3
+ export interface SyncCommandOptions {
4
+ outputDir: string;
5
+ dryRun: boolean;
6
+ force: boolean;
7
+ reportPath?: string;
8
+ }
9
+ export declare function runSync(root: string, config: Config, scanOpts: ScanOptions, opts: SyncCommandOptions): Promise<void>;
10
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnE,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,OAAO,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CAkBf"}
@@ -0,0 +1,20 @@
1
+ import { scanProject } from '../core/scanner.js';
2
+ import { postToSync, pullTranslations } from '../core/api.js';
3
+ export async function runSync(root, config, scanOpts, opts) {
4
+ console.log(`Scanning project: ${root}`);
5
+ const namespaces = scanProject(root, scanOpts);
6
+ await postToSync(config, namespaces, {
7
+ root,
8
+ force: opts.force,
9
+ dryRun: opts.dryRun,
10
+ reportPath: opts.reportPath,
11
+ });
12
+ // Skip pull when dry-running — there's nothing to pull yet
13
+ if (!opts.dryRun) {
14
+ await pullTranslations(config, {
15
+ outputDir: opts.outputDir,
16
+ force: opts.force,
17
+ });
18
+ }
19
+ }
20
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAoB,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAS9D,MAAM,CAAC,KAAK,UAAU,OAAO,CACzB,IAAY,EACZ,MAAc,EACd,QAAqB,EACrB,IAAwB;IAExB,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE;QACjC,IAAI;QACJ,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC9B,CAAC,CAAC;IAEH,2DAA2D;IAC3D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,gBAAgB,CAAC,MAAM,EAAE;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;SACpB,CAAC,CAAC;IACP,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Config } from '../config/resolve-config.js';
2
+ import { type ScanOptions } from '../core/scanner.js';
3
+ export declare function runWatch(root: string, config: Config, outputDir: string, scanOpts: ScanOptions): Promise<void>;
4
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnE,wBAAsB,QAAQ,CAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,GACtB,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -0,0 +1,51 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import { scanProject } from '../core/scanner.js';
4
+ import { postToSync, pullTranslations } from '../core/api.js';
5
+ export async function runWatch(root, config, outputDir, scanOpts) {
6
+ console.log(`[watch] Watching ${root} for changes...`);
7
+ console.log('[watch] Press Ctrl+C to stop.\n');
8
+ const sourceExtensions = new Set(scanOpts.sourceExtensions ?? ['.ts', '.tsx', '.js', '.jsx']);
9
+ let debounce = null;
10
+ let running = false;
11
+ const runSync = async () => {
12
+ if (running)
13
+ return;
14
+ running = true;
15
+ try {
16
+ const namespaces = scanProject(root, scanOpts);
17
+ await postToSync(config, namespaces, { root, force: true });
18
+ await pullTranslations(config, { outputDir, force: true });
19
+ }
20
+ catch (err) {
21
+ console.error('[watch] Sync error:', err instanceof Error ? err.message : String(err));
22
+ }
23
+ finally {
24
+ running = false;
25
+ }
26
+ };
27
+ // Initial sync on start
28
+ await runSync();
29
+ // Recursively watch for file changes
30
+ const watcher = fs.watch(root, { recursive: true }, (_evt, filename) => {
31
+ if (!filename)
32
+ return;
33
+ const ext = path.extname(filename);
34
+ if (!sourceExtensions.has(ext))
35
+ return;
36
+ if (debounce)
37
+ clearTimeout(debounce);
38
+ debounce = setTimeout(() => {
39
+ console.log(`[watch] Change detected: ${filename}`);
40
+ void runSync();
41
+ }, 500);
42
+ });
43
+ process.on('SIGINT', () => {
44
+ watcher.close();
45
+ console.log('\n[watch] Stopped.');
46
+ process.exit(0);
47
+ });
48
+ // Keep the process alive
49
+ await new Promise(() => undefined);
50
+ }
51
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAoB,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC1B,IAAY,EACZ,MAAc,EACd,SAAiB,EACjB,QAAqB;IAErB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,iBAAiB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC5B,QAAQ,CAAC,gBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAC9D,CAAC;IAEF,IAAI,QAAQ,GAAyC,IAAI,CAAC;IAC1D,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACtC,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/C,MAAM,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CACT,qBAAqB,EACrB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACnD,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,OAAO,GAAG,KAAK,CAAC;QACpB,CAAC;IACL,CAAC,CAAC;IAEF,wBAAwB;IACxB,MAAM,OAAO,EAAE,CAAC;IAEhB,qCAAqC;IACrC,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;QACnE,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QAEvC,IAAI,QAAQ;YAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrC,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;YACpD,KAAK,OAAO,EAAE,CAAC;QACnB,CAAC,EAAE,GAAG,CAAC,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,yBAAyB;IACzB,MAAM,IAAI,OAAO,CAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC"}
@@ -43,19 +43,10 @@ export interface TranslationsConfig {
43
43
  * @example 600000
44
44
  */
45
45
  pullTtlMs?: number;
46
- /**
47
- * Additional CSS / utility-framework namespace keywords to exclude from key
48
- * detection. Merged with the built-in list:
49
- * hover, focus, active, group, supports, peer, lg, md, sm, xl, 2xl, dark, localhost, http, https, ftp
50
- * @example ["after", "before", "placeholder"]
51
- */
52
- reservedCssNamespaces?: string[];
53
46
  /**
54
47
  * Mock params for dynamic route segments.
55
48
  * Keys are route patterns (e.g. "/[locale]/blog/[slug]"), values are the
56
49
  * params to fill in when generating preview URLs for that route.
57
- * The scanner automatically applies these to any key it detects on a
58
- * matching route — no need to repeat params per key.
59
50
  *
60
51
  * @example
61
52
  * {
@@ -70,4 +61,16 @@ export interface TranslationsConfig {
70
61
  * Returns an empty object when no config file is found — never throws.
71
62
  */
72
63
  export declare function loadConfigFile(root: string): TranslationsConfig;
73
- //# sourceMappingURL=load-config.d.ts.map
64
+ /**
65
+ * Resolved runtime config passed to all CLI operations.
66
+ */
67
+ export interface Config {
68
+ projectId: string;
69
+ apiKey: string;
70
+ cmsUrl: string;
71
+ }
72
+ export declare function loadEnvLocal(root: string): Record<string, string>;
73
+ export declare function parseArgs(): Partial<Config>;
74
+ export declare function findProjectRoot(): string;
75
+ export declare function resolveConfig(cwd?: string, fileConfig?: TranslationsConfig): Config;
76
+ //# sourceMappingURL=resolve-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-config.d.ts","sourceRoot":"","sources":["../../src/config/resolve-config.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxD;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAqB/D;AAMD;;GAEG;AACH,MAAM,WAAW,MAAM;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBjE;AAED,wBAAgB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAU3C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAaxC;AAED,wBAAgB,aAAa,CACzB,GAAG,CAAC,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,kBAAkB,GAChC,MAAM,CA4CR"}
@@ -1,5 +1,26 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ const CONFIG_FILENAMES = ['.translationsrc.json', 'translations.config.json'];
4
+ /**
5
+ * Load project-level config from .translationsrc.json or translations.config.json.
6
+ * Returns an empty object when no config file is found — never throws.
7
+ */
8
+ export function loadConfigFile(root) {
9
+ for (const filename of CONFIG_FILENAMES) {
10
+ const filePath = path.join(root, filename);
11
+ if (!fs.existsSync(filePath))
12
+ continue;
13
+ try {
14
+ const parsed = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
15
+ console.log(`[config] Loaded config from ${filename}`);
16
+ return parsed;
17
+ }
18
+ catch (err) {
19
+ console.warn(`[config] Failed to parse ${filename}: ${err instanceof Error ? err.message : String(err)}`);
20
+ }
21
+ }
22
+ return {};
23
+ }
3
24
  export function loadEnvLocal(root) {
4
25
  const envPath = path.join(root, '.env.local');
5
26
  if (!fs.existsSync(envPath))
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-config.js","sourceRoot":"","sources":["../../src/config/resolve-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utility helper functions for API operations.
3
+ */
4
+ /**
5
+ * Resolve a report path to an absolute path.
6
+ * If already absolute, returns as-is. Otherwise, resolves relative to root.
7
+ */
8
+ export declare function resolveReportPath(root: string, reportPath: string): string;
9
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/api-internals/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI1E"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Utility helper functions for API operations.
3
+ */
4
+ import path from 'path';
5
+ /**
6
+ * Resolve a report path to an absolute path.
7
+ * If already absolute, returns as-is. Otherwise, resolves relative to root.
8
+ */
9
+ export function resolveReportPath(root, reportPath) {
10
+ return path.isAbsolute(reportPath)
11
+ ? reportPath
12
+ : path.join(root, reportPath);
13
+ }
14
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/core/api-internals/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAAkB;IAC9D,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAC9B,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Pull (fetch) published translations from CMS to local JSON files.
3
+ */
4
+ import type { Config } from '../../config/resolve-config.js';
5
+ import type { PullOptions } from './types.js';
6
+ /**
7
+ * Fetch published translations from the CMS and write them to local JSON files.
8
+ * Supports caching with TTL and force refresh.
9
+ */
10
+ export declare function pullTranslations(config: Config, opts: PullOptions): Promise<void>;
11
+ //# sourceMappingURL=pull.d.ts.map