experimental-ciao-core 1.1.10 → 1.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +88 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +89 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -11
package/dist/index.cjs
CHANGED
|
@@ -29,9 +29,9 @@ let node_fs = require("node:fs");
|
|
|
29
29
|
node_fs = __toESM(node_fs);
|
|
30
30
|
let node_path = require("node:path");
|
|
31
31
|
node_path = __toESM(node_path);
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
let
|
|
32
|
+
let node_fs_promises = require("node:fs/promises");
|
|
33
|
+
node_fs_promises = __toESM(node_fs_promises);
|
|
34
|
+
let experimental_ciao_oxc = require("experimental-ciao-oxc");
|
|
35
35
|
let glob = require("glob");
|
|
36
36
|
|
|
37
37
|
//#region src/api/client.ts
|
|
@@ -39,10 +39,36 @@ var CiaoApiClient = class {
|
|
|
39
39
|
baseUrl;
|
|
40
40
|
apiKey;
|
|
41
41
|
timeout;
|
|
42
|
+
maxRetries;
|
|
42
43
|
constructor(options) {
|
|
44
|
+
if (!options.baseUrl || typeof options.baseUrl !== "string") throw new Error("CiaoApiClient: baseUrl is required and must be a string");
|
|
45
|
+
try {
|
|
46
|
+
new URL(options.baseUrl);
|
|
47
|
+
} catch {
|
|
48
|
+
throw new Error("CiaoApiClient: baseUrl must be a valid URL");
|
|
49
|
+
}
|
|
50
|
+
if (!options.apiKey || typeof options.apiKey !== "string" || options.apiKey.trim() === "") throw new Error("CiaoApiClient: apiKey is required and must be a non-empty string");
|
|
51
|
+
if (options.timeout !== void 0) {
|
|
52
|
+
if (typeof options.timeout !== "number" || options.timeout < 0 || options.timeout > 3e5) throw new Error("CiaoApiClient: timeout must be a number between 0 and 300000ms");
|
|
53
|
+
}
|
|
43
54
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
44
55
|
this.apiKey = options.apiKey;
|
|
45
56
|
this.timeout = options.timeout ?? 3e4;
|
|
57
|
+
this.maxRetries = options.maxRetries ?? 3;
|
|
58
|
+
}
|
|
59
|
+
sleep(ms) {
|
|
60
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
|
+
}
|
|
62
|
+
isRetryableError(error) {
|
|
63
|
+
if (error instanceof CiaoApiError) return [
|
|
64
|
+
0,
|
|
65
|
+
429,
|
|
66
|
+
500,
|
|
67
|
+
502,
|
|
68
|
+
503,
|
|
69
|
+
504
|
|
70
|
+
].includes(error.statusCode);
|
|
71
|
+
return error instanceof Error && (error.name === "AbortError" || error.message.includes("network"));
|
|
46
72
|
}
|
|
47
73
|
async request(method, path, body) {
|
|
48
74
|
const url = `${this.baseUrl}${path}`;
|
|
@@ -82,11 +108,29 @@ var CiaoApiClient = class {
|
|
|
82
108
|
throw new CiaoApiError("Unknown error", "UNKNOWN", 0);
|
|
83
109
|
}
|
|
84
110
|
}
|
|
111
|
+
async requestWithRetry(method, path, body) {
|
|
112
|
+
if (this.maxRetries === 0) return this.request(method, path, body);
|
|
113
|
+
const delays = [
|
|
114
|
+
1e3,
|
|
115
|
+
2e3,
|
|
116
|
+
4e3
|
|
117
|
+
];
|
|
118
|
+
let lastError;
|
|
119
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) try {
|
|
120
|
+
return await this.request(method, path, body);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
lastError = error;
|
|
123
|
+
if (!this.isRetryableError(error) || attempt === this.maxRetries) throw error;
|
|
124
|
+
const delay = delays[attempt] ?? delays[delays.length - 1];
|
|
125
|
+
await this.sleep(delay);
|
|
126
|
+
}
|
|
127
|
+
throw lastError;
|
|
128
|
+
}
|
|
85
129
|
async submitBuildSchema(buildSchema) {
|
|
86
|
-
return this.
|
|
130
|
+
return this.requestWithRetry("POST", "/api/translation/translate-strings", { buildSchema });
|
|
87
131
|
}
|
|
88
132
|
async getJobStatus(jobId) {
|
|
89
|
-
return this.
|
|
133
|
+
return this.requestWithRetry("GET", `/api/translation/job/${jobId}`);
|
|
90
134
|
}
|
|
91
135
|
};
|
|
92
136
|
var CiaoApiError = class extends Error {
|
|
@@ -112,22 +156,33 @@ async function pollJobUntilComplete(client, jobId, options = {}) {
|
|
|
112
156
|
...DEFAULT_OPTIONS,
|
|
113
157
|
...options
|
|
114
158
|
};
|
|
115
|
-
const { onProgress } = options;
|
|
159
|
+
const { onProgress, signal } = options;
|
|
116
160
|
let currentInterval = initialInterval;
|
|
117
161
|
let attempts = 0;
|
|
118
162
|
while (attempts < maxAttempts) {
|
|
163
|
+
if (signal?.aborted) throw new Error("Polling cancelled");
|
|
119
164
|
const status = await client.getJobStatus(jobId);
|
|
120
165
|
if (onProgress) onProgress(status);
|
|
121
166
|
if (status.status === "completed") return status;
|
|
122
167
|
if (status.status === "failed") throw new Error(status.error ?? "Job failed with unknown error");
|
|
123
|
-
await sleep(currentInterval);
|
|
168
|
+
await sleep(currentInterval, signal);
|
|
124
169
|
currentInterval = Math.min(currentInterval * backoffMultiplier, maxInterval);
|
|
125
170
|
attempts++;
|
|
126
171
|
}
|
|
127
172
|
throw new Error(`Job polling timed out after ${maxAttempts} attempts`);
|
|
128
173
|
}
|
|
129
|
-
function sleep(ms) {
|
|
130
|
-
return new Promise((resolve) =>
|
|
174
|
+
function sleep(ms, signal) {
|
|
175
|
+
return new Promise((resolve, reject) => {
|
|
176
|
+
if (signal?.aborted) {
|
|
177
|
+
reject(/* @__PURE__ */ new Error("Polling cancelled"));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const timeoutId = setTimeout(resolve, ms);
|
|
181
|
+
signal?.addEventListener("abort", () => {
|
|
182
|
+
clearTimeout(timeoutId);
|
|
183
|
+
reject(/* @__PURE__ */ new Error("Polling cancelled"));
|
|
184
|
+
}, { once: true });
|
|
185
|
+
});
|
|
131
186
|
}
|
|
132
187
|
|
|
133
188
|
//#endregion
|
|
@@ -147,8 +202,7 @@ const DEFAULT_CONFIG = {
|
|
|
147
202
|
"**/dist/**",
|
|
148
203
|
"**/.next/**"
|
|
149
204
|
],
|
|
150
|
-
outputDir: "__generated__"
|
|
151
|
-
serverUrl: "https://server.ciao-tools.com"
|
|
205
|
+
outputDir: "__generated__"
|
|
152
206
|
};
|
|
153
207
|
const CONFIG_FILE_NAMES = [
|
|
154
208
|
"ciao.config.ts",
|
|
@@ -170,7 +224,7 @@ async function loadConfig(options = {}) {
|
|
|
170
224
|
}
|
|
171
225
|
if (!configPath) throw new ConfigNotFoundError(`No ciao.config.ts found. Run 'ciao init' to create one.`);
|
|
172
226
|
const absolutePath = node_path.isAbsolute(configPath) ? configPath : node_path.join(cwd, configPath);
|
|
173
|
-
if (!node_fs.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${absolutePath}`);
|
|
227
|
+
if (!node_fs.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${node_path.relative(cwd, absolutePath) || absolutePath}`);
|
|
174
228
|
const config = await importConfig(absolutePath);
|
|
175
229
|
const useTypeScript = absolutePath.endsWith(".ts");
|
|
176
230
|
return {
|
|
@@ -180,6 +234,7 @@ async function loadConfig(options = {}) {
|
|
|
180
234
|
};
|
|
181
235
|
}
|
|
182
236
|
async function importConfig(configPath) {
|
|
237
|
+
const relativePath = node_path.relative(process.cwd(), configPath) || configPath;
|
|
183
238
|
try {
|
|
184
239
|
const module$1 = await (configPath.startsWith("file://") ? import(configPath) : import(`file://${configPath}`));
|
|
185
240
|
const config = module$1.default ?? module$1;
|
|
@@ -187,8 +242,8 @@ async function importConfig(configPath) {
|
|
|
187
242
|
return config;
|
|
188
243
|
} catch (error) {
|
|
189
244
|
if (error instanceof ConfigValidationError) throw error;
|
|
190
|
-
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${
|
|
191
|
-
throw new ConfigValidationError(`Failed to load config file: ${
|
|
245
|
+
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${relativePath}): ${error.message}`);
|
|
246
|
+
throw new ConfigValidationError(`Failed to load config file: ${relativePath}`);
|
|
192
247
|
}
|
|
193
248
|
}
|
|
194
249
|
function resolveConfig(config, cwd) {
|
|
@@ -197,11 +252,9 @@ function resolveConfig(config, cwd) {
|
|
|
197
252
|
const resolvedOutputDir = node_path.isAbsolute(outputDir) ? outputDir : node_path.join(cwd, outputDir);
|
|
198
253
|
return {
|
|
199
254
|
projectId: config.projectId,
|
|
200
|
-
styleId: config.styleId,
|
|
201
255
|
include: config.include ?? DEFAULT_CONFIG.include,
|
|
202
256
|
exclude: config.exclude ?? DEFAULT_CONFIG.exclude,
|
|
203
|
-
outputDir: resolvedOutputDir
|
|
204
|
-
serverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl
|
|
257
|
+
outputDir: resolvedOutputDir
|
|
205
258
|
};
|
|
206
259
|
}
|
|
207
260
|
var ConfigNotFoundError = class extends Error {
|
|
@@ -227,28 +280,28 @@ function defineCiaoConfig(config) {
|
|
|
227
280
|
//#region src/manifest/generator.ts
|
|
228
281
|
async function generateManifestFile(options) {
|
|
229
282
|
const { outputDir, data, useTypeScript = true } = options;
|
|
230
|
-
|
|
283
|
+
await node_fs_promises.mkdir(outputDir, { recursive: true });
|
|
231
284
|
const extension = useTypeScript ? "ts" : "js";
|
|
232
285
|
const manifestPath = node_path.join(outputDir, `ciao-manifest.${extension}`);
|
|
233
286
|
const content = useTypeScript ? generateTypeScriptManifestContent(data) : generateJavaScriptManifestContent(data);
|
|
234
|
-
|
|
287
|
+
await node_fs_promises.writeFile(manifestPath, content, "utf-8");
|
|
235
288
|
return manifestPath;
|
|
236
289
|
}
|
|
237
290
|
function generateTypeScriptManifestContent(data) {
|
|
238
|
-
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t
|
|
239
|
-
const languagesArray = data.languages.map((l) =>
|
|
291
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`).join(",\n");
|
|
292
|
+
const languagesArray = data.languages.map((l) => JSON.stringify(l)).join(", ");
|
|
240
293
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
241
294
|
// Generated at: ${data.generatedAt}
|
|
242
295
|
|
|
243
296
|
export const ciaoManifest = {
|
|
244
|
-
version:
|
|
245
|
-
projectId:
|
|
246
|
-
sourceLanguage:
|
|
297
|
+
version: ${JSON.stringify(data.version)},
|
|
298
|
+
projectId: ${JSON.stringify(data.projectId)},
|
|
299
|
+
sourceLanguage: ${JSON.stringify(data.sourceLanguage)},
|
|
247
300
|
languages: [${languagesArray}] as const,
|
|
248
301
|
cdnUrls: {
|
|
249
302
|
${cdnUrlsEntries}
|
|
250
303
|
} as const,
|
|
251
|
-
generatedAt:
|
|
304
|
+
generatedAt: ${JSON.stringify(data.generatedAt)},
|
|
252
305
|
} as const;
|
|
253
306
|
|
|
254
307
|
export type CiaoLanguage = (typeof ciaoManifest.languages)[number];
|
|
@@ -257,21 +310,21 @@ export type CiaoManifest = typeof ciaoManifest;
|
|
|
257
310
|
`;
|
|
258
311
|
}
|
|
259
312
|
function generateJavaScriptManifestContent(data) {
|
|
260
|
-
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t
|
|
261
|
-
const languagesArray = data.languages.map((l) =>
|
|
313
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`).join(",\n");
|
|
314
|
+
const languagesArray = data.languages.map((l) => JSON.stringify(l)).join(", ");
|
|
262
315
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
263
316
|
// Generated at: ${data.generatedAt}
|
|
264
317
|
|
|
265
318
|
/** @type {import("experimental-ciao-react").CiaoManifest} */
|
|
266
319
|
export const ciaoManifest = {
|
|
267
|
-
version:
|
|
268
|
-
projectId:
|
|
269
|
-
sourceLanguage:
|
|
320
|
+
version: ${JSON.stringify(data.version)},
|
|
321
|
+
projectId: ${JSON.stringify(data.projectId)},
|
|
322
|
+
sourceLanguage: ${JSON.stringify(data.sourceLanguage)},
|
|
270
323
|
languages: [${languagesArray}],
|
|
271
324
|
cdnUrls: {
|
|
272
325
|
${cdnUrlsEntries}
|
|
273
326
|
},
|
|
274
|
-
generatedAt:
|
|
327
|
+
generatedAt: ${JSON.stringify(data.generatedAt)},
|
|
275
328
|
};
|
|
276
329
|
`;
|
|
277
330
|
}
|
|
@@ -315,7 +368,6 @@ async function extractStringsFromProject(options) {
|
|
|
315
368
|
};
|
|
316
369
|
}
|
|
317
370
|
async function extractStringsFromFile(filePath) {
|
|
318
|
-
const code = node_fs.readFileSync(filePath, "utf-8");
|
|
319
371
|
const ext = node_path.extname(filePath);
|
|
320
372
|
if (![
|
|
321
373
|
".ts",
|
|
@@ -323,31 +375,12 @@ async function extractStringsFromFile(filePath) {
|
|
|
323
375
|
".js",
|
|
324
376
|
".jsx"
|
|
325
377
|
].includes(ext)) return null;
|
|
326
|
-
const isTypeScript = ext === ".ts" || ext === ".tsx";
|
|
327
|
-
let extractedStrings = [];
|
|
328
|
-
let extractedContextBlocks = [];
|
|
329
|
-
const extractionPlugin = (0, experimental_ciao_babel.createExtractionPlugin)({ onComplete: (result) => {
|
|
330
|
-
extractedStrings = result.strings;
|
|
331
|
-
extractedContextBlocks = result.contextBlocks;
|
|
332
|
-
} });
|
|
333
|
-
const presets = [];
|
|
334
|
-
if (isTypeScript) presets.push([require.resolve("@babel/preset-typescript"), {
|
|
335
|
-
isTSX: true,
|
|
336
|
-
allExtensions: true
|
|
337
|
-
}]);
|
|
338
|
-
presets.push([require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
|
|
339
378
|
try {
|
|
340
|
-
await
|
|
341
|
-
|
|
342
|
-
presets,
|
|
343
|
-
plugins: [extractionPlugin],
|
|
344
|
-
babelrc: false,
|
|
345
|
-
configFile: false
|
|
346
|
-
});
|
|
347
|
-
if (extractedStrings.length === 0 && extractedContextBlocks.length === 0) return null;
|
|
379
|
+
const result = (0, experimental_ciao_oxc.extractStrings)(await node_fs_promises.readFile(filePath, "utf-8"), filePath);
|
|
380
|
+
if (result.strings.length === 0 && result.contextBlocks.length === 0) return null;
|
|
348
381
|
return {
|
|
349
|
-
strings:
|
|
350
|
-
contextBlocks:
|
|
382
|
+
strings: result.strings,
|
|
383
|
+
contextBlocks: result.contextBlocks
|
|
351
384
|
};
|
|
352
385
|
} catch (error) {
|
|
353
386
|
console.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","path","fs","module","fs","path","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","fs","path","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]","babel"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: \"${data.generatedAt}\",\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["errorData: ApiError","lastError: Error | undefined","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<\n\tOmit<PollingOptions, \"onProgress\" | \"signal\">\n>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","path","fs","module","fs","path","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","path","fs"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\tprivate maxRetries: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tif (!options.baseUrl || typeof options.baseUrl !== \"string\") {\n\t\t\tthrow new Error(\"CiaoApiClient: baseUrl is required and must be a string\");\n\t\t}\n\t\ttry {\n\t\t\tnew URL(options.baseUrl);\n\t\t} catch {\n\t\t\tthrow new Error(\"CiaoApiClient: baseUrl must be a valid URL\");\n\t\t}\n\n\t\tif (\n\t\t\t!options.apiKey ||\n\t\t\ttypeof options.apiKey !== \"string\" ||\n\t\t\toptions.apiKey.trim() === \"\"\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t\"CiaoApiClient: apiKey is required and must be a non-empty string\",\n\t\t\t);\n\t\t}\n\n\t\tif (options.timeout !== undefined) {\n\t\t\tif (\n\t\t\t\ttypeof options.timeout !== \"number\" ||\n\t\t\t\toptions.timeout < 0 ||\n\t\t\t\toptions.timeout > 300000\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"CiaoApiClient: timeout must be a number between 0 and 300000ms\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t\tthis.maxRetries = options.maxRetries ?? 3;\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms));\n\t}\n\n\tprivate isRetryableError(error: unknown): boolean {\n\t\tif (error instanceof CiaoApiError) {\n\t\t\treturn [0, 429, 500, 502, 503, 504].includes(error.statusCode);\n\t\t}\n\t\treturn (\n\t\t\terror instanceof Error &&\n\t\t\t(error.name === \"AbortError\" || error.message.includes(\"network\"))\n\t\t);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tprivate async requestWithRetry<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tif (this.maxRetries === 0) {\n\t\t\treturn this.request<T>(method, path, body);\n\t\t}\n\n\t\tconst delays = [1000, 2000, 4000];\n\t\tlet lastError: Error | undefined;\n\n\t\tfor (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await this.request<T>(method, path, body);\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error as Error;\n\t\t\t\tif (!this.isRetryableError(error) || attempt === this.maxRetries) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst delay = delays[attempt] ?? delays[delays.length - 1];\n\t\t\t\tawait this.sleep(delay);\n\t\t\t}\n\t\t}\n\t\tthrow lastError;\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.requestWithRetry<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.requestWithRetry<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n\tsignal?: AbortSignal;\n}\n\nconst DEFAULT_OPTIONS: Required<\n\tOmit<PollingOptions, \"onProgress\" | \"signal\">\n> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress, signal } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Polling cancelled\");\n\t\t}\n\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval, signal);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(new Error(\"Polling cancelled\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst timeoutId = setTimeout(resolve, ms);\n\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\treject(new Error(\"Polling cancelled\"));\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tconst relativePath = path.relative(cwd, absolutePath) || absolutePath;\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${relativePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\tconst relativePath = path.relative(process.cwd(), configPath) || configPath;\n\ttry {\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${relativePath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${relativePath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tawait fs.mkdir(outputDir, { recursive: true });\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tawait fs.writeFile(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages\n\t\t.map((l) => JSON.stringify(l))\n\t\t.join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: ${JSON.stringify(data.version)},\n\tprojectId: ${JSON.stringify(data.projectId)},\n\tsourceLanguage: ${JSON.stringify(data.sourceLanguage)},\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: ${JSON.stringify(data.generatedAt)},\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages\n\t\t.map((l) => JSON.stringify(l))\n\t\t.join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: ${JSON.stringify(data.version)},\n\tprojectId: ${JSON.stringify(data.projectId)},\n\tsourceLanguage: ${JSON.stringify(data.sourceLanguage)},\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: ${JSON.stringify(data.generatedAt)},\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { extractStrings } from \"experimental-ciao-oxc\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst code = await fs.readFile(filePath, \"utf-8\");\n\t\tconst result = extractStrings(code, filePath);\n\n\t\tif (result.strings.length === 0 && result.contextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: result.strings,\n\t\t\tcontextBlocks: result.contextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAa,gBAAb,MAA2B;CAC1B,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,SAA2B;AACtC,MAAI,CAAC,QAAQ,WAAW,OAAO,QAAQ,YAAY,SAClD,OAAM,IAAI,MAAM,0DAA0D;AAE3E,MAAI;AACH,OAAI,IAAI,QAAQ,QAAQ;UACjB;AACP,SAAM,IAAI,MAAM,6CAA6C;;AAG9D,MACC,CAAC,QAAQ,UACT,OAAO,QAAQ,WAAW,YAC1B,QAAQ,OAAO,MAAM,KAAK,GAE1B,OAAM,IAAI,MACT,mEACA;AAGF,MAAI,QAAQ,YAAY,QACvB;OACC,OAAO,QAAQ,YAAY,YAC3B,QAAQ,UAAU,KAClB,QAAQ,UAAU,IAElB,OAAM,IAAI,MACT,iEACA;;AAIH,OAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,GAAG;AACjD,OAAK,SAAS,QAAQ;AACtB,OAAK,UAAU,QAAQ,WAAW;AAClC,OAAK,aAAa,QAAQ,cAAc;;CAGzC,AAAQ,MAAM,IAA2B;AACxC,SAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;CAGzD,AAAQ,iBAAiB,OAAyB;AACjD,MAAI,iBAAiB,aACpB,QAAO;GAAC;GAAG;GAAK;GAAK;GAAK;GAAK;GAAI,CAAC,SAAS,MAAM,WAAW;AAE/D,SACC,iBAAiB,UAChB,MAAM,SAAS,gBAAgB,MAAM,QAAQ,SAAS,UAAU;;CAInE,MAAc,QACb,QACA,MACA,MACa;EACb,MAAM,MAAM,GAAG,KAAK,UAAU;EAC9B,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,KAAK,QAAQ;AAEpE,MAAI;GACH,MAAM,WAAW,MAAM,MAAM,KAAK;IACjC;IACA,SAAS;KACR,gBAAgB;KAChB,eAAe,UAAU,KAAK;KAC9B;IACD,MAAM,OAAO,KAAK,UAAU,KAAK,GAAG;IACpC,QAAQ,WAAW;IACnB,CAAC;AAEF,gBAAa,UAAU;AAEvB,OAAI,CAAC,SAAS,IAAI;IACjB,IAAIA;AACJ,QAAI;AACH,iBAAY,MAAM,SAAS,MAAM;YAC1B;AACP,iBAAY;MACX,MAAM,QAAQ,SAAS;MACvB,SAAS,SAAS;MAClB;;AAEF,UAAM,IAAI,aACT,UAAU,SACV,UAAU,MACV,SAAS,QACT,UAAU,QACV;;AAGF,UAAO,SAAS,MAAM;WACd,OAAO;AACf,gBAAa,UAAU;AACvB,OAAI,iBAAiB,aACpB,OAAM;AAEP,OAAI,iBAAiB,OAAO;AAC3B,QAAI,MAAM,SAAS,aAClB,OAAM,IAAI,aAAa,qBAAqB,WAAW,EAAE;AAE1D,UAAM,IAAI,aAAa,MAAM,SAAS,iBAAiB,EAAE;;AAE1D,SAAM,IAAI,aAAa,iBAAiB,WAAW,EAAE;;;CAIvD,MAAc,iBACb,QACA,MACA,MACa;AACb,MAAI,KAAK,eAAe,EACvB,QAAO,KAAK,QAAW,QAAQ,MAAM,KAAK;EAG3C,MAAM,SAAS;GAAC;GAAM;GAAM;GAAK;EACjC,IAAIC;AAEJ,OAAK,IAAI,UAAU,GAAG,WAAW,KAAK,YAAY,UACjD,KAAI;AACH,UAAO,MAAM,KAAK,QAAW,QAAQ,MAAM,KAAK;WACxC,OAAO;AACf,eAAY;AACZ,OAAI,CAAC,KAAK,iBAAiB,MAAM,IAAI,YAAY,KAAK,WACrD,OAAM;GAEP,MAAM,QAAQ,OAAO,YAAY,OAAO,OAAO,SAAS;AACxD,SAAM,KAAK,MAAM,MAAM;;AAGzB,QAAM;;CAGP,MAAM,kBACL,aAC+B;AAC/B,SAAO,KAAK,iBACX,QACA,sCACA,EAAE,aAAa,CACf;;CAGF,MAAM,aAAa,OAA2C;AAC7D,SAAO,KAAK,iBACX,OACA,wBAAwB,QACxB;;;AAIH,IAAa,eAAb,cAAkC,MAAM;CACvC,YACC,SACA,AAAOC,MACP,AAAOC,YACP,AAAOC,SACN;AACD,QAAM,QAAQ;EAJP;EACA;EACA;AAGP,OAAK,OAAO;;;;;;ACnKd,MAAMC,kBAEF;CACH,iBAAiB;CACjB,aAAa;CACb,aAAa;CACb,mBAAmB;CACnB;AAED,eAAsB,qBACrB,QACA,OACA,UAA0B,EAAE,EACC;CAC7B,MAAM,EAAE,iBAAiB,aAAa,aAAa,sBAAsB;EACxE,GAAG;EACH,GAAG;EACH;CACD,MAAM,EAAE,YAAY,WAAW;CAE/B,IAAI,kBAAkB;CACtB,IAAI,WAAW;AAEf,QAAO,WAAW,aAAa;AAC9B,MAAI,QAAQ,QACX,OAAM,IAAI,MAAM,oBAAoB;EAGrC,MAAM,SAAS,MAAM,OAAO,aAAa,MAAM;AAE/C,MAAI,WACH,YAAW,OAAO;AAGnB,MAAI,OAAO,WAAW,YACrB,QAAO;AAGR,MAAI,OAAO,WAAW,SACrB,OAAM,IAAI,MAAM,OAAO,SAAS,gCAAgC;AAGjE,QAAM,MAAM,iBAAiB,OAAO;AACpC,oBAAkB,KAAK,IACtB,kBAAkB,mBAClB,YACA;AACD;;AAGD,OAAM,IAAI,MAAM,+BAA+B,YAAY,WAAW;;AAGvE,SAAS,MAAM,IAAY,QAAqC;AAC/D,QAAO,IAAI,SAAS,SAAS,WAAW;AACvC,MAAI,QAAQ,SAAS;AACpB,0BAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC;;EAGD,MAAM,YAAY,WAAW,SAAS,GAAG;AAEzC,UAAQ,iBACP,eACM;AACL,gBAAa,UAAU;AACvB,0BAAO,IAAI,MAAM,oBAAoB,CAAC;KAEvC,EAAE,MAAM,MAAM,CACd;GACA;;;;;AChFH,MAAaC,iBAAwD;CACpE,SAAS;EACR;EACA;EACA;EACA;EACA;CACD,SAAS;EACR;EACA;EACA;EACA;EACA;EACA;EACA;CACD,WAAW;CACX;AAED,MAAa,oBAAoB;CAChC;CACA;CACA;CACA;;;;ACRD,eAAsB,WACrB,UAA6B,EAAE,EACH;CAC5B,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,IAAI,aAAa,QAAQ;AAEzB,KAAI,CAAC,WACJ,MAAK,MAAM,YAAY,mBAAmB;EACzC,MAAM,YAAYC,UAAK,KAAK,KAAK,SAAS;AAC1C,MAAIC,QAAG,WAAW,UAAU,EAAE;AAC7B,gBAAa;AACb;;;AAKH,KAAI,CAAC,WACJ,OAAM,IAAI,oBACT,0DACA;CAGF,MAAM,eAAeD,UAAK,WAAW,WAAW,GAC7C,aACAA,UAAK,KAAK,KAAK,WAAW;AAE7B,KAAI,CAACC,QAAG,WAAW,aAAa,CAE/B,OAAM,IAAI,oBAAoB,0BADTD,UAAK,SAAS,KAAK,aAAa,IAAI,eACc;CAGxE,MAAM,SAAS,MAAM,aAAa,aAAa;CAC/C,MAAM,gBAAgB,aAAa,SAAS,MAAM;AAElD,QAAO;EACN,QAAQ,cAAc,QAAQ,IAAI;EAClC,gBAAgB;EAChB;EACA;;AAGF,eAAe,aAAa,YAAyC;CACpE,MAAM,eAAeA,UAAK,SAAS,QAAQ,KAAK,EAAE,WAAW,IAAI;AACjE,KAAI;EAIH,MAAME,WAAS,OAHC,WAAW,WAAW,UAAU,UAC7C,qBACA,UAAU;EAEb,MAAM,SAASA,SAAO,WAAWA;AAEjC,MAAI,CAAC,UAAU,OAAO,WAAW,SAChC,OAAM,IAAI,sBAAsB,oCAAoC;AAGrE,SAAO;UACC,OAAO;AACf,MAAI,iBAAiB,sBACpB,OAAM;AAEP,MAAI,iBAAiB,MACpB,OAAM,IAAI,sBACT,+BAA+B,aAAa,KAAK,MAAM,UACvD;AAEF,QAAM,IAAI,sBACT,+BAA+B,eAC/B;;;AAIH,SAAS,cAAc,QAAoB,KAAiC;AAC3E,KAAI,CAAC,OAAO,UACX,OAAM,IAAI,sBAAsB,0CAA0C;CAG3E,MAAM,YAAY,OAAO,aAAa,eAAe;CACrD,MAAM,oBAAoBF,UAAK,WAAW,UAAU,GACjD,YACAA,UAAK,KAAK,KAAK,UAAU;AAE5B,QAAO;EACN,WAAW,OAAO;EAClB,SAAS,OAAO,WAAW,eAAe;EAC1C,SAAS,OAAO,WAAW,eAAe;EAC1C,WAAW;EACX;;AAGF,IAAa,sBAAb,cAAyC,MAAM;CAC9C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,IAAa,wBAAb,cAA2C,MAAM;CAChD,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;ACpGd,SAAgB,iBAAiB,QAAgC;AAChE,QAAO;;;;;ACXR,eAAsB,qBACrB,SACkB;CAClB,MAAM,EAAE,WAAW,MAAM,gBAAgB,SAAS;AAElD,OAAMG,iBAAG,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;CAE9C,MAAM,YAAY,gBAAgB,OAAO;CACzC,MAAM,eAAeC,UAAK,KAAK,WAAW,iBAAiB,YAAY;CACvE,MAAM,UAAU,gBACb,kCAAkC,KAAK,GACvC,kCAAkC,KAAK;AAE1C,OAAMD,iBAAG,UAAU,cAAc,SAAS,QAAQ;AAElD,QAAO;;AAGR,SAAS,kCAAkC,MAA4B;CACtE,MAAM,iBAAiB,OAAO,QAAQ,KAAK,QAAQ,CACjD,KAAK,CAAC,MAAM,SAAS,KAAK,KAAK,UAAU,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CACzE,KAAK,MAAM;CAEb,MAAM,iBAAiB,KAAK,UAC1B,KAAK,MAAM,KAAK,UAAU,EAAE,CAAC,CAC7B,KAAK,KAAK;AAEZ,QAAO;mBACW,KAAK,YAAY;;;YAGxB,KAAK,UAAU,KAAK,QAAQ,CAAC;cAC3B,KAAK,UAAU,KAAK,UAAU,CAAC;mBAC1B,KAAK,UAAU,KAAK,eAAe,CAAC;eACxC,eAAe;;EAE5B,eAAe;;gBAED,KAAK,UAAU,KAAK,YAAY,CAAC;;;;;;;;AASjD,SAAS,kCAAkC,MAA4B;CACtE,MAAM,iBAAiB,OAAO,QAAQ,KAAK,QAAQ,CACjD,KAAK,CAAC,MAAM,SAAS,KAAK,KAAK,UAAU,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CACzE,KAAK,MAAM;CAEb,MAAM,iBAAiB,KAAK,UAC1B,KAAK,MAAM,KAAK,UAAU,EAAE,CAAC,CAC7B,KAAK,KAAK;AAEZ,QAAO;mBACW,KAAK,YAAY;;;;YAIxB,KAAK,UAAU,KAAK,QAAQ,CAAC;cAC3B,KAAK,UAAU,KAAK,UAAU,CAAC;mBAC1B,KAAK,UAAU,KAAK,eAAe,CAAC;eACxC,eAAe;;EAE5B,eAAe;;gBAED,KAAK,UAAU,KAAK,YAAY,CAAC;;;;AAKjD,SAAgB,mBACf,WACA,gBACA,WACA,SACA,SACe;AACf,QAAO;EACN;EACA;EACA;EACA;EACA;EACA,8BAAa,IAAI,MAAM,EAAC,aAAa;EACrC;;;;;AChFF,eAAsB,0BACrB,SACmC;CACnC,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,MAAME,aAAmC,EAAE;CAC3C,MAAMC,mBAAmC,EAAE;CAC3C,IAAI,iBAAiB;CAErB,MAAM,QAAQ,qBAAW,QAAQ,SAAS;EACzC;EACA,QAAQ,QAAQ;EAChB,UAAU;EACV,OAAO;EACP,CAAC;AAEF,MAAK,MAAM,YAAY,OAAO;EAC7B,MAAM,SAAS,MAAM,uBAAuB,SAAS;AACrD,MAAI,QAAQ;AACX,gBAAa,YAAY,OAAO,QAAQ;AACxC,sBAAmB,kBAAkB,OAAO,cAAc;AAC1D;;;AAIF,QAAO;EACN,SAAS;EACT,eAAe;EACf;EACA,cAAc,WAAW;EACzB;;AAGF,eAAe,uBACd,UAIS;CACT,MAAM,MAAMC,UAAK,QAAQ,SAAS;AAElC,KAAI,CAAC;EAAC;EAAO;EAAQ;EAAO;EAAO,CAAC,SAAS,IAAI,CAChD,QAAO;AAGR,KAAI;EAEH,MAAM,mDADO,MAAMC,iBAAG,SAAS,UAAU,QAAQ,EACb,SAAS;AAE7C,MAAI,OAAO,QAAQ,WAAW,KAAK,OAAO,cAAc,WAAW,EAClE,QAAO;AAGR,SAAO;GACN,SAAS,OAAO;GAChB,eAAe,OAAO;GACtB;UACO,OAAO;AACf,UAAQ,KAAK,yCAAyC,SAAS,IAAI,MAAM;AACzE,SAAO;;;AAIT,SAAS,aACR,QACA,QACO;AACP,MAAK,MAAM,OAAO,OAOjB,KAAI,CANgB,OAAO,MACzB,MACA,EAAE,SAAS,IAAI,QACf,EAAE,YAAY,IAAI,WAClB,EAAE,yBAAyB,IAAI,qBAChC,CAEA,QAAO,KAAK,IAAI;;AAKnB,SAAS,mBACR,QACA,QACO;AACP,MAAK,MAAM,SAAS,OAEnB,KAAI,CADgB,OAAO,MAAM,MAAM,EAAE,OAAO,MAAM,GAAG,CAExD,QAAO,KAAK,MAAM"}
|
package/dist/index.d.cts
CHANGED
|
@@ -17,7 +17,6 @@ interface BuildSchemaMetadata {
|
|
|
17
17
|
interface BuildSchemaRequest {
|
|
18
18
|
version: "1.0";
|
|
19
19
|
projectId: string;
|
|
20
|
-
styleId?: string;
|
|
21
20
|
strings: TranslatableString[];
|
|
22
21
|
contextBlocks: ContextBlock[];
|
|
23
22
|
metadata: BuildSchemaMetadata;
|
|
@@ -58,6 +57,7 @@ interface ApiClientOptions {
|
|
|
58
57
|
baseUrl: string;
|
|
59
58
|
apiKey: string;
|
|
60
59
|
timeout?: number;
|
|
60
|
+
maxRetries?: number;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/api/client.d.ts
|
|
@@ -65,8 +65,12 @@ declare class CiaoApiClient {
|
|
|
65
65
|
private baseUrl;
|
|
66
66
|
private apiKey;
|
|
67
67
|
private timeout;
|
|
68
|
+
private maxRetries;
|
|
68
69
|
constructor(options: ApiClientOptions);
|
|
70
|
+
private sleep;
|
|
71
|
+
private isRetryableError;
|
|
69
72
|
private request;
|
|
73
|
+
private requestWithRetry;
|
|
70
74
|
submitBuildSchema(buildSchema: BuildSchemaRequest): Promise<TranslationResponse>;
|
|
71
75
|
getJobStatus(jobId: string): Promise<JobStatusResponse>;
|
|
72
76
|
}
|
|
@@ -84,25 +88,22 @@ interface PollingOptions {
|
|
|
84
88
|
maxAttempts?: number;
|
|
85
89
|
backoffMultiplier?: number;
|
|
86
90
|
onProgress?: (status: JobStatusResponse) => void;
|
|
91
|
+
signal?: AbortSignal;
|
|
87
92
|
}
|
|
88
93
|
declare function pollJobUntilComplete(client: CiaoApiClient, jobId: string, options?: PollingOptions): Promise<JobStatusResponse>;
|
|
89
94
|
//#endregion
|
|
90
95
|
//#region src/config/types.d.ts
|
|
91
96
|
interface CiaoConfig {
|
|
92
97
|
projectId: string;
|
|
93
|
-
styleId?: string;
|
|
94
98
|
include?: string[];
|
|
95
99
|
exclude?: string[];
|
|
96
100
|
outputDir?: string;
|
|
97
|
-
serverUrl?: string;
|
|
98
101
|
}
|
|
99
102
|
interface ResolvedCiaoConfig {
|
|
100
103
|
projectId: string;
|
|
101
|
-
styleId?: string;
|
|
102
104
|
include: string[];
|
|
103
105
|
exclude: string[];
|
|
104
106
|
outputDir: string;
|
|
105
|
-
serverUrl: string;
|
|
106
107
|
}
|
|
107
108
|
declare function defineCiaoConfig(config: CiaoConfig): CiaoConfig;
|
|
108
109
|
//#endregion
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":";;;UAAiB,kBAAA;;;EAAA,oBAAA,CAAkB,EAAA,MAAA;AAMnC;AAIiB,UAJA,YAAA,CAImB;EAMnB,EAAA,EAAA,MAAA;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -17,7 +17,6 @@ interface BuildSchemaMetadata {
|
|
|
17
17
|
interface BuildSchemaRequest {
|
|
18
18
|
version: "1.0";
|
|
19
19
|
projectId: string;
|
|
20
|
-
styleId?: string;
|
|
21
20
|
strings: TranslatableString[];
|
|
22
21
|
contextBlocks: ContextBlock[];
|
|
23
22
|
metadata: BuildSchemaMetadata;
|
|
@@ -58,6 +57,7 @@ interface ApiClientOptions {
|
|
|
58
57
|
baseUrl: string;
|
|
59
58
|
apiKey: string;
|
|
60
59
|
timeout?: number;
|
|
60
|
+
maxRetries?: number;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/api/client.d.ts
|
|
@@ -65,8 +65,12 @@ declare class CiaoApiClient {
|
|
|
65
65
|
private baseUrl;
|
|
66
66
|
private apiKey;
|
|
67
67
|
private timeout;
|
|
68
|
+
private maxRetries;
|
|
68
69
|
constructor(options: ApiClientOptions);
|
|
70
|
+
private sleep;
|
|
71
|
+
private isRetryableError;
|
|
69
72
|
private request;
|
|
73
|
+
private requestWithRetry;
|
|
70
74
|
submitBuildSchema(buildSchema: BuildSchemaRequest): Promise<TranslationResponse>;
|
|
71
75
|
getJobStatus(jobId: string): Promise<JobStatusResponse>;
|
|
72
76
|
}
|
|
@@ -84,25 +88,22 @@ interface PollingOptions {
|
|
|
84
88
|
maxAttempts?: number;
|
|
85
89
|
backoffMultiplier?: number;
|
|
86
90
|
onProgress?: (status: JobStatusResponse) => void;
|
|
91
|
+
signal?: AbortSignal;
|
|
87
92
|
}
|
|
88
93
|
declare function pollJobUntilComplete(client: CiaoApiClient, jobId: string, options?: PollingOptions): Promise<JobStatusResponse>;
|
|
89
94
|
//#endregion
|
|
90
95
|
//#region src/config/types.d.ts
|
|
91
96
|
interface CiaoConfig {
|
|
92
97
|
projectId: string;
|
|
93
|
-
styleId?: string;
|
|
94
98
|
include?: string[];
|
|
95
99
|
exclude?: string[];
|
|
96
100
|
outputDir?: string;
|
|
97
|
-
serverUrl?: string;
|
|
98
101
|
}
|
|
99
102
|
interface ResolvedCiaoConfig {
|
|
100
103
|
projectId: string;
|
|
101
|
-
styleId?: string;
|
|
102
104
|
include: string[];
|
|
103
105
|
exclude: string[];
|
|
104
106
|
outputDir: string;
|
|
105
|
-
serverUrl: string;
|
|
106
107
|
}
|
|
107
108
|
declare function defineCiaoConfig(config: CiaoConfig): CiaoConfig;
|
|
108
109
|
//#endregion
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":";;;UAAiB,kBAAA;;;EAAA,oBAAA,CAAkB,EAAA,MAAA;AAMnC;AAIiB,UAJA,YAAA,CAImB;EAMnB,EAAA,EAAA,MAAA;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,44 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as fs from "node:fs";
|
|
1
|
+
import * as fs$1 from "node:fs";
|
|
3
2
|
import * as path from "node:path";
|
|
4
|
-
import * as
|
|
5
|
-
import {
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import { extractStrings } from "experimental-ciao-oxc";
|
|
6
5
|
import { glob } from "glob";
|
|
7
6
|
|
|
8
|
-
//#region rolldown:runtime
|
|
9
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
7
|
//#region src/api/client.ts
|
|
13
8
|
var CiaoApiClient = class {
|
|
14
9
|
baseUrl;
|
|
15
10
|
apiKey;
|
|
16
11
|
timeout;
|
|
12
|
+
maxRetries;
|
|
17
13
|
constructor(options) {
|
|
14
|
+
if (!options.baseUrl || typeof options.baseUrl !== "string") throw new Error("CiaoApiClient: baseUrl is required and must be a string");
|
|
15
|
+
try {
|
|
16
|
+
new URL(options.baseUrl);
|
|
17
|
+
} catch {
|
|
18
|
+
throw new Error("CiaoApiClient: baseUrl must be a valid URL");
|
|
19
|
+
}
|
|
20
|
+
if (!options.apiKey || typeof options.apiKey !== "string" || options.apiKey.trim() === "") throw new Error("CiaoApiClient: apiKey is required and must be a non-empty string");
|
|
21
|
+
if (options.timeout !== void 0) {
|
|
22
|
+
if (typeof options.timeout !== "number" || options.timeout < 0 || options.timeout > 3e5) throw new Error("CiaoApiClient: timeout must be a number between 0 and 300000ms");
|
|
23
|
+
}
|
|
18
24
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
19
25
|
this.apiKey = options.apiKey;
|
|
20
26
|
this.timeout = options.timeout ?? 3e4;
|
|
27
|
+
this.maxRetries = options.maxRetries ?? 3;
|
|
28
|
+
}
|
|
29
|
+
sleep(ms) {
|
|
30
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
|
+
}
|
|
32
|
+
isRetryableError(error) {
|
|
33
|
+
if (error instanceof CiaoApiError) return [
|
|
34
|
+
0,
|
|
35
|
+
429,
|
|
36
|
+
500,
|
|
37
|
+
502,
|
|
38
|
+
503,
|
|
39
|
+
504
|
|
40
|
+
].includes(error.statusCode);
|
|
41
|
+
return error instanceof Error && (error.name === "AbortError" || error.message.includes("network"));
|
|
21
42
|
}
|
|
22
43
|
async request(method, path$1, body) {
|
|
23
44
|
const url = `${this.baseUrl}${path$1}`;
|
|
@@ -57,11 +78,29 @@ var CiaoApiClient = class {
|
|
|
57
78
|
throw new CiaoApiError("Unknown error", "UNKNOWN", 0);
|
|
58
79
|
}
|
|
59
80
|
}
|
|
81
|
+
async requestWithRetry(method, path$1, body) {
|
|
82
|
+
if (this.maxRetries === 0) return this.request(method, path$1, body);
|
|
83
|
+
const delays = [
|
|
84
|
+
1e3,
|
|
85
|
+
2e3,
|
|
86
|
+
4e3
|
|
87
|
+
];
|
|
88
|
+
let lastError;
|
|
89
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) try {
|
|
90
|
+
return await this.request(method, path$1, body);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
lastError = error;
|
|
93
|
+
if (!this.isRetryableError(error) || attempt === this.maxRetries) throw error;
|
|
94
|
+
const delay = delays[attempt] ?? delays[delays.length - 1];
|
|
95
|
+
await this.sleep(delay);
|
|
96
|
+
}
|
|
97
|
+
throw lastError;
|
|
98
|
+
}
|
|
60
99
|
async submitBuildSchema(buildSchema) {
|
|
61
|
-
return this.
|
|
100
|
+
return this.requestWithRetry("POST", "/api/translation/translate-strings", { buildSchema });
|
|
62
101
|
}
|
|
63
102
|
async getJobStatus(jobId) {
|
|
64
|
-
return this.
|
|
103
|
+
return this.requestWithRetry("GET", `/api/translation/job/${jobId}`);
|
|
65
104
|
}
|
|
66
105
|
};
|
|
67
106
|
var CiaoApiError = class extends Error {
|
|
@@ -87,22 +126,33 @@ async function pollJobUntilComplete(client, jobId, options = {}) {
|
|
|
87
126
|
...DEFAULT_OPTIONS,
|
|
88
127
|
...options
|
|
89
128
|
};
|
|
90
|
-
const { onProgress } = options;
|
|
129
|
+
const { onProgress, signal } = options;
|
|
91
130
|
let currentInterval = initialInterval;
|
|
92
131
|
let attempts = 0;
|
|
93
132
|
while (attempts < maxAttempts) {
|
|
133
|
+
if (signal?.aborted) throw new Error("Polling cancelled");
|
|
94
134
|
const status = await client.getJobStatus(jobId);
|
|
95
135
|
if (onProgress) onProgress(status);
|
|
96
136
|
if (status.status === "completed") return status;
|
|
97
137
|
if (status.status === "failed") throw new Error(status.error ?? "Job failed with unknown error");
|
|
98
|
-
await sleep(currentInterval);
|
|
138
|
+
await sleep(currentInterval, signal);
|
|
99
139
|
currentInterval = Math.min(currentInterval * backoffMultiplier, maxInterval);
|
|
100
140
|
attempts++;
|
|
101
141
|
}
|
|
102
142
|
throw new Error(`Job polling timed out after ${maxAttempts} attempts`);
|
|
103
143
|
}
|
|
104
|
-
function sleep(ms) {
|
|
105
|
-
return new Promise((resolve) =>
|
|
144
|
+
function sleep(ms, signal) {
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
if (signal?.aborted) {
|
|
147
|
+
reject(/* @__PURE__ */ new Error("Polling cancelled"));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const timeoutId = setTimeout(resolve, ms);
|
|
151
|
+
signal?.addEventListener("abort", () => {
|
|
152
|
+
clearTimeout(timeoutId);
|
|
153
|
+
reject(/* @__PURE__ */ new Error("Polling cancelled"));
|
|
154
|
+
}, { once: true });
|
|
155
|
+
});
|
|
106
156
|
}
|
|
107
157
|
|
|
108
158
|
//#endregion
|
|
@@ -122,8 +172,7 @@ const DEFAULT_CONFIG = {
|
|
|
122
172
|
"**/dist/**",
|
|
123
173
|
"**/.next/**"
|
|
124
174
|
],
|
|
125
|
-
outputDir: "__generated__"
|
|
126
|
-
serverUrl: "https://server.ciao-tools.com"
|
|
175
|
+
outputDir: "__generated__"
|
|
127
176
|
};
|
|
128
177
|
const CONFIG_FILE_NAMES = [
|
|
129
178
|
"ciao.config.ts",
|
|
@@ -138,14 +187,14 @@ async function loadConfig(options = {}) {
|
|
|
138
187
|
let configPath = options.configPath;
|
|
139
188
|
if (!configPath) for (const fileName of CONFIG_FILE_NAMES) {
|
|
140
189
|
const candidate = path.join(cwd, fileName);
|
|
141
|
-
if (fs.existsSync(candidate)) {
|
|
190
|
+
if (fs$1.existsSync(candidate)) {
|
|
142
191
|
configPath = candidate;
|
|
143
192
|
break;
|
|
144
193
|
}
|
|
145
194
|
}
|
|
146
195
|
if (!configPath) throw new ConfigNotFoundError(`No ciao.config.ts found. Run 'ciao init' to create one.`);
|
|
147
196
|
const absolutePath = path.isAbsolute(configPath) ? configPath : path.join(cwd, configPath);
|
|
148
|
-
if (!fs.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${absolutePath}`);
|
|
197
|
+
if (!fs$1.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${path.relative(cwd, absolutePath) || absolutePath}`);
|
|
149
198
|
const config = await importConfig(absolutePath);
|
|
150
199
|
const useTypeScript = absolutePath.endsWith(".ts");
|
|
151
200
|
return {
|
|
@@ -155,6 +204,7 @@ async function loadConfig(options = {}) {
|
|
|
155
204
|
};
|
|
156
205
|
}
|
|
157
206
|
async function importConfig(configPath) {
|
|
207
|
+
const relativePath = path.relative(process.cwd(), configPath) || configPath;
|
|
158
208
|
try {
|
|
159
209
|
const module = await (configPath.startsWith("file://") ? import(configPath) : import(`file://${configPath}`));
|
|
160
210
|
const config = module.default ?? module;
|
|
@@ -162,8 +212,8 @@ async function importConfig(configPath) {
|
|
|
162
212
|
return config;
|
|
163
213
|
} catch (error) {
|
|
164
214
|
if (error instanceof ConfigValidationError) throw error;
|
|
165
|
-
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${
|
|
166
|
-
throw new ConfigValidationError(`Failed to load config file: ${
|
|
215
|
+
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${relativePath}): ${error.message}`);
|
|
216
|
+
throw new ConfigValidationError(`Failed to load config file: ${relativePath}`);
|
|
167
217
|
}
|
|
168
218
|
}
|
|
169
219
|
function resolveConfig(config, cwd) {
|
|
@@ -172,11 +222,9 @@ function resolveConfig(config, cwd) {
|
|
|
172
222
|
const resolvedOutputDir = path.isAbsolute(outputDir) ? outputDir : path.join(cwd, outputDir);
|
|
173
223
|
return {
|
|
174
224
|
projectId: config.projectId,
|
|
175
|
-
styleId: config.styleId,
|
|
176
225
|
include: config.include ?? DEFAULT_CONFIG.include,
|
|
177
226
|
exclude: config.exclude ?? DEFAULT_CONFIG.exclude,
|
|
178
|
-
outputDir: resolvedOutputDir
|
|
179
|
-
serverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl
|
|
227
|
+
outputDir: resolvedOutputDir
|
|
180
228
|
};
|
|
181
229
|
}
|
|
182
230
|
var ConfigNotFoundError = class extends Error {
|
|
@@ -202,28 +250,28 @@ function defineCiaoConfig(config) {
|
|
|
202
250
|
//#region src/manifest/generator.ts
|
|
203
251
|
async function generateManifestFile(options) {
|
|
204
252
|
const { outputDir, data, useTypeScript = true } = options;
|
|
205
|
-
|
|
253
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
206
254
|
const extension = useTypeScript ? "ts" : "js";
|
|
207
255
|
const manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);
|
|
208
256
|
const content = useTypeScript ? generateTypeScriptManifestContent(data) : generateJavaScriptManifestContent(data);
|
|
209
|
-
fs.
|
|
257
|
+
await fs.writeFile(manifestPath, content, "utf-8");
|
|
210
258
|
return manifestPath;
|
|
211
259
|
}
|
|
212
260
|
function generateTypeScriptManifestContent(data) {
|
|
213
|
-
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t
|
|
214
|
-
const languagesArray = data.languages.map((l) =>
|
|
261
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`).join(",\n");
|
|
262
|
+
const languagesArray = data.languages.map((l) => JSON.stringify(l)).join(", ");
|
|
215
263
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
216
264
|
// Generated at: ${data.generatedAt}
|
|
217
265
|
|
|
218
266
|
export const ciaoManifest = {
|
|
219
|
-
version:
|
|
220
|
-
projectId:
|
|
221
|
-
sourceLanguage:
|
|
267
|
+
version: ${JSON.stringify(data.version)},
|
|
268
|
+
projectId: ${JSON.stringify(data.projectId)},
|
|
269
|
+
sourceLanguage: ${JSON.stringify(data.sourceLanguage)},
|
|
222
270
|
languages: [${languagesArray}] as const,
|
|
223
271
|
cdnUrls: {
|
|
224
272
|
${cdnUrlsEntries}
|
|
225
273
|
} as const,
|
|
226
|
-
generatedAt:
|
|
274
|
+
generatedAt: ${JSON.stringify(data.generatedAt)},
|
|
227
275
|
} as const;
|
|
228
276
|
|
|
229
277
|
export type CiaoLanguage = (typeof ciaoManifest.languages)[number];
|
|
@@ -232,21 +280,21 @@ export type CiaoManifest = typeof ciaoManifest;
|
|
|
232
280
|
`;
|
|
233
281
|
}
|
|
234
282
|
function generateJavaScriptManifestContent(data) {
|
|
235
|
-
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t
|
|
236
|
-
const languagesArray = data.languages.map((l) =>
|
|
283
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`).join(",\n");
|
|
284
|
+
const languagesArray = data.languages.map((l) => JSON.stringify(l)).join(", ");
|
|
237
285
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
238
286
|
// Generated at: ${data.generatedAt}
|
|
239
287
|
|
|
240
288
|
/** @type {import("experimental-ciao-react").CiaoManifest} */
|
|
241
289
|
export const ciaoManifest = {
|
|
242
|
-
version:
|
|
243
|
-
projectId:
|
|
244
|
-
sourceLanguage:
|
|
290
|
+
version: ${JSON.stringify(data.version)},
|
|
291
|
+
projectId: ${JSON.stringify(data.projectId)},
|
|
292
|
+
sourceLanguage: ${JSON.stringify(data.sourceLanguage)},
|
|
245
293
|
languages: [${languagesArray}],
|
|
246
294
|
cdnUrls: {
|
|
247
295
|
${cdnUrlsEntries}
|
|
248
296
|
},
|
|
249
|
-
generatedAt:
|
|
297
|
+
generatedAt: ${JSON.stringify(data.generatedAt)},
|
|
250
298
|
};
|
|
251
299
|
`;
|
|
252
300
|
}
|
|
@@ -290,7 +338,6 @@ async function extractStringsFromProject(options) {
|
|
|
290
338
|
};
|
|
291
339
|
}
|
|
292
340
|
async function extractStringsFromFile(filePath) {
|
|
293
|
-
const code = fs.readFileSync(filePath, "utf-8");
|
|
294
341
|
const ext = path.extname(filePath);
|
|
295
342
|
if (![
|
|
296
343
|
".ts",
|
|
@@ -298,31 +345,12 @@ async function extractStringsFromFile(filePath) {
|
|
|
298
345
|
".js",
|
|
299
346
|
".jsx"
|
|
300
347
|
].includes(ext)) return null;
|
|
301
|
-
const isTypeScript = ext === ".ts" || ext === ".tsx";
|
|
302
|
-
let extractedStrings = [];
|
|
303
|
-
let extractedContextBlocks = [];
|
|
304
|
-
const extractionPlugin = createExtractionPlugin({ onComplete: (result) => {
|
|
305
|
-
extractedStrings = result.strings;
|
|
306
|
-
extractedContextBlocks = result.contextBlocks;
|
|
307
|
-
} });
|
|
308
|
-
const presets = [];
|
|
309
|
-
if (isTypeScript) presets.push([__require.resolve("@babel/preset-typescript"), {
|
|
310
|
-
isTSX: true,
|
|
311
|
-
allExtensions: true
|
|
312
|
-
}]);
|
|
313
|
-
presets.push([__require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
|
|
314
348
|
try {
|
|
315
|
-
await
|
|
316
|
-
|
|
317
|
-
presets,
|
|
318
|
-
plugins: [extractionPlugin],
|
|
319
|
-
babelrc: false,
|
|
320
|
-
configFile: false
|
|
321
|
-
});
|
|
322
|
-
if (extractedStrings.length === 0 && extractedContextBlocks.length === 0) return null;
|
|
349
|
+
const result = extractStrings(await fs.readFile(filePath, "utf-8"), filePath);
|
|
350
|
+
if (result.strings.length === 0 && result.contextBlocks.length === 0) return null;
|
|
323
351
|
return {
|
|
324
|
-
strings:
|
|
325
|
-
contextBlocks:
|
|
352
|
+
strings: result.strings,
|
|
353
|
+
contextBlocks: result.contextBlocks
|
|
326
354
|
};
|
|
327
355
|
} catch (error) {
|
|
328
356
|
console.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["path","errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: \"${data.generatedAt}\",\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["path","errorData: ApiError","lastError: Error | undefined","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<\n\tOmit<PollingOptions, \"onProgress\" | \"signal\">\n>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","fs","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\tprivate maxRetries: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tif (!options.baseUrl || typeof options.baseUrl !== \"string\") {\n\t\t\tthrow new Error(\"CiaoApiClient: baseUrl is required and must be a string\");\n\t\t}\n\t\ttry {\n\t\t\tnew URL(options.baseUrl);\n\t\t} catch {\n\t\t\tthrow new Error(\"CiaoApiClient: baseUrl must be a valid URL\");\n\t\t}\n\n\t\tif (\n\t\t\t!options.apiKey ||\n\t\t\ttypeof options.apiKey !== \"string\" ||\n\t\t\toptions.apiKey.trim() === \"\"\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t\"CiaoApiClient: apiKey is required and must be a non-empty string\",\n\t\t\t);\n\t\t}\n\n\t\tif (options.timeout !== undefined) {\n\t\t\tif (\n\t\t\t\ttypeof options.timeout !== \"number\" ||\n\t\t\t\toptions.timeout < 0 ||\n\t\t\t\toptions.timeout > 300000\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"CiaoApiClient: timeout must be a number between 0 and 300000ms\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t\tthis.maxRetries = options.maxRetries ?? 3;\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms));\n\t}\n\n\tprivate isRetryableError(error: unknown): boolean {\n\t\tif (error instanceof CiaoApiError) {\n\t\t\treturn [0, 429, 500, 502, 503, 504].includes(error.statusCode);\n\t\t}\n\t\treturn (\n\t\t\terror instanceof Error &&\n\t\t\t(error.name === \"AbortError\" || error.message.includes(\"network\"))\n\t\t);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tprivate async requestWithRetry<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tif (this.maxRetries === 0) {\n\t\t\treturn this.request<T>(method, path, body);\n\t\t}\n\n\t\tconst delays = [1000, 2000, 4000];\n\t\tlet lastError: Error | undefined;\n\n\t\tfor (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await this.request<T>(method, path, body);\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error as Error;\n\t\t\t\tif (!this.isRetryableError(error) || attempt === this.maxRetries) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst delay = delays[attempt] ?? delays[delays.length - 1];\n\t\t\t\tawait this.sleep(delay);\n\t\t\t}\n\t\t}\n\t\tthrow lastError;\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.requestWithRetry<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.requestWithRetry<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n\tsignal?: AbortSignal;\n}\n\nconst DEFAULT_OPTIONS: Required<\n\tOmit<PollingOptions, \"onProgress\" | \"signal\">\n> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress, signal } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tif (signal?.aborted) {\n\t\t\tthrow new Error(\"Polling cancelled\");\n\t\t}\n\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval, signal);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(new Error(\"Polling cancelled\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst timeoutId = setTimeout(resolve, ms);\n\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\treject(new Error(\"Polling cancelled\"));\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tconst relativePath = path.relative(cwd, absolutePath) || absolutePath;\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${relativePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\tconst relativePath = path.relative(process.cwd(), configPath) || configPath;\n\ttry {\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${relativePath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${relativePath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tawait fs.mkdir(outputDir, { recursive: true });\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tawait fs.writeFile(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages\n\t\t.map((l) => JSON.stringify(l))\n\t\t.join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: ${JSON.stringify(data.version)},\n\tprojectId: ${JSON.stringify(data.projectId)},\n\tsourceLanguage: ${JSON.stringify(data.sourceLanguage)},\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: ${JSON.stringify(data.generatedAt)},\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t${JSON.stringify(lang)}: ${JSON.stringify(url)}`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages\n\t\t.map((l) => JSON.stringify(l))\n\t\t.join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: ${JSON.stringify(data.version)},\n\tprojectId: ${JSON.stringify(data.projectId)},\n\tsourceLanguage: ${JSON.stringify(data.sourceLanguage)},\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: ${JSON.stringify(data.generatedAt)},\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { extractStrings } from \"experimental-ciao-oxc\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst code = await fs.readFile(filePath, \"utf-8\");\n\t\tconst result = extractStrings(code, filePath);\n\n\t\tif (result.strings.length === 0 && result.contextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: result.strings,\n\t\t\tcontextBlocks: result.contextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "experimental-ciao-core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core utilities for ciao-tools - API client, config loading, manifest generation, and string extraction",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -46,16 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"experimental-ciao-
|
|
49
|
+
"experimental-ciao-oxc": "^1.1.12",
|
|
50
50
|
"glob": "^11.0.0"
|
|
51
|
-
},
|
|
52
|
-
"peerDependencies": {
|
|
53
|
-
"@babel/core": "^7.0.0"
|
|
54
|
-
},
|
|
55
|
-
"devDependencies": {
|
|
56
|
-
"@babel/core": "^7.24.0",
|
|
57
|
-
"@babel/preset-react": "^7.24.0",
|
|
58
|
-
"@babel/preset-typescript": "^7.24.0",
|
|
59
|
-
"@types/babel__core": "^7.20.5"
|
|
60
51
|
}
|
|
61
52
|
}
|