@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.
Files changed (197) hide show
  1. package/dist/api.d.ts +105 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +208 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/bin.d.ts +25 -0
  6. package/dist/bin.d.ts.map +1 -0
  7. package/dist/bin.js +208 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/commands/init.d.ts +10 -0
  10. package/dist/commands/init.d.ts.map +1 -0
  11. package/dist/commands/init.js +107 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/pull.d.ts +10 -0
  14. package/dist/commands/pull.d.ts.map +1 -0
  15. package/dist/commands/pull.js +35 -0
  16. package/dist/commands/pull.js.map +1 -0
  17. package/dist/commands/status.d.ts +15 -0
  18. package/dist/commands/status.d.ts.map +1 -0
  19. package/dist/commands/status.js +62 -0
  20. package/dist/commands/status.js.map +1 -0
  21. package/dist/commands/sync.d.ts +24 -0
  22. package/dist/commands/sync.d.ts.map +1 -0
  23. package/dist/commands/sync.js +131 -0
  24. package/dist/commands/sync.js.map +1 -0
  25. package/dist/commands/watch.d.ts +18 -0
  26. package/dist/commands/watch.d.ts.map +1 -0
  27. package/dist/commands/watch.js +71 -0
  28. package/dist/commands/watch.js.map +1 -0
  29. package/dist/config/config-internals/args.d.ts +11 -0
  30. package/dist/config/config-internals/args.d.ts.map +1 -0
  31. package/dist/config/config-internals/args.js +22 -0
  32. package/dist/config/config-internals/args.js.map +1 -0
  33. package/dist/config/config-internals/env.d.ts +10 -0
  34. package/dist/config/config-internals/env.d.ts.map +1 -0
  35. package/dist/config/config-internals/env.js +35 -0
  36. package/dist/config/config-internals/env.js.map +1 -0
  37. package/dist/config/config-internals/file.d.ts +11 -0
  38. package/dist/config/config-internals/file.d.ts.map +1 -0
  39. package/dist/config/config-internals/file.js +28 -0
  40. package/dist/config/config-internals/file.js.map +1 -0
  41. package/dist/config/config-internals/resolve.d.ts +21 -0
  42. package/dist/config/config-internals/resolve.d.ts.map +1 -0
  43. package/dist/config/config-internals/resolve.js +73 -0
  44. package/dist/config/config-internals/resolve.js.map +1 -0
  45. package/dist/config/config-internals/root.d.ts +9 -0
  46. package/dist/config/config-internals/root.d.ts.map +1 -0
  47. package/dist/config/config-internals/root.js +22 -0
  48. package/dist/config/config-internals/root.js.map +1 -0
  49. package/dist/config/config-internals/types.d.ts +91 -0
  50. package/dist/config/config-internals/types.d.ts.map +1 -0
  51. package/dist/config/config-internals/types.js +9 -0
  52. package/dist/config/config-internals/types.js.map +1 -0
  53. package/dist/config/resolve-config.d.ts +11 -0
  54. package/dist/config/resolve-config.d.ts.map +1 -0
  55. package/dist/config/resolve-config.js +10 -0
  56. package/dist/config/resolve-config.js.map +1 -0
  57. package/dist/core/api-internals/helpers.d.ts +9 -0
  58. package/dist/core/api-internals/helpers.d.ts.map +1 -0
  59. package/dist/core/api-internals/helpers.js +14 -0
  60. package/dist/core/api-internals/helpers.js.map +1 -0
  61. package/dist/core/api-internals/pull.d.ts +19 -0
  62. package/dist/core/api-internals/pull.d.ts.map +1 -0
  63. package/dist/core/api-internals/pull.js +269 -0
  64. package/dist/core/api-internals/pull.js.map +1 -0
  65. package/dist/core/api-internals/route-config.d.ts +13 -0
  66. package/dist/core/api-internals/route-config.d.ts.map +1 -0
  67. package/dist/core/api-internals/route-config.js +34 -0
  68. package/dist/core/api-internals/route-config.js.map +1 -0
  69. package/dist/core/api-internals/sync.d.ts +19 -0
  70. package/dist/core/api-internals/sync.d.ts.map +1 -0
  71. package/dist/core/api-internals/sync.js +139 -0
  72. package/dist/core/api-internals/sync.js.map +1 -0
  73. package/dist/core/api-internals/types.d.ts +33 -0
  74. package/dist/core/api-internals/types.d.ts.map +1 -0
  75. package/dist/core/api-internals/types.js +5 -0
  76. package/dist/core/api-internals/types.js.map +1 -0
  77. package/dist/core/api.d.ts +11 -0
  78. package/dist/core/api.d.ts.map +1 -0
  79. package/dist/core/api.js +11 -0
  80. package/dist/core/api.js.map +1 -0
  81. package/dist/core/cache-internals/format.d.ts +20 -0
  82. package/dist/core/cache-internals/format.d.ts.map +1 -0
  83. package/dist/core/cache-internals/format.js +33 -0
  84. package/dist/core/cache-internals/format.js.map +1 -0
  85. package/dist/core/cache-internals/params.d.ts +33 -0
  86. package/dist/core/cache-internals/params.d.ts.map +1 -0
  87. package/dist/core/cache-internals/params.js +155 -0
  88. package/dist/core/cache-internals/params.js.map +1 -0
  89. package/dist/core/cache-internals/pull.d.ts +17 -0
  90. package/dist/core/cache-internals/pull.d.ts.map +1 -0
  91. package/dist/core/cache-internals/pull.js +34 -0
  92. package/dist/core/cache-internals/pull.js.map +1 -0
  93. package/dist/core/cache-internals/sync.d.ts +29 -0
  94. package/dist/core/cache-internals/sync.d.ts.map +1 -0
  95. package/dist/core/cache-internals/sync.js +104 -0
  96. package/dist/core/cache-internals/sync.js.map +1 -0
  97. package/dist/core/cache-internals/types.d.ts +48 -0
  98. package/dist/core/cache-internals/types.d.ts.map +1 -0
  99. package/dist/core/cache-internals/types.js +2 -0
  100. package/dist/core/cache-internals/types.js.map +1 -0
  101. package/dist/core/cache.d.ts +13 -0
  102. package/dist/core/cache.d.ts.map +1 -0
  103. package/dist/core/cache.js +33 -0
  104. package/dist/core/cache.js.map +1 -0
  105. package/dist/core/scanner-internals/ast.d.ts +40 -0
  106. package/dist/core/scanner-internals/ast.d.ts.map +1 -0
  107. package/dist/core/scanner-internals/ast.js +100 -0
  108. package/dist/core/scanner-internals/ast.js.map +1 -0
  109. package/dist/core/scanner-internals/file-walker.d.ts +10 -0
  110. package/dist/core/scanner-internals/file-walker.d.ts.map +1 -0
  111. package/dist/core/scanner-internals/file-walker.js +23 -0
  112. package/dist/core/scanner-internals/file-walker.js.map +1 -0
  113. package/dist/core/scanner-internals/import-resolver.d.ts +21 -0
  114. package/dist/core/scanner-internals/import-resolver.d.ts.map +1 -0
  115. package/dist/core/scanner-internals/import-resolver.js +119 -0
  116. package/dist/core/scanner-internals/import-resolver.js.map +1 -0
  117. package/dist/core/scanner-internals/key-extractor.d.ts +20 -0
  118. package/dist/core/scanner-internals/key-extractor.d.ts.map +1 -0
  119. package/dist/core/scanner-internals/key-extractor.js +274 -0
  120. package/dist/core/scanner-internals/key-extractor.js.map +1 -0
  121. package/dist/core/scanner-internals/nav-config-scanner.d.ts +30 -0
  122. package/dist/core/scanner-internals/nav-config-scanner.d.ts.map +1 -0
  123. package/dist/core/scanner-internals/nav-config-scanner.js +170 -0
  124. package/dist/core/scanner-internals/nav-config-scanner.js.map +1 -0
  125. package/dist/core/scanner-internals/route-detector.d.ts +27 -0
  126. package/dist/core/scanner-internals/route-detector.d.ts.map +1 -0
  127. package/dist/core/scanner-internals/route-detector.js +78 -0
  128. package/dist/core/scanner-internals/route-detector.js.map +1 -0
  129. package/dist/core/scanner-internals/types.d.ts +60 -0
  130. package/dist/core/scanner-internals/types.d.ts.map +1 -0
  131. package/dist/core/scanner-internals/types.js +29 -0
  132. package/dist/core/scanner-internals/types.js.map +1 -0
  133. package/dist/core/scanner.d.ts +21 -0
  134. package/dist/core/scanner.d.ts.map +1 -0
  135. package/dist/core/scanner.js +162 -0
  136. package/dist/core/scanner.js.map +1 -0
  137. package/dist/index.d.ts +3 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +3 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/next.d.ts +33 -0
  142. package/dist/next.d.ts.map +1 -0
  143. package/dist/next.js +110 -0
  144. package/dist/next.js.map +1 -0
  145. package/dist/preview/index.d.ts +39 -0
  146. package/dist/preview/index.d.ts.map +1 -0
  147. package/dist/preview/index.js +123 -0
  148. package/dist/preview/index.js.map +1 -0
  149. package/dist/preview/internals/highlight.d.ts +31 -0
  150. package/dist/preview/internals/highlight.d.ts.map +1 -0
  151. package/dist/preview/internals/highlight.js +184 -0
  152. package/dist/preview/internals/highlight.js.map +1 -0
  153. package/dist/preview/internals/interactions.d.ts +15 -0
  154. package/dist/preview/internals/interactions.d.ts.map +1 -0
  155. package/dist/preview/internals/interactions.js +38 -0
  156. package/dist/preview/internals/interactions.js.map +1 -0
  157. package/dist/preview/internals/interactive.d.ts +14 -0
  158. package/dist/preview/internals/interactive.d.ts.map +1 -0
  159. package/dist/preview/internals/interactive.js +122 -0
  160. package/dist/preview/internals/interactive.js.map +1 -0
  161. package/dist/preview/internals/locales.d.ts +9 -0
  162. package/dist/preview/internals/locales.d.ts.map +1 -0
  163. package/dist/preview/internals/locales.js +24 -0
  164. package/dist/preview/internals/locales.js.map +1 -0
  165. package/dist/preview/internals/state.d.ts +37 -0
  166. package/dist/preview/internals/state.d.ts.map +1 -0
  167. package/dist/preview/internals/state.js +74 -0
  168. package/dist/preview/internals/state.js.map +1 -0
  169. package/dist/preview/internals/styles.d.ts +8 -0
  170. package/dist/preview/internals/styles.d.ts.map +1 -0
  171. package/dist/preview/internals/styles.js +28 -0
  172. package/dist/preview/internals/styles.js.map +1 -0
  173. package/dist/preview/internals/types.d.ts +74 -0
  174. package/dist/preview/internals/types.d.ts.map +1 -0
  175. package/dist/preview/internals/types.js +5 -0
  176. package/dist/preview/internals/types.js.map +1 -0
  177. package/dist/preview/internals/ui-indicators.d.ts +15 -0
  178. package/dist/preview/internals/ui-indicators.d.ts.map +1 -0
  179. package/dist/preview/internals/ui-indicators.js +92 -0
  180. package/dist/preview/internals/ui-indicators.js.map +1 -0
  181. package/dist/scaffold/index.d.ts +3 -0
  182. package/dist/scaffold/index.d.ts.map +1 -0
  183. package/dist/scaffold/index.js +3 -0
  184. package/dist/scaffold/index.js.map +1 -0
  185. package/dist/scaffold/intenrals/scaffold.d.ts +24 -0
  186. package/dist/scaffold/intenrals/scaffold.d.ts.map +1 -0
  187. package/dist/scaffold/intenrals/scaffold.js +53 -0
  188. package/dist/scaffold/intenrals/scaffold.js.map +1 -0
  189. package/dist/scaffold/intenrals/templates.d.ts +10 -0
  190. package/dist/scaffold/intenrals/templates.d.ts.map +1 -0
  191. package/dist/scaffold/intenrals/templates.js +344 -0
  192. package/dist/scaffold/intenrals/templates.js.map +1 -0
  193. package/dist/scaffold/intenrals/types.d.ts +14 -0
  194. package/dist/scaffold/intenrals/types.d.ts.map +1 -0
  195. package/dist/scaffold/intenrals/types.js +5 -0
  196. package/dist/scaffold/intenrals/types.js.map +1 -0
  197. package/package.json +3 -3
