experimental-ciao-core 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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:
|
|
309
|
+
isTSX: true,
|
|
311
310
|
allExtensions: true
|
|
312
311
|
}]);
|
|
313
|
-
|
|
312
|
+
presets.push([require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
|
|
314
313
|
try {
|
|
315
314
|
await __babel_core.transformAsync(code, {
|
|
316
315
|
filename: filePath,
|
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\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":"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"}
|
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,
|
|
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.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
|
@@ -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:
|
|
284
|
+
isTSX: true,
|
|
286
285
|
allExtensions: true
|
|
287
286
|
}]);
|
|
288
|
-
|
|
287
|
+
presets.push([__require.resolve("@babel/preset-react"), { runtime: "automatic" }]);
|
|
289
288
|
try {
|
|
290
289
|
await babel.transformAsync(code, {
|
|
291
290
|
filename: filePath,
|
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\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
|
+
"version": "1.1.0",
|
|
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
|
|
49
|
+
"experimental-ciao-babel": "^1.1.0",
|
|
50
50
|
"glob": "^11.0.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|