experimental-ciao-core 1.1.4 → 1.1.6
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 +31 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +31 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -171,7 +171,13 @@ async function loadConfig(options = {}) {
|
|
|
171
171
|
if (!configPath) throw new ConfigNotFoundError(`No ciao.config.ts found. Run 'ciao init' to create one.`);
|
|
172
172
|
const absolutePath = node_path.isAbsolute(configPath) ? configPath : node_path.join(cwd, configPath);
|
|
173
173
|
if (!node_fs.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${absolutePath}`);
|
|
174
|
-
|
|
174
|
+
const config = await importConfig(absolutePath);
|
|
175
|
+
const useTypeScript = absolutePath.endsWith(".ts");
|
|
176
|
+
return {
|
|
177
|
+
config: resolveConfig(config, cwd),
|
|
178
|
+
configFilePath: absolutePath,
|
|
179
|
+
useTypeScript
|
|
180
|
+
};
|
|
175
181
|
}
|
|
176
182
|
async function importConfig(configPath) {
|
|
177
183
|
try {
|
|
@@ -220,14 +226,15 @@ function defineCiaoConfig(config) {
|
|
|
220
226
|
//#endregion
|
|
221
227
|
//#region src/manifest/generator.ts
|
|
222
228
|
async function generateManifestFile(options) {
|
|
223
|
-
const { outputDir, data } = options;
|
|
229
|
+
const { outputDir, data, useTypeScript = true } = options;
|
|
224
230
|
if (!node_fs.existsSync(outputDir)) node_fs.mkdirSync(outputDir, { recursive: true });
|
|
225
|
-
const
|
|
226
|
-
const
|
|
231
|
+
const extension = useTypeScript ? "ts" : "js";
|
|
232
|
+
const manifestPath = node_path.join(outputDir, `ciao-manifest.${extension}`);
|
|
233
|
+
const content = useTypeScript ? generateTypeScriptManifestContent(data) : generateJavaScriptManifestContent(data);
|
|
227
234
|
node_fs.writeFileSync(manifestPath, content, "utf-8");
|
|
228
235
|
return manifestPath;
|
|
229
236
|
}
|
|
230
|
-
function
|
|
237
|
+
function generateTypeScriptManifestContent(data) {
|
|
231
238
|
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t"${lang}": "${url}"`).join(",\n");
|
|
232
239
|
const languagesArray = data.languages.map((l) => `"${l}"`).join(", ");
|
|
233
240
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
@@ -249,6 +256,25 @@ export type CiaoLanguage = (typeof ciaoManifest.languages)[number];
|
|
|
249
256
|
export type CiaoManifest = typeof ciaoManifest;
|
|
250
257
|
`;
|
|
251
258
|
}
|
|
259
|
+
function generateJavaScriptManifestContent(data) {
|
|
260
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t"${lang}": "${url}"`).join(",\n");
|
|
261
|
+
const languagesArray = data.languages.map((l) => `"${l}"`).join(", ");
|
|
262
|
+
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
263
|
+
// Generated at: ${data.generatedAt}
|
|
264
|
+
|
|
265
|
+
/** @type {import("experimental-ciao-react").CiaoManifest} */
|
|
266
|
+
export const ciaoManifest = {
|
|
267
|
+
version: "${data.version}",
|
|
268
|
+
projectId: "${data.projectId}",
|
|
269
|
+
sourceLanguage: "${data.sourceLanguage}",
|
|
270
|
+
languages: [${languagesArray}],
|
|
271
|
+
cdnUrls: {
|
|
272
|
+
${cdnUrlsEntries}
|
|
273
|
+
},
|
|
274
|
+
generatedAt: "${data.generatedAt}",
|
|
275
|
+
};
|
|
276
|
+
`;
|
|
277
|
+
}
|
|
252
278
|
function createManifestData(projectId, sourceLanguage, languages, cdnUrls, version) {
|
|
253
279
|
return {
|
|
254
280
|
version,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","path","fs","module","fs","path","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","fs","path","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]","babel"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<ResolvedCiaoConfig> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\treturn resolveConfig(config, cwd);\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst manifestPath = path.join(outputDir, \"ciao-manifest.ts\");\n\tconst content = generateManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","path","fs","module","fs","path","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","fs","path","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]","babel"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: \"${data.generatedAt}\",\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -111,7 +111,12 @@ interface LoadConfigOptions {
|
|
|
111
111
|
cwd?: string;
|
|
112
112
|
configPath?: string;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
interface LoadConfigResult {
|
|
115
|
+
config: ResolvedCiaoConfig;
|
|
116
|
+
configFilePath: string;
|
|
117
|
+
useTypeScript: boolean;
|
|
118
|
+
}
|
|
119
|
+
declare function loadConfig(options?: LoadConfigOptions): Promise<LoadConfigResult>;
|
|
115
120
|
declare class ConfigNotFoundError extends Error {
|
|
116
121
|
constructor(message: string);
|
|
117
122
|
}
|
|
@@ -135,6 +140,7 @@ interface ManifestData {
|
|
|
135
140
|
interface GenerateManifestOptions {
|
|
136
141
|
outputDir: string;
|
|
137
142
|
data: ManifestData;
|
|
143
|
+
useTypeScript?: boolean;
|
|
138
144
|
}
|
|
139
145
|
//#endregion
|
|
140
146
|
//#region src/manifest/generator.d.ts
|
|
@@ -157,5 +163,5 @@ interface ProjectExtractionResult {
|
|
|
157
163
|
//#region src/extraction/runner.d.ts
|
|
158
164
|
declare function extractStringsFromProject(options: ExtractionOptions): Promise<ProjectExtractionResult>;
|
|
159
165
|
//#endregion
|
|
160
|
-
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 GenerateManifestOptions, type JobStatusResponse, type LoadConfigOptions, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ResolvedCiaoConfig, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, createManifestData, defineCiaoConfig, extractStringsFromProject, generateManifestFile, loadConfig, pollJobUntilComplete };
|
|
166
|
+
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 GenerateManifestOptions, type JobStatusResponse, type LoadConfigOptions, type LoadConfigResult, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ResolvedCiaoConfig, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, createManifestData, defineCiaoConfig, extractStringsFromProject, generateManifestFile, loadConfig, pollJobUntilComplete };
|
|
161
167
|
//# 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;;AAKD,UAXC,mBAAA,CAWD;EACL,WAAA,EAAA,MAAA;EAAmB,YAAA,EAAA,MAAA;EAGb,kBAAc,EAAA,MAAA;AAM/B;AAQiB,UAvBA,kBAAA,CAuBmB;EACrB,OAAA,EAAA,KAAA;EAGuB,SAAA,EAAA,MAAA;EAAf,OAAA,CAAA,EAAA,MAAA;EAAM,OAAA,EAvBnB,kBAuBmB,EAAA;EAGZ,aAAA,EAzBD,YAyBkB,EAAA;EAUjB,QAAA,EAlCN,mBAkCc;AAMzB;UArCiB,cAAA;;;ECjBJ,GAAA,CAAA,EAAA,MAAA;;AAoEE,UD7CE,YAAA,CC6CF;EACH,OAAA,EAAA,KAAA;EAAR,SAAA,EAAA,MAAA;EAQwC,cAAA,EAAA,MAAA;EAAR,WAAA,EAAA,MAAA;EAAO,eAAA,EDjDzB,cCiDyB,EAAA;AAQ3C;UDtDiB,mBAAA;gBACF;;EErCE,MAAA,EAAA,SAAc,GAAA,YAKR,GAAA,WAAiB;EAUlB,mBAAA,CAAA,EFyBC,MEzBmB,CAAA,MAAA,EFyBJ,MEzBI,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;AAGhC,UFyBO,iBAAA,CEzBP;EACC,KAAA,EAAA,MAAA;EAAR,MAAA,EAAA,SAAA,GAAA,YAAA,GAAA,WAAA,GAAA,QAAA;EAAO,QAAA,CAAA,EAAA,MAAA;eF4BI;;;EGlDG,WAAA,CAAA,EAAU,MAAA;AAS3B;AASgB,UHsCC,QAAA,CGtCe;;;;ACbhC;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -111,7 +111,12 @@ interface LoadConfigOptions {
|
|
|
111
111
|
cwd?: string;
|
|
112
112
|
configPath?: string;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
interface LoadConfigResult {
|
|
115
|
+
config: ResolvedCiaoConfig;
|
|
116
|
+
configFilePath: string;
|
|
117
|
+
useTypeScript: boolean;
|
|
118
|
+
}
|
|
119
|
+
declare function loadConfig(options?: LoadConfigOptions): Promise<LoadConfigResult>;
|
|
115
120
|
declare class ConfigNotFoundError extends Error {
|
|
116
121
|
constructor(message: string);
|
|
117
122
|
}
|
|
@@ -135,6 +140,7 @@ interface ManifestData {
|
|
|
135
140
|
interface GenerateManifestOptions {
|
|
136
141
|
outputDir: string;
|
|
137
142
|
data: ManifestData;
|
|
143
|
+
useTypeScript?: boolean;
|
|
138
144
|
}
|
|
139
145
|
//#endregion
|
|
140
146
|
//#region src/manifest/generator.d.ts
|
|
@@ -157,5 +163,5 @@ interface ProjectExtractionResult {
|
|
|
157
163
|
//#region src/extraction/runner.d.ts
|
|
158
164
|
declare function extractStringsFromProject(options: ExtractionOptions): Promise<ProjectExtractionResult>;
|
|
159
165
|
//#endregion
|
|
160
|
-
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 GenerateManifestOptions, type JobStatusResponse, type LoadConfigOptions, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ResolvedCiaoConfig, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, createManifestData, defineCiaoConfig, extractStringsFromProject, generateManifestFile, loadConfig, pollJobUntilComplete };
|
|
166
|
+
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 GenerateManifestOptions, type JobStatusResponse, type LoadConfigOptions, type LoadConfigResult, type ManifestData, type OutputConfig, type PollingOptions, type ProjectExtractionResult, type ResolvedCiaoConfig, type TargetLanguage, type TranslatableString$1 as TranslatableString, type TranslationResponse, createManifestData, defineCiaoConfig, extractStringsFromProject, generateManifestFile, loadConfig, pollJobUntilComplete };
|
|
161
167
|
//# 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;;AAKD,UAXC,mBAAA,CAWD;EACL,WAAA,EAAA,MAAA;EAAmB,YAAA,EAAA,MAAA;EAGb,kBAAc,EAAA,MAAA;AAM/B;AAQiB,UAvBA,kBAAA,CAuBmB;EACrB,OAAA,EAAA,KAAA;EAGuB,SAAA,EAAA,MAAA;EAAf,OAAA,CAAA,EAAA,MAAA;EAAM,OAAA,EAvBnB,kBAuBmB,EAAA;EAGZ,aAAA,EAzBD,YAyBkB,EAAA;EAUjB,QAAA,EAlCN,mBAkCc;AAMzB;UArCiB,cAAA;;;ECjBJ,GAAA,CAAA,EAAA,MAAA;;AAoEE,UD7CE,YAAA,CC6CF;EACH,OAAA,EAAA,KAAA;EAAR,SAAA,EAAA,MAAA;EAQwC,cAAA,EAAA,MAAA;EAAR,WAAA,EAAA,MAAA;EAAO,eAAA,EDjDzB,cCiDyB,EAAA;AAQ3C;UDtDiB,mBAAA;gBACF;;EErCE,MAAA,EAAA,SAAc,GAAA,YAKR,GAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/api/types.ts","../src/api/client.ts","../src/api/polling.ts","../src/config/types.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/manifest/types.ts","../src/manifest/generator.ts","../src/extraction/types.ts","../src/extraction/runner.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -146,7 +146,13 @@ async function loadConfig(options = {}) {
|
|
|
146
146
|
if (!configPath) throw new ConfigNotFoundError(`No ciao.config.ts found. Run 'ciao init' to create one.`);
|
|
147
147
|
const absolutePath = path.isAbsolute(configPath) ? configPath : path.join(cwd, configPath);
|
|
148
148
|
if (!fs.existsSync(absolutePath)) throw new ConfigNotFoundError(`Config file not found: ${absolutePath}`);
|
|
149
|
-
|
|
149
|
+
const config = await importConfig(absolutePath);
|
|
150
|
+
const useTypeScript = absolutePath.endsWith(".ts");
|
|
151
|
+
return {
|
|
152
|
+
config: resolveConfig(config, cwd),
|
|
153
|
+
configFilePath: absolutePath,
|
|
154
|
+
useTypeScript
|
|
155
|
+
};
|
|
150
156
|
}
|
|
151
157
|
async function importConfig(configPath) {
|
|
152
158
|
try {
|
|
@@ -195,14 +201,15 @@ function defineCiaoConfig(config) {
|
|
|
195
201
|
//#endregion
|
|
196
202
|
//#region src/manifest/generator.ts
|
|
197
203
|
async function generateManifestFile(options) {
|
|
198
|
-
const { outputDir, data } = options;
|
|
204
|
+
const { outputDir, data, useTypeScript = true } = options;
|
|
199
205
|
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
200
|
-
const
|
|
201
|
-
const
|
|
206
|
+
const extension = useTypeScript ? "ts" : "js";
|
|
207
|
+
const manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);
|
|
208
|
+
const content = useTypeScript ? generateTypeScriptManifestContent(data) : generateJavaScriptManifestContent(data);
|
|
202
209
|
fs.writeFileSync(manifestPath, content, "utf-8");
|
|
203
210
|
return manifestPath;
|
|
204
211
|
}
|
|
205
|
-
function
|
|
212
|
+
function generateTypeScriptManifestContent(data) {
|
|
206
213
|
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t"${lang}": "${url}"`).join(",\n");
|
|
207
214
|
const languagesArray = data.languages.map((l) => `"${l}"`).join(", ");
|
|
208
215
|
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
@@ -224,6 +231,25 @@ export type CiaoLanguage = (typeof ciaoManifest.languages)[number];
|
|
|
224
231
|
export type CiaoManifest = typeof ciaoManifest;
|
|
225
232
|
`;
|
|
226
233
|
}
|
|
234
|
+
function generateJavaScriptManifestContent(data) {
|
|
235
|
+
const cdnUrlsEntries = Object.entries(data.cdnUrls).map(([lang, url]) => `\t"${lang}": "${url}"`).join(",\n");
|
|
236
|
+
const languagesArray = data.languages.map((l) => `"${l}"`).join(", ");
|
|
237
|
+
return `// This file is auto-generated by ciao-tools. Do not edit manually.
|
|
238
|
+
// Generated at: ${data.generatedAt}
|
|
239
|
+
|
|
240
|
+
/** @type {import("experimental-ciao-react").CiaoManifest} */
|
|
241
|
+
export const ciaoManifest = {
|
|
242
|
+
version: "${data.version}",
|
|
243
|
+
projectId: "${data.projectId}",
|
|
244
|
+
sourceLanguage: "${data.sourceLanguage}",
|
|
245
|
+
languages: [${languagesArray}],
|
|
246
|
+
cdnUrls: {
|
|
247
|
+
${cdnUrlsEntries}
|
|
248
|
+
},
|
|
249
|
+
generatedAt: "${data.generatedAt}",
|
|
250
|
+
};
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
227
253
|
function createManifestData(projectId, sourceLanguage, languages, cdnUrls, version) {
|
|
228
254
|
return {
|
|
229
255
|
version,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["path","errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<ResolvedCiaoConfig> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\treturn resolveConfig(config, cwd);\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst manifestPath = path.join(outputDir, \"ciao-manifest.ts\");\n\tconst content = generateManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["path","errorData: ApiError","code: string","statusCode: number","details?: unknown","DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">>","DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\">","allStrings: TranslatableString[]","allContextBlocks: ContextBlock[]","extractedStrings: TranslatableString[]","extractedContextBlocks: ContextBlock[]","presets: babel.PluginItem[]"],"sources":["../src/api/client.ts","../src/api/polling.ts","../src/config/defaults.ts","../src/config/loader.ts","../src/config/types.ts","../src/manifest/generator.ts","../src/extraction/runner.ts"],"sourcesContent":["import type {\n\tApiClientOptions,\n\tApiError,\n\tBuildSchemaRequest,\n\tJobStatusResponse,\n\tTranslationResponse,\n} from \"./types\";\n\nexport class CiaoApiClient {\n\tprivate baseUrl: string;\n\tprivate apiKey: string;\n\tprivate timeout: number;\n\n\tconstructor(options: ApiClientOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? 30000;\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorData: ApiError;\n\t\t\t\ttry {\n\t\t\t\t\terrorData = await response.json();\n\t\t\t\t} catch {\n\t\t\t\t\terrorData = {\n\t\t\t\t\t\tcode: `HTTP_${response.status}`,\n\t\t\t\t\t\tmessage: response.statusText,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(\n\t\t\t\t\terrorData.message,\n\t\t\t\t\terrorData.code,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\terrorData.details,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.json() as Promise<T>;\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (error instanceof CiaoApiError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error instanceof Error) {\n\t\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\t\tthrow new CiaoApiError(\"Request timed out\", \"TIMEOUT\", 0);\n\t\t\t\t}\n\t\t\t\tthrow new CiaoApiError(error.message, \"NETWORK_ERROR\", 0);\n\t\t\t}\n\t\t\tthrow new CiaoApiError(\"Unknown error\", \"UNKNOWN\", 0);\n\t\t}\n\t}\n\n\tasync submitBuildSchema(\n\t\tbuildSchema: BuildSchemaRequest,\n\t): Promise<TranslationResponse> {\n\t\treturn this.request<TranslationResponse>(\n\t\t\t\"POST\",\n\t\t\t\"/api/translation/translate-strings\",\n\t\t\t{ buildSchema },\n\t\t);\n\t}\n\n\tasync getJobStatus(jobId: string): Promise<JobStatusResponse> {\n\t\treturn this.request<JobStatusResponse>(\n\t\t\t\"GET\",\n\t\t\t`/api/translation/job/${jobId}`,\n\t\t);\n\t}\n}\n\nexport class CiaoApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic statusCode: number,\n\t\tpublic details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CiaoApiError\";\n\t}\n}\n","import type { CiaoApiClient } from \"./client\";\nimport type { JobStatusResponse } from \"./types\";\n\nexport interface PollingOptions {\n\tinitialInterval?: number;\n\tmaxInterval?: number;\n\tmaxAttempts?: number;\n\tbackoffMultiplier?: number;\n\tonProgress?: (status: JobStatusResponse) => void;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<PollingOptions, \"onProgress\">> = {\n\tinitialInterval: 1000,\n\tmaxInterval: 10000,\n\tmaxAttempts: 120,\n\tbackoffMultiplier: 1.5,\n};\n\nexport async function pollJobUntilComplete(\n\tclient: CiaoApiClient,\n\tjobId: string,\n\toptions: PollingOptions = {},\n): Promise<JobStatusResponse> {\n\tconst { initialInterval, maxInterval, maxAttempts, backoffMultiplier } = {\n\t\t...DEFAULT_OPTIONS,\n\t\t...options,\n\t};\n\tconst { onProgress } = options;\n\n\tlet currentInterval = initialInterval;\n\tlet attempts = 0;\n\n\twhile (attempts < maxAttempts) {\n\t\tconst status = await client.getJobStatus(jobId);\n\n\t\tif (onProgress) {\n\t\t\tonProgress(status);\n\t\t}\n\n\t\tif (status.status === \"completed\") {\n\t\t\treturn status;\n\t\t}\n\n\t\tif (status.status === \"failed\") {\n\t\t\tthrow new Error(status.error ?? \"Job failed with unknown error\");\n\t\t}\n\n\t\tawait sleep(currentInterval);\n\t\tcurrentInterval = Math.min(\n\t\t\tcurrentInterval * backoffMultiplier,\n\t\t\tmaxInterval,\n\t\t);\n\t\tattempts++;\n\t}\n\n\tthrow new Error(`Job polling timed out after ${maxAttempts} attempts`);\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ResolvedCiaoConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG: Omit<ResolvedCiaoConfig, \"projectId\"> = {\n\tinclude: [\n\t\t\"src/**/*.{ts,tsx,js,jsx}\",\n\t\t\"app/**/*.{ts,tsx,js,jsx}\",\n\t\t\"pages/**/*.{ts,tsx,js,jsx}\",\n\t\t\"components/**/*.{ts,tsx,js,jsx}\",\n\t],\n\texclude: [\n\t\t\"**/node_modules/**\",\n\t\t\"**/*.test.{ts,tsx,js,jsx}\",\n\t\t\"**/*.spec.{ts,tsx,js,jsx}\",\n\t\t\"**/__tests__/**\",\n\t\t\"**/dist/**\",\n\t\t\"**/.next/**\",\n\t],\n\toutputDir: \"__generated__\",\n\tserverUrl: \"https://server.ciao-tools.com\",\n};\n\nexport const CONFIG_FILE_NAMES = [\n\t\"ciao.config.ts\",\n\t\"ciao.config.js\",\n\t\"ciao.config.mjs\",\n] as const;\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { CONFIG_FILE_NAMES, DEFAULT_CONFIG } from \"./defaults\";\nimport type { CiaoConfig, ResolvedCiaoConfig } from \"./types\";\n\nexport interface LoadConfigOptions {\n\tcwd?: string;\n\tconfigPath?: string;\n}\n\nexport interface LoadConfigResult {\n\tconfig: ResolvedCiaoConfig;\n\tconfigFilePath: string;\n\tuseTypeScript: boolean;\n}\n\nexport async function loadConfig(\n\toptions: LoadConfigOptions = {},\n): Promise<LoadConfigResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tlet configPath = options.configPath;\n\n\tif (!configPath) {\n\t\tfor (const fileName of CONFIG_FILE_NAMES) {\n\t\t\tconst candidate = path.join(cwd, fileName);\n\t\t\tif (fs.existsSync(candidate)) {\n\t\t\t\tconfigPath = candidate;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!configPath) {\n\t\tthrow new ConfigNotFoundError(\n\t\t\t`No ciao.config.ts found. Run 'ciao init' to create one.`,\n\t\t);\n\t}\n\n\tconst absolutePath = path.isAbsolute(configPath)\n\t\t? configPath\n\t\t: path.join(cwd, configPath);\n\n\tif (!fs.existsSync(absolutePath)) {\n\t\tthrow new ConfigNotFoundError(`Config file not found: ${absolutePath}`);\n\t}\n\n\tconst config = await importConfig(absolutePath);\n\tconst useTypeScript = absolutePath.endsWith(\".ts\");\n\n\treturn {\n\t\tconfig: resolveConfig(config, cwd),\n\t\tconfigFilePath: absolutePath,\n\t\tuseTypeScript,\n\t};\n}\n\nasync function importConfig(configPath: string): Promise<CiaoConfig> {\n\ttry {\n\t\t// Use file:// URL for ESM compatibility\n\t\tconst fileUrl = configPath.startsWith(\"file://\")\n\t\t\t? configPath\n\t\t\t: `file://${configPath}`;\n\t\tconst module = await import(fileUrl);\n\t\tconst config = module.default ?? module;\n\n\t\tif (!config || typeof config !== \"object\") {\n\t\t\tthrow new ConfigValidationError(\"Config file must export an object\");\n\t\t}\n\n\t\treturn config as CiaoConfig;\n\t} catch (error) {\n\t\tif (error instanceof ConfigValidationError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new ConfigValidationError(\n\t\t\t\t`Failed to load config file (${configPath}): ${error.message}`,\n\t\t\t);\n\t\t}\n\t\tthrow new ConfigValidationError(\n\t\t\t`Failed to load config file: ${configPath}`,\n\t\t);\n\t}\n}\n\nfunction resolveConfig(config: CiaoConfig, cwd: string): ResolvedCiaoConfig {\n\tif (!config.projectId) {\n\t\tthrow new ConfigValidationError(\"projectId is required in ciao.config.ts\");\n\t}\n\n\tconst outputDir = config.outputDir ?? DEFAULT_CONFIG.outputDir;\n\tconst resolvedOutputDir = path.isAbsolute(outputDir)\n\t\t? outputDir\n\t\t: path.join(cwd, outputDir);\n\n\treturn {\n\t\tprojectId: config.projectId,\n\t\tstyleId: config.styleId,\n\t\tinclude: config.include ?? DEFAULT_CONFIG.include,\n\t\texclude: config.exclude ?? DEFAULT_CONFIG.exclude,\n\t\toutputDir: resolvedOutputDir,\n\t\tserverUrl: config.serverUrl ?? DEFAULT_CONFIG.serverUrl,\n\t};\n}\n\nexport class ConfigNotFoundError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigNotFoundError\";\n\t}\n}\n\nexport class ConfigValidationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n","export interface CiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude?: string[];\n\texclude?: string[];\n\toutputDir?: string;\n\tserverUrl?: string;\n}\n\nexport interface ResolvedCiaoConfig {\n\tprojectId: string;\n\tstyleId?: string;\n\tinclude: string[];\n\texclude: string[];\n\toutputDir: string;\n\tserverUrl: string;\n}\n\nexport function defineCiaoConfig(config: CiaoConfig): CiaoConfig {\n\treturn config;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { GenerateManifestOptions, ManifestData } from \"./types\";\n\nexport async function generateManifestFile(\n\toptions: GenerateManifestOptions,\n): Promise<string> {\n\tconst { outputDir, data, useTypeScript = true } = options;\n\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\tconst extension = useTypeScript ? \"ts\" : \"js\";\n\tconst manifestPath = path.join(outputDir, `ciao-manifest.${extension}`);\n\tconst content = useTypeScript\n\t\t? generateTypeScriptManifestContent(data)\n\t\t: generateJavaScriptManifestContent(data);\n\n\tfs.writeFileSync(manifestPath, content, \"utf-8\");\n\n\treturn manifestPath;\n}\n\nfunction generateTypeScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}] as const,\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t} as const,\n\tgeneratedAt: \"${data.generatedAt}\",\n} as const;\n\nexport type CiaoLanguage = (typeof ciaoManifest.languages)[number];\n\nexport type CiaoManifest = typeof ciaoManifest;\n`;\n}\n\nfunction generateJavaScriptManifestContent(data: ManifestData): string {\n\tconst cdnUrlsEntries = Object.entries(data.cdnUrls)\n\t\t.map(([lang, url]) => `\\t\"${lang}\": \"${url}\"`)\n\t\t.join(\",\\n\");\n\n\tconst languagesArray = data.languages.map((l) => `\"${l}\"`).join(\", \");\n\n\treturn `// This file is auto-generated by ciao-tools. Do not edit manually.\n// Generated at: ${data.generatedAt}\n\n/** @type {import(\"experimental-ciao-react\").CiaoManifest} */\nexport const ciaoManifest = {\n\tversion: \"${data.version}\",\n\tprojectId: \"${data.projectId}\",\n\tsourceLanguage: \"${data.sourceLanguage}\",\n\tlanguages: [${languagesArray}],\n\tcdnUrls: {\n${cdnUrlsEntries}\n\t},\n\tgeneratedAt: \"${data.generatedAt}\",\n};\n`;\n}\n\nexport function createManifestData(\n\tprojectId: string,\n\tsourceLanguage: string,\n\tlanguages: string[],\n\tcdnUrls: Record<string, string>,\n\tversion: string,\n): ManifestData {\n\treturn {\n\t\tversion,\n\t\tprojectId,\n\t\tsourceLanguage,\n\t\tlanguages,\n\t\tcdnUrls,\n\t\tgeneratedAt: new Date().toISOString(),\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as babel from \"@babel/core\";\nimport { createExtractionPlugin } from \"experimental-ciao-babel\";\nimport { glob } from \"glob\";\nimport type {\n\tContextBlock,\n\tExtractionOptions,\n\tProjectExtractionResult,\n\tTranslatableString,\n} from \"./types\";\n\nexport async function extractStringsFromProject(\n\toptions: ExtractionOptions,\n): Promise<ProjectExtractionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst allStrings: TranslatableString[] = [];\n\tconst allContextBlocks: ContextBlock[] = [];\n\tlet filesProcessed = 0;\n\n\tconst files = await glob(options.include, {\n\t\tcwd,\n\t\tignore: options.exclude,\n\t\tabsolute: true,\n\t\tnodir: true,\n\t});\n\n\tfor (const filePath of files) {\n\t\tconst result = await extractStringsFromFile(filePath);\n\t\tif (result) {\n\t\t\tmergeStrings(allStrings, result.strings);\n\t\t\tmergeContextBlocks(allContextBlocks, result.contextBlocks);\n\t\t\tfilesProcessed++;\n\t\t}\n\t}\n\n\treturn {\n\t\tstrings: allStrings,\n\t\tcontextBlocks: allContextBlocks,\n\t\tfilesProcessed,\n\t\ttotalStrings: allStrings.length,\n\t};\n}\n\nasync function extractStringsFromFile(\n\tfilePath: string,\n): Promise<{\n\tstrings: TranslatableString[];\n\tcontextBlocks: ContextBlock[];\n} | null> {\n\tconst code = fs.readFileSync(filePath, \"utf-8\");\n\tconst ext = path.extname(filePath);\n\n\tif (![\".ts\", \".tsx\", \".js\", \".jsx\"].includes(ext)) {\n\t\treturn null;\n\t}\n\n\tconst isTypeScript = ext === \".ts\" || ext === \".tsx\";\n\n\tlet extractedStrings: TranslatableString[] = [];\n\tlet extractedContextBlocks: ContextBlock[] = [];\n\n\tconst extractionPlugin = createExtractionPlugin({\n\t\tonComplete: (result) => {\n\t\t\textractedStrings = result.strings;\n\t\t\textractedContextBlocks = result.contextBlocks;\n\t\t},\n\t});\n\n\tconst presets: babel.PluginItem[] = [];\n\n\tif (isTypeScript) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-typescript\"),\n\t\t\t{ isTSX: true, allExtensions: true },\n\t\t]);\n\t}\n\n\tpresets.push([\n\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t{ runtime: \"automatic\" },\n\t]);\n\n\ttry {\n\t\tawait babel.transformAsync(code, {\n\t\t\tfilename: filePath,\n\t\t\tpresets,\n\t\t\tplugins: [extractionPlugin],\n\t\t\tbabelrc: false,\n\t\t\tconfigFile: false,\n\t\t});\n\n\t\tif (extractedStrings.length === 0 && extractedContextBlocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tstrings: extractedStrings,\n\t\t\tcontextBlocks: extractedContextBlocks,\n\t\t};\n\t} catch (error) {\n\t\tconsole.warn(`[ciao-tools] Warning: Failed to parse ${filePath}:`, error);\n\t\treturn null;\n\t}\n}\n\nfunction mergeStrings(\n\ttarget: TranslatableString[],\n\tsource: TranslatableString[],\n): void {\n\tfor (const str of source) {\n\t\tconst isDuplicate = target.some(\n\t\t\t(s) =>\n\t\t\t\ts.text === str.text &&\n\t\t\t\ts.context === str.context &&\n\t\t\t\ts.parentContextBlockId === str.parentContextBlockId,\n\t\t);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(str);\n\t\t}\n\t}\n}\n\nfunction mergeContextBlocks(\n\ttarget: ContextBlock[],\n\tsource: ContextBlock[],\n): void {\n\tfor (const block of source) {\n\t\tconst isDuplicate = target.some((b) => b.id === block.id);\n\t\tif (!isDuplicate) {\n\t\t\ttarget.push(block);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "experimental-ciao-core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
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-babel": "^1.1.
|
|
49
|
+
"experimental-ciao-babel": "^1.1.6",
|
|
50
50
|
"glob": "^11.0.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|