package/dist/api.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Programmatic API for translation sync
3
+ *
4
+ * Use this if you want to integrate sync into your own tooling, CI/CD,
5
+ * or custom workflows.
6
+ *
7
+ * Usage:
8
+ * import { syncTranslations, pullTranslations } from '@translation-cms/sync/api';
9
+ *
10
+ * // Scan and sync keys to CMS
11
+ * await syncTranslations({ projectRoot: './my-project' });
12
+ *
13
+ * // Fetch translations from CMS
14
+ * await pullTranslations({ projectRoot: './my-project' });
15
+ */
16
+ export interface SyncOptions {
17
+ /** Project root directory. If omitted, searches up from cwd */
18
+ projectRoot?: string;
19
+ /** Dry run: show changes without uploading */
20
+ dryRun?: boolean;
21
+ /** Force refresh: ignore cache */
22
+ force?: boolean;
23
+ /** Write sync report to this file path */
24
+ reportPath?: string;
25
+ /** Show verbose output */
26
+ verbose?: boolean;
27
+ /** Path alias mappings (mirrors tsconfig `paths`). Used to resolve @/ imports. */
28
+ pathMappings?: Record<string, string[]>;
29
+ }
30
+ export interface PullOptions {
31
+ /** Project root directory. If omitted, searches up from cwd */
32
+ projectRoot?: string;
33
+ /** Custom output directory for JSON files */
34
+ outputDir?: string;
35
+ /** Force refresh: ignore cache */
36
+ force?: boolean;
37
+ /** Override cache TTL in milliseconds */
38
+ ttl?: number;
39
+ /** Pull from specific environment */
40
+ environment?: string;
41
+ /** Show verbose output */
42
+ verbose?: boolean;
43
+ }
44
+ /**
45
+ * Scans codebase for translation keys and syncs them to the CMS.
46
+ *
47
+ * @example
48
+ * const result = await syncTranslations({
49
+ * projectRoot: './apps/web',
50
+ * dryRun: false,
51
+ * verbose: true,
52
+ * });
53
+ *
54
+ * console.log(`Synced ${result.keysAdded} new keys`);
55
+ */
56
+ export declare function syncTranslations(options?: SyncOptions): Promise<{
57
+ keysAdded: number;
58
+ keysUpdated: number;
59
+ }>;
60
+ /**
61
+ * Fetches translations from the CMS and writes them as local JSON files.
62
+ *
63
+ * @example
64
+ * await pullTranslations({
65
+ * projectRoot: './apps/web',
66
+ * outputDir: './src/i18n/locales',
67
+ * force: true,
68
+ * });
69
+ */
70
+ export declare function pullTranslations(options?: PullOptions): Promise<{
71
+ locales: string[];
72
+ fileCount: number;
73
+ }>;
74
+ export interface WatchOptions {
75
+ /** Project root directory. If omitted, searches up from cwd */
76
+ projectRoot?: string;
77
+ /** Custom output directory to watch (must match the pull outputDir) */
78
+ outputDir?: string;
79
+ /**
80
+ * How often (in ms) to poll the CMS for new translations.
81
+ * Default: 10000 (10 seconds). Set to 0 to disable.
82
+ */
83
+ interval?: number;
84
+ }
85
+ /**
86
+ * Starts a polling loop that detects new CMS publishes and automatically
87
+ * re-pulls translations to local JSON files. Non-blocking — returns immediately.
88
+ *
89
+ * Call this once in dev mode after the initial pull:
90
+ *
91
+ * @example
92
+ * if (phase === PHASE_DEVELOPMENT_SERVER) {
93
+ * await pullTranslations({ projectRoot: '.' });
94
+ * watchTranslations({ projectRoot: '.' });
95
+ * }
96
+ */
97
+ export declare function watchTranslations(options?: WatchOptions): void;
98
+ /**
99
+ * Sync and pull in one operation (equivalent to CLI `sync` command)
100
+ */
101
+ export declare function syncAndPull(options?: SyncOptions & PullOptions): Promise<{
102
+ synced: boolean;
103
+ pulled: boolean;
104
+ }>;
105
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,MAAM,WAAW,WAAW;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,WAAW;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAClC,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAmErD;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAClC,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA4DnD;AAED,MAAM,WAAW,YAAY;IACzB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,YAAiB,GAAG,IAAI,CAqDlE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC7B,OAAO,GAAE,WAAW,GAAG,WAAgB,GACxC,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,CAQ/C"}
package/dist/api.js ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Programmatic API for translation sync
3
+ *
4
+ * Use this if you want to integrate sync into your own tooling, CI/CD,
5
+ * or custom workflows.
6
+ *
7
+ * Usage:
8
+ * import { syncTranslations, pullTranslations } from '@translation-cms/sync/api';
9
+ *
10
+ * // Scan and sync keys to CMS
11
+ * await syncTranslations({ projectRoot: './my-project' });
12
+ *
13
+ * // Fetch translations from CMS
14
+ * await pullTranslations({ projectRoot: './my-project' });
15
+ */
16
+ import path from 'path';
17
+ import { resolveConfig, resolveRouteParams, findProjectRoot as findProjectRootHelper, loadConfigFile, } from './config/resolve-config.js';
18
+ import { fetchRouteParams } from './core/api.js';
19
+ import { runSync } from './commands/sync.js';
20
+ import { runPull } from './commands/pull.js';
21
+ import { getLastPulledTime } from './core/cache.js';
22
+ /**
23
+ * Scans codebase for translation keys and syncs them to the CMS.
24
+ *
25
+ * @example
26
+ * const result = await syncTranslations({
27
+ * projectRoot: './apps/web',
28
+ * dryRun: false,
29
+ * verbose: true,
30
+ * });
31
+ *
32
+ * console.log(`Synced ${result.keysAdded} new keys`);
33
+ */
34
+ export async function syncTranslations(options = {}) {
35
+ const { projectRoot = findProjectRootHelper(), dryRun = false, force = false, reportPath, verbose = false, pathMappings, } = options;
36
+ if (verbose) {
37
+ // eslint-disable-next-line no-console
38
+ console.log(`[sync-translations] Syncing from ${projectRoot}...`);
39
+ }
40
+ const fileConfig = loadConfigFile(projectRoot);
41
+ const config = resolveConfig(projectRoot, fileConfig);
42
+ if (!config.cmsUrl || !config.projectId || !config.apiKey) {
43
+ throw new Error('Missing CMS configuration. Set NEXT_PUBLIC_CMS_URL, NEXT_PUBLIC_CMS_PROJECT_ID, and CMS_SYNC_API_KEY.');
44
+ }
45
+ // Fetch route params from CMS and merge with local config
46
+ const cmsRouteParams = await fetchRouteParams(config);
47
+ const userRouteParams = resolveRouteParams(projectRoot, fileConfig);
48
+ const scanOpts = {
49
+ excludedDirs: fileConfig.excludedDirs,
50
+ sourceExtensions: fileConfig.sourceExtensions,
51
+ routeParams: { ...cmsRouteParams, ...userRouteParams },
52
+ projectRoot,
53
+ includeNavRoutes: fileConfig.includeNavRoutes,
54
+ pathMappings,
55
+ };
56
+ const outputDir = fileConfig.outputDir ?? path.join(projectRoot, 'public', 'locales');
57
+ try {
58
+ await runSync(projectRoot, config, scanOpts, {
59
+ outputDir,
60
+ dryRun,
61
+ force,
62
+ reportPath,
63
+ mockDataPath: fileConfig.mockDataPath,
64
+ userRouteParams,
65
+ });
66
+ if (verbose) {
67
+ // eslint-disable-next-line no-console
68
+ console.log(`[sync-translations] Sync complete`);
69
+ }
70
+ // Return placeholder stats (actual stats are logged by runSync)
71
+ return {
72
+ keysAdded: 0,
73
+ keysUpdated: 0,
74
+ };
75
+ }
76
+ catch (error) {
77
+ if (verbose && error instanceof Error) {
78
+ // eslint-disable-next-line no-console
79
+ console.error('[sync-translations] Sync failed:', error.message);
80
+ }
81
+ throw error;
82
+ }
83
+ }
84
+ /**
85
+ * Fetches translations from the CMS and writes them as local JSON files.
86
+ *
87
+ * @example
88
+ * await pullTranslations({
89
+ * projectRoot: './apps/web',
90
+ * outputDir: './src/i18n/locales',
91
+ * force: true,
92
+ * });
93
+ */
94
+ export async function pullTranslations(options = {}) {
95
+ const { projectRoot = findProjectRootHelper(), outputDir, force = false, ttl, environment, verbose = false, } = options;
96
+ if (verbose) {
97
+ // eslint-disable-next-line no-console
98
+ console.log(`[sync-translations] Pulling to ${projectRoot}...`);
99
+ }
100
+ const fileConfig = loadConfigFile(projectRoot);
101
+ const config = resolveConfig(projectRoot, fileConfig);
102
+ if (!config.cmsUrl || !config.projectId || !config.apiKey) {
103
+ throw new Error('Missing CMS configuration. Set NEXT_PUBLIC_CMS_URL, NEXT_PUBLIC_CMS_PROJECT_ID, and CMS_SYNC_API_KEY.');
104
+ }
105
+ // Build args array for runPull
106
+ const args = [];
107
+ if (force)
108
+ args.push('--force');
109
+ if (environment) {
110
+ args.push('--env');
111
+ args.push(environment);
112
+ }
113
+ if (ttl) {
114
+ args.push('--ttl');
115
+ args.push(String(ttl));
116
+ }
117
+ if (outputDir) {
118
+ args.push('--output');
119
+ args.push(outputDir);
120
+ }
121
+ try {
122
+ await runPull(projectRoot, config, fileConfig, args);
123
+ if (verbose) {
124
+ // eslint-disable-next-line no-console
125
+ console.log(`[sync-translations] Pull complete`);
126
+ }
127
+ // Return placeholder stats
128
+ return {
129
+ locales: [],
130
+ fileCount: 0,
131
+ };
132
+ }
133
+ catch (error) {
134
+ if (verbose && error instanceof Error) {
135
+ // eslint-disable-next-line no-console
136
+ console.error('[sync-translations] Pull failed:', error.message);
137
+ }
138
+ throw error;
139
+ }
140
+ }
141
+ /**
142
+ * Starts a polling loop that detects new CMS publishes and automatically
143
+ * re-pulls translations to local JSON files. Non-blocking — returns immediately.
144
+ *
145
+ * Call this once in dev mode after the initial pull:
146
+ *
147
+ * @example
148
+ * if (phase === PHASE_DEVELOPMENT_SERVER) {
149
+ * await pullTranslations({ projectRoot: '.' });
150
+ * watchTranslations({ projectRoot: '.' });
151
+ * }
152
+ */
153
+ export function watchTranslations(options = {}) {
154
+ const { projectRoot = findProjectRootHelper(), interval = 10_000 } = options;
155
+ if (interval <= 0)
156
+ return;
157
+ const fileConfig = loadConfigFile(projectRoot);
158
+ const config = resolveConfig(projectRoot, fileConfig);
159
+ if (!config.cmsUrl || !config.projectId || !config.apiKey) {
160
+ // eslint-disable-next-line no-console
161
+ console.warn('[CMS] Missing config — watch disabled');
162
+ return;
163
+ }
164
+ const resolvedOutputDir = options.outputDir ??
165
+ fileConfig.outputDir ??
166
+ path.join(projectRoot, 'public', 'locales');
167
+ const statusUrl = `${config.cmsUrl.replace(/\/$/, '')}/api/sync/${config.projectId}/status`;
168
+ const poll = async () => {
169
+ try {
170
+ const res = await fetch(statusUrl, {
171
+ headers: { 'x-api-key': config.apiKey },
172
+ signal: AbortSignal.timeout(5000),
173
+ });
174
+ if (!res.ok)
175
+ return;
176
+ const { lastPublishedAt } = (await res.json());
177
+ if (!lastPublishedAt)
178
+ return;
179
+ const lastPulled = getLastPulledTime(resolvedOutputDir);
180
+ const publishedMs = new Date(lastPublishedAt).getTime();
181
+ if (lastPulled === null || publishedMs > lastPulled) {
182
+ // eslint-disable-next-line no-console
183
+ console.log('[CMS] New translations detected — pulling...');
184
+ await runPull(projectRoot, config, fileConfig, ['--force']);
185
+ }
186
+ }
187
+ catch {
188
+ // Silently ignore — CMS may be unreachable or dev server starting up
189
+ }
190
+ };
191
+ setInterval(poll, interval);
192
+ // eslint-disable-next-line no-console
193
+ console.log(`[CMS] Watching for translation updates every ${interval / 1000}s`);
194
+ }
195
+ /**
196
+ * Sync and pull in one operation (equivalent to CLI `sync` command)
197
+ */
198
+ export async function syncAndPull(options = {}) {
199
+ try {
200
+ await syncTranslations(options);
201
+ await pullTranslations(options);
202
+ return { synced: true, pulled: true };
203
+ }
204
+ catch {
205
+ return { synced: false, pulled: false };
206
+ }
207
+ }
208
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
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,208 @@
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, resolveRouteParams, 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
+ function stripJsonComments(input) {
37
+ let result = '';
38
+ let i = 0;
39
+ while (i < input.length) {
40
+ // --- String literal: copy char-by-char, respecting escape sequences ---
41
+ if (input[i] === '"') {
42
+ result += '"';
43
+ i++;
44
+ while (i < input.length) {
45
+ const ch = input[i];
46
+ result += ch;
47
+ i++;
48
+ if (ch === '\\') {
49
+ // Escaped character — copy next char unconditionally
50
+ if (i < input.length)
51
+ result += input[i++];
52
+ }
53
+ else if (ch === '"') {
54
+ break; // closing quote
55
+ }
56
+ }
57
+ continue;
58
+ }
59
+ // --- Line comment: skip everything up to the newline ---
60
+ if (input[i] === '/' && input[i + 1] === '/') {
61
+ while (i < input.length && input[i] !== '\n')
62
+ i++;
63
+ continue;
64
+ }
65
+ // --- Block comment: skip until closing */ ---
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
+ /**
82
+ * Load TypeScript path alias mappings from `tsconfig.json` at the project root.
83
+ *
84
+ * These mappings are passed to the scanner so that aliased imports such as
85
+ * `@/components/button` can be resolved to absolute file paths. tsconfig
86
+ * files are JSONC (JSON with comments) so we strip comments before parsing.
87
+ *
88
+ * Returns null when tsconfig.json is absent, unreadable, or has no `paths`.
89
+ */
90
+ function loadTsConfigPathMappings(root) {
91
+ const tsconfigPath = path.join(root, 'tsconfig.json');
92
+ if (!fs.existsSync(tsconfigPath))
93
+ return null;
94
+ try {
95
+ const cleaned = stripJsonComments(fs.readFileSync(tsconfigPath, 'utf-8'));
96
+ const tsconfig = JSON.parse(cleaned);
97
+ // Drill into compilerOptions.paths — guard each level against unexpected shapes
98
+ if (typeof tsconfig !== 'object' || tsconfig === null)
99
+ return null;
100
+ if (!('compilerOptions' in tsconfig))
101
+ return null;
102
+ const opts = tsconfig.compilerOptions;
103
+ if (typeof opts !== 'object' || opts === null)
104
+ return null;
105
+ if (!('paths' in opts))
106
+ return null;
107
+ const paths = opts.paths;
108
+ if (typeof paths === 'object' && paths !== null)
109
+ return paths;
110
+ }
111
+ catch {
112
+ // Silently ignore tsconfig parse errors — scanning continues without alias resolution
113
+ }
114
+ return null;
115
+ }
116
+ /** Return the value that follows `flag` in `args`, or undefined if absent. */
117
+ function getFlag(args, flag) {
118
+ const idx = args.indexOf(flag);
119
+ return idx !== -1 && args[idx + 1] ? args[idx + 1] : undefined;
120
+ }
121
+ /** Return true when any of the given flag strings is present in `args`. */
122
+ function hasFlag(args, ...flags) {
123
+ return flags.some(f => args.includes(f));
124
+ }
125
+ // ---------------------------------------------------------------------------
126
+ // Main
127
+ // ---------------------------------------------------------------------------
128
+ /** All valid subcommand names. Used for validation and dispatch. */
129
+ const SUBCOMMANDS = new Set(['sync', 'pull', 'status', 'watch', 'init']);
130
+ /**
131
+ * CLI entry point.
132
+ *
133
+ * Resolves config, loads tsconfig path mappings, and dispatches to the
134
+ * appropriate command handler. Config resolution and scanner setup are shared
135
+ * across all commands except `init` (which runs before a config file exists).
136
+ */
137
+ async function main() {
138
+ const args = process.argv.slice(2);
139
+ // First non-flag argument is the subcommand; default to 'sync' when omitted
140
+ const subcommand = args.find(a => !a.startsWith('-')) ?? 'sync';
141
+ if (!SUBCOMMANDS.has(subcommand)) {
142
+ // eslint-disable-next-line no-console
143
+ console.error(`Unknown subcommand: ${subcommand}`);
144
+ // eslint-disable-next-line no-console
145
+ console.error(`Available: ${[...SUBCOMMANDS].join(', ')}`);
146
+ process.exit(1);
147
+ }
148
+ const root = findProjectRoot();
149
+ const fileConfig = loadConfigFile(root);
150
+ // `init` runs before a config file exists, so it short-circuits here
151
+ if (subcommand === 'init') {
152
+ await runInit(root);
153
+ return;
154
+ }
155
+ const config = resolveConfig(root, fileConfig);
156
+ // Path mappings let the scanner resolve aliased imports (e.g. @/components/…)
157
+ const pathMappings = loadTsConfigPathMappings(root);
158
+ // Route params from the CMS are merged with locally configured params;
159
+ // skip the network call for `pull` since it doesn't scan the codebase
160
+ let cmsRouteParams = {};
161
+ if (subcommand !== 'pull') {
162
+ cmsRouteParams = await fetchRouteParams(config);
163
+ }
164
+ // User-defined params (from config) take precedence over CMS-generated ones
165
+ const allRouteParams = resolveRouteParams(root, fileConfig);
166
+ const scanOpts = {
167
+ excludedDirs: fileConfig.excludedDirs,
168
+ sourceExtensions: fileConfig.sourceExtensions,
169
+ routeParams: { ...cmsRouteParams, ...allRouteParams },
170
+ pathMappings: pathMappings ?? undefined,
171
+ projectRoot: root,
172
+ includeNavRoutes: fileConfig.includeNavRoutes,
173
+ };
174
+ if (subcommand === 'status') {
175
+ runStatus(root, scanOpts);
176
+ return;
177
+ }
178
+ if (subcommand === 'watch') {
179
+ const outputDir = fileConfig.outputDir ?? path.join(root, 'public', 'locales');
180
+ await runWatch(root, config, outputDir, scanOpts);
181
+ return;
182
+ }
183
+ if (subcommand === 'pull') {
184
+ await runPull(root, config, fileConfig, args);
185
+ return;
186
+ }
187
+ // --- sync (default) ---
188
+ const outputDir = fileConfig.outputDir ?? path.join(root, 'public', 'locales');
189
+ const reportArg = getFlag(args, '--report');
190
+ await runSync(root, config, scanOpts, {
191
+ outputDir,
192
+ dryRun: hasFlag(args, '--dry-run'),
193
+ force: hasFlag(args, '--force'),
194
+ // Resolve report path relative to project root when not absolute
195
+ reportPath: reportArg
196
+ ? path.isAbsolute(reportArg)
197
+ ? reportArg
198
+ : path.join(root, reportArg)
199
+ : undefined,
200
+ mockDataPath: fileConfig.mockDataPath,
201
+ userRouteParams: fileConfig.routeParams,
202
+ });
203
+ }
204
+ main().catch(err => {
205
+ process.stderr.write(`${err instanceof Error ? (err.stack ?? err.message) : String(err)}\n`);
206
+ process.exit(1);
207
+ });
208
+ //# 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,10 @@
1
+ /**
2
+ * Interactive `init` command.
3
+ *
4
+ * Walks the user through a series of prompts and writes a
5
+ * `.translationsrc.json` config file to the project root.
6
+ * Optionally scaffolds the i18n boilerplate files (settings,
7
+ * client, server, provider) into the chosen i18n directory.
8
+ */
9
+ export declare function runInit(root: string): Promise<void>;
10
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHzD"}