glotto 2.9.0 → 3.1.0

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 (151) hide show
  1. package/README.md +150 -54
  2. package/esm/cli.js +155 -43
  3. package/esm/deno.d.ts +5 -1
  4. package/esm/deno.js +18 -7
  5. package/esm/src/config.d.ts +4 -0
  6. package/esm/src/config.d.ts.map +1 -0
  7. package/esm/src/config.js +95 -0
  8. package/esm/src/contants.d.ts +6 -2
  9. package/esm/src/contants.d.ts.map +1 -1
  10. package/esm/src/contants.js +34 -15
  11. package/esm/src/diff.d.ts +4 -0
  12. package/esm/src/diff.d.ts.map +1 -0
  13. package/esm/src/diff.js +53 -0
  14. package/esm/src/file.d.ts +5 -9
  15. package/esm/src/file.d.ts.map +1 -1
  16. package/esm/src/file.js +14 -103
  17. package/esm/src/providers/anthropic.d.ts +6 -11
  18. package/esm/src/providers/anthropic.d.ts.map +1 -1
  19. package/esm/src/providers/anthropic.js +21 -107
  20. package/esm/src/providers/gemini.d.ts +6 -11
  21. package/esm/src/providers/gemini.d.ts.map +1 -1
  22. package/esm/src/providers/gemini.js +20 -113
  23. package/esm/src/providers/openai.d.ts +6 -11
  24. package/esm/src/providers/openai.d.ts.map +1 -1
  25. package/esm/src/providers/openai.js +17 -108
  26. package/esm/src/translator.d.ts +15 -0
  27. package/esm/src/translator.d.ts.map +1 -0
  28. package/esm/src/translator.js +284 -0
  29. package/esm/src/types.d.ts +58 -13
  30. package/esm/src/types.d.ts.map +1 -1
  31. package/esm/src/utilites.d.ts +3 -10
  32. package/esm/src/utilites.d.ts.map +1 -1
  33. package/esm/src/utilites.js +41 -131
  34. package/package.json +20 -6
  35. package/schema/glotto.schema.json +87 -0
  36. package/script/cli.js +153 -41
  37. package/script/deno.d.ts +5 -1
  38. package/script/deno.js +18 -7
  39. package/script/src/config.d.ts +4 -0
  40. package/script/src/config.d.ts.map +1 -0
  41. package/script/src/config.js +132 -0
  42. package/script/src/contants.d.ts +6 -2
  43. package/script/src/contants.d.ts.map +1 -1
  44. package/script/src/contants.js +35 -16
  45. package/script/src/diff.d.ts +4 -0
  46. package/script/src/diff.d.ts.map +1 -0
  47. package/script/src/diff.js +57 -0
  48. package/script/src/file.d.ts +5 -9
  49. package/script/src/file.d.ts.map +1 -1
  50. package/script/src/file.js +19 -113
  51. package/script/src/providers/anthropic.d.ts +6 -11
  52. package/script/src/providers/anthropic.d.ts.map +1 -1
  53. package/script/src/providers/anthropic.js +20 -106
  54. package/script/src/providers/gemini.d.ts +6 -11
  55. package/script/src/providers/gemini.d.ts.map +1 -1
  56. package/script/src/providers/gemini.js +19 -112
  57. package/script/src/providers/openai.d.ts +6 -11
  58. package/script/src/providers/openai.d.ts.map +1 -1
  59. package/script/src/providers/openai.js +16 -107
  60. package/script/src/translator.d.ts +15 -0
  61. package/script/src/translator.d.ts.map +1 -0
  62. package/script/src/translator.js +294 -0
  63. package/script/src/types.d.ts +58 -13
  64. package/script/src/types.d.ts.map +1 -1
  65. package/script/src/utilites.d.ts +3 -10
  66. package/script/src/utilites.d.ts.map +1 -1
  67. package/script/src/utilites.js +44 -138
  68. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  69. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  70. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -51
  71. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts +0 -35
  72. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts.map +0 -1
  73. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common32.js +0 -192
  74. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts +0 -35
  75. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts.map +0 -1
  76. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common64.js +0 -113
  77. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  78. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  79. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -13
  80. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  81. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  82. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -2
  83. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts +0 -2
  84. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts.map +0 -1
  85. package/esm/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.js +0 -26
  86. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts +0 -61
  87. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts.map +0 -1
  88. package/esm/deps/jsr.io/@std/encoding/1.0.10/ascii85.js +0 -152
  89. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts +0 -40
  90. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts.map +0 -1
  91. package/esm/deps/jsr.io/@std/encoding/1.0.10/base32.js +0 -87
  92. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts +0 -40
  93. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts.map +0 -1
  94. package/esm/deps/jsr.io/@std/encoding/1.0.10/base58.js +0 -131
  95. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts +0 -40
  96. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts.map +0 -1
  97. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64.js +0 -82
  98. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts +0 -40
  99. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts.map +0 -1
  100. package/esm/deps/jsr.io/@std/encoding/1.0.10/base64url.js +0 -72
  101. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  102. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  103. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -87
  104. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts +0 -98
  105. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts.map +0 -1
  106. package/esm/deps/jsr.io/@std/encoding/1.0.10/mod.js +0 -99
  107. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts +0 -120
  108. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts.map +0 -1
  109. package/esm/deps/jsr.io/@std/encoding/1.0.10/varint.js +0 -205
  110. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  111. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  112. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -57
  113. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts +0 -35
  114. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.d.ts.map +0 -1
  115. package/script/deps/jsr.io/@std/encoding/1.0.10/_common32.js +0 -198
  116. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts +0 -35
  117. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.d.ts.map +0 -1
  118. package/script/deps/jsr.io/@std/encoding/1.0.10/_common64.js +0 -119
  119. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  120. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  121. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -16
  122. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  123. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  124. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -3
  125. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts +0 -2
  126. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.d.ts.map +0 -1
  127. package/script/deps/jsr.io/@std/encoding/1.0.10/_validate_binary_like.js +0 -29
  128. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts +0 -61
  129. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.d.ts.map +0 -1
  130. package/script/deps/jsr.io/@std/encoding/1.0.10/ascii85.js +0 -156
  131. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts +0 -40
  132. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.d.ts.map +0 -1
  133. package/script/deps/jsr.io/@std/encoding/1.0.10/base32.js +0 -91
  134. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts +0 -40
  135. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.d.ts.map +0 -1
  136. package/script/deps/jsr.io/@std/encoding/1.0.10/base58.js +0 -135
  137. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts +0 -40
  138. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.d.ts.map +0 -1
  139. package/script/deps/jsr.io/@std/encoding/1.0.10/base64.js +0 -86
  140. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts +0 -40
  141. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.d.ts.map +0 -1
  142. package/script/deps/jsr.io/@std/encoding/1.0.10/base64url.js +0 -76
  143. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  144. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  145. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -91
  146. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts +0 -98
  147. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.d.ts.map +0 -1
  148. package/script/deps/jsr.io/@std/encoding/1.0.10/mod.js +0 -115
  149. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts +0 -120
  150. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.d.ts.map +0 -1
  151. package/script/deps/jsr.io/@std/encoding/1.0.10/varint.js +0 -211
