experimental-ciao-core 1.1.13 → 1.1.15
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 +146 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +22 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +144 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -86,16 +86,12 @@ var CiaoApiClient = class {
|
|
|
86
86
|
});
|
|
87
87
|
clearTimeout(timeoutId);
|
|
88
88
|
if (!response.ok) {
|
|
89
|
-
let errorData;
|
|
89
|
+
let errorData = {};
|
|
90
90
|
try {
|
|
91
91
|
errorData = await response.json();
|
|
92
|
-
} catch {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
message: response.statusText
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
throw new CiaoApiError(errorData.message, errorData.code, response.status, errorData.details);
|
|
92
|
+
} catch {}
|
|
93
|
+
const code = errorData.code ?? `HTTP_${response.status}`;
|
|
94
|
+
throw new CiaoApiError(errorData.message ?? errorData.error ?? (response.statusText || "Unknown error"), code, response.status, errorData.details);
|
|
99
95
|
}
|
|
100
96
|
return response.json();
|
|
101
97
|
} catch (error) {
|
|
@@ -188,6 +184,7 @@ function sleep(ms, signal) {
|
|
|
188
184
|
//#endregion
|
|
189
185
|
//#region src/config/defaults.ts
|
|
190
186
|
const DEFAULT_CONFIG = {
|
|
187
|
+
projectType: "client",
|
|
191
188
|
include: [
|
|
192
189
|
"src/**/*.{ts,tsx,js,jsx}",
|
|
193
190
|
"app/**/*.{ts,tsx,js,jsx}",
|
|
@@ -241,6 +238,7 @@ async function importConfig(configPath) {
|
|
|
241
238
|
if (!config || typeof config !== "object") throw new ConfigValidationError("Config file must export an object");
|
|
242
239
|
return config;
|
|
243
240
|
} catch (error) {
|
|
241
|
+
console.log("error", error);
|
|
244
242
|
if (error instanceof ConfigValidationError) throw error;
|
|
245
243
|
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${relativePath}): ${error.message}`);
|
|
246
244
|
throw new ConfigValidationError(`Failed to load config file: ${relativePath}`);
|
|
@@ -252,6 +250,8 @@ function resolveConfig(config, cwd) {
|
|
|
252
250
|
const resolvedOutputDir = node_path.isAbsolute(outputDir) ? outputDir : node_path.join(cwd, outputDir);
|
|
253
251
|
return {
|
|
254
252
|
projectId: config.projectId,
|
|
253
|
+
projectType: config.projectType ?? DEFAULT_CONFIG.projectType,
|
|
254
|
+
framework: config.framework,
|
|
255
255
|
include: config.include ?? DEFAULT_CONFIG.include,
|
|
256
256
|
exclude: config.exclude ?? DEFAULT_CONFIG.exclude,
|
|
257
257
|
outputDir: resolvedOutputDir
|
|
@@ -394,6 +394,141 @@ function mergeContextBlocks(target, source) {
|
|
|
394
394
|
for (const block of source) if (!target.some((b) => b.id === block.id)) target.push(block);
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/interpolation/index.ts
|
|
399
|
+
const MAX_CACHE_SIZE = 100;
|
|
400
|
+
function createBoundedCache(maxSize) {
|
|
401
|
+
const cache = /* @__PURE__ */ new Map();
|
|
402
|
+
return {
|
|
403
|
+
get(key) {
|
|
404
|
+
return cache.get(key);
|
|
405
|
+
},
|
|
406
|
+
set(key, value) {
|
|
407
|
+
if (cache.size >= maxSize) {
|
|
408
|
+
const firstKey = cache.keys().next().value;
|
|
409
|
+
if (firstKey !== void 0) cache.delete(firstKey);
|
|
410
|
+
}
|
|
411
|
+
cache.set(key, value);
|
|
412
|
+
},
|
|
413
|
+
has(key) {
|
|
414
|
+
return cache.has(key);
|
|
415
|
+
},
|
|
416
|
+
clear() {
|
|
417
|
+
cache.clear();
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
const numberFormatCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
422
|
+
const dateFormatCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
423
|
+
const pluralRulesCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
424
|
+
function clearFormatterCache() {
|
|
425
|
+
numberFormatCache.clear();
|
|
426
|
+
dateFormatCache.clear();
|
|
427
|
+
pluralRulesCache.clear();
|
|
428
|
+
}
|
|
429
|
+
function getNumberFormatter(locale) {
|
|
430
|
+
const key = `number:${locale}`;
|
|
431
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, { maximumFractionDigits: 20 }));
|
|
432
|
+
return numberFormatCache.get(key);
|
|
433
|
+
}
|
|
434
|
+
function getCurrencyFormatter(locale, currency) {
|
|
435
|
+
const key = `currency:${locale}:${currency}`;
|
|
436
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, {
|
|
437
|
+
style: "currency",
|
|
438
|
+
currency
|
|
439
|
+
}));
|
|
440
|
+
return numberFormatCache.get(key);
|
|
441
|
+
}
|
|
442
|
+
function getPercentFormatter(locale) {
|
|
443
|
+
const key = `percent:${locale}`;
|
|
444
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, {
|
|
445
|
+
style: "percent",
|
|
446
|
+
minimumFractionDigits: 0,
|
|
447
|
+
maximumFractionDigits: 2
|
|
448
|
+
}));
|
|
449
|
+
return numberFormatCache.get(key);
|
|
450
|
+
}
|
|
451
|
+
function getDateFormatter(locale, style) {
|
|
452
|
+
const key = `date:${locale}:${style}`;
|
|
453
|
+
if (!dateFormatCache.has(key)) {
|
|
454
|
+
const options = { dateStyle: style };
|
|
455
|
+
dateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));
|
|
456
|
+
}
|
|
457
|
+
return dateFormatCache.get(key);
|
|
458
|
+
}
|
|
459
|
+
function getTimeFormatter(locale, style) {
|
|
460
|
+
const key = `time:${locale}:${style}`;
|
|
461
|
+
if (!dateFormatCache.has(key)) {
|
|
462
|
+
const options = { timeStyle: style };
|
|
463
|
+
dateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));
|
|
464
|
+
}
|
|
465
|
+
return dateFormatCache.get(key);
|
|
466
|
+
}
|
|
467
|
+
function getPluralRules(locale) {
|
|
468
|
+
if (!pluralRulesCache.has(locale)) pluralRulesCache.set(locale, new Intl.PluralRules(locale));
|
|
469
|
+
return pluralRulesCache.get(locale);
|
|
470
|
+
}
|
|
471
|
+
function formatValue(value, format, locale) {
|
|
472
|
+
if (value === null || value === void 0) return "";
|
|
473
|
+
if (!format) return String(value);
|
|
474
|
+
const parts = format.split(":");
|
|
475
|
+
switch (parts[0]) {
|
|
476
|
+
case "number": {
|
|
477
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
478
|
+
if (Number.isNaN(num)) return String(value);
|
|
479
|
+
return getNumberFormatter(locale).format(num);
|
|
480
|
+
}
|
|
481
|
+
case "currency": {
|
|
482
|
+
const currency = parts[1];
|
|
483
|
+
if (!currency) return String(value);
|
|
484
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
485
|
+
if (Number.isNaN(num)) return String(value);
|
|
486
|
+
return getCurrencyFormatter(locale, currency).format(num);
|
|
487
|
+
}
|
|
488
|
+
case "percent": {
|
|
489
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
490
|
+
if (Number.isNaN(num)) return String(value);
|
|
491
|
+
return getPercentFormatter(locale).format(num);
|
|
492
|
+
}
|
|
493
|
+
case "date":
|
|
494
|
+
if (!(value instanceof Date)) return String(value);
|
|
495
|
+
return getDateFormatter(locale, parts[1] || "medium").format(value);
|
|
496
|
+
case "time":
|
|
497
|
+
if (!(value instanceof Date)) return String(value);
|
|
498
|
+
return getTimeFormatter(locale, parts[1] || "medium").format(value);
|
|
499
|
+
case "plural": {
|
|
500
|
+
const singular = parts[1];
|
|
501
|
+
const plural = parts[2];
|
|
502
|
+
if (!singular || !plural) return String(value);
|
|
503
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
504
|
+
return getPluralRules(locale).select(num) === "one" ? singular : plural;
|
|
505
|
+
}
|
|
506
|
+
default: return String(value);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function interpolate(text, values, locale) {
|
|
510
|
+
const escaped = text.replace(/\{\{/g, "\0").replace(/\}\}/g, "");
|
|
511
|
+
let result;
|
|
512
|
+
if (!values || Object.keys(values).length === 0) result = escaped;
|
|
513
|
+
else result = escaped.replace(/\{([^}]+)\}/g, (match, placeholder) => {
|
|
514
|
+
const trimmed = placeholder.trim();
|
|
515
|
+
const colonIndex = trimmed.indexOf(":");
|
|
516
|
+
let key;
|
|
517
|
+
let format;
|
|
518
|
+
if (colonIndex === -1) {
|
|
519
|
+
key = trimmed;
|
|
520
|
+
format = void 0;
|
|
521
|
+
} else {
|
|
522
|
+
key = trimmed.substring(0, colonIndex);
|
|
523
|
+
format = trimmed.substring(colonIndex + 1);
|
|
524
|
+
}
|
|
525
|
+
if (!(key in values)) return match;
|
|
526
|
+
const value = values[key];
|
|
527
|
+
return formatValue(value, format, locale);
|
|
528
|
+
});
|
|
529
|
+
return result.replace(/\x00/g, "{").replace(/\x01/g, "}");
|
|
530
|
+
}
|
|
531
|
+
|
|
397
532
|
//#endregion
|
|
398
533
|
exports.CONFIG_FILE_NAMES = CONFIG_FILE_NAMES;
|
|
399
534
|
exports.CiaoApiClient = CiaoApiClient;
|
|
@@ -401,10 +536,13 @@ exports.CiaoApiError = CiaoApiError;
|
|
|
401
536
|
exports.ConfigNotFoundError = ConfigNotFoundError;
|
|
402
537
|
exports.ConfigValidationError = ConfigValidationError;
|
|
403
538
|
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
539
|
+
exports.clearFormatterCache = clearFormatterCache;
|
|
404
540
|
exports.createManifestData = createManifestData;
|
|
405
541
|
exports.defineCiaoConfig = defineCiaoConfig;
|
|
406
542
|
exports.extractStringsFromProject = extractStringsFromProject;
|
|
543
|
+
exports.formatValue = formatValue;
|
|
407
544
|
exports.generateManifestFile = generateManifestFile;
|
|
545
|
+
exports.interpolate = interpolate;
|
|
408
546
|
exports.loadConfig = loadConfig;
|
|
409
547
|
exports.pollJobUntilComplete = pollJobUntilComplete;
|
|
410
548
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["errorData: Record<string, unknown>","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","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined"],"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","../src/interpolation/index.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: Record<string, unknown> = {};\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\t// JSON parsing failed - keep errorData empty\n\t\t\t\t}\n\n\t\t\t\tconst code =\n\t\t\t\t\t(errorData.code as string) ?? `HTTP_${response.status}`;\n\t\t\t\tconst message =\n\t\t\t\t\t(errorData.message as string) ??\n\t\t\t\t\t(errorData.error as string) ??\n\t\t\t\t\t(response.statusText || \"Unknown error\");\n\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\tmessage,\n\t\t\t\t\tcode,\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\tprojectType: \"client\",\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 console.log('error', 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\tprojectType: config.projectType ?? DEFAULT_CONFIG.projectType,\n\t\tframework: config.framework,\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 type ProjectType = \"client\" | \"server\";\nexport type Framework = \"react\" | \"express\";\n\nexport interface CiaoConfig {\n\tprojectId: string;\n\tprojectType?: ProjectType;\n\tframework?: Framework;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tprojectType: ProjectType;\n\tframework?: Framework;\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","export type InterpolationValues = Record<string, unknown>;\n\nconst MAX_CACHE_SIZE = 100;\n\ninterface BoundedCache<K, V> {\n\tget(key: K): V | undefined;\n\tset(key: K, value: V): void;\n\thas(key: K): boolean;\n\tclear(): void;\n}\n\nfunction createBoundedCache<K, V>(maxSize: number): BoundedCache<K, V> {\n\tconst cache = new Map<K, V>();\n\treturn {\n\t\tget(key: K): V | undefined {\n\t\t\treturn cache.get(key);\n\t\t},\n\t\tset(key: K, value: V): void {\n\t\t\tif (cache.size >= maxSize) {\n\t\t\t\tconst firstKey = cache.keys().next().value;\n\t\t\t\tif (firstKey !== undefined) {\n\t\t\t\t\tcache.delete(firstKey);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcache.set(key, value);\n\t\t},\n\t\thas(key: K): boolean {\n\t\t\treturn cache.has(key);\n\t\t},\n\t\tclear(): void {\n\t\t\tcache.clear();\n\t\t},\n\t};\n}\n\nconst numberFormatCache = createBoundedCache<string, Intl.NumberFormat>(MAX_CACHE_SIZE);\nconst dateFormatCache = createBoundedCache<string, Intl.DateTimeFormat>(MAX_CACHE_SIZE);\nconst pluralRulesCache = createBoundedCache<string, Intl.PluralRules>(MAX_CACHE_SIZE);\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nexport function formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -93,14 +93,20 @@ interface PollingOptions {
|
|
|
93
93
|
declare function pollJobUntilComplete(client: CiaoApiClient, jobId: string, options?: PollingOptions): Promise<JobStatusResponse>;
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region src/config/types.d.ts
|
|
96
|
+
type ProjectType = "client" | "server";
|
|
97
|
+
type Framework = "react" | "express";
|
|
96
98
|
interface CiaoConfig {
|
|
97
99
|
projectId: string;
|
|
100
|
+
projectType?: ProjectType;
|
|
101
|
+
framework?: Framework;
|
|
98
102
|
include?: string[];
|
|
99
103
|
exclude?: string[];
|
|
100
104
|
outputDir?: string;
|
|
101
105
|
}
|
|
102
106
|
interface ResolvedCiaoConfig {
|
|
103
107
|
projectId: string;
|
|
108
|
+
projectType: ProjectType;
|
|
109
|
+
framework?: Framework;
|
|
104
110
|
include: string[];
|
|
105
111
|
exclude: string[];
|
|
106
112
|
outputDir: string;
|
|
@@ -138,6 +144,15 @@ interface ManifestData {
|
|
|
138
144
|
cdnUrls: Record<string, string>;
|
|
139
145
|
generatedAt: string;
|
|
140
146
|
}
|
|
147
|
+
interface ServerManifestData {
|
|
148
|
+
version: string;
|
|
149
|
+
projectId: string;
|
|
150
|
+
projectType: "server";
|
|
151
|
+
sourceLanguage: string;
|
|
152
|
+
languages: string[];
|
|
153
|
+
translationsDir: string;
|
|
154
|
+
generatedAt: string;
|
|
155
|
+
}
|
|
141
156
|
interface GenerateManifestOptions {
|
|
142
157
|
outputDir: string;
|
|
143
158
|
data: ManifestData;
|
|
@@ -164,5 +179,11 @@ interface ProjectExtractionResult {
|
|
|
164
179
|
//#region src/extraction/runner.d.ts
|
|
165
180
|
declare function extractStringsFromProject(options: ExtractionOptions): Promise<ProjectExtractionResult>;
|
|
166
181
|
//#endregion
|
|
167
|
-
|
|
182
|
+
//#region src/interpolation/index.d.ts
|
|
183
|
+
type InterpolationValues = Record<string, unknown>;
|
|
184
|
+
declare function clearFormatterCache(): void;
|
|
185
|
+
declare function formatValue(value: unknown, format: string | undefined, locale: string): string;
|
|
186
|
+
declare function interpolate(text: string, values: InterpolationValues | undefined, locale: string): string;
|
|
187
|
+
//#endregion
|
|
188
|
+
export { type ApiClientOptions, type ContextBlock as ApiContextBlock, type ApiError, type TranslatableString as ApiTranslatableString, type BuildSchemaMetadata, type BuildSchemaRequest, CONFIG_FILE_NAMES, CiaoApiClient, CiaoApiError, type CiaoConfig, ConfigNotFoundError, ConfigValidationError, type ContextBlock$1 as ContextBlock, DEFAULT_CONFIG, type ExtractionOptions, type ExtractionResult, type Framework, type GenerateManifestOptions, type InterpolationValues, type JobStatusResponse, type LoadConfigOptions, type LoadConfigResult, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ProjectType, type ResolvedCiaoConfig, type ServerManifestData, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, clearFormatterCache, createManifestData, defineCiaoConfig, extractStringsFromProject, formatValue, generateManifestFile, interpolate, loadConfig, pollJobUntilComplete };
|
|
168
189
|
//# sourceMappingURL=index.d.cts.map
|
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;;AAID,UAVC,mBAAA,CAUD;EACL,WAAA,EAAA,MAAA;EAAmB,YAAA,EAAA,MAAA;EAGb,kBAAc,EAAA,MAAA;AAM/B;AAQiB,UAtBA,kBAAA,CAsBmB;EACrB,OAAA,EAAA,KAAA;EAGuB,SAAA,EAAA,MAAA;EAAf,OAAA,EAvBb,kBAuBa,EAAA;EAAM,aAAA,EAtBb,YAsBa,EAAA;EAGZ,QAAA,EAxBN,mBAwBuB;AAUlC;AAMiB,UArCA,cAAA,CAqCgB;;;;ACrDjC;AAMsB,UDgBL,YAAA,CChBK;
|
|
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","../src/interpolation/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -93,14 +93,20 @@ interface PollingOptions {
|
|
|
93
93
|
declare function pollJobUntilComplete(client: CiaoApiClient, jobId: string, options?: PollingOptions): Promise<JobStatusResponse>;
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region src/config/types.d.ts
|
|
96
|
+
type ProjectType = "client" | "server";
|
|
97
|
+
type Framework = "react" | "express";
|
|
96
98
|
interface CiaoConfig {
|
|
97
99
|
projectId: string;
|
|
100
|
+
projectType?: ProjectType;
|
|
101
|
+
framework?: Framework;
|
|
98
102
|
include?: string[];
|
|
99
103
|
exclude?: string[];
|
|
100
104
|
outputDir?: string;
|
|
101
105
|
}
|
|
102
106
|
interface ResolvedCiaoConfig {
|
|
103
107
|
projectId: string;
|
|
108
|
+
projectType: ProjectType;
|
|
109
|
+
framework?: Framework;
|
|
104
110
|
include: string[];
|
|
105
111
|
exclude: string[];
|
|
106
112
|
outputDir: string;
|
|
@@ -138,6 +144,15 @@ interface ManifestData {
|
|
|
138
144
|
cdnUrls: Record<string, string>;
|
|
139
145
|
generatedAt: string;
|
|
140
146
|
}
|
|
147
|
+
interface ServerManifestData {
|
|
148
|
+
version: string;
|
|
149
|
+
projectId: string;
|
|
150
|
+
projectType: "server";
|
|
151
|
+
sourceLanguage: string;
|
|
152
|
+
languages: string[];
|
|
153
|
+
translationsDir: string;
|
|
154
|
+
generatedAt: string;
|
|
155
|
+
}
|
|
141
156
|
interface GenerateManifestOptions {
|
|
142
157
|
outputDir: string;
|
|
143
158
|
data: ManifestData;
|
|
@@ -164,5 +179,11 @@ interface ProjectExtractionResult {
|
|
|
164
179
|
//#region src/extraction/runner.d.ts
|
|
165
180
|
declare function extractStringsFromProject(options: ExtractionOptions): Promise<ProjectExtractionResult>;
|
|
166
181
|
//#endregion
|
|
167
|
-
|
|
182
|
+
//#region src/interpolation/index.d.ts
|
|
183
|
+
type InterpolationValues = Record<string, unknown>;
|
|
184
|
+
declare function clearFormatterCache(): void;
|
|
185
|
+
declare function formatValue(value: unknown, format: string | undefined, locale: string): string;
|
|
186
|
+
declare function interpolate(text: string, values: InterpolationValues | undefined, locale: string): string;
|
|
187
|
+
//#endregion
|
|
188
|
+
export { type ApiClientOptions, type ContextBlock as ApiContextBlock, type ApiError, type TranslatableString as ApiTranslatableString, type BuildSchemaMetadata, type BuildSchemaRequest, CONFIG_FILE_NAMES, CiaoApiClient, CiaoApiError, type CiaoConfig, ConfigNotFoundError, ConfigValidationError, type ContextBlock$1 as ContextBlock, DEFAULT_CONFIG, type ExtractionOptions, type ExtractionResult, type Framework, type GenerateManifestOptions, type InterpolationValues, type JobStatusResponse, type LoadConfigOptions, type LoadConfigResult, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ProjectType, type ResolvedCiaoConfig, type ServerManifestData, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, clearFormatterCache, createManifestData, defineCiaoConfig, extractStringsFromProject, formatValue, generateManifestFile, interpolate, loadConfig, pollJobUntilComplete };
|
|
168
189
|
//# sourceMappingURL=index.d.mts.map
|
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;;AAID,UAVC,mBAAA,CAUD;EACL,WAAA,EAAA,MAAA;EAAmB,YAAA,EAAA,MAAA;EAGb,kBAAc,EAAA,MAAA;AAM/B;AAQiB,UAtBA,kBAAA,CAsBmB;EACrB,OAAA,EAAA,KAAA;EAGuB,SAAA,EAAA,MAAA;EAAf,OAAA,EAvBb,kBAuBa,EAAA;EAAM,aAAA,EAtBb,YAsBa,EAAA;EAGZ,QAAA,EAxBN,mBAwBuB;AAUlC;AAMiB,UArCA,cAAA,CAqCgB;;;;ACrDjC;AAMsB,UDgBL,YAAA,CChBK;
|
|
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","../src/interpolation/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -56,16 +56,12 @@ var CiaoApiClient = class {
|
|
|
56
56
|
});
|
|
57
57
|
clearTimeout(timeoutId);
|
|
58
58
|
if (!response.ok) {
|
|
59
|
-
let errorData;
|
|
59
|
+
let errorData = {};
|
|
60
60
|
try {
|
|
61
61
|
errorData = await response.json();
|
|
62
|
-
} catch {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
message: response.statusText
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
throw new CiaoApiError(errorData.message, errorData.code, response.status, errorData.details);
|
|
62
|
+
} catch {}
|
|
63
|
+
const code = errorData.code ?? `HTTP_${response.status}`;
|
|
64
|
+
throw new CiaoApiError(errorData.message ?? errorData.error ?? (response.statusText || "Unknown error"), code, response.status, errorData.details);
|
|
69
65
|
}
|
|
70
66
|
return response.json();
|
|
71
67
|
} catch (error) {
|
|
@@ -158,6 +154,7 @@ function sleep(ms, signal) {
|
|
|
158
154
|
//#endregion
|
|
159
155
|
//#region src/config/defaults.ts
|
|
160
156
|
const DEFAULT_CONFIG = {
|
|
157
|
+
projectType: "client",
|
|
161
158
|
include: [
|
|
162
159
|
"src/**/*.{ts,tsx,js,jsx}",
|
|
163
160
|
"app/**/*.{ts,tsx,js,jsx}",
|
|
@@ -211,6 +208,7 @@ async function importConfig(configPath) {
|
|
|
211
208
|
if (!config || typeof config !== "object") throw new ConfigValidationError("Config file must export an object");
|
|
212
209
|
return config;
|
|
213
210
|
} catch (error) {
|
|
211
|
+
console.log("error", error);
|
|
214
212
|
if (error instanceof ConfigValidationError) throw error;
|
|
215
213
|
if (error instanceof Error) throw new ConfigValidationError(`Failed to load config file (${relativePath}): ${error.message}`);
|
|
216
214
|
throw new ConfigValidationError(`Failed to load config file: ${relativePath}`);
|
|
@@ -222,6 +220,8 @@ function resolveConfig(config, cwd) {
|
|
|
222
220
|
const resolvedOutputDir = path.isAbsolute(outputDir) ? outputDir : path.join(cwd, outputDir);
|
|
223
221
|
return {
|
|
224
222
|
projectId: config.projectId,
|
|
223
|
+
projectType: config.projectType ?? DEFAULT_CONFIG.projectType,
|
|
224
|
+
framework: config.framework,
|
|
225
225
|
include: config.include ?? DEFAULT_CONFIG.include,
|
|
226
226
|
exclude: config.exclude ?? DEFAULT_CONFIG.exclude,
|
|
227
227
|
outputDir: resolvedOutputDir
|
|
@@ -365,5 +365,140 @@ function mergeContextBlocks(target, source) {
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
//#endregion
|
|
368
|
-
|
|
368
|
+
//#region src/interpolation/index.ts
|
|
369
|
+
const MAX_CACHE_SIZE = 100;
|
|
370
|
+
function createBoundedCache(maxSize) {
|
|
371
|
+
const cache = /* @__PURE__ */ new Map();
|
|
372
|
+
return {
|
|
373
|
+
get(key) {
|
|
374
|
+
return cache.get(key);
|
|
375
|
+
},
|
|
376
|
+
set(key, value) {
|
|
377
|
+
if (cache.size >= maxSize) {
|
|
378
|
+
const firstKey = cache.keys().next().value;
|
|
379
|
+
if (firstKey !== void 0) cache.delete(firstKey);
|
|
380
|
+
}
|
|
381
|
+
cache.set(key, value);
|
|
382
|
+
},
|
|
383
|
+
has(key) {
|
|
384
|
+
return cache.has(key);
|
|
385
|
+
},
|
|
386
|
+
clear() {
|
|
387
|
+
cache.clear();
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const numberFormatCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
392
|
+
const dateFormatCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
393
|
+
const pluralRulesCache = createBoundedCache(MAX_CACHE_SIZE);
|
|
394
|
+
function clearFormatterCache() {
|
|
395
|
+
numberFormatCache.clear();
|
|
396
|
+
dateFormatCache.clear();
|
|
397
|
+
pluralRulesCache.clear();
|
|
398
|
+
}
|
|
399
|
+
function getNumberFormatter(locale) {
|
|
400
|
+
const key = `number:${locale}`;
|
|
401
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, { maximumFractionDigits: 20 }));
|
|
402
|
+
return numberFormatCache.get(key);
|
|
403
|
+
}
|
|
404
|
+
function getCurrencyFormatter(locale, currency) {
|
|
405
|
+
const key = `currency:${locale}:${currency}`;
|
|
406
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, {
|
|
407
|
+
style: "currency",
|
|
408
|
+
currency
|
|
409
|
+
}));
|
|
410
|
+
return numberFormatCache.get(key);
|
|
411
|
+
}
|
|
412
|
+
function getPercentFormatter(locale) {
|
|
413
|
+
const key = `percent:${locale}`;
|
|
414
|
+
if (!numberFormatCache.has(key)) numberFormatCache.set(key, new Intl.NumberFormat(locale, {
|
|
415
|
+
style: "percent",
|
|
416
|
+
minimumFractionDigits: 0,
|
|
417
|
+
maximumFractionDigits: 2
|
|
418
|
+
}));
|
|
419
|
+
return numberFormatCache.get(key);
|
|
420
|
+
}
|
|
421
|
+
function getDateFormatter(locale, style) {
|
|
422
|
+
const key = `date:${locale}:${style}`;
|
|
423
|
+
if (!dateFormatCache.has(key)) {
|
|
424
|
+
const options = { dateStyle: style };
|
|
425
|
+
dateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));
|
|
426
|
+
}
|
|
427
|
+
return dateFormatCache.get(key);
|
|
428
|
+
}
|
|
429
|
+
function getTimeFormatter(locale, style) {
|
|
430
|
+
const key = `time:${locale}:${style}`;
|
|
431
|
+
if (!dateFormatCache.has(key)) {
|
|
432
|
+
const options = { timeStyle: style };
|
|
433
|
+
dateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));
|
|
434
|
+
}
|
|
435
|
+
return dateFormatCache.get(key);
|
|
436
|
+
}
|
|
437
|
+
function getPluralRules(locale) {
|
|
438
|
+
if (!pluralRulesCache.has(locale)) pluralRulesCache.set(locale, new Intl.PluralRules(locale));
|
|
439
|
+
return pluralRulesCache.get(locale);
|
|
440
|
+
}
|
|
441
|
+
function formatValue(value, format, locale) {
|
|
442
|
+
if (value === null || value === void 0) return "";
|
|
443
|
+
if (!format) return String(value);
|
|
444
|
+
const parts = format.split(":");
|
|
445
|
+
switch (parts[0]) {
|
|
446
|
+
case "number": {
|
|
447
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
448
|
+
if (Number.isNaN(num)) return String(value);
|
|
449
|
+
return getNumberFormatter(locale).format(num);
|
|
450
|
+
}
|
|
451
|
+
case "currency": {
|
|
452
|
+
const currency = parts[1];
|
|
453
|
+
if (!currency) return String(value);
|
|
454
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
455
|
+
if (Number.isNaN(num)) return String(value);
|
|
456
|
+
return getCurrencyFormatter(locale, currency).format(num);
|
|
457
|
+
}
|
|
458
|
+
case "percent": {
|
|
459
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
460
|
+
if (Number.isNaN(num)) return String(value);
|
|
461
|
+
return getPercentFormatter(locale).format(num);
|
|
462
|
+
}
|
|
463
|
+
case "date":
|
|
464
|
+
if (!(value instanceof Date)) return String(value);
|
|
465
|
+
return getDateFormatter(locale, parts[1] || "medium").format(value);
|
|
466
|
+
case "time":
|
|
467
|
+
if (!(value instanceof Date)) return String(value);
|
|
468
|
+
return getTimeFormatter(locale, parts[1] || "medium").format(value);
|
|
469
|
+
case "plural": {
|
|
470
|
+
const singular = parts[1];
|
|
471
|
+
const plural = parts[2];
|
|
472
|
+
if (!singular || !plural) return String(value);
|
|
473
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
474
|
+
return getPluralRules(locale).select(num) === "one" ? singular : plural;
|
|
475
|
+
}
|
|
476
|
+
default: return String(value);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function interpolate(text, values, locale) {
|
|
480
|
+
const escaped = text.replace(/\{\{/g, "\0").replace(/\}\}/g, "");
|
|
481
|
+
let result;
|
|
482
|
+
if (!values || Object.keys(values).length === 0) result = escaped;
|
|
483
|
+
else result = escaped.replace(/\{([^}]+)\}/g, (match, placeholder) => {
|
|
484
|
+
const trimmed = placeholder.trim();
|
|
485
|
+
const colonIndex = trimmed.indexOf(":");
|
|
486
|
+
let key;
|
|
487
|
+
let format;
|
|
488
|
+
if (colonIndex === -1) {
|
|
489
|
+
key = trimmed;
|
|
490
|
+
format = void 0;
|
|
491
|
+
} else {
|
|
492
|
+
key = trimmed.substring(0, colonIndex);
|
|
493
|
+
format = trimmed.substring(colonIndex + 1);
|
|
494
|
+
}
|
|
495
|
+
if (!(key in values)) return match;
|
|
496
|
+
const value = values[key];
|
|
497
|
+
return formatValue(value, format, locale);
|
|
498
|
+
});
|
|
499
|
+
return result.replace(/\x00/g, "{").replace(/\x01/g, "}");
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
//#endregion
|
|
503
|
+
export { CONFIG_FILE_NAMES, CiaoApiClient, CiaoApiError, ConfigNotFoundError, ConfigValidationError, DEFAULT_CONFIG, clearFormatterCache, createManifestData, defineCiaoConfig, extractStringsFromProject, formatValue, generateManifestFile, interpolate, loadConfig, pollJobUntilComplete };
|
|
369
504
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["path","errorData: Record<string, unknown>","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[]","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined"],"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","../src/interpolation/index.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: Record<string, unknown> = {};\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\t// JSON parsing failed - keep errorData empty\n\t\t\t\t}\n\n\t\t\t\tconst code =\n\t\t\t\t\t(errorData.code as string) ?? `HTTP_${response.status}`;\n\t\t\t\tconst message =\n\t\t\t\t\t(errorData.message as string) ??\n\t\t\t\t\t(errorData.error as string) ??\n\t\t\t\t\t(response.statusText || \"Unknown error\");\n\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\tmessage,\n\t\t\t\t\tcode,\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\tprojectType: \"client\",\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 console.log('error', 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\tprojectType: config.projectType ?? DEFAULT_CONFIG.projectType,\n\t\tframework: config.framework,\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 type ProjectType = \"client\" | \"server\";\nexport type Framework = \"react\" | \"express\";\n\nexport interface CiaoConfig {\n\tprojectId: string;\n\tprojectType?: ProjectType;\n\tframework?: Framework;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tprojectType: ProjectType;\n\tframework?: Framework;\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","export type InterpolationValues = Record<string, unknown>;\n\nconst MAX_CACHE_SIZE = 100;\n\ninterface BoundedCache<K, V> {\n\tget(key: K): V | undefined;\n\tset(key: K, value: V): void;\n\thas(key: K): boolean;\n\tclear(): void;\n}\n\nfunction createBoundedCache<K, V>(maxSize: number): BoundedCache<K, V> {\n\tconst cache = new Map<K, V>();\n\treturn {\n\t\tget(key: K): V | undefined {\n\t\t\treturn cache.get(key);\n\t\t},\n\t\tset(key: K, value: V): void {\n\t\t\tif (cache.size >= maxSize) {\n\t\t\t\tconst firstKey = cache.keys().next().value;\n\t\t\t\tif (firstKey !== undefined) {\n\t\t\t\t\tcache.delete(firstKey);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcache.set(key, value);\n\t\t},\n\t\thas(key: K): boolean {\n\t\t\treturn cache.has(key);\n\t\t},\n\t\tclear(): void {\n\t\t\tcache.clear();\n\t\t},\n\t};\n}\n\nconst numberFormatCache = createBoundedCache<string, Intl.NumberFormat>(MAX_CACHE_SIZE);\nconst dateFormatCache = createBoundedCache<string, Intl.DateTimeFormat>(MAX_CACHE_SIZE);\nconst pluralRulesCache = createBoundedCache<string, Intl.PluralRules>(MAX_CACHE_SIZE);\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nexport function formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\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.15",
|
|
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,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"experimental-ciao-oxc": "^1.1.
|
|
49
|
+
"experimental-ciao-oxc": "^1.1.15",
|
|
50
50
|
"glob": "^11.0.0"
|
|
51
51
|
}
|
|
52
52
|
}
|