experimental-ciao-core 1.0.3 → 1.0.4

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 CHANGED
@@ -298,7 +298,6 @@ async function extractStringsFromFile(filePath) {
298
298
  ".jsx"
299
299
  ].includes(ext)) return null;
300
300
  const isTypeScript = ext === ".ts" || ext === ".tsx";
301
- const isJSX = ext === ".tsx" || ext === ".jsx";
302
301
  let extractedStrings = [];
303
302
  let extractedContextBlocks = [];
304
303
  const extractionPlugin = (0, experimental_ciao_babel.createExtractionPlugin)({ onComplete: (result) => {
@@ -307,10 +306,10 @@ async function extractStringsFromFile(filePath) {
307
306
  } });
308
307
  const presets = [];
309
308
  if (isTypeScript) presets.push([require.resolve("@babel/preset-typescript"), {
310
- isTSX: isJSX,
309
+ isTSX: true,
311
310
  allExtensions: true
312
311
  }]);
313
- if (isJSX) presets.push([require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
312
+ presets.push([require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
314
313
  try {
315
314
  await __babel_core.transformAsync(code, {
316
315
  filename: filePath,
@@ -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\tconst isJSX = ext === \".tsx\" || ext === \".jsx\";\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: isJSX, allExtensions: true },\n\t\t]);\n\t}\n\n\tif (isJSX) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t\t{ runtime: \"automatic\" },\n\t\t]);\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 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAa,gBAAb,MAA2B;CAC1B,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,SAA2B;AACtC,OAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,GAAG;AACjD,OAAK,SAAS,QAAQ;AACtB,OAAK,UAAU,QAAQ,WAAW;;CAGnC,MAAc,QACb,QACA,MACA,MACa;EACb,MAAM,MAAM,GAAG,KAAK,UAAU;EAC9B,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,KAAK,QAAQ;AAEpE,MAAI;GACH,MAAM,WAAW,MAAM,MAAM,KAAK;IACjC;IACA,SAAS;KACR,gBAAgB;KAChB,eAAe,UAAU,KAAK;KAC9B;IACD,MAAM,OAAO,KAAK,UAAU,KAAK,GAAG;IACpC,QAAQ,WAAW;IACnB,CAAC;AAEF,gBAAa,UAAU;AAEvB,OAAI,CAAC,SAAS,IAAI;IACjB,IAAIA;AACJ,QAAI;AACH,iBAAY,MAAM,SAAS,MAAM;YAC1B;AACP,iBAAY;MACX,MAAM,QAAQ,SAAS;MACvB,SAAS,SAAS;MAClB;;AAEF,UAAM,IAAI,aACT,UAAU,SACV,UAAU,MACV,SAAS,QACT,UAAU,QACV;;AAGF,UAAO,SAAS,MAAM;WACd,OAAO;AACf,gBAAa,UAAU;AACvB,OAAI,iBAAiB,aACpB,OAAM;AAEP,OAAI,iBAAiB,OAAO;AAC3B,QAAI,MAAM,SAAS,aAClB,OAAM,IAAI,aAAa,qBAAqB,WAAW,EAAE;AAE1D,UAAM,IAAI,aAAa,MAAM,SAAS,iBAAiB,EAAE;;AAE1D,SAAM,IAAI,aAAa,iBAAiB,WAAW,EAAE;;;CAIvD,MAAM,kBACL,aAC+B;AAC/B,SAAO,KAAK,QACX,QACA,sCACA,EAAE,aAAa,CACf;;CAGF,MAAM,aAAa,OAA2C;AAC7D,SAAO,KAAK,QACX,OACA,wBAAwB,QACxB;;;AAIH,IAAa,eAAb,cAAkC,MAAM;CACvC,YACC,SACA,AAAOC,MACP,AAAOC,YACP,AAAOC,SACN;AACD,QAAM,QAAQ;EAJP;EACA;EACA;AAGP,OAAK,OAAO;;;;;;AC1Fd,MAAMC,kBAAgE;CACrE,iBAAiB;CACjB,aAAa;CACb,aAAa;CACb,mBAAmB;CACnB;AAED,eAAsB,qBACrB,QACA,OACA,UAA0B,EAAE,EACC;CAC7B,MAAM,EAAE,iBAAiB,aAAa,aAAa,sBAAsB;EACxE,GAAG;EACH,GAAG;EACH;CACD,MAAM,EAAE,eAAe;CAEvB,IAAI,kBAAkB;CACtB,IAAI,WAAW;AAEf,QAAO,WAAW,aAAa;EAC9B,MAAM,SAAS,MAAM,OAAO,aAAa,MAAM;AAE/C,MAAI,WACH,YAAW,OAAO;AAGnB,MAAI,OAAO,WAAW,YACrB,QAAO;AAGR,MAAI,OAAO,WAAW,SACrB,OAAM,IAAI,MAAM,OAAO,SAAS,gCAAgC;AAGjE,QAAM,MAAM,gBAAgB;AAC5B,oBAAkB,KAAK,IACtB,kBAAkB,mBAClB,YACA;AACD;;AAGD,OAAM,IAAI,MAAM,+BAA+B,YAAY,WAAW;;AAGvE,SAAS,MAAM,IAA2B;AACzC,QAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;;;;ACzDzD,MAAaC,iBAAwD;CACpE,SAAS;EACR;EACA;EACA;EACA;EACA;CACD,SAAS;EACR;EACA;EACA;EACA;EACA;EACA;EACA;CACD,WAAW;CACX,WAAW;CACX;AAED,MAAa,oBAAoB;CAChC;CACA;CACA;CACA;;;;ACfD,eAAsB,WACrB,UAA6B,EAAE,EACD;CAC9B,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,IAAI,aAAa,QAAQ;AAEzB,KAAI,CAAC,WACJ,MAAK,MAAM,YAAY,mBAAmB;EACzC,MAAM,YAAYC,UAAK,KAAK,KAAK,SAAS;AAC1C,MAAIC,QAAG,WAAW,UAAU,EAAE;AAC7B,gBAAa;AACb;;;AAKH,KAAI,CAAC,WACJ,OAAM,IAAI,oBACT,0DACA;CAGF,MAAM,eAAeD,UAAK,WAAW,WAAW,GAC7C,aACAA,UAAK,KAAK,KAAK,WAAW;AAE7B,KAAI,CAACC,QAAG,WAAW,aAAa,CAC/B,OAAM,IAAI,oBAAoB,0BAA0B,eAAe;AAIxE,QAAO,cADQ,MAAM,aAAa,aAAa,EAClB,IAAI;;AAGlC,eAAe,aAAa,YAAyC;AACpE,KAAI;EAKH,MAAMC,WAAS,OAHC,WAAW,WAAW,UAAU,UAC7C,qBACA,UAAU;EAEb,MAAM,SAASA,SAAO,WAAWA;AAEjC,MAAI,CAAC,UAAU,OAAO,WAAW,SAChC,OAAM,IAAI,sBAAsB,oCAAoC;AAGrE,SAAO;UACC,OAAO;AACf,MAAI,iBAAiB,sBACpB,OAAM;AAEP,MAAI,iBAAiB,MACpB,OAAM,IAAI,sBACT,+BAA+B,WAAW,KAAK,MAAM,UACrD;AAEF,QAAM,IAAI,sBACT,+BAA+B,aAC/B;;;AAIH,SAAS,cAAc,QAAoB,KAAiC;AAC3E,KAAI,CAAC,OAAO,UACX,OAAM,IAAI,sBAAsB,0CAA0C;CAG3E,MAAM,YAAY,OAAO,aAAa,eAAe;CACrD,MAAM,oBAAoBF,UAAK,WAAW,UAAU,GACjD,YACAA,UAAK,KAAK,KAAK,UAAU;AAE5B,QAAO;EACN,WAAW,OAAO;EAClB,SAAS,OAAO;EAChB,SAAS,OAAO,WAAW,eAAe;EAC1C,SAAS,OAAO,WAAW,eAAe;EAC1C,WAAW;EACX,WAAW,OAAO,aAAa,eAAe;EAC9C;;AAGF,IAAa,sBAAb,cAAyC,MAAM;CAC9C,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAId,IAAa,wBAAb,cAA2C,MAAM;CAChD,YAAY,SAAiB;AAC5B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;ACrFd,SAAgB,iBAAiB,QAAgC;AAChE,QAAO;;;;;ACfR,eAAsB,qBACrB,SACkB;CAClB,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,CAACG,QAAG,WAAW,UAAU,CAC5B,SAAG,UAAU,WAAW,EAAE,WAAW,MAAM,CAAC;CAG7C,MAAM,eAAeC,UAAK,KAAK,WAAW,mBAAmB;CAC7D,MAAM,UAAU,wBAAwB,KAAK;AAE7C,SAAG,cAAc,cAAc,SAAS,QAAQ;AAEhD,QAAO;;AAGR,SAAS,wBAAwB,MAA4B;CAC5D,MAAM,iBAAiB,OAAO,QAAQ,KAAK,QAAQ,CACjD,KAAK,CAAC,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI,GAAG,CAC7C,KAAK,MAAM;CAEb,MAAM,iBAAiB,KAAK,UAAU,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK;AAErE,QAAO;mBACW,KAAK,YAAY;;;aAGvB,KAAK,QAAQ;eACX,KAAK,UAAU;oBACV,KAAK,eAAe;eACzB,eAAe;;EAE5B,eAAe;;iBAEA,KAAK,YAAY;;;;;;;;AASlC,SAAgB,mBACf,WACA,gBACA,WACA,SACA,SACe;AACf,QAAO;EACN;EACA;EACA;EACA;EACA;EACA,8BAAa,IAAI,MAAM,EAAC,aAAa;EACrC;;;;;AClDF,eAAsB,0BACrB,SACmC;CACnC,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;CACxC,MAAMC,aAAmC,EAAE;CAC3C,MAAMC,mBAAmC,EAAE;CAC3C,IAAI,iBAAiB;CAErB,MAAM,QAAQ,qBAAW,QAAQ,SAAS;EACzC;EACA,QAAQ,QAAQ;EAChB,UAAU;EACV,OAAO;EACP,CAAC;AAEF,MAAK,MAAM,YAAY,OAAO;EAC7B,MAAM,SAAS,MAAM,uBAAuB,SAAS;AACrD,MAAI,QAAQ;AACX,gBAAa,YAAY,OAAO,QAAQ;AACxC,sBAAmB,kBAAkB,OAAO,cAAc;AAC1D;;;AAIF,QAAO;EACN,SAAS;EACT,eAAe;EACf;EACA,cAAc,WAAW;EACzB;;AAGF,eAAe,uBACd,UAIS;CACT,MAAM,OAAOC,QAAG,aAAa,UAAU,QAAQ;CAC/C,MAAM,MAAMC,UAAK,QAAQ,SAAS;AAElC,KAAI,CAAC;EAAC;EAAO;EAAQ;EAAO;EAAO,CAAC,SAAS,IAAI,CAChD,QAAO;CAGR,MAAM,eAAe,QAAQ,SAAS,QAAQ;CAE9C,IAAIC,mBAAyC,EAAE;CAC/C,IAAIC,yBAAyC,EAAE;CAE/C,MAAM,uEAA0C,EAC/C,aAAa,WAAW;AACvB,qBAAmB,OAAO;AAC1B,2BAAyB,OAAO;IAEjC,CAAC;CAEF,MAAMC,UAA8B,EAAE;AAEtC,KAAI,aACH,SAAQ,KAAK,CACZ,QAAQ,QAAQ,2BAA2B,EAC3C;EAAE,OAAO;EAAM,eAAe;EAAM,CACpC,CAAC;AAGH,SAAQ,KAAK,CACZ,QAAQ,QAAQ,sBAAsB,EACtC,EAAE,SAAS,aAAa,CACxB,CAAC;AAEF,KAAI;AACH,QAAMC,aAAM,eAAe,MAAM;GAChC,UAAU;GACV;GACA,SAAS,CAAC,iBAAiB;GAC3B,SAAS;GACT,YAAY;GACZ,CAAC;AAEF,MAAI,iBAAiB,WAAW,KAAK,uBAAuB,WAAW,EACtE,QAAO;AAGR,SAAO;GACN,SAAS;GACT,eAAe;GACf;UACO,OAAO;AACf,UAAQ,KAAK,yCAAyC,SAAS,IAAI,MAAM;AACzE,SAAO;;;AAIT,SAAS,aACR,QACA,QACO;AACP,MAAK,MAAM,OAAO,OAOjB,KAAI,CANgB,OAAO,MACzB,MACA,EAAE,SAAS,IAAI,QACf,EAAE,YAAY,IAAI,WAClB,EAAE,yBAAyB,IAAI,qBAChC,CAEA,QAAO,KAAK,IAAI;;AAKnB,SAAS,mBACR,QACA,QACO;AACP,MAAK,MAAM,SAAS,OAEnB,KAAI,CADgB,OAAO,MAAM,MAAM,EAAE,OAAO,MAAM,GAAG,CAExD,QAAO,KAAK,MAAM"}
@@ -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":"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"}
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
@@ -273,7 +273,6 @@ async function extractStringsFromFile(filePath) {
273
273
  ".jsx"
274
274
  ].includes(ext)) return null;
275
275
  const isTypeScript = ext === ".ts" || ext === ".tsx";
276
- const isJSX = ext === ".tsx" || ext === ".jsx";
277
276
  let extractedStrings = [];
278
277
  let extractedContextBlocks = [];
279
278
  const extractionPlugin = createExtractionPlugin({ onComplete: (result) => {
@@ -282,10 +281,10 @@ async function extractStringsFromFile(filePath) {
282
281
  } });
283
282
  const presets = [];
284
283
  if (isTypeScript) presets.push([__require.resolve("@babel/preset-typescript"), {
285
- isTSX: isJSX,
284
+ isTSX: true,
286
285
  allExtensions: true
287
286
  }]);
288
- if (isJSX) presets.push([__require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
287
+ presets.push([__require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
289
288
  try {
290
289
  await babel.transformAsync(code, {
291
290
  filename: filePath,
@@ -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\tconst isJSX = ext === \".tsx\" || ext === \".jsx\";\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: isJSX, allExtensions: true },\n\t\t]);\n\t}\n\n\tif (isJSX) {\n\t\tpresets.push([\n\t\t\trequire.resolve(\"@babel/preset-react\"),\n\t\t\t{ runtime: \"automatic\" },\n\t\t]);\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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ciao-core",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
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.0.3",
49
+ "experimental-ciao-babel": "^1.0.4",
50
50
  "glob": "^11.0.0"
51
51
  },
52
52
  "peerDependencies": {