package/script/cli.js CHANGED
@@ -42,6 +42,9 @@ const dntShim = __importStar(require("./_dnt.shims.js"));
42
42
  const unstable_spinner_js_1 = require("./deps/jsr.io/@std/cli/1.0.29/unstable_spinner.js");
43
43
  const mod_js_1 = require("./deps/jsr.io/@std/cli/1.0.29/mod.js");
44
44
  const file_js_1 = require("./src/file.js");
45
+ const translator_js_1 = require("./src/translator.js");
46
+ const diff_js_1 = require("./src/diff.js");
47
+ const config_js_1 = require("./src/config.js");
45
48
  const contants_js_1 = require("./src/contants.js");
46
49
  const utilites_js_1 = require("./src/utilites.js");
47
50
  const logger_js_1 = require("./src/logger.js");
@@ -50,11 +53,110 @@ const gemini_js_1 = __importDefault(require("./src/providers/gemini.js"));
50
53
  const openai_js_1 = __importDefault(require("./src/providers/openai.js"));
51
54
  const anthropic_js_1 = __importDefault(require("./src/providers/anthropic.js"));
52
55
  const spinner = new unstable_spinner_js_1.Spinner({ message: 'AI Thinks...', color: 'cyan' });
56
+ function createTranslator(args, options) {
57
+ switch (args.provider) {
58
+ case 'gemini':
59
+ return new gemini_js_1.default(args.key, args.model, options);
60
+ case 'openai':
61
+ return new openai_js_1.default(args.key, args.url, args.model, options);
62
+ case 'anthropic':
63
+ return new anthropic_js_1.default(args.key, args.url, args.model, options);
64
+ default:
65
+ throw new Error(`Unknown provider: ${args.provider}`);
66
+ }
67
+ }
68
+ function printBanner() {
69
+ logger_js_1.logger.box(`Glotto AI Translator v${deno_js_1.default.version}\n${contants_js_1.GITHUB_REPO_URL}`);
70
+ }
71
+ function printStats(args, perTarget) {
72
+ const totalInput = perTarget.reduce((sum, t) => sum + t.usage.inputTokens, 0);
73
+ const totalOutput = perTarget.reduce((sum, t) => sum + t.usage.outputTokens, 0);
74
+ const totalCalls = perTarget.reduce((sum, t) => sum + t.calls, 0);
75
+ const totalBytes = perTarget.reduce((sum, t) => sum + t.bytes, 0);
76
+ const totalTranslated = perTarget.reduce((sum, t) => sum + t.translatedCount, 0);
77
+ const lines = [];
78
+ lines.push(`Provider: ${args.provider}${args.model ? ` (${args.model})` : ''}`);
79
+ lines.push(`Targets: ${perTarget.length}`);
80
+ lines.push('');
81
+ for (const t of perTarget) {
82
+ const mode = t.incrementalApplied ? ' [incremental]' : '';
83
+ lines.push(`→ ${t.to} (${t.output})${mode}: ${t.translatedCount}/${t.fullCount} entries, ${t.batchCount} batch(es), ${(0, utilites_js_1.formatBytes)(t.bytes)}, ${t.calls} call(s)`);
84
+ lines.push(` tokens — in: ${t.usage.inputTokens}, out: ${t.usage.outputTokens}`);
85
+ }
86
+ lines.push('');
87
+ lines.push(`Total: ${totalTranslated} entries translated, ${totalCalls} call(s), ${(0, utilites_js_1.formatBytes)(totalBytes)}`);
88
+ lines.push(`Total tokens — in: ${totalInput}, out: ${totalOutput}, sum: ${totalInput + totalOutput}`);
89
+ logger_js_1.logger.box(lines.join('\n'));
90
+ }
91
+ async function translateForTarget(validatedArgs, fileContent, allLeaves, to, outputRel, translator, translateOptions, targetIndex, totalTargets) {
92
+ const outputPath = (0, file_js_1.resolvePath)(outputRel);
93
+ const targetLabel = `[Target ${targetIndex + 1}/${totalTargets}: ${to}]`;
94
+ logger_js_1.logger.info(`${targetLabel} → ${outputRel}`);
95
+ const translatableLeaves = allLeaves.filter((leaf) => leaf.translatable);
96
+ let leavesToTranslate = translatableLeaves;
97
+ let existingTarget = null;
98
+ let incrementalApplied = false;
99
+ if (validatedArgs.incremental) {
100
+ existingTarget = await (0, file_js_1.readJsonIfExists)(outputPath);
101
+ if (existingTarget !== null) {
102
+ leavesToTranslate = (0, diff_js_1.findMissingLeaves)(allLeaves, existingTarget);
103
+ incrementalApplied = true;
104
+ logger_js_1.logger.info(`${targetLabel} Incremental: ${leavesToTranslate.length}/${translatableLeaves.length} entries missing in existing target`);
105
+ }
106
+ else {
107
+ logger_js_1.logger.info(`${targetLabel} Incremental: target file not found, doing full translation`);
108
+ }
109
+ }
110
+ if (leavesToTranslate.length === 0) {
111
+ logger_js_1.logger.info(`${targetLabel} Nothing to translate, writing existing/source content`);
112
+ const content = existingTarget !== null ? existingTarget : fileContent;
113
+ await (0, file_js_1.writeOutput)(outputPath, JSON.stringify(content, null, 2));
114
+ return {
115
+ to,
116
+ output: outputRel,
117
+ fullCount: translatableLeaves.length,
118
+ translatedCount: 0,
119
+ batchCount: 0,
120
+ bytes: 0,
121
+ calls: 0,
122
+ usage: { inputTokens: 0, outputTokens: 0 },
123
+ incrementalApplied,
124
+ };
125
+ }
126
+ const batches = (0, translator_js_1.groupIntoBatches)(leavesToTranslate, validatedArgs.maxBatchBytes);
127
+ const totalBytes = batches.reduce((sum, b) => sum + b.byteSize, 0);
128
+ logger_js_1.logger.info(`${targetLabel} ${leavesToTranslate.length} translatable entries, ${(0, utilites_js_1.formatBytes)(totalBytes)}, split into ${batches.length} batch(es)`);
129
+ for (const batch of batches) {
130
+ logger_js_1.logger.info(` Batch ${batch.index + 1}: ${batch.leaves.length} entries, ${(0, utilites_js_1.formatBytes)(batch.byteSize)}`);
131
+ }
132
+ spinner.start();
133
+ const result = await (0, translator_js_1.runBatches)(batches, translator, validatedArgs.from, to, translateOptions);
134
+ spinner.stop();
135
+ let finalContent;
136
+ if (incrementalApplied && existingTarget !== null) {
137
+ finalContent = (0, diff_js_1.mergeTranslations)(existingTarget, allLeaves, result.translations);
138
+ }
139
+ else {
140
+ finalContent = (0, translator_js_1.reconstruct)(allLeaves, result.translations);
141
+ }
142
+ await (0, file_js_1.writeOutput)(outputPath, JSON.stringify(finalContent, null, 2));
143
+ return {
144
+ to,
145
+ output: outputRel,
146
+ fullCount: translatableLeaves.length,
147
+ translatedCount: result.translations.size,
148
+ batchCount: batches.length,
149
+ bytes: totalBytes,
150
+ calls: result.calls,
151
+ usage: result.usage,
152
+ incrementalApplied,
153
+ };
154
+ }
53
155
  async function main() {
54
156
  try {
55
157
  const args = (0, mod_js_1.parseArgs)(dntShim.Deno.args, {
56
- string: ['key', 'provider', 'model', 'input', 'output', 'from', 'to', 'url'],
57
- boolean: ['help', 'version'],
158
+ string: ['key', 'provider', 'model', 'input', 'output', 'from', 'to', 'url', 'max-batch-size', 'config'],
159
+ boolean: ['help', 'version', 'no-limit', 'no-timeout', 'stats', 'incremental'],
58
160
  alias: {
59
161
  provider: 'p',
60
162
  model: 'm',
@@ -66,75 +168,85 @@ async function main() {
66
168
  help: 'h',
67
169
  version: 'v',
68
170
  },
69
- default: { provider: contants_js_1.DEFAULT_PROVIDER },
70
171
  });
71
172
  const help = args.help || dntShim.Deno.args.length === 0;
72
173
  const version = args.version;
73
174
  if (version) {
74
- const VERSION = deno_js_1.default.version;
75
- logger_js_1.logger.info('Glotto version: ' + VERSION);
175
+ logger_js_1.logger.info('Glotto version: ' + deno_js_1.default.version);
76
176
  dntShim.Deno.exit(0);
77
177
  }
78
178
  if (help) {
179
+ printBanner();
79
180
  logger_js_1.logger.box(contants_js_1.HELP_TEXT);
80
181
  dntShim.Deno.exit(0);
81
182
  }
82
- const validatedArgs = (0, utilites_js_1.validateArgs)(args);
183
+ printBanner();
184
+ const config = await (0, config_js_1.loadConfig)(args.config);
185
+ const merged = (0, config_js_1.applyConfig)(args, config, dntShim.Deno.args);
186
+ if (!merged.provider) {
187
+ merged.provider = contants_js_1.DEFAULT_PROVIDER;
188
+ }
189
+ const validatedArgs = (0, utilites_js_1.validateArgs)(merged);
83
190
  const fileContent = await (0, file_js_1.getImportJson)(validatedArgs.input);
84
- const chunks = (0, file_js_1.splitJson)(fileContent);
85
- const totalBytes = chunks.reduce((sum, c) => sum + c.byteSize, 0);
86
- const totalKeys = chunks.reduce((sum, c) => sum + c.keyCount, 0);
87
- const outputPath = (0, file_js_1.resolvePath)(validatedArgs.output);
191
+ const allLeaves = (0, translator_js_1.extractLeaves)(fileContent);
192
+ const translatableLeaves = allLeaves.filter((leaf) => leaf.translatable);
88
193
  logger_js_1.logger.info('Provider: ', validatedArgs.provider);
89
194
  logger_js_1.logger.info('Input: ', validatedArgs.input);
90
- logger_js_1.logger.info('Output: ', validatedArgs.output);
195
+ logger_js_1.logger.info('Targets: ', validatedArgs.to.map((to, i) => `${to} → ${validatedArgs.output[i]}`).join(', '));
91
196
  logger_js_1.logger.info('From: ', validatedArgs.from);
92
- logger_js_1.logger.info('To: ', validatedArgs.to);
93
197
  if (validatedArgs.model) {
94
198
  logger_js_1.logger.info('Model: ', validatedArgs.model);
95
199
  }
96
200
  if (validatedArgs.url) {
97
201
  logger_js_1.logger.info('URL: ', validatedArgs.url);
98
202
  }
99
- logger_js_1.logger.info(`Total: ${totalKeys} keys, ${(0, utilites_js_1.formatBytes)(totalBytes)}, split into ${chunks.length} chunk(s)`);
100
- for (const chunk of chunks) {
101
- logger_js_1.logger.info(` Chunk ${chunk.index + 1}: ${chunk.keyCount} keys, ${(0, utilites_js_1.formatBytes)(chunk.byteSize)}`);
203
+ if (validatedArgs.noLimit) {
204
+ logger_js_1.logger.info('Rate limit protection: disabled (--no-limit)');
102
205
  }
103
- spinner.start();
104
- let result = '';
105
- switch (validatedArgs.provider) {
106
- case 'gemini': {
107
- const gemini = new gemini_js_1.default(validatedArgs.key, chunks, validatedArgs.from, validatedArgs.to, validatedArgs.model);
108
- result = await gemini.translate();
109
- break;
110
- }
111
- case 'openai': {
112
- const openai = new openai_js_1.default(validatedArgs.key, chunks, validatedArgs.from, validatedArgs.to, validatedArgs.url, validatedArgs.model);
113
- result = await openai.translate();
114
- break;
115
- }
116
- case 'anthropic': {
117
- const anthropic = new anthropic_js_1.default(validatedArgs.key, chunks, validatedArgs.from, validatedArgs.to, validatedArgs.url, validatedArgs.model);
118
- result = await anthropic.translate();
119
- break;
120
- }
121
- default: {
122
- logger_js_1.logger.warn('Provider not found');
123
- break;
206
+ if (validatedArgs.noTimeout) {
207
+ logger_js_1.logger.info('Request timeout: disabled (--no-timeout)');
208
+ }
209
+ if (validatedArgs.incremental) {
210
+ logger_js_1.logger.info('Incremental mode: enabled (--incremental)');
211
+ }
212
+ if (validatedArgs.stats) {
213
+ logger_js_1.logger.info('Stats: enabled (--stats)');
214
+ }
215
+ if (validatedArgs.maxBatchBytes !== contants_js_1.DEFAULT_MAX_BATCH_BYTES) {
216
+ logger_js_1.logger.info(`Max batch size: ${(0, utilites_js_1.formatBytes)(validatedArgs.maxBatchBytes)}`);
217
+ }
218
+ logger_js_1.logger.info(`Source: ${translatableLeaves.length} translatable entries (of ${allLeaves.length} leaves)`);
219
+ if (translatableLeaves.length === 0 && !validatedArgs.incremental) {
220
+ logger_js_1.logger.warn('No translatable entries found, copying input to output(s)');
221
+ for (const outputRel of validatedArgs.output) {
222
+ await (0, file_js_1.writeOutput)((0, file_js_1.resolvePath)(outputRel), JSON.stringify(fileContent, null, 2));
124
223
  }
224
+ logger_js_1.logger.success('Translation completed');
225
+ logger_js_1.logger.info(`★ Glotto faydalı olduysa GitHub'da yıldızlamayı unutma: ${contants_js_1.GITHUB_REPO_URL}`);
226
+ dntShim.Deno.exit(0);
227
+ }
228
+ const translateOptions = {
229
+ noLimit: validatedArgs.noLimit,
230
+ noTimeout: validatedArgs.noTimeout,
231
+ };
232
+ const translator = createTranslator(validatedArgs, translateOptions);
233
+ const perTarget = [];
234
+ for (let i = 0; i < validatedArgs.to.length; i++) {
235
+ const stat = await translateForTarget(validatedArgs, fileContent, allLeaves, validatedArgs.to[i], validatedArgs.output[i], translator, translateOptions, i, validatedArgs.to.length);
236
+ perTarget.push(stat);
125
237
  }
126
- await (0, file_js_1.writeOutput)(outputPath, result);
127
238
  spinner.stop();
128
239
  logger_js_1.logger.success('Translation completed');
240
+ if (validatedArgs.stats) {
241
+ printStats(validatedArgs, perTarget);
242
+ }
243
+ logger_js_1.logger.info(`★ Glotto faydalı olduysa GitHub'da yıldızlamayı unutma: ${contants_js_1.GITHUB_REPO_URL}`);
244
+ dntShim.Deno.exit(0);
129
245
  }
130
246
  catch (error) {
131
247
  spinner.stop();
132
248
  logger_js_1.logger.error(error);
133
249
  dntShim.Deno.exit(1);
134
250
  }
135
- finally {
136
- spinner.stop();
137
- dntShim.Deno.exit(0);
138
- }
139
251
  }
140
252
  main();
package/script/deno.d.ts CHANGED
@@ -11,19 +11,23 @@ declare namespace _default {
11
11
  publish: string;
12
12
  "publish:npm": string;
13
13
  check: string;
14
+ test: string;
14
15
  };
15
16
  namespace fmt {
16
17
  let semiColons: boolean;
17
18
  let singleQuote: boolean;
18
19
  let lineWidth: number;
19
20
  }
21
+ namespace publish {
22
+ let exclude: string[];
23
+ }
20
24
  let imports: {
21
25
  "@anthropic-ai/sdk": string;
22
26
  "@deno/dnt": string;
23
27
  "@google/genai": string;
24
28
  "@openai/openai": string;
29
+ "@std/assert": string;
25
30
  "@std/cli": string;
26
- "@std/encoding": string;
27
31
  "@std/path": string;
28
32
  consola: string;
29
33
  };
package/script/deno.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = {
4
4
  "name": "@ibodev/glotto",
5
- "version": "2.9.0",
5
+ "version": "3.1.0",
6
6
  "exports": "./cli.ts",
7
7
  "lock": false,
8
8
  "nodeModulesDir": "auto",
@@ -12,22 +12,33 @@ exports.default = {
12
12
  "build:npm": "deno run -A scripts/build_npm.ts",
13
13
  "publish": "deno publish",
14
14
  "publish:npm": "cd ./npm && npm publish",
15
- "check": "deno check **/*.ts"
15
+ "check": "deno check **/*.ts",
16
+ "test": "deno test -A --no-check tests/"
16
17
  },
17
18
  "fmt": {
18
19
  "semiColons": true,
19
20
  "singleQuote": true,
20
21
  "lineWidth": 160
21
22
  },
23
+ "publish": {
24
+ "exclude": [
25
+ "tests/",
26
+ "scripts/",
27
+ "npm/",
28
+ "assets/",
29
+ "glotto.exe",
30
+ "CLAUDE.md"
31
+ ]
32
+ },
22
33
  "imports": {
23
- "@anthropic-ai/sdk": "npm:@anthropic-ai/sdk@^0.95.0",
34
+ "@anthropic-ai/sdk": "npm:@anthropic-ai/sdk@^0.95.1",
24
35
  "@deno/dnt": "jsr:@deno/dnt@^0.42.3",
25
- "@google/genai": "npm:@google/genai@^1.52.0",
26
- "@openai/openai": "npm:openai@^6.36.0",
36
+ "@google/genai": "npm:@google/genai@^2.0.0",
37
+ "@openai/openai": "npm:openai@^6.37.0",
38
+ "@std/assert": "jsr:@std/assert@^1.0.19",
27
39
  "@std/cli": "jsr:@std/cli@^1.0.29",
28
- "@std/encoding": "jsr:@std/encoding@^1.0.10",
29
40
  "@std/path": "jsr:@std/path@^1.1.4",
30
41
  "consola": "npm:consola@^3.4.2"
31
42
  },
32
- "allowScripts": ["npm:@google/genai@1.52.0", "npm:protobufjs@7.5.6"]
43
+ "allowScripts": ["npm:@google/genai@1.52.0", "npm:@google/genai@2.0.0", "npm:protobufjs@7.5.6"]
33
44
  };
@@ -0,0 +1,4 @@
1
+ import type { GlottoConfig, TranslateArgs } from './types.js';
2
+ export declare function loadConfig(explicitPath?: string): Promise<GlottoConfig>;
3
+ export declare function applyConfig(cli: TranslateArgs, config: GlottoConfig, rawArgs: string[]): TranslateArgs;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuB9D,wBAAsB,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAc7E;AAkBD,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,CA0CtG"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ exports.applyConfig = applyConfig;
38
+ const dntShim = __importStar(require("../_dnt.shims.js"));
39
+ const mod_js_1 = require("../deps/jsr.io/@std/path/1.1.4/mod.js");
40
+ const contants_js_1 = require("./contants.js");
41
+ async function readConfigFile(path) {
42
+ let raw;
43
+ try {
44
+ raw = await dntShim.Deno.readTextFile(path);
45
+ }
46
+ catch (error) {
47
+ if (error instanceof dntShim.Deno.errors.NotFound) {
48
+ return null;
49
+ }
50
+ throw error;
51
+ }
52
+ if (raw.trim() === '') {
53
+ return {};
54
+ }
55
+ const parsed = JSON.parse(raw);
56
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
57
+ throw new Error(`Config file must contain a JSON object: ${path}`);
58
+ }
59
+ return parsed;
60
+ }
61
+ async function loadConfig(explicitPath) {
62
+ if (explicitPath) {
63
+ const config = await readConfigFile(explicitPath);
64
+ if (config === null) {
65
+ throw new Error(`Config file not found: ${explicitPath}`);
66
+ }
67
+ return config;
68
+ }
69
+ const defaultPath = (0, mod_js_1.join)(dntShim.Deno.cwd(), contants_js_1.CONFIG_FILE_NAME);
70
+ const config = await readConfigFile(defaultPath);
71
+ if (config === null) {
72
+ return {};
73
+ }
74
+ return config;
75
+ }
76
+ function joinList(value) {
77
+ if (value === undefined) {
78
+ return undefined;
79
+ }
80
+ if (Array.isArray(value)) {
81
+ return value.join(',');
82
+ }
83
+ return value;
84
+ }
85
+ function rawArgsHas(rawArgs, flag) {
86
+ const long = `--${flag}`;
87
+ const longEq = `--${flag}=`;
88
+ return rawArgs.some((a) => a === long || a.startsWith(longEq));
89
+ }
90
+ function applyConfig(cli, config, rawArgs) {
91
+ const merged = { ...cli };
92
+ if (merged.key === undefined && config.key !== undefined) {
93
+ merged.key = config.key;
94
+ }
95
+ if (merged.provider === undefined && config.provider !== undefined) {
96
+ merged.provider = config.provider;
97
+ }
98
+ if (merged.model === undefined && config.model !== undefined) {
99
+ merged.model = config.model;
100
+ }
101
+ if (merged.input === undefined && config.input !== undefined) {
102
+ merged.input = config.input;
103
+ }
104
+ if (merged.output === undefined && config.output !== undefined) {
105
+ merged.output = joinList(config.output);
106
+ }
107
+ if (merged.from === undefined && config.from !== undefined) {
108
+ merged.from = config.from;
109
+ }
110
+ if (merged.to === undefined && config.to !== undefined) {
111
+ merged.to = joinList(config.to);
112
+ }
113
+ if (merged.url === undefined && config.url !== undefined) {
114
+ merged.url = config.url;
115
+ }
116
+ if (merged['max-batch-size'] === undefined && config.maxBatchSize !== undefined) {
117
+ merged['max-batch-size'] = String(config.maxBatchSize);
118
+ }
119
+ if (!rawArgsHas(rawArgs, 'no-limit') && config.noLimit !== undefined) {
120
+ merged['no-limit'] = config.noLimit;
121
+ }
122
+ if (!rawArgsHas(rawArgs, 'no-timeout') && config.noTimeout !== undefined) {
123
+ merged['no-timeout'] = config.noTimeout;
124
+ }
125
+ if (!rawArgsHas(rawArgs, 'stats') && config.stats !== undefined) {
126
+ merged.stats = config.stats;
127
+ }
128
+ if (!rawArgsHas(rawArgs, 'incremental') && config.incremental !== undefined) {
129
+ merged.incremental = config.incremental;
130
+ }
131
+ return merged;
132
+ }
@@ -1,9 +1,13 @@
1
1
  import type { Provider } from './types.js';
2
2
  export declare const DEFAULT_PROVIDER: Provider;
3
3
  export declare const DEFAULT_MODELS: Record<Provider, string>;
4
- export declare const DEFAULT_MAX_CHUNK_BYTES: 30000;
4
+ export declare const DEFAULT_MAX_BATCH_BYTES: 12000;
5
5
  export declare const MAX_RETRIES: 3;
6
6
  export declare const BASE_RETRY_DELAY_MS: 2000;
7
- export declare const INTER_CHUNK_DELAY_MS: 1500;
7
+ export declare const INTER_BATCH_DELAY_MS: 1500;
8
+ export declare const INTER_LEAF_DELAY_MS: 200;
9
+ export declare const PER_LEAF_FALLBACK_RATIO: 0.5;
10
+ export declare const GITHUB_REPO_URL: "https://github.com/ibodev1/glotto";
11
+ export declare const CONFIG_FILE_NAME: "glotto.config.json";
8
12
  export declare const HELP_TEXT: string;
9
13
  //# sourceMappingURL=contants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contants.d.ts","sourceRoot":"","sources":["../../src/src/contants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,gBAAgB,EAAE,QAAmB,CAAC;AAEnD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAInD,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAG,KAAe,CAAC;AAEvD,eAAO,MAAM,WAAW,EAAG,CAAU,CAAC;AAEtC,eAAO,MAAM,mBAAmB,EAAG,IAAc,CAAC;AAElD,eAAO,MAAM,oBAAoB,EAAG,IAAc,CAAC;AAEnD,eAAO,MAAM,SAAS,QAsBrB,CAAC"}
1
+ {"version":3,"file":"contants.d.ts","sourceRoot":"","sources":["../../src/src/contants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,gBAAgB,EAAE,QAAmB,CAAC;AAEnD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAInD,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAG,KAAe,CAAC;AAEvD,eAAO,MAAM,WAAW,EAAG,CAAU,CAAC;AAEtC,eAAO,MAAM,mBAAmB,EAAG,IAAc,CAAC;AAElD,eAAO,MAAM,oBAAoB,EAAG,IAAc,CAAC;AAEnD,eAAO,MAAM,mBAAmB,EAAG,GAAY,CAAC;AAEhD,eAAO,MAAM,uBAAuB,EAAG,GAAY,CAAC;AAEpD,eAAO,MAAM,eAAe,EAAG,mCAA4C,CAAC;AAE5E,eAAO,MAAM,gBAAgB,EAAG,oBAA6B,CAAC;AAE9D,eAAO,MAAM,SAAS,QAqCrB,CAAC"}
@@ -1,36 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HELP_TEXT = exports.INTER_CHUNK_DELAY_MS = exports.BASE_RETRY_DELAY_MS = exports.MAX_RETRIES = exports.DEFAULT_MAX_CHUNK_BYTES = exports.DEFAULT_MODELS = exports.DEFAULT_PROVIDER = void 0;
4
- exports.DEFAULT_PROVIDER = 'gemini';
3
+ exports.HELP_TEXT = exports.CONFIG_FILE_NAME = exports.GITHUB_REPO_URL = exports.PER_LEAF_FALLBACK_RATIO = exports.INTER_LEAF_DELAY_MS = exports.INTER_BATCH_DELAY_MS = exports.BASE_RETRY_DELAY_MS = exports.MAX_RETRIES = exports.DEFAULT_MAX_BATCH_BYTES = exports.DEFAULT_MODELS = exports.DEFAULT_PROVIDER = void 0;
4
+ exports.DEFAULT_PROVIDER = 'openai';
5
5
  exports.DEFAULT_MODELS = {
6
6
  gemini: 'gemini-2.5-flash',
7
7
  openai: 'gpt-4.1-mini',
8
8
  anthropic: 'claude-3-5-haiku-latest',
9
9
  };
10
- exports.DEFAULT_MAX_CHUNK_BYTES = 30_000;
10
+ exports.DEFAULT_MAX_BATCH_BYTES = 12_000;
11
11
  exports.MAX_RETRIES = 3;
12
12
  exports.BASE_RETRY_DELAY_MS = 2_000;
13
- exports.INTER_CHUNK_DELAY_MS = 1_500;
13
+ exports.INTER_BATCH_DELAY_MS = 1_500;
14
+ exports.INTER_LEAF_DELAY_MS = 200;
15
+ exports.PER_LEAF_FALLBACK_RATIO = 0.5;
16
+ exports.GITHUB_REPO_URL = 'https://github.com/ibodev1/glotto';
17
+ exports.CONFIG_FILE_NAME = 'glotto.config.json';
14
18
  exports.HELP_TEXT = `
15
19
  Glotto AI Translator
16
20
  -------------------
17
21
  A tool for translating i18n JSON files using AI services.
18
22
 
23
+ Glotto walks the input JSON, extracts every string leaf with its path, sends them to the
24
+ chosen provider as plain-text batches (using ≪id≫value≪/id≫ tagged entries), and
25
+ reconstructs the JSON from the responses. JSON structure, keys, variables and HTML tags
26
+ are preserved by the tool itself — the model only sees and produces text.
27
+
19
28
  Options:
20
- --key API key for the AI service (required)
21
- -p, --provider AI translation provider to use (default: ${exports.DEFAULT_PROVIDER})
22
- -m, --model Model name for the selected provider (optional)
23
- -i, --input Path to source JSON file (required)
24
- -o, --output Path to target JSON file (required)
25
- -f, --from Source language (required)
26
- -t, --to Target language (required)
27
- --url Custom base URL for OpenAI/Anthropic (optional)
28
- -h, --help Display this help message
29
- -v, --version Display version
29
+ --key API key for the AI service (required)
30
+ -p, --provider AI translation provider to use (default: ${exports.DEFAULT_PROVIDER})
31
+ -m, --model Model name for the selected provider (optional)
32
+ -i, --input Path to source JSON file (required)
33
+ -o, --output Target JSON file path. Comma-separated for multi-target (required)
34
+ -f, --from Source language (required)
35
+ -t, --to Target language. Comma-separated for multi-target (required)
36
+ --url Custom base URL for OpenAI/Anthropic (optional)
37
+ --config Path to a glotto.config.json (default: ./glotto.config.json if present)
38
+ --stats Print AI usage stats (input/output tokens, calls) at the end
39
+ --incremental Translate only missing/empty keys when the target file already exists
40
+ --no-limit Disable rate limit delay between batches
41
+ --no-timeout Disable request timeout (wait indefinitely for AI response)
42
+ --max-batch-size Maximum source size per batch, in KB (default: ${exports.DEFAULT_MAX_BATCH_BYTES / 1024} KB)
43
+ -h, --help Display this help message
44
+ -v, --version Display version
30
45
 
31
46
  Examples:
32
47
  glotto --key {{key}} --input=en.json --output=tr.json --from=english --to=turkish
33
48
  glotto --key {{key}} -i en.json -o tr.json -f english -t turkish -p gemini
34
- glotto --key {{key}} -i en.json -o tr.json -f english -t turkish -p openai
35
- glotto --key {{key}} -i en.json -o tr.json -f english -t turkish -p anthropic
49
+ glotto --key {{key}} -i en.json -f english -t "turkish,french" -o "tr.json,fr.json"
50
+ glotto --key {{key}} -i en.json -o tr.json -f english -t turkish --incremental
51
+ glotto --key {{key}} -i en.json -o tr.json -f english -t turkish --stats
52
+ glotto --key {{key}} --config ./glotto.config.json
53
+ glotto --key {{key}} -i en.json -o tr.json -f english -t turkish --no-limit --no-timeout
54
+ glotto --key {{key}} -i en.json -o tr.json -f english -t turkish --max-batch-size 8
36
55
  `;
@@ -0,0 +1,4 @@
1
+ import type { JsonValue, Leaf } from './types.js';
2
+ export declare function findMissingLeaves(sourceLeaves: Leaf[], existingTarget: JsonValue): Leaf[];
3
+ export declare function mergeTranslations(existingTarget: JsonValue, sourceLeaves: Leaf[], translations: Map<number, string>): JsonValue;
4
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAQ,MAAM,YAAY,CAAC;AAyBxD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,SAAS,GAAG,IAAI,EAAE,CAYzF;AASD,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,SAAS,EACzB,YAAY,EAAE,IAAI,EAAE,EACpB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,SAAS,CAYX"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findMissingLeaves = findMissingLeaves;
4
+ exports.mergeTranslations = mergeTranslations;
5
+ const translator_js_1 = require("./translator.js");
6
+ function getPath(root, path) {
7
+ let node = root;
8
+ for (const key of path) {
9
+ if (node === null || typeof node !== 'object') {
10
+ return undefined;
11
+ }
12
+ const container = node;
13
+ if (!(key in container)) {
14
+ return undefined;
15
+ }
16
+ node = container[key];
17
+ }
18
+ return node;
19
+ }
20
+ function isPresentTranslation(value) {
21
+ if (typeof value !== 'string') {
22
+ return false;
23
+ }
24
+ return value.trim().length > 0;
25
+ }
26
+ function findMissingLeaves(sourceLeaves, existingTarget) {
27
+ const missing = [];
28
+ for (const leaf of sourceLeaves) {
29
+ if (!leaf.translatable) {
30
+ continue;
31
+ }
32
+ const existingValue = getPath(existingTarget, leaf.path);
33
+ if (!isPresentTranslation(existingValue)) {
34
+ missing.push(leaf);
35
+ }
36
+ }
37
+ return missing;
38
+ }
39
+ function deepClone(value) {
40
+ if (value === null || typeof value !== 'object') {
41
+ return value;
42
+ }
43
+ return JSON.parse(JSON.stringify(value));
44
+ }
45
+ function mergeTranslations(existingTarget, sourceLeaves, translations) {
46
+ const clone = deepClone(existingTarget);
47
+ for (const leaf of sourceLeaves) {
48
+ if (!translations.has(leaf.id)) {
49
+ continue;
50
+ }
51
+ if (leaf.path.length === 0) {
52
+ return translations.get(leaf.id);
53
+ }
54
+ (0, translator_js_1.setPath)(clone, leaf.path, translations.get(leaf.id));
55
+ }
56
+ return clone;
57
+ }
@@ -1,10 +1,6 @@
1
- import type { ChunkInfo, JsonObject } from './types.js';
2
- export declare const resolvePath: (...paths: string[]) => string;
3
- export declare const getImportJson: <T = JsonObject>(input: string) => Promise<T>;
4
- export declare const writeOutput: (outputPath: string, content: string) => Promise<void>;
5
- export declare const existsFile: (path: string) => Promise<boolean>;
6
- export declare const ensureDirectoryExists: (directory: string) => Promise<void>;
7
- export declare const splitJson: (data: JsonObject, maxChunkBytes?: number) => ChunkInfo[];
8
- export declare const mergeInputs: (inputs: JsonObject[]) => JsonObject;
9
- export declare const writeTemp: (targetLanguage: string, tempJsonFileName: string, content: string) => Promise<void>;
1
+ import type { JsonValue } from './types.js';
2
+ export declare function resolvePath(...paths: string[]): string;
3
+ export declare function getImportJson<T = JsonValue>(input: string): Promise<T>;
4
+ export declare function writeOutput(outputPath: string, content: string): Promise<void>;
5
+ export declare function readJsonIfExists<T = JsonValue>(path: string): Promise<T | null>;
10
6
  //# sourceMappingURL=file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/src/file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxD,eAAO,MAAM,WAAW,GAAI,GAAG,OAAO,MAAM,EAAE,WAE7C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,CAAC,GAAG,UAAU,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,CAS5E,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,YAAY,MAAM,EAAE,SAAS,MAAM,kBAEpE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,qBAW5C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAK3E,CAAC;AAeF,eAAO,MAAM,SAAS,GAAI,MAAM,UAAU,EAAE,gBAAe,MAAe,KAAG,SAAS,EA4DrF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,QAAQ,UAAU,EAAE,KAAG,UAElD,CAAC;AAkBF,eAAO,MAAM,SAAS,GAAU,gBAAgB,MAAM,EAAE,kBAAkB,MAAM,EAAE,SAAS,MAAM,kBAKhG,CAAC"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/src/file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED,wBAAsB,aAAa,CAAC,CAAC,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAO5E;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpF;AAED,wBAAsB,gBAAgB,CAAC,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAcrF"}