generaltranslation 9.0.3 → 9.0.5
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/CHANGELOG.md +22 -0
- package/dist/derive/condenseVars.js +2 -3
- package/dist/derive/utils/traverseHelpers.d.ts +1 -1
- package/dist/derive/utils/traverseHelpers.js +1 -1
- package/dist/derive/utils/traverseIcu.d.ts +1 -1
- package/dist/derive/utils/traverseIcu.js +1 -1
- package/dist/derive/utils/types.d.ts +1 -1
- package/dist/{derive-BvtWyo5B.cjs → derive-Cbl7M1SY.cjs} +7 -7
- package/dist/derive-Cbl7M1SY.cjs.map +1 -0
- package/dist/{derive-ClAsLQOX.mjs → derive-DDwuyrKI.mjs} +2 -2
- package/dist/derive-DDwuyrKI.mjs.map +1 -0
- package/dist/id.d.cts +1 -1
- package/dist/id.d.mts +1 -1
- package/dist/index.cjs +30 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -5
- package/dist/index.mjs +30 -13
- package/dist/index.mjs.map +1 -1
- package/dist/internal.cjs +4 -97
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/internal.mjs +3 -96
- package/dist/internal.mjs.map +1 -1
- package/dist/{runtime-WSpZppgm.mjs → runtime-DsKdTOSO.mjs} +2 -2
- package/dist/{runtime-WSpZppgm.mjs.map → runtime-DsKdTOSO.mjs.map} +1 -1
- package/dist/{runtime-wK7jzE9f.cjs → runtime-mKpF6P4Q.cjs} +2 -2
- package/dist/{runtime-wK7jzE9f.cjs.map → runtime-mKpF6P4Q.cjs.map} +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +3 -3
- package/dist/runtime.mjs +1 -1
- package/dist/translate/awaitJobs.js +76 -32
- package/dist/types-dir/config.d.ts +2 -0
- package/dist/{types-algPgkHv.d.mts → types-iO493WgK.d.mts} +3 -2
- package/dist/{types-f-_m5D_X.d.cts → types-wj-Dtih8.d.cts} +3 -2
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +3 -4
- package/dist/derive/utils/printIcuAst.d.ts +0 -12
- package/dist/derive/utils/printIcuAst.js +0 -138
- package/dist/derive-BvtWyo5B.cjs.map +0 -1
- package/dist/derive-ClAsLQOX.mjs.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/translate/setupProject.ts","../src/translate/utils/batch.ts","../src/translate/utils/validateFileFormatTransform.ts","../src/translate/enqueueFiles.ts","../src/translate/createTag.ts","../src/translate/downloadFileBatch.ts","../src/translate/submitUserEditDiffs.ts","../src/translate/uploadSourceFiles.ts","../src/translate/uploadTranslations.ts","../src/translate/querySourceFile.ts","../src/projects/getProjectData.ts","../src/translate/checkJobStatus.ts","../src/translate/awaitJobs.ts","../src/translate/queryFileData.ts","../src/translate/getProjectInfo.ts","../src/translate/queryBranchData.ts","../src/translate/createBranch.ts","../src/translate/processFileMoves.ts","../src/translate/getOrphanedFiles.ts","../src/translate/publishFiles.ts","../src/index.ts"],"sourcesContent":["import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { FileReference } from '../types-dir/api/file';\n\nexport type SetupProjectFileReference = Pick<\n FileReference,\n 'branchId' | 'fileId' | 'versionId'\n>;\n\nexport type SetupProjectResult =\n | { setupJobId: string; status: 'queued' }\n | { status: 'completed' };\n\nexport type SetupProjectOptions = {\n force?: boolean;\n locales?: string[];\n timeoutMs?: number;\n};\n\n/**\n * @internal\n * Enqueues files for project setup the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param config - The configuration for the API call.\n * @param timeoutMS - The timeout in milliseconds\n * @returns The result of the API call.\n */\nexport async function _setupProject(\n files: SetupProjectFileReference[],\n config: TranslationRequestConfig,\n options?: SetupProjectOptions\n): Promise<SetupProjectResult> {\n return apiRequest<SetupProjectResult>(config, '/v2/project/setup/generate', {\n body: {\n files: files.map((f) => ({\n branchId: f.branchId,\n fileId: f.fileId,\n versionId: f.versionId,\n })),\n locales: options?.locales,\n force: options?.force,\n },\n timeout: options?.timeoutMs,\n });\n}\n","/**\n * Splits an array into batches of a specified size.\n * @param items - The array to split into batches.\n * @param batchSize - The maximum size of each batch.\n * @returns An array of batches.\n */\nexport function createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n}\n\n/**\n * Result of processing batches.\n */\nexport interface BatchList<T> {\n /** The items successfully processed across all batches */\n data: T[];\n /** The total number of items processed */\n count: number;\n /** The number of batches processed */\n batchCount: number;\n}\n\n/**\n * Options for batch processing.\n */\nexport interface BatchProcessOptions {\n /** Maximum number of items per batch (default: 100) */\n batchSize?: number;\n /** Whether to process batches in parallel (default: true) */\n parallel?: boolean;\n}\n\n/**\n * Processes items in batches using a provided processor function.\n *\n * @param items - The items to process.\n * @param processor - Async function that processes a single batch and returns items.\n * @param options - Optional configuration for batch processing.\n * @returns Promise that resolves to a BatchList containing all processed items.\n *\n * @example\n * ```typescript\n * const result = await processBatches(\n * files,\n * async (batch) => {\n * const response = await uploadFiles(batch);\n * return response.uploadedFiles;\n * },\n * { batchSize: 100 }\n * );\n *\n * console.log(result.data); // All items\n * console.log(result.count); // Total count\n * console.log(result.batchCount); // Number of batches processed\n * ```\n */\nexport async function processBatches<TInput, TOutput>(\n items: TInput[],\n processor: (batch: TInput[]) => Promise<TOutput[]>,\n options: BatchProcessOptions = {}\n): Promise<BatchList<TOutput>> {\n const { batchSize = 100, parallel = true } = options;\n\n if (items.length === 0) {\n return {\n data: [],\n count: 0,\n batchCount: 0,\n };\n }\n\n const batches = createBatches(items, batchSize);\n const allItems: TOutput[] = [];\n\n if (parallel) {\n // Process all batches in parallel.\n const results = await Promise.all(batches.map((batch) => processor(batch)));\n for (const result of results) {\n if (result) {\n allItems.push(...result);\n }\n }\n } else {\n // Process batches sequentially.\n for (const batch of batches) {\n const result = await processor(batch);\n if (result) {\n allItems.push(...result);\n }\n }\n }\n\n return {\n data: allItems,\n count: allItems.length,\n batchCount: batches.length,\n };\n}\n","import type { FileFormat } from '../../types-dir/api/file';\nimport { isSupportedFileFormatTransform } from '../../utils/isSupportedFileFormatTransform';\n\nexport type FileFormatTransformInput = {\n fileFormat?: FileFormat;\n transformFormat?: FileFormat;\n fileName?: string;\n fileId?: string;\n};\n\n/**\n * Returns a user-facing validation error when a requested file format transform\n * is missing source format context or is not currently supported.\n */\nexport function getFileFormatTransformError(\n file: FileFormatTransformInput\n): string | undefined {\n if (!file.transformFormat) return undefined;\n const fileLabel = file.fileName ?? file.fileId ?? 'unknown file';\n if (!file.fileFormat) {\n return `fileFormat is required when transformFormat is provided for ${fileLabel}`;\n }\n if (!isSupportedFileFormatTransform(file.fileFormat, file.transformFormat)) {\n return `Unsupported file format transform: ${file.fileFormat} -> ${file.transformFormat}`;\n }\n return undefined;\n}\n\n/**\n * Validates file format transforms before sending upload/enqueue requests.\n */\nexport function validateFileFormatTransforms(\n files: FileFormatTransformInput[]\n): void {\n for (const file of files) {\n const error = getFileFormatTransformError(file);\n if (error) throw new Error(error);\n }\n}\n","import { TranslationRequestConfig, EnqueueFilesResult } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { FileReferenceIds } from '../types-dir/api/file';\nimport { processBatches } from './utils/batch';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\nexport type EnqueueFilesOptions = {\n sourceLocale?: string;\n targetLocales: string[];\n modelProvider?: string;\n force?: boolean;\n timeout?: number;\n};\n\n/**\n * @internal\n * Enqueues files for translation in the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport async function _enqueueFiles(\n files: FileReferenceIds[],\n options: EnqueueFilesOptions,\n config: TranslationRequestConfig\n): Promise<EnqueueFilesResult> {\n validateFileFormatTransforms(files);\n\n const result = await processBatches(\n files,\n async (batch) => {\n const body = {\n files: batch.map((f) => ({\n branchId: f.branchId,\n fileId: f.fileId,\n versionId: f.versionId,\n fileName: f.fileName,\n transformFormat: f.transformFormat,\n })),\n targetLocales: options.targetLocales,\n sourceLocale: options.sourceLocale,\n modelProvider: options.modelProvider,\n force: options.force,\n };\n\n const apiResult = await apiRequest<EnqueueFilesResult>(\n config,\n '/v2/project/translations/enqueue',\n { body, timeout: options.timeout }\n );\n return Array.from(Object.entries(apiResult.jobData));\n },\n { batchSize: 100 }\n );\n // flatten the result\n const jobs = Object.fromEntries(\n result.data.map(([jobId, jobData]) => [jobId, jobData])\n );\n return {\n jobData: jobs,\n locales: options.targetLocales,\n message: `Successfully enqueued ${result.count} file translation jobs in ${result.batchCount} batch(es)`,\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type CreateTagFileReference = {\n fileId: string;\n versionId: string;\n branchId: string;\n};\n\nexport type CreateTagOptions = {\n tagId: string;\n files: CreateTagFileReference[];\n message?: string;\n};\n\nexport type CreateTagResult = {\n tag: {\n id: string;\n tagId: string;\n message: string | null;\n createdAt: string;\n updatedAt: string;\n };\n};\n\n/**\n * @internal\n * Creates or upserts a file tag in the General Translation API.\n * @param options - The tag creation options.\n * @param config - The configuration for the API call.\n * @returns The created or updated tag.\n */\nexport async function _createTag(\n options: CreateTagOptions,\n config: TranslationRequestConfig\n): Promise<CreateTagResult> {\n return await apiRequest<CreateTagResult>(config, '/v2/project/tags/create', {\n body: {\n tagId: options.tagId,\n files: options.files,\n ...(options.message && { message: options.message }),\n },\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n DownloadFileBatchOptions,\n DownloadFileBatchRequest,\n DownloadFileBatchResult,\n} from '../types-dir/api/downloadFileBatch';\nimport { apiRequest } from './utils/apiRequest';\nimport { decode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\n/**\n * @internal\n * Downloads multiple translation files in batches.\n * @param files - Array of files to download\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns Promise resolving to a BatchList with all downloaded files\n */\nexport async function _downloadFileBatch(\n requests: DownloadFileBatchRequest,\n options: DownloadFileBatchOptions,\n config: TranslationRequestConfig\n) {\n return processBatches(\n requests,\n async (batch) => {\n const result = await apiRequest<DownloadFileBatchResult>(\n config,\n '/v2/project/files/download',\n { body: batch, timeout: options.timeout }\n );\n\n // convert from base64 to string\n const files = result.files.map((file) => ({\n ...file,\n data: decode(file.data),\n }));\n\n return files;\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type SubmitUserEditDiff = {\n fileName: string;\n locale: string;\n diff: string;\n branchId: string;\n versionId: string;\n fileId: string;\n localContent: string;\n};\n\nexport type SubmitUserEditDiffsPayload = {\n diffs: SubmitUserEditDiff[];\n};\n\n/**\n * @internal\n * Submits user edit diffs so the service can learn/persist user-intended rules.\n */\nexport async function _submitUserEditDiffs(\n payload: SubmitUserEditDiffsPayload,\n config: TranslationRequestConfig,\n options: { timeout?: number } = {}\n): Promise<{ success: boolean }> {\n await processBatches(\n payload.diffs,\n async (batch) => {\n await apiRequest(config, '/v2/project/files/diffs', {\n body: { diffs: batch } satisfies SubmitUserEditDiffsPayload,\n timeout: options.timeout,\n });\n return [{ success: true }];\n },\n { batchSize: 100 }\n );\n\n return { success: true };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { encode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\nimport {\n FileUpload,\n UploadFilesResponse,\n RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\n\n/**\n * @internal\n * Uploads source files to the General Translation API in batches.\n * @param files - The files to upload.\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport async function _uploadSourceFiles(\n files: { source: FileUpload }[],\n options: RequiredUploadFilesOptions,\n config: TranslationRequestConfig\n) {\n return processBatches(\n files,\n async (batch) => {\n const body = {\n data: batch.map(({ source }) => ({\n source: {\n content: encode(source.content),\n fileName: source.fileName,\n fileFormat: source.fileFormat,\n locale: source.locale,\n dataFormat: source.dataFormat,\n formatMetadata: source.formatMetadata,\n fileId: source.fileId,\n versionId: source.versionId,\n branchId: source.branchId,\n incomingBranchId: source.incomingBranchId,\n checkedOutBranchId: source.checkedOutBranchId,\n },\n })),\n sourceLocale: options.sourceLocale,\n };\n\n const result = await apiRequest<UploadFilesResponse>(\n config,\n '/v2/project/files/upload-files',\n { body, timeout: options.timeout }\n );\n\n return result.uploadedFiles || [];\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nimport {\n FileUpload,\n UploadFilesResponse,\n RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\nimport { encode } from '../utils/base64';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\n/**\n * @internal\n * Uploads multiple translations to the General Translation API in batches.\n * @param files - Translations to upload with their source\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport async function _uploadTranslations(\n files: {\n source: FileUpload;\n translations: FileUpload[];\n }[],\n options: RequiredUploadFilesOptions,\n config: TranslationRequestConfig\n) {\n validateFileFormatTransforms(files.map(({ source }) => source));\n\n return processBatches(\n files,\n async (batch) => {\n const body = {\n data: batch.map(({ source, translations }) => ({\n source: {\n content: encode(source.content),\n fileName: source.fileName,\n fileFormat: source.fileFormat,\n transformFormat: source.transformFormat,\n locale: source.locale,\n dataFormat: source.dataFormat,\n formatMetadata: source.formatMetadata,\n fileId: source.fileId,\n versionId: source.versionId,\n branchId: source.branchId,\n },\n translations: translations.map((t) => ({\n content: encode(t.content),\n fileName: t.fileName,\n fileFormat: t.fileFormat,\n locale: t.locale,\n dataFormat: t.dataFormat,\n fileId: t.fileId,\n versionId: t.versionId,\n branchId: t.branchId,\n })),\n })),\n sourceLocale: options.sourceLocale,\n };\n\n const result = await apiRequest<UploadFilesResponse>(\n config,\n '/v2/project/files/upload-translations',\n { body, timeout: options.timeout }\n );\n\n return result.uploadedFiles || [];\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n CheckFileTranslationsOptions,\n FileQueryResult,\n} from '../types-dir/api/checkFileTranslations';\nimport { FileQuery } from '../types-dir/api/checkFileTranslations';\nimport { apiRequest } from './utils/apiRequest';\n\n/**\n * @internal\n * Gets the source file and translation information for a given file ID and version ID.\n * @param query - The file ID and version ID to get the source file and translation information for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The source file and translation information for the given file ID and version ID\n */\nexport async function _querySourceFile(\n query: FileQuery,\n options: CheckFileTranslationsOptions,\n config: TranslationRequestConfig\n): Promise<FileQueryResult> {\n const branchId = query.branchId;\n const versionId = query.versionId;\n const fileId = query.fileId;\n\n const searchParams = new URLSearchParams();\n if (branchId) {\n searchParams.set('branchId', branchId);\n }\n if (versionId) {\n searchParams.set('versionId', versionId);\n }\n const endpoint = `/v2/project/translations/files/status/${encodeURIComponent(fileId)}?${searchParams.toString()}`;\n\n return apiRequest<FileQueryResult>(config, endpoint, {\n method: 'GET',\n timeout: options.timeout,\n });\n}\n","import { defaultBaseUrl } from '../settings/settingsUrls';\nimport { fetchWithTimeout } from '../translate/utils/fetchWithTimeout';\nimport { defaultTimeout } from '../settings/settings';\nimport { validateResponse } from '../translate/utils/validateResponse';\nimport { handleFetchError } from '../translate/utils/handleFetchError';\nimport { TranslationRequestConfig } from '../types';\nimport { generateRequestHeaders } from '../translate/utils/generateRequestHeaders';\nimport { ProjectData } from '../types-dir/api/project';\n\n/**\n * @internal\n * Gets the project data for a given project ID.\n * @param projectId - The project ID to get the project data for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The project data for the given project ID.\n */\nexport async function _getProjectData(\n projectId: string,\n options: { timeout?: number },\n config: TranslationRequestConfig\n): Promise<ProjectData> {\n const { baseUrl } = config;\n const timeout = options.timeout ? options.timeout : defaultTimeout;\n const url = `${baseUrl || defaultBaseUrl}/v2/project/info/${encodeURIComponent(projectId)}`;\n\n // Get the project data\n let response;\n try {\n response = await fetchWithTimeout(\n url,\n {\n method: 'GET',\n headers: generateRequestHeaders(config),\n },\n timeout\n );\n } catch (error) {\n handleFetchError(error, timeout);\n }\n\n // Validate the response\n await validateResponse(response);\n\n const result = await response.json();\n return result as ProjectData;\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type JobStatus =\n | 'queued'\n | 'processing'\n | 'completed'\n | 'failed'\n | 'unknown';\n\nexport type CheckJobStatusResult = {\n jobId: string;\n status: JobStatus;\n error?: { message: string };\n}[];\n\n/**\n * @internal\n * Queries job statuses for a project.\n * @param jobIds - Job IDs.\n * @param config - The configuration for the API call.\n * @param timeoutMs - The timeout in milliseconds.\n * @returns The result of the API call.\n */\nexport async function _checkJobStatus(\n jobIds: string[],\n config: TranslationRequestConfig,\n timeoutMs?: number\n): Promise<CheckJobStatusResult> {\n return apiRequest<CheckJobStatusResult>(config, '/v2/project/jobs/info', {\n body: { jobIds },\n timeout: timeoutMs,\n });\n}\n","import { EnqueueFilesResult } from '../types-dir/api/enqueueFiles';\nimport { TranslationRequestConfig } from '../types';\nimport { _checkJobStatus, JobStatus } from './checkJobStatus';\n\nexport type AwaitJobsOptions = {\n /** Polling interval in seconds. Defaults to 5. */\n pollingIntervalSeconds?: number;\n /** Timeout in seconds. Defaults to 600 (10 minutes). If reached, resolves with whatever status is current. */\n timeoutSeconds?: number;\n};\n\nexport type JobResult = {\n jobId: string;\n status: JobStatus;\n error?: { message: string };\n};\n\nexport type AwaitJobsResult = {\n /** Whether all jobs completed (none still in progress). */\n complete: boolean;\n jobs: JobResult[];\n};\n\n/**\n * @internal\n * Polls job statuses until all jobs are finished or the timeout is reached.\n * @param enqueueResult - The result from enqueueFiles.\n * @param options - Polling configuration.\n * @param config - API credentials and configuration.\n * @returns The final status of all jobs.\n */\nexport async function _awaitJobs(\n enqueueResult: EnqueueFilesResult,\n options: AwaitJobsOptions | undefined,\n config: TranslationRequestConfig\n): Promise<AwaitJobsResult> {\n const pollingInterval = (options?.pollingIntervalSeconds ?? 5) * 1000;\n const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n const timeout =\n options?.timeoutSeconds !== undefined\n ? options.timeoutSeconds * 1000\n : DEFAULT_TIMEOUT_MS;\n\n const jobIds = Object.keys(enqueueResult.jobData);\n\n if (jobIds.length === 0) {\n return { complete: true, jobs: [] };\n }\n\n const startTime = Date.now();\n const finalStatuses = new Map<string, JobResult>(\n jobIds.map((id) => [id, { jobId: id, status: 'unknown' as JobStatus }])\n );\n const pendingJobIds = new Set(jobIds);\n\n while (pendingJobIds.size > 0) {\n const statuses = await _checkJobStatus(Array.from(pendingJobIds), config);\n\n for (const job of statuses) {\n if (\n job.status === 'completed' ||\n job.status === 'failed' ||\n job.status === 'unknown'\n ) {\n finalStatuses.set(job.jobId, {\n jobId: job.jobId,\n status: job.status,\n ...(job.error ? { error: job.error } : {}),\n });\n pendingJobIds.delete(job.jobId);\n } else {\n finalStatuses.set(job.jobId, {\n jobId: job.jobId,\n status: job.status,\n });\n }\n }\n\n if (pendingJobIds.size === 0) break;\n\n if (Date.now() - startTime >= timeout) break;\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n\n return {\n complete: pendingJobIds.size === 0,\n jobs: Array.from(finalStatuses.values()),\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { CheckFileTranslationsOptions } from '../types-dir/api/checkFileTranslations';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type FileDataQuery = {\n sourceFiles?: {\n fileId: string;\n versionId: string;\n branchId: string;\n }[];\n translatedFiles?: {\n fileId: string;\n versionId: string;\n branchId: string;\n locale: string;\n }[];\n};\n\nexport type FileDataResult = {\n sourceFiles?: {\n branchId: string;\n fileId: string;\n versionId: string;\n fileName: string;\n fileFormat: string;\n dataFormat: string | null;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n locales: string[];\n sourceLocale: string;\n }[];\n translatedFiles?: {\n branchId: string;\n fileId: string;\n versionId: string;\n fileFormat: string;\n dataFormat: string | null;\n createdAt: string;\n updatedAt: string;\n approvedAt: string | null;\n publishedAt: string | null;\n completedAt: string | null;\n locale: string;\n }[];\n};\n\n/**\n * @internal\n * Queries data about one or more source or translation files.\n * @param data - Object mapping source or translation file information\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The file data.\n */\nexport async function _queryFileData(\n data: FileDataQuery,\n options: CheckFileTranslationsOptions = {},\n config: TranslationRequestConfig\n): Promise<FileDataResult> {\n const body = {\n sourceFiles: data.sourceFiles?.map((item) => ({\n fileId: item.fileId,\n versionId: item.versionId,\n branchId: item.branchId,\n })),\n translatedFiles: data.translatedFiles?.map((item) => ({\n fileId: item.fileId,\n versionId: item.versionId,\n branchId: item.branchId,\n locale: item.locale,\n })),\n };\n\n return apiRequest<FileDataResult>(config, '/v2/project/files/info', {\n body,\n timeout: options.timeout,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type ProjectInfoResult = {\n id: string;\n name: string;\n orgId: string;\n defaultLocale: string;\n currentLocales: string[];\n autoApprove?: boolean;\n};\n\nexport type GetProjectInfoOptions = {\n timeout?: number;\n};\n\n/**\n * @internal\n * Fetches project info (name, locales, review settings) for a project.\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The project info.\n */\nexport async function _getProjectInfo(\n options: GetProjectInfoOptions,\n config: TranslationRequestConfig\n): Promise<ProjectInfoResult> {\n return apiRequest<ProjectInfoResult>(\n config,\n `/v2/project/info/${config.projectId}`,\n {\n method: 'GET',\n timeout: options.timeout,\n }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { BranchDataResult } from '../types-dir/api/branch';\n\nexport type BranchQuery = {\n branchNames: string[];\n};\n\n/**\n * @internal\n * Queries branch information from the API.\n * @param query - Object mapping the current branch and incoming branches\n * @param config - The configuration for the API call.\n * @returns The branch information.\n */\nexport async function _queryBranchData(\n query: BranchQuery,\n config: TranslationRequestConfig\n): Promise<BranchDataResult> {\n return apiRequest<BranchDataResult>(config, '/v2/project/branches/info', {\n body: query,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type CreateBranchQuery = {\n branchName: string;\n defaultBranch: boolean;\n};\n\nexport type CreateBranchResult = {\n branch: { id: string; name: string };\n};\n\n/**\n * @internal\n * Creates a new branch in the API.\n * @param query - Object mapping the branch name and default branch flag\n * @param config - The configuration for the API call.\n * @returns The created branch information.\n */\nexport async function _createBranch(\n query: CreateBranchQuery,\n config: TranslationRequestConfig\n): Promise<CreateBranchResult> {\n return apiRequest<CreateBranchResult>(config, '/v2/project/branches/create', {\n body: query,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type MoveMapping = {\n oldFileId: string;\n newFileId: string;\n newFileName: string;\n};\n\nexport type MoveResult = {\n oldFileId: string;\n newFileId: string;\n success: boolean;\n newSourceFileId?: string;\n clonedTranslationsCount?: number;\n error?: string;\n};\n\nexport type ProcessMovesResponse = {\n results: MoveResult[];\n summary: {\n total: number;\n succeeded: number;\n failed: number;\n };\n};\n\nexport type ProcessMovesOptions = {\n timeout?: number;\n branchId?: string;\n};\n\n/**\n * @internal\n * Processes file moves by cloning source files and translations with new fileIds.\n * Called when the CLI detects that files have been moved/renamed.\n * @param moves - Array of move mappings (old fileId to new fileId)\n * @param options - Options including branchId and timeout\n * @param config - The configuration for the API call.\n * @returns Promise resolving to the move results\n */\nexport async function _processFileMoves(\n moves: MoveMapping[],\n options: ProcessMovesOptions,\n config: TranslationRequestConfig\n): Promise<ProcessMovesResponse> {\n if (moves.length === 0) {\n return {\n results: [],\n summary: { total: 0, succeeded: 0, failed: 0 },\n };\n }\n\n const batchResult = await processBatches(\n moves,\n async (batch) => {\n const result = await apiRequest<ProcessMovesResponse>(\n config,\n '/v2/project/files/moves',\n {\n body: { branchId: options.branchId, moves: batch },\n timeout: options.timeout,\n }\n );\n return result.results;\n },\n { batchSize: 100 }\n );\n\n const succeeded = batchResult.data.filter((r) => r.success).length;\n const failed = batchResult.data.filter((r) => !r.success).length;\n\n return {\n results: batchResult.data,\n summary: {\n total: moves.length,\n succeeded,\n failed,\n },\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { createBatches } from './utils/batch';\n\nexport type OrphanedFile = {\n fileId: string;\n versionId: string;\n fileName: string;\n};\n\nexport type GetOrphanedFilesResult = {\n orphanedFiles: OrphanedFile[];\n};\n\n/**\n * @internal\n * Gets orphaned files for a branch - files that exist on the branch\n * but whose fileIds are not in the provided list.\n * Used for move detection.\n * @param branchId - The branch to check for orphaned files\n * @param fileIds - List of current file IDs (files that are NOT orphaned)\n * @param options - The options for the API call\n * @param config - The configuration for the API call\n * @returns The orphaned files\n */\nexport async function _getOrphanedFiles(\n branchId: string,\n fileIds: string[],\n options: { timeout?: number } = {},\n config: TranslationRequestConfig\n): Promise<GetOrphanedFilesResult> {\n const makeRequest = (batchFileIds: string[]) =>\n apiRequest<GetOrphanedFilesResult>(config, '/v2/project/files/orphaned', {\n body: { branchId, fileIds: batchFileIds },\n timeout: options.timeout,\n });\n\n // If no fileIds, make a single request\n if (fileIds.length === 0) {\n return makeRequest([]);\n }\n\n // Split fileIds into batches of 100\n const batches = createBatches(fileIds, 100);\n\n // Process batches in parallel\n // Each batch returns files NOT in that batch's fileIds\n // True orphans are files that appear in ALL batch responses (intersection)\n const batchResults = await Promise.all(\n batches.map((batch) => makeRequest(batch))\n );\n\n if (batchResults.length === 1) {\n return batchResults[0];\n }\n\n // Find intersection of orphaned files across all batches\n // A file is truly orphaned only if it's not in ANY of our fileId batches\n // Start with first batch's orphans\n const orphanedFileMap = new Map<string, OrphanedFile>();\n for (const orphan of batchResults[0].orphanedFiles) {\n orphanedFileMap.set(orphan.fileId, orphan);\n }\n\n // Intersect with each subsequent batch.\n for (let i = 1; i < batchResults.length; i++) {\n const batchOrphanIds = new Set(\n batchResults[i].orphanedFiles.map((f) => f.fileId)\n );\n Array.from(orphanedFileMap.keys()).forEach((fileId) => {\n if (!batchOrphanIds.has(fileId)) {\n orphanedFileMap.delete(fileId);\n }\n });\n }\n\n return {\n orphanedFiles: Array.from(orphanedFileMap.values()),\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type PublishFileEntry = {\n fileId: string;\n versionId: string;\n branchId?: string;\n publish: boolean;\n fileName?: string;\n};\n\nexport type PublishFilesResult = {\n results: {\n fileId: string;\n versionId: string;\n locale?: string; // if locale is provided, it means this result is for a translation. Else it is for a source file.\n branchId: string;\n success: boolean;\n error?: string;\n }[];\n};\n\n/**\n * @internal\n * Publishes or unpublishes files on the CDN.\n * @param files - Array of file entries with publish flags\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport async function _publishFiles(\n files: PublishFileEntry[],\n config: TranslationRequestConfig\n): Promise<PublishFilesResult> {\n return await apiRequest<PublishFilesResult>(\n config,\n '/v2/project/files/publish',\n {\n body: { files },\n }\n );\n}\n","// `generaltranslation` language toolkit\n// © 2026, General Translation, Inc.\n\n// ----- IMPORTS ----- //\n\nimport {\n EnqueueFilesResult,\n CheckFileTranslationsOptions,\n DownloadFileBatchOptions,\n DownloadFileBatchResult,\n DownloadFileOptions,\n} from './types';\nimport { libraryDefaultLocale } from './settings/settings';\nimport {\n noSourceLocaleProvidedError,\n noTargetLocaleProvidedError,\n} from './logging/errors';\nimport { gtInstanceLogger } from './logging/logger';\nimport {\n _setupProject,\n SetupProjectResult,\n SetupProjectOptions,\n type SetupProjectFileReference,\n} from './translate/setupProject';\nimport {\n _enqueueFiles,\n type EnqueueFilesOptions,\n} from './translate/enqueueFiles';\nimport {\n _createTag,\n CreateTagOptions,\n CreateTagResult,\n} from './translate/createTag';\nimport { _downloadFileBatch } from './translate/downloadFileBatch';\nimport {\n FileQuery,\n FileQueryResult,\n} from './types-dir/api/checkFileTranslations';\nimport {\n _submitUserEditDiffs,\n SubmitUserEditDiffsPayload,\n} from './translate/submitUserEditDiffs';\nimport { _uploadSourceFiles } from './translate/uploadSourceFiles';\nimport { _uploadTranslations } from './translate/uploadTranslations';\nimport {\n FileUpload,\n RequiredUploadFilesOptions,\n UploadFilesOptions,\n UploadFilesResponse,\n} from './types-dir/api/uploadFiles';\nimport { _querySourceFile } from './translate/querySourceFile';\nimport { ProjectData } from './types-dir/api/project';\nimport { _getProjectData } from './projects/getProjectData';\nimport { DownloadFileBatchRequest } from './types-dir/api/downloadFileBatch';\nimport {\n _checkJobStatus,\n CheckJobStatusResult,\n} from './translate/checkJobStatus';\nimport {\n _awaitJobs,\n AwaitJobsOptions,\n AwaitJobsResult,\n} from './translate/awaitJobs';\nimport type { FileDataQuery, FileDataResult } from './translate/queryFileData';\nimport { _queryFileData } from './translate/queryFileData';\nimport type {\n GetProjectInfoOptions,\n ProjectInfoResult,\n} from './translate/getProjectInfo';\nimport { _getProjectInfo } from './translate/getProjectInfo';\nimport type { BranchQuery } from './translate/queryBranchData';\nimport type { BranchDataResult } from './types-dir/api/branch';\nimport { _queryBranchData } from './translate/queryBranchData';\nimport type {\n CreateBranchQuery,\n CreateBranchResult,\n} from './translate/createBranch';\nimport { _createBranch } from './translate/createBranch';\nimport type { FileReferenceIds } from './types-dir/api/file';\nimport {\n _processFileMoves,\n type MoveMapping,\n type ProcessMovesResponse,\n type ProcessMovesOptions,\n} from './translate/processFileMoves';\nimport {\n _getOrphanedFiles,\n type GetOrphanedFilesResult,\n} from './translate/getOrphanedFiles';\nimport {\n _publishFiles,\n type PublishFileEntry,\n type PublishFilesResult,\n} from './translate/publishFiles';\nimport { GTRuntime } from './runtime';\n\nexport { GTRuntime, type GTConstructorParams } from './runtime';\nexport { decodeVars } from './derive/decodeVars';\nexport { declareVar } from './derive/declareVar';\nexport { derive } from './derive/derive';\n\nexport {\n LocaleConfig,\n type LocaleConfigConstructorParams,\n} from '@generaltranslation/format';\n\nexport {\n determineLocale,\n formatCurrency,\n formatCutoff,\n formatDateTime,\n formatList,\n formatListToParts,\n formatMessage,\n formatNum,\n formatRelativeTime,\n formatRelativeTimeFromDate,\n getLocaleDirection,\n getLocaleEmoji,\n getLocaleName,\n getLocaleProperties,\n getRegionProperties,\n isSameDialect,\n isSameLanguage,\n isSupersetLocale,\n isValidLocale,\n requiresTranslation,\n resolveAliasLocale,\n resolveCanonicalLocale,\n standardizeLocale,\n} from '@generaltranslation/format';\n\n// ============================================================ //\n// Core Class //\n// ============================================================ //\n\n/**\n * GT is the core driver for the General Translation library.\n * It extends {@link GTRuntime} (locale management, formatting, and runtime\n * translation) with the project and file management API client used by\n * tooling such as the CLI.\n *\n * Browser-facing SDK code should construct {@link GTRuntime} instead so\n * production bundles do not ship the file management client.\n *\n * @class GT\n * @description A comprehensive toolkit for handling internationalization and localization.\n *\n * @example\n * const gt = new GT({\n * sourceLocale: 'en-US',\n * targetLocale: 'es-ES',\n * locales: ['en-US', 'es-ES', 'fr-FR']\n * });\n */\nexport class GT extends GTRuntime {\n // -------------- Branch Methods -------------- //\n\n /**\n * Queries branch information from the API.\n *\n * @param {BranchQuery} query - Object mapping the current branch and incoming branches\n * @returns {Promise<BranchDataResult>} The branch information.\n */\n async queryBranchData(query: BranchQuery): Promise<BranchDataResult> {\n this._validateAuth('queryBranchData');\n return await _queryBranchData(query, this._getTranslationConfig());\n }\n\n /**\n * Creates a new branch in the API. If the branch already exists, it will be returned.\n *\n * @param {CreateBranchQuery} query - Object mapping the branch name and default branch flag\n * @returns {Promise<CreateBranchResult>} The created branch information.\n */\n async createBranch(query: CreateBranchQuery): Promise<CreateBranchResult> {\n this._validateAuth('createBranch');\n return await _createBranch(query, this._getTranslationConfig());\n }\n\n /**\n * Processes file moves by cloning source files and translations with new fileIds.\n * This is called when files have been moved/renamed and we want to preserve translations.\n *\n * @param {MoveMapping[]} moves - Array of move mappings (old fileId to new fileId)\n * @param {ProcessMovesOptions} options - Options including branchId and timeout\n * @returns {Promise<ProcessMovesResponse>} The move processing results.\n *\n * @example\n * const result = await gt.processFileMoves([\n * { oldFileId: 'abc123', newFileId: 'def456', newFileName: 'locales/en.json' }\n * ], { branchId: 'main' });\n */\n async processFileMoves(\n moves: MoveMapping[],\n options: ProcessMovesOptions = {}\n ): Promise<ProcessMovesResponse> {\n this._validateAuth('processFileMoves');\n return await _processFileMoves(\n moves,\n options,\n this._getTranslationConfig()\n );\n }\n\n /**\n * Gets orphaned files for a branch - files that exist on the branch\n * but whose fileIds are not in the provided list.\n * Used for move detection.\n *\n * @param {string} branchId - The branch to check for orphaned files.\n * @param {string[]} fileIds - List of current file IDs (files that are NOT orphaned)\n * @param {Object} options - Options including timeout.\n * @returns {Promise<GetOrphanedFilesResult>} The orphaned files.\n *\n * @example\n * const result = await gt.getOrphanedFiles('branch-id', ['file-1', 'file-2']);\n */\n async getOrphanedFiles(\n branchId: string,\n fileIds: string[],\n options: { timeout?: number } = {}\n ): Promise<GetOrphanedFilesResult> {\n this._validateAuth('getOrphanedFiles');\n return await _getOrphanedFiles(\n branchId,\n fileIds,\n options,\n this._getTranslationConfig()\n );\n }\n\n // -------------- Translation Methods -------------- //\n\n /**\n * Enqueues project setup job using the specified file references\n *\n * This method creates setup jobs that will process source file references\n * and generate a project setup. The files parameter contains references (IDs) to source\n * files that have already been uploaded via uploadSourceFiles. The setup jobs are queued\n * for processing and will generate a project setup based on the source files.\n *\n * @param {SetupProjectFileReference[]} files - Array of file references containing IDs of previously uploaded source files\n * @param {SetupProjectOptions} [options] - Optional settings for target locales and timeout.\n * @returns {Promise<SetupProjectResult>} Object containing the jobId and status\n */\n async setupProject(\n files: SetupProjectFileReference[],\n options?: SetupProjectOptions\n ): Promise<SetupProjectResult> {\n this._validateAuth('setupProject');\n options = {\n ...options,\n locales: options?.locales?.map((locale) =>\n this.resolveCanonicalLocale(locale)\n ),\n };\n return await _setupProject(files, this._getTranslationConfig(), options);\n }\n\n /**\n * Checks the current status of one or more project jobs by their unique identifiers.\n *\n * This method polls the API to determine whether one or more jobs are still running,\n * have completed successfully, or have failed. Jobs are created after calling either enqueueFiles or setupProject.\n *\n * @param {string[]} jobIds - The unique identifiers of the jobs to check.\n * @param {number} [timeoutMs] - Optional timeout in milliseconds for the API request.\n * @returns {Promise<CheckJobStatusResult>} Object containing the job status.\n *\n * @example\n * const result = await gt.checkJobStatus([\n * 'job-123',\n * 'job-456',\n * ], 10000);\n */\n async checkJobStatus(\n jobIds: string[],\n timeoutMs?: number\n ): Promise<CheckJobStatusResult> {\n this._validateAuth('checkJobStatus');\n return await _checkJobStatus(\n jobIds,\n this._getTranslationConfig(),\n timeoutMs\n );\n }\n\n /**\n * Polls job statuses until all jobs from enqueueFiles are finished or the timeout is reached.\n *\n * @param {EnqueueFilesResult} enqueueResult - The result returned from enqueueFiles.\n * @param {AwaitJobsOptions} [options] - Polling configuration (interval, timeout).\n * @returns {Promise<AwaitJobsResult>} The final status of all jobs and whether they all completed.\n */\n async awaitJobs(\n enqueueResult: EnqueueFilesResult,\n options?: AwaitJobsOptions\n ): Promise<AwaitJobsResult> {\n this._validateAuth('awaitJobs');\n return await _awaitJobs(\n enqueueResult,\n options,\n this._getTranslationConfig()\n );\n }\n\n /**\n * Enqueues translation jobs for previously uploaded source files.\n *\n * This method creates translation jobs that will process existing source files\n * and generate translations in the specified target languages. The files parameter\n * contains references (IDs) to source files that have already been uploaded via\n * uploadSourceFiles. The translation jobs are queued for processing and will\n * generate translated content based on the source files and target locales provided.\n *\n * @param {FileReferenceIds[]} files - Array of file references containing IDs of previously uploaded source files\n * @param {EnqueueFilesOptions} options - Configuration options including source locale, target locales, and job settings.\n * @returns {Promise<EnqueueFilesResult>} Result containing job IDs, queue status, and processing information.\n */\n async enqueueFiles(\n files: FileReferenceIds[],\n options: EnqueueFilesOptions\n ): Promise<EnqueueFilesResult> {\n // Validation\n this._validateAuth('enqueueFiles');\n\n // Merge instance settings with options.\n let mergedOptions: EnqueueFilesOptions = {\n ...options,\n sourceLocale: options.sourceLocale ?? this.sourceLocale!,\n targetLocales: options.targetLocales ?? [this.targetLocale!],\n };\n\n // Require source locale\n if (!mergedOptions.sourceLocale) {\n const error = noSourceLocaleProvidedError('enqueueFiles');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n // Require target locale(s)\n if (\n !mergedOptions.targetLocales ||\n mergedOptions.targetLocales.length === 0\n ) {\n const error = noTargetLocaleProvidedError('enqueueFiles');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n // Replace target locales with canonical locales\n mergedOptions = {\n ...mergedOptions,\n targetLocales: mergedOptions.targetLocales.map((locale) =>\n this.resolveCanonicalLocale(locale)\n ),\n };\n\n return await _enqueueFiles(\n files,\n mergedOptions,\n this._getTranslationConfig()\n );\n }\n\n /**\n * Creates or upserts a file tag, associating a set of source files\n * with a user-defined tag ID and optional message.\n *\n * @param {CreateTagOptions} options - Tag creation options including tagId, sourceFileIds, and optional message\n * @returns {Promise<CreateTagResult>} The created or updated tag.\n */\n async createTag(options: CreateTagOptions): Promise<CreateTagResult> {\n this._validateAuth('createTag');\n return await _createTag(options, this._getTranslationConfig());\n }\n\n /**\n * Publishes or unpublishes files on the CDN.\n *\n * @param {PublishFileEntry[]} files - Array of file entries with publish flags\n * @returns {Promise<PublishFilesResult>} Result containing per-file success/failure\n */\n async publishFiles(files: PublishFileEntry[]): Promise<PublishFilesResult> {\n this._validateAuth('publishFiles');\n return await _publishFiles(files, this._getTranslationConfig());\n }\n\n /**\n * Submits user edit diffs for existing translations so future generations preserve user intent.\n *\n * @param {SubmitUserEditDiffsPayload} payload - Project-scoped diff payload.\n * @returns {Promise<void>} Resolves when submission succeeds.\n */\n async submitUserEditDiffs(\n payload: SubmitUserEditDiffsPayload\n ): Promise<void> {\n this._validateAuth('submitUserEditDiffs');\n // Normalize locales to canonical form before submission.\n const normalized: SubmitUserEditDiffsPayload = {\n ...payload,\n diffs: (payload.diffs || []).map((d) => ({\n ...d,\n locale: this.resolveCanonicalLocale(d.locale),\n })),\n };\n await _submitUserEditDiffs(normalized, this._getTranslationConfig());\n }\n\n /**\n * Queries data about one or more source or translation files.\n *\n * @param {FileDataQuery} data - Object mapping source and translation file information.\n * @param {CheckFileTranslationsOptions} options - Options for the API call.\n * @returns {Promise<FileDataResult>} The source and translation file data information.\n *\n * @example\n * const result = await gt.queryFileData({\n * sourceFiles: [\n * { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890' },\n * ],\n * translatedFiles: [\n * { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890', locale: 'es-ES' },\n * ],\n * }, {\n * timeout: 10000,\n * });\n *\n */\n /**\n * Fetches project info (name, locales, review settings) for the\n * authenticated project.\n * @param options - The options for the API call.\n * @returns The project info.\n */\n async getProjectInfo(\n options: GetProjectInfoOptions = {}\n ): Promise<ProjectInfoResult> {\n this._validateAuth('getProjectInfo');\n return await _getProjectInfo(options, this._getTranslationConfig());\n }\n\n async queryFileData(\n data: FileDataQuery,\n options: CheckFileTranslationsOptions = {}\n ): Promise<FileDataResult> {\n // Validation\n this._validateAuth('queryFileData');\n\n // Replace target locales with canonical locales\n data.translatedFiles = data.translatedFiles?.map((item) => ({\n ...item,\n locale: this.resolveCanonicalLocale(item.locale),\n }));\n\n // Request the file translation status\n const result = await _queryFileData(\n data,\n options,\n this._getTranslationConfig()\n );\n\n // Resolve canonical locales\n result.translatedFiles = result.translatedFiles?.map((item) => ({\n ...item,\n ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n }));\n result.sourceFiles = result.sourceFiles?.map((item) => ({\n ...item,\n ...(item.sourceLocale && {\n sourceLocale: this.resolveAliasLocale(item.sourceLocale),\n }),\n locales: item.locales.map((locale) => this.resolveAliasLocale(locale)),\n }));\n return result;\n }\n\n /**\n * Gets source and translation information for a given file ID and version ID.\n *\n * @param {FileQuery} data - File query containing file ID and version ID.\n * @param {CheckFileTranslationsOptions} options - Options for getting source and translation information.\n * @returns {Promise<FileQueryResult>} The source file and translation information.\n *\n * @example\n * const result = await gt.querySourceFile(\n * { fileId: '1234567890', versionId: '1234567890' },\n * { timeout: 10000 }\n * );\n *\n */\n async querySourceFile(\n data: FileQuery,\n options: CheckFileTranslationsOptions = {}\n ): Promise<FileQueryResult> {\n // Validation\n this._validateAuth('querySourceFile');\n\n // Request the file translation status\n const result = await _querySourceFile(\n data,\n options,\n this._getTranslationConfig()\n );\n // Replace locales with canonical locales\n result.translations = result.translations.map((item) => ({\n ...item,\n ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n }));\n result.sourceFile.locales = result.sourceFile.locales.map((locale) =>\n this.resolveAliasLocale(locale)\n );\n if (result.sourceFile.sourceLocale) {\n result.sourceFile.sourceLocale = this.resolveAliasLocale(\n result.sourceFile.sourceLocale\n );\n }\n return result;\n }\n /**\n * Get project data for a given project ID.\n *\n * @param {string} projectId - The ID of the project to get the data for.\n * @returns {Promise<ProjectData>} The project data.\n *\n * @example\n * const result = await gt.getProjectData(\n * '1234567890'\n * );\n *\n */\n async getProjectData(\n projectId: string,\n options: { timeout?: number } = {}\n ): Promise<ProjectData> {\n // Validation\n this._validateAuth('getProjectData');\n\n // Request the file translation status\n const result = await _getProjectData(\n projectId,\n options,\n this._getTranslationConfig()\n );\n // Replace locales with canonical locales\n result.currentLocales = result.currentLocales.map((item) =>\n this.resolveAliasLocale(item)\n );\n result.defaultLocale = this.resolveAliasLocale(result.defaultLocale);\n return result;\n }\n\n /**\n * Downloads a single file.\n *\n * @param file - The file query object.\n * @param {string} file.fileId - The ID of the file to download.\n * @param {string} [file.branchId] - The ID of the branch to download the file from. If not provided, the default branch will be used.\n * @param {string} [file.locale] - The locale to download the file for. If not provided, the source file will be downloaded.\n * @param {string} [file.versionId] - The version ID to download the file from. If not provided, the latest version will be used.\n * @param {DownloadFileOptions} options - Options for downloading the file.\n * @returns {Promise<string>} The downloaded file content.\n *\n * @example\n * const result = await gt.downloadFile({\n * fileId: '1234567890',\n * branchId: '1234567890',\n * locale: 'es-ES',\n * versionId: '1234567890',\n * }, {\n * timeout: 10000,\n * });\n */\n async downloadFile(\n file: {\n fileId: string;\n branchId?: string;\n locale?: string;\n versionId?: string;\n useLatestAvailableVersion?: boolean;\n },\n options: DownloadFileOptions = {}\n ): Promise<string> {\n // Validation\n this._validateAuth('downloadTranslatedFile');\n\n const result = await _downloadFileBatch(\n [\n {\n fileId: file.fileId,\n branchId: file.branchId,\n locale: file.locale\n ? this.resolveCanonicalLocale(file.locale)\n : undefined,\n versionId: file.versionId,\n useLatestAvailableVersion: file.useLatestAvailableVersion,\n },\n ],\n options,\n this._getTranslationConfig()\n );\n return result.data?.[0]?.data ?? '';\n }\n\n /**\n * Downloads multiple files in a batch.\n *\n * @param {DownloadFileBatchRequest} requests - Array of file query objects to download.\n * @param {DownloadFileBatchOptions} options - Options for the batch download.\n * @returns {Promise<DownloadFileBatchResult>} The batch download results.\n *\n * @example\n * const result = await gt.downloadFileBatch([{\n * fileId: '1234567890',\n * locale: 'es-ES',\n * versionId: '1234567890',\n * }], {\n * timeout: 10000,\n * });\n */\n async downloadFileBatch(\n requests: DownloadFileBatchRequest,\n options: DownloadFileBatchOptions = {}\n ): Promise<DownloadFileBatchResult> {\n // Validation\n this._validateAuth('downloadFileBatch');\n\n requests = requests.map((request) => ({\n ...request,\n locale: request.locale\n ? this.resolveCanonicalLocale(request.locale)\n : undefined,\n }));\n\n // Request the batch download.\n const result = await _downloadFileBatch(\n requests,\n options,\n this._getTranslationConfig()\n );\n\n return {\n files: result.data.map((file) => ({\n ...file,\n ...(file.locale && {\n locale: this.resolveAliasLocale(file.locale),\n }),\n })),\n count: result.count,\n };\n }\n\n /**\n * Uploads source files to the translation service without any translation content.\n *\n * This method creates or replaces source file entries in your project. Each uploaded\n * file becomes a source that can later be translated into target languages. The files\n * are processed and stored as base entries that serve as the foundation for generating\n * translations through the translation workflow.\n *\n * @param {Array<{source: FileUpload}>} files - Array of objects containing source file data to upload\n * @param {UploadFilesOptions} options - Configuration options including source locale and other upload settings.\n * @returns {Promise<UploadFilesResponse>} Upload result containing file IDs, version information, and upload status.\n */\n async uploadSourceFiles(\n files: { source: FileUpload }[],\n options: UploadFilesOptions\n ): Promise<UploadFilesResponse> {\n // Validation\n this._validateAuth('uploadSourceFiles');\n\n // Merge instance settings with options.\n const mergedOptions: UploadFilesOptions = {\n ...options,\n sourceLocale: this.resolveCanonicalLocale(\n options.sourceLocale ?? this.sourceLocale ?? libraryDefaultLocale\n ),\n };\n\n // resolve canonical locales\n files = files.map((f) => ({\n ...f,\n source: {\n ...f.source,\n locale: this.resolveCanonicalLocale(f.source.locale),\n },\n }));\n\n // Process files in batches and convert result to UploadFilesResponse\n const result = await _uploadSourceFiles(\n files,\n mergedOptions as RequiredUploadFilesOptions,\n this._getTranslationConfig()\n );\n\n return {\n uploadedFiles: result.data,\n count: result.count,\n message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n };\n }\n\n /**\n * Uploads translation files that correspond to previously uploaded source files.\n *\n * This method allows you to provide translated content for existing source files in your project.\n * Each translation must reference an existing source file and include the translated content\n * along with the target locale information. This is used when you have pre-existing translations\n * that you want to upload directly rather than generating them through the translation service.\n *\n * @param {Array<{source: FileUpload, translations: FileUpload[]}>} files - Array of file objects where:\n * - `source`: Reference to the existing source file (contains IDs but no content).\n * - `translations`: Array of translated files, each containing content, locale, and reference IDs\n * @param {UploadFilesOptions} options - Configuration options including source locale and upload settings.\n * @returns {Promise<UploadFilesResponse>} Upload result containing translation IDs, status, and processing information.\n */\n async uploadTranslations(\n files: {\n source: FileUpload; // reference only (no content)\n translations: FileUpload[]; // each has content + ids + locale\n }[],\n options: UploadFilesOptions\n ): Promise<UploadFilesResponse> {\n // Validation\n this._validateAuth('uploadTranslations');\n\n // Merge instance settings with options.\n const mergedOptions: UploadFilesOptions = {\n ...options,\n sourceLocale: options.sourceLocale ?? this.sourceLocale,\n };\n\n // Require source locale\n if (!mergedOptions.sourceLocale) {\n const error = noSourceLocaleProvidedError('uploadTranslations');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n mergedOptions.sourceLocale = this.resolveCanonicalLocale(\n mergedOptions.sourceLocale\n );\n\n // Ensure all translation locales use canonical locales\n const targetFiles = files.map((f) => ({\n ...f,\n translations: f.translations.map((t) => ({\n ...t,\n locale: this.resolveCanonicalLocale(t.locale),\n })),\n }));\n\n // Process files in batches and convert result to UploadFilesResponse\n const result = await _uploadTranslations(\n targetFiles,\n mergedOptions as RequiredUploadFilesOptions,\n this._getTranslationConfig()\n );\n\n return {\n uploadedFiles: result.data,\n count: result.count,\n message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/translate/setupProject.ts","../src/translate/utils/batch.ts","../src/translate/utils/validateFileFormatTransform.ts","../src/translate/enqueueFiles.ts","../src/translate/createTag.ts","../src/translate/downloadFileBatch.ts","../src/translate/submitUserEditDiffs.ts","../src/translate/uploadSourceFiles.ts","../src/translate/uploadTranslations.ts","../src/translate/querySourceFile.ts","../src/projects/getProjectData.ts","../src/translate/checkJobStatus.ts","../src/translate/awaitJobs.ts","../src/translate/queryFileData.ts","../src/translate/getProjectInfo.ts","../src/translate/queryBranchData.ts","../src/translate/createBranch.ts","../src/translate/processFileMoves.ts","../src/translate/getOrphanedFiles.ts","../src/translate/publishFiles.ts","../src/index.ts"],"sourcesContent":["import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { FileReference } from '../types-dir/api/file';\n\nexport type SetupProjectFileReference = Pick<\n FileReference,\n 'branchId' | 'fileId' | 'versionId'\n>;\n\nexport type SetupProjectResult =\n | { setupJobId: string; status: 'queued' }\n | { status: 'completed' };\n\nexport type SetupProjectOptions = {\n force?: boolean;\n locales?: string[];\n timeoutMs?: number;\n};\n\n/**\n * @internal\n * Enqueues files for project setup the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param config - The configuration for the API call.\n * @param timeoutMS - The timeout in milliseconds\n * @returns The result of the API call.\n */\nexport async function _setupProject(\n files: SetupProjectFileReference[],\n config: TranslationRequestConfig,\n options?: SetupProjectOptions\n): Promise<SetupProjectResult> {\n return apiRequest<SetupProjectResult>(config, '/v2/project/setup/generate', {\n body: {\n files: files.map((f) => ({\n branchId: f.branchId,\n fileId: f.fileId,\n versionId: f.versionId,\n })),\n locales: options?.locales,\n force: options?.force,\n },\n timeout: options?.timeoutMs,\n });\n}\n","/**\n * Splits an array into batches of a specified size.\n * @param items - The array to split into batches.\n * @param batchSize - The maximum size of each batch.\n * @returns An array of batches.\n */\nexport function createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n}\n\n/**\n * Result of processing batches.\n */\nexport interface BatchList<T> {\n /** The items successfully processed across all batches */\n data: T[];\n /** The total number of items processed */\n count: number;\n /** The number of batches processed */\n batchCount: number;\n}\n\n/**\n * Options for batch processing.\n */\nexport interface BatchProcessOptions {\n /** Maximum number of items per batch (default: 100) */\n batchSize?: number;\n /** Whether to process batches in parallel (default: true) */\n parallel?: boolean;\n}\n\n/**\n * Processes items in batches using a provided processor function.\n *\n * @param items - The items to process.\n * @param processor - Async function that processes a single batch and returns items.\n * @param options - Optional configuration for batch processing.\n * @returns Promise that resolves to a BatchList containing all processed items.\n *\n * @example\n * ```typescript\n * const result = await processBatches(\n * files,\n * async (batch) => {\n * const response = await uploadFiles(batch);\n * return response.uploadedFiles;\n * },\n * { batchSize: 100 }\n * );\n *\n * console.log(result.data); // All items\n * console.log(result.count); // Total count\n * console.log(result.batchCount); // Number of batches processed\n * ```\n */\nexport async function processBatches<TInput, TOutput>(\n items: TInput[],\n processor: (batch: TInput[]) => Promise<TOutput[]>,\n options: BatchProcessOptions = {}\n): Promise<BatchList<TOutput>> {\n const { batchSize = 100, parallel = true } = options;\n\n if (items.length === 0) {\n return {\n data: [],\n count: 0,\n batchCount: 0,\n };\n }\n\n const batches = createBatches(items, batchSize);\n const allItems: TOutput[] = [];\n\n if (parallel) {\n // Process all batches in parallel.\n const results = await Promise.all(batches.map((batch) => processor(batch)));\n for (const result of results) {\n if (result) {\n allItems.push(...result);\n }\n }\n } else {\n // Process batches sequentially.\n for (const batch of batches) {\n const result = await processor(batch);\n if (result) {\n allItems.push(...result);\n }\n }\n }\n\n return {\n data: allItems,\n count: allItems.length,\n batchCount: batches.length,\n };\n}\n","import type { FileFormat } from '../../types-dir/api/file';\nimport { isSupportedFileFormatTransform } from '../../utils/isSupportedFileFormatTransform';\n\nexport type FileFormatTransformInput = {\n fileFormat?: FileFormat;\n transformFormat?: FileFormat;\n fileName?: string;\n fileId?: string;\n};\n\n/**\n * Returns a user-facing validation error when a requested file format transform\n * is missing source format context or is not currently supported.\n */\nexport function getFileFormatTransformError(\n file: FileFormatTransformInput\n): string | undefined {\n if (!file.transformFormat) return undefined;\n const fileLabel = file.fileName ?? file.fileId ?? 'unknown file';\n if (!file.fileFormat) {\n return `fileFormat is required when transformFormat is provided for ${fileLabel}`;\n }\n if (!isSupportedFileFormatTransform(file.fileFormat, file.transformFormat)) {\n return `Unsupported file format transform: ${file.fileFormat} -> ${file.transformFormat}`;\n }\n return undefined;\n}\n\n/**\n * Validates file format transforms before sending upload/enqueue requests.\n */\nexport function validateFileFormatTransforms(\n files: FileFormatTransformInput[]\n): void {\n for (const file of files) {\n const error = getFileFormatTransformError(file);\n if (error) throw new Error(error);\n }\n}\n","import { TranslationRequestConfig, EnqueueFilesResult } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { FileReferenceIds } from '../types-dir/api/file';\nimport { processBatches } from './utils/batch';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\nexport type EnqueueFilesOptions = {\n sourceLocale?: string;\n targetLocales: string[];\n modelProvider?: string;\n force?: boolean;\n timeout?: number;\n};\n\n/**\n * @internal\n * Enqueues files for translation in the General Translation API.\n * @param files - References of files to translate (file content already uploaded)\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport async function _enqueueFiles(\n files: FileReferenceIds[],\n options: EnqueueFilesOptions,\n config: TranslationRequestConfig\n): Promise<EnqueueFilesResult> {\n validateFileFormatTransforms(files);\n\n const result = await processBatches(\n files,\n async (batch) => {\n const body = {\n files: batch.map((f) => ({\n branchId: f.branchId,\n fileId: f.fileId,\n versionId: f.versionId,\n fileName: f.fileName,\n transformFormat: f.transformFormat,\n })),\n targetLocales: options.targetLocales,\n sourceLocale: options.sourceLocale,\n modelProvider: options.modelProvider,\n force: options.force,\n };\n\n const apiResult = await apiRequest<EnqueueFilesResult>(\n config,\n '/v2/project/translations/enqueue',\n { body, timeout: options.timeout }\n );\n return Array.from(Object.entries(apiResult.jobData));\n },\n { batchSize: 100 }\n );\n // flatten the result\n const jobs = Object.fromEntries(\n result.data.map(([jobId, jobData]) => [jobId, jobData])\n );\n return {\n jobData: jobs,\n locales: options.targetLocales,\n message: `Successfully enqueued ${result.count} file translation jobs in ${result.batchCount} batch(es)`,\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type CreateTagFileReference = {\n fileId: string;\n versionId: string;\n branchId: string;\n};\n\nexport type CreateTagOptions = {\n tagId: string;\n files: CreateTagFileReference[];\n message?: string;\n};\n\nexport type CreateTagResult = {\n tag: {\n id: string;\n tagId: string;\n message: string | null;\n createdAt: string;\n updatedAt: string;\n };\n};\n\n/**\n * @internal\n * Creates or upserts a file tag in the General Translation API.\n * @param options - The tag creation options.\n * @param config - The configuration for the API call.\n * @returns The created or updated tag.\n */\nexport async function _createTag(\n options: CreateTagOptions,\n config: TranslationRequestConfig\n): Promise<CreateTagResult> {\n return await apiRequest<CreateTagResult>(config, '/v2/project/tags/create', {\n body: {\n tagId: options.tagId,\n files: options.files,\n ...(options.message && { message: options.message }),\n },\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n DownloadFileBatchOptions,\n DownloadFileBatchRequest,\n DownloadFileBatchResult,\n} from '../types-dir/api/downloadFileBatch';\nimport { apiRequest } from './utils/apiRequest';\nimport { decode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\n/**\n * @internal\n * Downloads multiple translation files in batches.\n * @param files - Array of files to download\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns Promise resolving to a BatchList with all downloaded files\n */\nexport async function _downloadFileBatch(\n requests: DownloadFileBatchRequest,\n options: DownloadFileBatchOptions,\n config: TranslationRequestConfig\n) {\n return processBatches(\n requests,\n async (batch) => {\n const result = await apiRequest<DownloadFileBatchResult>(\n config,\n '/v2/project/files/download',\n { body: batch, timeout: options.timeout }\n );\n\n // convert from base64 to string\n const files = result.files.map((file) => ({\n ...file,\n data: decode(file.data),\n }));\n\n return files;\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type SubmitUserEditDiff = {\n fileName: string;\n locale: string;\n diff: string;\n branchId: string;\n versionId: string;\n fileId: string;\n localContent: string;\n};\n\nexport type SubmitUserEditDiffsPayload = {\n diffs: SubmitUserEditDiff[];\n};\n\n/**\n * @internal\n * Submits user edit diffs so the service can learn/persist user-intended rules.\n */\nexport async function _submitUserEditDiffs(\n payload: SubmitUserEditDiffsPayload,\n config: TranslationRequestConfig,\n options: { timeout?: number } = {}\n): Promise<{ success: boolean }> {\n await processBatches(\n payload.diffs,\n async (batch) => {\n await apiRequest(config, '/v2/project/files/diffs', {\n body: { diffs: batch } satisfies SubmitUserEditDiffsPayload,\n timeout: options.timeout,\n });\n return [{ success: true }];\n },\n { batchSize: 100 }\n );\n\n return { success: true };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { encode } from '../utils/base64';\nimport { processBatches } from './utils/batch';\n\nimport {\n FileUpload,\n UploadFilesResponse,\n RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\n\n/**\n * @internal\n * Uploads source files to the General Translation API in batches.\n * @param files - The files to upload.\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport async function _uploadSourceFiles(\n files: { source: FileUpload }[],\n options: RequiredUploadFilesOptions,\n config: TranslationRequestConfig\n) {\n return processBatches(\n files,\n async (batch) => {\n const body = {\n data: batch.map(({ source }) => ({\n source: {\n content: encode(source.content),\n fileName: source.fileName,\n fileFormat: source.fileFormat,\n locale: source.locale,\n dataFormat: source.dataFormat,\n formatMetadata: source.formatMetadata,\n fileId: source.fileId,\n versionId: source.versionId,\n branchId: source.branchId,\n incomingBranchId: source.incomingBranchId,\n checkedOutBranchId: source.checkedOutBranchId,\n },\n })),\n sourceLocale: options.sourceLocale,\n };\n\n const result = await apiRequest<UploadFilesResponse>(\n config,\n '/v2/project/files/upload-files',\n { body, timeout: options.timeout }\n );\n\n return result.uploadedFiles || [];\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nimport {\n FileUpload,\n UploadFilesResponse,\n RequiredUploadFilesOptions,\n} from '../types-dir/api/uploadFiles';\nimport { encode } from '../utils/base64';\nimport { validateFileFormatTransforms } from './utils/validateFileFormatTransform';\n\n/**\n * @internal\n * Uploads multiple translations to the General Translation API in batches.\n * @param files - Translations to upload with their source\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns Promise resolving to a BatchList with all uploaded files\n */\nexport async function _uploadTranslations(\n files: {\n source: FileUpload;\n translations: FileUpload[];\n }[],\n options: RequiredUploadFilesOptions,\n config: TranslationRequestConfig\n) {\n validateFileFormatTransforms(files.map(({ source }) => source));\n\n return processBatches(\n files,\n async (batch) => {\n const body = {\n data: batch.map(({ source, translations }) => ({\n source: {\n content: encode(source.content),\n fileName: source.fileName,\n fileFormat: source.fileFormat,\n transformFormat: source.transformFormat,\n locale: source.locale,\n dataFormat: source.dataFormat,\n formatMetadata: source.formatMetadata,\n fileId: source.fileId,\n versionId: source.versionId,\n branchId: source.branchId,\n },\n translations: translations.map((t) => ({\n content: encode(t.content),\n fileName: t.fileName,\n fileFormat: t.fileFormat,\n locale: t.locale,\n dataFormat: t.dataFormat,\n fileId: t.fileId,\n versionId: t.versionId,\n branchId: t.branchId,\n })),\n })),\n sourceLocale: options.sourceLocale,\n };\n\n const result = await apiRequest<UploadFilesResponse>(\n config,\n '/v2/project/files/upload-translations',\n { body, timeout: options.timeout }\n );\n\n return result.uploadedFiles || [];\n },\n { batchSize: 100 }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport {\n CheckFileTranslationsOptions,\n FileQueryResult,\n} from '../types-dir/api/checkFileTranslations';\nimport { FileQuery } from '../types-dir/api/checkFileTranslations';\nimport { apiRequest } from './utils/apiRequest';\n\n/**\n * @internal\n * Gets the source file and translation information for a given file ID and version ID.\n * @param query - The file ID and version ID to get the source file and translation information for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The source file and translation information for the given file ID and version ID\n */\nexport async function _querySourceFile(\n query: FileQuery,\n options: CheckFileTranslationsOptions,\n config: TranslationRequestConfig\n): Promise<FileQueryResult> {\n const branchId = query.branchId;\n const versionId = query.versionId;\n const fileId = query.fileId;\n\n const searchParams = new URLSearchParams();\n if (branchId) {\n searchParams.set('branchId', branchId);\n }\n if (versionId) {\n searchParams.set('versionId', versionId);\n }\n const endpoint = `/v2/project/translations/files/status/${encodeURIComponent(fileId)}?${searchParams.toString()}`;\n\n return apiRequest<FileQueryResult>(config, endpoint, {\n method: 'GET',\n timeout: options.timeout,\n });\n}\n","import { defaultBaseUrl } from '../settings/settingsUrls';\nimport { fetchWithTimeout } from '../translate/utils/fetchWithTimeout';\nimport { defaultTimeout } from '../settings/settings';\nimport { validateResponse } from '../translate/utils/validateResponse';\nimport { handleFetchError } from '../translate/utils/handleFetchError';\nimport { TranslationRequestConfig } from '../types';\nimport { generateRequestHeaders } from '../translate/utils/generateRequestHeaders';\nimport { ProjectData } from '../types-dir/api/project';\n\n/**\n * @internal\n * Gets the project data for a given project ID.\n * @param projectId - The project ID to get the project data for\n * @param options - The options for the API call.\n * @param config - The configuration for the request.\n * @returns The project data for the given project ID.\n */\nexport async function _getProjectData(\n projectId: string,\n options: { timeout?: number },\n config: TranslationRequestConfig\n): Promise<ProjectData> {\n const { baseUrl } = config;\n const timeout = options.timeout ? options.timeout : defaultTimeout;\n const url = `${baseUrl || defaultBaseUrl}/v2/project/info/${encodeURIComponent(projectId)}`;\n\n // Get the project data\n let response;\n try {\n response = await fetchWithTimeout(\n url,\n {\n method: 'GET',\n headers: generateRequestHeaders(config),\n },\n timeout\n );\n } catch (error) {\n handleFetchError(error, timeout);\n }\n\n // Validate the response\n await validateResponse(response);\n\n const result = await response.json();\n return result as ProjectData;\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type JobStatus =\n | 'queued'\n | 'processing'\n | 'completed'\n | 'failed'\n | 'unknown';\n\nexport type CheckJobStatusResult = {\n jobId: string;\n status: JobStatus;\n error?: { message: string };\n}[];\n\n/**\n * @internal\n * Queries job statuses for a project.\n * @param jobIds - Job IDs.\n * @param config - The configuration for the API call.\n * @param timeoutMs - The timeout in milliseconds.\n * @returns The result of the API call.\n */\nexport async function _checkJobStatus(\n jobIds: string[],\n config: TranslationRequestConfig,\n timeoutMs?: number\n): Promise<CheckJobStatusResult> {\n return apiRequest<CheckJobStatusResult>(config, '/v2/project/jobs/info', {\n body: { jobIds },\n timeout: timeoutMs,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { defaultTimeout } from '../settings/settings';\nimport {\n _checkJobStatus,\n CheckJobStatusResult,\n JobStatus,\n} from './checkJobStatus';\n\nexport type AwaitJobsOptions = {\n /** Polling interval in seconds. Defaults to 5. */\n pollingIntervalSeconds?: number;\n /** Timeout in seconds. Defaults to 600 (10 minutes). If reached, resolves with whatever status is current. */\n timeoutSeconds?: number;\n};\n\nexport type JobResult = {\n jobId: string;\n status: JobStatus;\n error?: { message: string };\n};\n\nexport type AwaitJobsResult = {\n /** Whether all jobs completed (none still in progress). */\n complete: boolean;\n jobs: JobResult[];\n};\n\n/**\n * @internal\n * Polls job statuses until all jobs are finished or the timeout is reached.\n * @param jobIds - Job IDs to poll.\n * @param options - Polling configuration.\n * @param config - API credentials and configuration.\n * @returns The final status of all jobs.\n */\nexport async function _awaitJobIds(\n jobIds: string[],\n options: AwaitJobsOptions | undefined,\n config: TranslationRequestConfig\n): Promise<AwaitJobsResult> {\n const pollingInterval = (options?.pollingIntervalSeconds ?? 5) * 1000;\n const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n const timeout =\n options?.timeoutSeconds !== undefined\n ? options.timeoutSeconds * 1000\n : DEFAULT_TIMEOUT_MS;\n\n if (jobIds.length === 0) {\n return { complete: true, jobs: [] };\n }\n\n const deadline = Date.now() + timeout;\n const finalStatuses = new Map<string, JobResult>(\n jobIds.map((id) => [id, { jobId: id, status: 'unknown' as JobStatus }])\n );\n const pendingJobIds = new Set(jobIds);\n\n while (pendingJobIds.size > 0) {\n const remainingTime = deadline - Date.now();\n if (remainingTime <= 0) break;\n\n let statuses: CheckJobStatusResult;\n try {\n statuses = await _checkJobStatus(\n Array.from(pendingJobIds),\n config,\n Math.min(remainingTime, defaultTimeout)\n );\n } catch (error) {\n if (Date.now() >= deadline) break;\n throw error;\n }\n\n if (Date.now() >= deadline) break;\n\n const returnedJobIds = new Set(statuses.map(({ jobId }) => jobId));\n\n for (const job of statuses) {\n if (\n job.status === 'completed' ||\n job.status === 'failed' ||\n job.status === 'unknown'\n ) {\n finalStatuses.set(job.jobId, {\n jobId: job.jobId,\n status: job.status,\n ...(job.error ? { error: job.error } : {}),\n });\n pendingJobIds.delete(job.jobId);\n } else {\n finalStatuses.set(job.jobId, {\n jobId: job.jobId,\n status: job.status,\n });\n }\n }\n\n for (const jobId of Array.from(pendingJobIds)) {\n if (!returnedJobIds.has(jobId)) {\n finalStatuses.set(jobId, { jobId, status: 'unknown' });\n pendingJobIds.delete(jobId);\n }\n }\n\n if (pendingJobIds.size === 0) break;\n\n const remainingSleepTime = deadline - Date.now();\n if (remainingSleepTime <= 0) break;\n\n await new Promise((resolve) =>\n setTimeout(resolve, Math.min(pollingInterval, remainingSleepTime))\n );\n }\n\n return {\n complete: pendingJobIds.size === 0,\n jobs: Array.from(finalStatuses.values()),\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { CheckFileTranslationsOptions } from '../types-dir/api/checkFileTranslations';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type FileDataQuery = {\n sourceFiles?: {\n fileId: string;\n versionId: string;\n branchId: string;\n }[];\n translatedFiles?: {\n fileId: string;\n versionId: string;\n branchId: string;\n locale: string;\n }[];\n};\n\nexport type FileDataResult = {\n sourceFiles?: {\n branchId: string;\n fileId: string;\n versionId: string;\n fileName: string;\n fileFormat: string;\n dataFormat: string | null;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n locales: string[];\n sourceLocale: string;\n }[];\n translatedFiles?: {\n branchId: string;\n fileId: string;\n versionId: string;\n fileFormat: string;\n dataFormat: string | null;\n createdAt: string;\n updatedAt: string;\n approvedAt: string | null;\n publishedAt: string | null;\n completedAt: string | null;\n locale: string;\n }[];\n};\n\n/**\n * @internal\n * Queries data about one or more source or translation files.\n * @param data - Object mapping source or translation file information\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The file data.\n */\nexport async function _queryFileData(\n data: FileDataQuery,\n options: CheckFileTranslationsOptions = {},\n config: TranslationRequestConfig\n): Promise<FileDataResult> {\n const body = {\n sourceFiles: data.sourceFiles?.map((item) => ({\n fileId: item.fileId,\n versionId: item.versionId,\n branchId: item.branchId,\n })),\n translatedFiles: data.translatedFiles?.map((item) => ({\n fileId: item.fileId,\n versionId: item.versionId,\n branchId: item.branchId,\n locale: item.locale,\n })),\n };\n\n return apiRequest<FileDataResult>(config, '/v2/project/files/info', {\n body,\n timeout: options.timeout,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type ProjectInfoResult = {\n id: string;\n name: string;\n orgId: string;\n defaultLocale: string;\n currentLocales: string[];\n autoApprove?: boolean;\n};\n\nexport type GetProjectInfoOptions = {\n timeout?: number;\n};\n\n/**\n * @internal\n * Fetches project info (name, locales, review settings) for a project.\n * @param options - The options for the API call.\n * @param config - The configuration for the API call.\n * @returns The project info.\n */\nexport async function _getProjectInfo(\n options: GetProjectInfoOptions,\n config: TranslationRequestConfig\n): Promise<ProjectInfoResult> {\n return apiRequest<ProjectInfoResult>(\n config,\n `/v2/project/info/${config.projectId}`,\n {\n method: 'GET',\n timeout: options.timeout,\n }\n );\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport type { BranchDataResult } from '../types-dir/api/branch';\n\nexport type BranchQuery = {\n branchNames: string[];\n};\n\n/**\n * @internal\n * Queries branch information from the API.\n * @param query - Object mapping the current branch and incoming branches\n * @param config - The configuration for the API call.\n * @returns The branch information.\n */\nexport async function _queryBranchData(\n query: BranchQuery,\n config: TranslationRequestConfig\n): Promise<BranchDataResult> {\n return apiRequest<BranchDataResult>(config, '/v2/project/branches/info', {\n body: query,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type CreateBranchQuery = {\n branchName: string;\n defaultBranch: boolean;\n};\n\nexport type CreateBranchResult = {\n branch: { id: string; name: string };\n};\n\n/**\n * @internal\n * Creates a new branch in the API.\n * @param query - Object mapping the branch name and default branch flag\n * @param config - The configuration for the API call.\n * @returns The created branch information.\n */\nexport async function _createBranch(\n query: CreateBranchQuery,\n config: TranslationRequestConfig\n): Promise<CreateBranchResult> {\n return apiRequest<CreateBranchResult>(config, '/v2/project/branches/create', {\n body: query,\n });\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { processBatches } from './utils/batch';\n\nexport type MoveMapping = {\n oldFileId: string;\n newFileId: string;\n newFileName: string;\n};\n\nexport type MoveResult = {\n oldFileId: string;\n newFileId: string;\n success: boolean;\n newSourceFileId?: string;\n clonedTranslationsCount?: number;\n error?: string;\n};\n\nexport type ProcessMovesResponse = {\n results: MoveResult[];\n summary: {\n total: number;\n succeeded: number;\n failed: number;\n };\n};\n\nexport type ProcessMovesOptions = {\n timeout?: number;\n branchId?: string;\n};\n\n/**\n * @internal\n * Processes file moves by cloning source files and translations with new fileIds.\n * Called when the CLI detects that files have been moved/renamed.\n * @param moves - Array of move mappings (old fileId to new fileId)\n * @param options - Options including branchId and timeout\n * @param config - The configuration for the API call.\n * @returns Promise resolving to the move results\n */\nexport async function _processFileMoves(\n moves: MoveMapping[],\n options: ProcessMovesOptions,\n config: TranslationRequestConfig\n): Promise<ProcessMovesResponse> {\n if (moves.length === 0) {\n return {\n results: [],\n summary: { total: 0, succeeded: 0, failed: 0 },\n };\n }\n\n const batchResult = await processBatches(\n moves,\n async (batch) => {\n const result = await apiRequest<ProcessMovesResponse>(\n config,\n '/v2/project/files/moves',\n {\n body: { branchId: options.branchId, moves: batch },\n timeout: options.timeout,\n }\n );\n return result.results;\n },\n { batchSize: 100 }\n );\n\n const succeeded = batchResult.data.filter((r) => r.success).length;\n const failed = batchResult.data.filter((r) => !r.success).length;\n\n return {\n results: batchResult.data,\n summary: {\n total: moves.length,\n succeeded,\n failed,\n },\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\nimport { createBatches } from './utils/batch';\n\nexport type OrphanedFile = {\n fileId: string;\n versionId: string;\n fileName: string;\n};\n\nexport type GetOrphanedFilesResult = {\n orphanedFiles: OrphanedFile[];\n};\n\n/**\n * @internal\n * Gets orphaned files for a branch - files that exist on the branch\n * but whose fileIds are not in the provided list.\n * Used for move detection.\n * @param branchId - The branch to check for orphaned files\n * @param fileIds - List of current file IDs (files that are NOT orphaned)\n * @param options - The options for the API call\n * @param config - The configuration for the API call\n * @returns The orphaned files\n */\nexport async function _getOrphanedFiles(\n branchId: string,\n fileIds: string[],\n options: { timeout?: number } = {},\n config: TranslationRequestConfig\n): Promise<GetOrphanedFilesResult> {\n const makeRequest = (batchFileIds: string[]) =>\n apiRequest<GetOrphanedFilesResult>(config, '/v2/project/files/orphaned', {\n body: { branchId, fileIds: batchFileIds },\n timeout: options.timeout,\n });\n\n // If no fileIds, make a single request\n if (fileIds.length === 0) {\n return makeRequest([]);\n }\n\n // Split fileIds into batches of 100\n const batches = createBatches(fileIds, 100);\n\n // Process batches in parallel\n // Each batch returns files NOT in that batch's fileIds\n // True orphans are files that appear in ALL batch responses (intersection)\n const batchResults = await Promise.all(\n batches.map((batch) => makeRequest(batch))\n );\n\n if (batchResults.length === 1) {\n return batchResults[0];\n }\n\n // Find intersection of orphaned files across all batches\n // A file is truly orphaned only if it's not in ANY of our fileId batches\n // Start with first batch's orphans\n const orphanedFileMap = new Map<string, OrphanedFile>();\n for (const orphan of batchResults[0].orphanedFiles) {\n orphanedFileMap.set(orphan.fileId, orphan);\n }\n\n // Intersect with each subsequent batch.\n for (let i = 1; i < batchResults.length; i++) {\n const batchOrphanIds = new Set(\n batchResults[i].orphanedFiles.map((f) => f.fileId)\n );\n Array.from(orphanedFileMap.keys()).forEach((fileId) => {\n if (!batchOrphanIds.has(fileId)) {\n orphanedFileMap.delete(fileId);\n }\n });\n }\n\n return {\n orphanedFiles: Array.from(orphanedFileMap.values()),\n };\n}\n","import { TranslationRequestConfig } from '../types';\nimport { apiRequest } from './utils/apiRequest';\n\nexport type PublishFileEntry = {\n fileId: string;\n versionId: string;\n branchId?: string;\n publish: boolean;\n fileName?: string;\n};\n\nexport type PublishFilesResult = {\n results: {\n fileId: string;\n versionId: string;\n locale?: string; // if locale is provided, it means this result is for a translation. Else it is for a source file.\n branchId: string;\n success: boolean;\n error?: string;\n }[];\n};\n\n/**\n * @internal\n * Publishes or unpublishes files on the CDN.\n * @param files - Array of file entries with publish flags\n * @param config - The configuration for the API call.\n * @returns The result of the API call.\n */\nexport async function _publishFiles(\n files: PublishFileEntry[],\n config: TranslationRequestConfig\n): Promise<PublishFilesResult> {\n return await apiRequest<PublishFilesResult>(\n config,\n '/v2/project/files/publish',\n {\n body: { files },\n }\n );\n}\n","// `generaltranslation` language toolkit\n// © 2026, General Translation, Inc.\n\n// ----- IMPORTS ----- //\n\nimport {\n EnqueueFilesResult,\n CheckFileTranslationsOptions,\n DownloadFileBatchOptions,\n DownloadFileBatchResult,\n DownloadFileOptions,\n} from './types';\nimport { libraryDefaultLocale } from './settings/settings';\nimport {\n noSourceLocaleProvidedError,\n noTargetLocaleProvidedError,\n} from './logging/errors';\nimport { gtInstanceLogger } from './logging/logger';\nimport {\n _setupProject,\n SetupProjectResult,\n SetupProjectOptions,\n type SetupProjectFileReference,\n} from './translate/setupProject';\nimport {\n _enqueueFiles,\n type EnqueueFilesOptions,\n} from './translate/enqueueFiles';\nimport {\n _createTag,\n CreateTagOptions,\n CreateTagResult,\n} from './translate/createTag';\nimport { _downloadFileBatch } from './translate/downloadFileBatch';\nimport {\n FileQuery,\n FileQueryResult,\n} from './types-dir/api/checkFileTranslations';\nimport {\n _submitUserEditDiffs,\n SubmitUserEditDiffsPayload,\n} from './translate/submitUserEditDiffs';\nimport { _uploadSourceFiles } from './translate/uploadSourceFiles';\nimport { _uploadTranslations } from './translate/uploadTranslations';\nimport {\n FileUpload,\n RequiredUploadFilesOptions,\n UploadFilesOptions,\n UploadFilesResponse,\n} from './types-dir/api/uploadFiles';\nimport { _querySourceFile } from './translate/querySourceFile';\nimport { ProjectData } from './types-dir/api/project';\nimport { _getProjectData } from './projects/getProjectData';\nimport { DownloadFileBatchRequest } from './types-dir/api/downloadFileBatch';\nimport {\n _checkJobStatus,\n CheckJobStatusResult,\n} from './translate/checkJobStatus';\nimport {\n _awaitJobIds,\n AwaitJobsOptions,\n AwaitJobsResult,\n} from './translate/awaitJobs';\nimport type { FileDataQuery, FileDataResult } from './translate/queryFileData';\nimport { _queryFileData } from './translate/queryFileData';\nimport type {\n GetProjectInfoOptions,\n ProjectInfoResult,\n} from './translate/getProjectInfo';\nimport { _getProjectInfo } from './translate/getProjectInfo';\nimport type { BranchQuery } from './translate/queryBranchData';\nimport type { BranchDataResult } from './types-dir/api/branch';\nimport { _queryBranchData } from './translate/queryBranchData';\nimport type {\n CreateBranchQuery,\n CreateBranchResult,\n} from './translate/createBranch';\nimport { _createBranch } from './translate/createBranch';\nimport type { FileReferenceIds } from './types-dir/api/file';\nimport {\n _processFileMoves,\n type MoveMapping,\n type ProcessMovesResponse,\n type ProcessMovesOptions,\n} from './translate/processFileMoves';\nimport {\n _getOrphanedFiles,\n type GetOrphanedFilesResult,\n} from './translate/getOrphanedFiles';\nimport {\n _publishFiles,\n type PublishFileEntry,\n type PublishFilesResult,\n} from './translate/publishFiles';\nimport { GTRuntime } from './runtime';\n\nexport { GTRuntime, type GTConstructorParams } from './runtime';\nexport { decodeVars } from './derive/decodeVars';\nexport { declareVar } from './derive/declareVar';\nexport { derive } from './derive/derive';\n\nexport {\n LocaleConfig,\n type LocaleConfigConstructorParams,\n} from '@generaltranslation/format';\n\nexport {\n determineLocale,\n formatCurrency,\n formatCutoff,\n formatDateTime,\n formatList,\n formatListToParts,\n formatMessage,\n formatNum,\n formatRelativeTime,\n formatRelativeTimeFromDate,\n getLocaleDirection,\n getLocaleEmoji,\n getLocaleName,\n getLocaleProperties,\n getRegionProperties,\n isSameDialect,\n isSameLanguage,\n isSupersetLocale,\n isValidLocale,\n requiresTranslation,\n resolveAliasLocale,\n resolveCanonicalLocale,\n standardizeLocale,\n} from '@generaltranslation/format';\n\n// ============================================================ //\n// Core Class //\n// ============================================================ //\n\n/**\n * GT is the core driver for the General Translation library.\n * It extends {@link GTRuntime} (locale management, formatting, and runtime\n * translation) with the project and file management API client used by\n * tooling such as the CLI.\n *\n * Browser-facing SDK code should construct {@link GTRuntime} instead so\n * production bundles do not ship the file management client.\n *\n * @class GT\n * @description A comprehensive toolkit for handling internationalization and localization.\n *\n * @example\n * const gt = new GT({\n * sourceLocale: 'en-US',\n * targetLocale: 'es-ES',\n * locales: ['en-US', 'es-ES', 'fr-FR']\n * });\n */\nexport class GT extends GTRuntime {\n // -------------- Branch Methods -------------- //\n\n /**\n * Queries branch information from the API.\n *\n * @param {BranchQuery} query - Object mapping the current branch and incoming branches\n * @returns {Promise<BranchDataResult>} The branch information.\n */\n async queryBranchData(query: BranchQuery): Promise<BranchDataResult> {\n this._validateAuth('queryBranchData');\n return await _queryBranchData(query, this._getTranslationConfig());\n }\n\n /**\n * Creates a new branch in the API. If the branch already exists, it will be returned.\n *\n * @param {CreateBranchQuery} query - Object mapping the branch name and default branch flag\n * @returns {Promise<CreateBranchResult>} The created branch information.\n */\n async createBranch(query: CreateBranchQuery): Promise<CreateBranchResult> {\n this._validateAuth('createBranch');\n return await _createBranch(query, this._getTranslationConfig());\n }\n\n /**\n * Processes file moves by cloning source files and translations with new fileIds.\n * This is called when files have been moved/renamed and we want to preserve translations.\n *\n * @param {MoveMapping[]} moves - Array of move mappings (old fileId to new fileId)\n * @param {ProcessMovesOptions} options - Options including branchId and timeout\n * @returns {Promise<ProcessMovesResponse>} The move processing results.\n *\n * @example\n * const result = await gt.processFileMoves([\n * { oldFileId: 'abc123', newFileId: 'def456', newFileName: 'locales/en.json' }\n * ], { branchId: 'main' });\n */\n async processFileMoves(\n moves: MoveMapping[],\n options: ProcessMovesOptions = {}\n ): Promise<ProcessMovesResponse> {\n this._validateAuth('processFileMoves');\n return await _processFileMoves(\n moves,\n options,\n this._getTranslationConfig()\n );\n }\n\n /**\n * Gets orphaned files for a branch - files that exist on the branch\n * but whose fileIds are not in the provided list.\n * Used for move detection.\n *\n * @param {string} branchId - The branch to check for orphaned files.\n * @param {string[]} fileIds - List of current file IDs (files that are NOT orphaned)\n * @param {Object} options - Options including timeout.\n * @returns {Promise<GetOrphanedFilesResult>} The orphaned files.\n *\n * @example\n * const result = await gt.getOrphanedFiles('branch-id', ['file-1', 'file-2']);\n */\n async getOrphanedFiles(\n branchId: string,\n fileIds: string[],\n options: { timeout?: number } = {}\n ): Promise<GetOrphanedFilesResult> {\n this._validateAuth('getOrphanedFiles');\n return await _getOrphanedFiles(\n branchId,\n fileIds,\n options,\n this._getTranslationConfig()\n );\n }\n\n // -------------- Translation Methods -------------- //\n\n /**\n * Enqueues project setup job using the specified file references\n *\n * This method creates setup jobs that will process source file references\n * and generate a project setup. The files parameter contains references (IDs) to source\n * files that have already been uploaded via uploadSourceFiles. The setup jobs are queued\n * for processing and will generate a project setup based on the source files.\n *\n * @param {SetupProjectFileReference[]} files - Array of file references containing IDs of previously uploaded source files\n * @param {SetupProjectOptions} [options] - Optional settings for target locales and timeout.\n * @returns {Promise<SetupProjectResult>} Object containing the jobId and status\n */\n async setupProject(\n files: SetupProjectFileReference[],\n options?: SetupProjectOptions\n ): Promise<SetupProjectResult> {\n this._validateAuth('setupProject');\n options = {\n ...options,\n locales: options?.locales?.map((locale) =>\n this.resolveCanonicalLocale(locale)\n ),\n };\n return await _setupProject(files, this._getTranslationConfig(), options);\n }\n\n /**\n * Checks the current status of one or more project jobs by their unique identifiers.\n *\n * This method polls the API to determine whether one or more jobs are still running,\n * have completed successfully, or have failed. Jobs are created after calling either enqueueFiles or setupProject.\n *\n * @param {string[]} jobIds - The unique identifiers of the jobs to check.\n * @param {number} [timeoutMs] - Optional timeout in milliseconds for the API request.\n * @returns {Promise<CheckJobStatusResult>} Object containing the job status.\n *\n * @example\n * const result = await gt.checkJobStatus([\n * 'job-123',\n * 'job-456',\n * ], 10000);\n */\n async checkJobStatus(\n jobIds: string[],\n timeoutMs?: number\n ): Promise<CheckJobStatusResult> {\n this._validateAuth('checkJobStatus');\n return await _checkJobStatus(\n jobIds,\n this._getTranslationConfig(),\n timeoutMs\n );\n }\n\n /**\n * Polls job statuses until all jobs are finished or the timeout is reached.\n *\n * @param {EnqueueFilesResult | string[]} jobs - Job IDs or the result returned from enqueueFiles.\n * @param {AwaitJobsOptions} [options] - Polling configuration (interval, timeout).\n * @returns {Promise<AwaitJobsResult>} The final status of all jobs and whether they all completed.\n */\n async awaitJobs(\n jobs: EnqueueFilesResult | string[],\n options?: AwaitJobsOptions\n ): Promise<AwaitJobsResult> {\n this._validateAuth('awaitJobs');\n const jobIds = Array.isArray(jobs) ? jobs : Object.keys(jobs.jobData);\n return await _awaitJobIds(jobIds, options, this._getTranslationConfig());\n }\n\n /**\n * Enqueues translation jobs for previously uploaded source files.\n *\n * This method creates translation jobs that will process existing source files\n * and generate translations in the specified target languages. The files parameter\n * contains references (IDs) to source files that have already been uploaded via\n * uploadSourceFiles. The translation jobs are queued for processing and will\n * generate translated content based on the source files and target locales provided.\n *\n * @param {FileReferenceIds[]} files - Array of file references containing IDs of previously uploaded source files\n * @param {EnqueueFilesOptions} options - Configuration options including source locale, target locales, and job settings.\n * @returns {Promise<EnqueueFilesResult>} Result containing job IDs, queue status, and processing information.\n */\n async enqueueFiles(\n files: FileReferenceIds[],\n options: EnqueueFilesOptions\n ): Promise<EnqueueFilesResult> {\n // Validation\n this._validateAuth('enqueueFiles');\n\n // Merge instance settings with options.\n let mergedOptions: EnqueueFilesOptions = {\n ...options,\n sourceLocale: options.sourceLocale ?? this.sourceLocale!,\n targetLocales: options.targetLocales ?? [this.targetLocale!],\n };\n\n // Require source locale\n if (!mergedOptions.sourceLocale) {\n const error = noSourceLocaleProvidedError('enqueueFiles');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n // Require target locale(s)\n if (\n !mergedOptions.targetLocales ||\n mergedOptions.targetLocales.length === 0\n ) {\n const error = noTargetLocaleProvidedError('enqueueFiles');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n // Replace target locales with canonical locales\n mergedOptions = {\n ...mergedOptions,\n targetLocales: mergedOptions.targetLocales.map((locale) =>\n this.resolveCanonicalLocale(locale)\n ),\n };\n\n return await _enqueueFiles(\n files,\n mergedOptions,\n this._getTranslationConfig()\n );\n }\n\n /**\n * Creates or upserts a file tag, associating a set of source files\n * with a user-defined tag ID and optional message.\n *\n * @param {CreateTagOptions} options - Tag creation options including tagId, sourceFileIds, and optional message\n * @returns {Promise<CreateTagResult>} The created or updated tag.\n */\n async createTag(options: CreateTagOptions): Promise<CreateTagResult> {\n this._validateAuth('createTag');\n return await _createTag(options, this._getTranslationConfig());\n }\n\n /**\n * Publishes or unpublishes files on the CDN.\n *\n * @param {PublishFileEntry[]} files - Array of file entries with publish flags\n * @returns {Promise<PublishFilesResult>} Result containing per-file success/failure\n */\n async publishFiles(files: PublishFileEntry[]): Promise<PublishFilesResult> {\n this._validateAuth('publishFiles');\n return await _publishFiles(files, this._getTranslationConfig());\n }\n\n /**\n * Submits user edit diffs for existing translations so future generations preserve user intent.\n *\n * @param {SubmitUserEditDiffsPayload} payload - Project-scoped diff payload.\n * @returns {Promise<void>} Resolves when submission succeeds.\n */\n async submitUserEditDiffs(\n payload: SubmitUserEditDiffsPayload\n ): Promise<void> {\n this._validateAuth('submitUserEditDiffs');\n // Normalize locales to canonical form before submission.\n const normalized: SubmitUserEditDiffsPayload = {\n ...payload,\n diffs: (payload.diffs || []).map((d) => ({\n ...d,\n locale: this.resolveCanonicalLocale(d.locale),\n })),\n };\n await _submitUserEditDiffs(normalized, this._getTranslationConfig());\n }\n\n /**\n * Queries data about one or more source or translation files.\n *\n * @param {FileDataQuery} data - Object mapping source and translation file information.\n * @param {CheckFileTranslationsOptions} options - Options for the API call.\n * @returns {Promise<FileDataResult>} The source and translation file data information.\n *\n * @example\n * const result = await gt.queryFileData({\n * sourceFiles: [\n * { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890' },\n * ],\n * translatedFiles: [\n * { fileId: '1234567890', versionId: '1234567890', branchId: '1234567890', locale: 'es-ES' },\n * ],\n * }, {\n * timeout: 10000,\n * });\n *\n */\n /**\n * Fetches project info (name, locales, review settings) for the\n * authenticated project.\n * @param options - The options for the API call.\n * @returns The project info.\n */\n async getProjectInfo(\n options: GetProjectInfoOptions = {}\n ): Promise<ProjectInfoResult> {\n this._validateAuth('getProjectInfo');\n return await _getProjectInfo(options, this._getTranslationConfig());\n }\n\n async queryFileData(\n data: FileDataQuery,\n options: CheckFileTranslationsOptions = {}\n ): Promise<FileDataResult> {\n // Validation\n this._validateAuth('queryFileData');\n\n // Replace target locales with canonical locales\n data.translatedFiles = data.translatedFiles?.map((item) => ({\n ...item,\n locale: this.resolveCanonicalLocale(item.locale),\n }));\n\n // Request the file translation status\n const result = await _queryFileData(\n data,\n options,\n this._getTranslationConfig()\n );\n\n // Resolve canonical locales\n result.translatedFiles = result.translatedFiles?.map((item) => ({\n ...item,\n ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n }));\n result.sourceFiles = result.sourceFiles?.map((item) => ({\n ...item,\n ...(item.sourceLocale && {\n sourceLocale: this.resolveAliasLocale(item.sourceLocale),\n }),\n locales: item.locales.map((locale) => this.resolveAliasLocale(locale)),\n }));\n return result;\n }\n\n /**\n * Gets source and translation information for a given file ID and version ID.\n *\n * @param {FileQuery} data - File query containing file ID and version ID.\n * @param {CheckFileTranslationsOptions} options - Options for getting source and translation information.\n * @returns {Promise<FileQueryResult>} The source file and translation information.\n *\n * @example\n * const result = await gt.querySourceFile(\n * { fileId: '1234567890', versionId: '1234567890' },\n * { timeout: 10000 }\n * );\n *\n */\n async querySourceFile(\n data: FileQuery,\n options: CheckFileTranslationsOptions = {}\n ): Promise<FileQueryResult> {\n // Validation\n this._validateAuth('querySourceFile');\n\n // Request the file translation status\n const result = await _querySourceFile(\n data,\n options,\n this._getTranslationConfig()\n );\n // Replace locales with canonical locales\n result.translations = result.translations.map((item) => ({\n ...item,\n ...(item.locale && { locale: this.resolveAliasLocale(item.locale) }),\n }));\n result.sourceFile.locales = result.sourceFile.locales.map((locale) =>\n this.resolveAliasLocale(locale)\n );\n if (result.sourceFile.sourceLocale) {\n result.sourceFile.sourceLocale = this.resolveAliasLocale(\n result.sourceFile.sourceLocale\n );\n }\n return result;\n }\n /**\n * Get project data for a given project ID.\n *\n * @param {string} projectId - The ID of the project to get the data for.\n * @returns {Promise<ProjectData>} The project data.\n *\n * @example\n * const result = await gt.getProjectData(\n * '1234567890'\n * );\n *\n */\n async getProjectData(\n projectId: string,\n options: { timeout?: number } = {}\n ): Promise<ProjectData> {\n // Validation\n this._validateAuth('getProjectData');\n\n // Request the file translation status\n const result = await _getProjectData(\n projectId,\n options,\n this._getTranslationConfig()\n );\n // Replace locales with canonical locales\n result.currentLocales = result.currentLocales.map((item) =>\n this.resolveAliasLocale(item)\n );\n result.defaultLocale = this.resolveAliasLocale(result.defaultLocale);\n return result;\n }\n\n /**\n * Downloads a single file.\n *\n * @param file - The file query object.\n * @param {string} file.fileId - The ID of the file to download.\n * @param {string} [file.branchId] - The ID of the branch to download the file from. If not provided, the default branch will be used.\n * @param {string} [file.locale] - The locale to download the file for. If not provided, the source file will be downloaded.\n * @param {string} [file.versionId] - The version ID to download the file from. If not provided, the latest version will be used.\n * @param {DownloadFileOptions} options - Options for downloading the file.\n * @returns {Promise<string>} The downloaded file content.\n *\n * @example\n * const result = await gt.downloadFile({\n * fileId: '1234567890',\n * branchId: '1234567890',\n * locale: 'es-ES',\n * versionId: '1234567890',\n * }, {\n * timeout: 10000,\n * });\n */\n async downloadFile(\n file: {\n fileId: string;\n branchId?: string;\n locale?: string;\n versionId?: string;\n useLatestAvailableVersion?: boolean;\n },\n options: DownloadFileOptions = {}\n ): Promise<string> {\n // Validation\n this._validateAuth('downloadTranslatedFile');\n\n const result = await _downloadFileBatch(\n [\n {\n fileId: file.fileId,\n branchId: file.branchId,\n locale: file.locale\n ? this.resolveCanonicalLocale(file.locale)\n : undefined,\n versionId: file.versionId,\n useLatestAvailableVersion: file.useLatestAvailableVersion,\n },\n ],\n options,\n this._getTranslationConfig()\n );\n return result.data?.[0]?.data ?? '';\n }\n\n /**\n * Downloads multiple files in a batch.\n *\n * @param {DownloadFileBatchRequest} requests - Array of file query objects to download.\n * @param {DownloadFileBatchOptions} options - Options for the batch download.\n * @returns {Promise<DownloadFileBatchResult>} The batch download results.\n *\n * @example\n * const result = await gt.downloadFileBatch([{\n * fileId: '1234567890',\n * locale: 'es-ES',\n * versionId: '1234567890',\n * }], {\n * timeout: 10000,\n * });\n */\n async downloadFileBatch(\n requests: DownloadFileBatchRequest,\n options: DownloadFileBatchOptions = {}\n ): Promise<DownloadFileBatchResult> {\n // Validation\n this._validateAuth('downloadFileBatch');\n\n requests = requests.map((request) => ({\n ...request,\n locale: request.locale\n ? this.resolveCanonicalLocale(request.locale)\n : undefined,\n }));\n\n // Request the batch download.\n const result = await _downloadFileBatch(\n requests,\n options,\n this._getTranslationConfig()\n );\n\n return {\n files: result.data.map((file) => ({\n ...file,\n ...(file.locale && {\n locale: this.resolveAliasLocale(file.locale),\n }),\n })),\n count: result.count,\n };\n }\n\n /**\n * Uploads source files to the translation service without any translation content.\n *\n * This method creates or replaces source file entries in your project. Each uploaded\n * file becomes a source that can later be translated into target languages. The files\n * are processed and stored as base entries that serve as the foundation for generating\n * translations through the translation workflow.\n *\n * @param {Array<{source: FileUpload}>} files - Array of objects containing source file data to upload\n * @param {UploadFilesOptions} options - Configuration options including source locale and other upload settings.\n * @returns {Promise<UploadFilesResponse>} Upload result containing file IDs, version information, and upload status.\n */\n async uploadSourceFiles(\n files: { source: FileUpload }[],\n options: UploadFilesOptions\n ): Promise<UploadFilesResponse> {\n // Validation\n this._validateAuth('uploadSourceFiles');\n\n // Merge instance settings with options.\n const mergedOptions: UploadFilesOptions = {\n ...options,\n sourceLocale: this.resolveCanonicalLocale(\n options.sourceLocale ?? this.sourceLocale ?? libraryDefaultLocale\n ),\n };\n\n // resolve canonical locales\n files = files.map((f) => ({\n ...f,\n source: {\n ...f.source,\n locale: this.resolveCanonicalLocale(f.source.locale),\n },\n }));\n\n // Process files in batches and convert result to UploadFilesResponse\n const result = await _uploadSourceFiles(\n files,\n mergedOptions as RequiredUploadFilesOptions,\n this._getTranslationConfig()\n );\n\n return {\n uploadedFiles: result.data,\n count: result.count,\n message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n };\n }\n\n /**\n * Uploads translation files that correspond to previously uploaded source files.\n *\n * This method allows you to provide translated content for existing source files in your project.\n * Each translation must reference an existing source file and include the translated content\n * along with the target locale information. This is used when you have pre-existing translations\n * that you want to upload directly rather than generating them through the translation service.\n *\n * @param {Array<{source: FileUpload, translations: FileUpload[]}>} files - Array of file objects where:\n * - `source`: Reference to the existing source file (contains IDs but no content).\n * - `translations`: Array of translated files, each containing content, locale, and reference IDs\n * @param {UploadFilesOptions} options - Configuration options including source locale and upload settings.\n * @returns {Promise<UploadFilesResponse>} Upload result containing translation IDs, status, and processing information.\n */\n async uploadTranslations(\n files: {\n source: FileUpload; // reference only (no content)\n translations: FileUpload[]; // each has content + ids + locale\n }[],\n options: UploadFilesOptions\n ): Promise<UploadFilesResponse> {\n // Validation\n this._validateAuth('uploadTranslations');\n\n // Merge instance settings with options.\n const mergedOptions: UploadFilesOptions = {\n ...options,\n sourceLocale: options.sourceLocale ?? this.sourceLocale,\n };\n\n // Require source locale\n if (!mergedOptions.sourceLocale) {\n const error = noSourceLocaleProvidedError('uploadTranslations');\n gtInstanceLogger.error(error);\n throw new Error(error);\n }\n\n mergedOptions.sourceLocale = this.resolveCanonicalLocale(\n mergedOptions.sourceLocale\n );\n\n // Ensure all translation locales use canonical locales\n const targetFiles = files.map((f) => ({\n ...f,\n translations: f.translations.map((t) => ({\n ...t,\n locale: this.resolveCanonicalLocale(t.locale),\n })),\n }));\n\n // Process files in batches and convert result to UploadFilesResponse\n const result = await _uploadTranslations(\n targetFiles,\n mergedOptions as RequiredUploadFilesOptions,\n this._getTranslationConfig()\n );\n\n return {\n uploadedFiles: result.data,\n count: result.count,\n message: `Successfully uploaded ${result.count} files in ${result.batchCount} batch(es)`,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/internal.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_api = require("./api-B2fSa2JN.cjs");
|
|
3
|
-
const require_derive = require("./derive-
|
|
3
|
+
const require_derive = require("./derive-Cbl7M1SY.cjs");
|
|
4
4
|
const require_isVariable = require("./isVariable-E-vOsD6G.cjs");
|
|
5
|
-
let
|
|
5
|
+
let _generaltranslation_icu = require("@generaltranslation/icu");
|
|
6
6
|
let _generaltranslation_format_internal = require("@generaltranslation/format/internal");
|
|
7
7
|
//#region src/settings/plurals.ts
|
|
8
8
|
const pluralForms = [
|
|
@@ -133,99 +133,6 @@ function extractVars(icuString) {
|
|
|
133
133
|
return variables;
|
|
134
134
|
}
|
|
135
135
|
//#endregion
|
|
136
|
-
//#region src/derive/utils/printIcuAst.ts
|
|
137
|
-
/*!
|
|
138
|
-
MIT License
|
|
139
|
-
|
|
140
|
-
Copyright (c) 2023 FormatJS
|
|
141
|
-
|
|
142
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
143
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
144
|
-
in the Software without restriction, including without limitation the rights
|
|
145
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
146
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
147
|
-
furnished to do so, subject to the following conditions:
|
|
148
|
-
|
|
149
|
-
The above copyright notice and this permission notice shall be included in all
|
|
150
|
-
copies or substantial portions of the Software.
|
|
151
|
-
|
|
152
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
153
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
154
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
155
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
156
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
157
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
158
|
-
SOFTWARE.
|
|
159
|
-
*/
|
|
160
|
-
/**
|
|
161
|
-
* Local copy of FormatJS `printAST` (see the license header above). The
|
|
162
|
-
* published printer subpath is CommonJS-only, which browsers and Vite-based
|
|
163
|
-
* dev servers (e.g. TanStack Start) cannot load from our ESM build, and the
|
|
164
|
-
* package's ESM variant uses extensionless relative imports that fail Node
|
|
165
|
-
* resolution.
|
|
166
|
-
*
|
|
167
|
-
* Output must stay byte-identical to FormatJS `printAST` because condensed
|
|
168
|
-
* ICU strings feed into hashing.
|
|
169
|
-
*/
|
|
170
|
-
function printIcuAst(ast) {
|
|
171
|
-
return doPrintAst(ast, false);
|
|
172
|
-
}
|
|
173
|
-
function doPrintAst(ast, isInPlural) {
|
|
174
|
-
return ast.map((el, i) => {
|
|
175
|
-
switch (el.type) {
|
|
176
|
-
case _formatjs_icu_messageformat_parser.TYPE.literal: return printLiteralElement(el, isInPlural, i === 0, i === ast.length - 1);
|
|
177
|
-
case _formatjs_icu_messageformat_parser.TYPE.argument: return `{${el.value}}`;
|
|
178
|
-
case _formatjs_icu_messageformat_parser.TYPE.date:
|
|
179
|
-
case _formatjs_icu_messageformat_parser.TYPE.time:
|
|
180
|
-
case _formatjs_icu_messageformat_parser.TYPE.number: return printSimpleFormatElement(el);
|
|
181
|
-
case _formatjs_icu_messageformat_parser.TYPE.plural: return printPluralElement(el);
|
|
182
|
-
case _formatjs_icu_messageformat_parser.TYPE.select: return printSelectElement(el);
|
|
183
|
-
case _formatjs_icu_messageformat_parser.TYPE.pound: return "#";
|
|
184
|
-
case _formatjs_icu_messageformat_parser.TYPE.tag: return printTagElement(el);
|
|
185
|
-
}
|
|
186
|
-
}).join("");
|
|
187
|
-
}
|
|
188
|
-
function printTagElement(el) {
|
|
189
|
-
return `<${el.value}>${printIcuAst(el.children)}</${el.value}>`;
|
|
190
|
-
}
|
|
191
|
-
function printEscapedMessage(message) {
|
|
192
|
-
return message.replace(/([{}](?:[\s\S]*[{}])?)/, "'$1'");
|
|
193
|
-
}
|
|
194
|
-
function printLiteralElement({ value }, isInPlural, isFirstEl, isLastEl) {
|
|
195
|
-
let escaped = value;
|
|
196
|
-
if (!isFirstEl && escaped[0] === "'") escaped = `''${escaped.slice(1)}`;
|
|
197
|
-
if (!isLastEl && escaped[escaped.length - 1] === "'") escaped = `${escaped.slice(0, escaped.length - 1)}''`;
|
|
198
|
-
escaped = printEscapedMessage(escaped);
|
|
199
|
-
return isInPlural ? escaped.replace("#", "'#'") : escaped;
|
|
200
|
-
}
|
|
201
|
-
function printSimpleFormatElement(el) {
|
|
202
|
-
return `{${el.value}, ${_formatjs_icu_messageformat_parser.TYPE[el.type]}${el.style ? `, ${printArgumentStyle(el.style)}` : ""}}`;
|
|
203
|
-
}
|
|
204
|
-
function printNumberSkeletonToken(token) {
|
|
205
|
-
const { stem, options } = token;
|
|
206
|
-
return options.length === 0 ? stem : `${stem}${options.map((o) => `/${o}`).join("")}`;
|
|
207
|
-
}
|
|
208
|
-
function printArgumentStyle(style) {
|
|
209
|
-
if (typeof style === "string") return printEscapedMessage(style);
|
|
210
|
-
else if (style.type === _formatjs_icu_messageformat_parser.SKELETON_TYPE.dateTime) return `::${style.pattern}`;
|
|
211
|
-
else return `::${style.tokens.map(printNumberSkeletonToken).join(" ")}`;
|
|
212
|
-
}
|
|
213
|
-
function printSelectElement(el) {
|
|
214
|
-
return `{${[
|
|
215
|
-
el.value,
|
|
216
|
-
"select",
|
|
217
|
-
Object.keys(el.options).map((id) => `${id}{${doPrintAst(el.options[id].value, false)}}`).join(" ")
|
|
218
|
-
].join(",")}}`;
|
|
219
|
-
}
|
|
220
|
-
function printPluralElement(el) {
|
|
221
|
-
const type = el.pluralType === "cardinal" ? "plural" : "selectordinal";
|
|
222
|
-
return `{${[
|
|
223
|
-
el.value,
|
|
224
|
-
type,
|
|
225
|
-
[el.offset ? `offset:${el.offset}` : "", ...Object.keys(el.options).map((id) => `${id}{${doPrintAst(el.options[id].value, true)}}`)].filter(Boolean).join(" ")
|
|
226
|
-
].join(",")}}`;
|
|
227
|
-
}
|
|
228
|
-
//#endregion
|
|
229
136
|
//#region src/derive/condenseVars.ts
|
|
230
137
|
const CONTAINS_INDEXED_GT_REGEX = new RegExp(`${require_derive.VAR_IDENTIFIER}\\d+`);
|
|
231
138
|
/**
|
|
@@ -239,10 +146,10 @@ const CONTAINS_INDEXED_GT_REGEX = new RegExp(`${require_derive.VAR_IDENTIFIER}\\
|
|
|
239
146
|
function condenseVars(icuString) {
|
|
240
147
|
if (!CONTAINS_INDEXED_GT_REGEX.test(icuString)) return icuString;
|
|
241
148
|
function visitor(child) {
|
|
242
|
-
child.type =
|
|
149
|
+
child.type = _generaltranslation_icu.TYPE.argument;
|
|
243
150
|
Reflect.deleteProperty(child, "options");
|
|
244
151
|
}
|
|
245
|
-
return
|
|
152
|
+
return (0, _generaltranslation_icu.printAST)(require_derive.traverseIcu({
|
|
246
153
|
icuString,
|
|
247
154
|
shouldVisit: require_derive.isGTIndexedSelectElement,
|
|
248
155
|
visitor,
|
package/dist/internal.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.cjs","names":["isGTUnindexedSelectElement","VAR_IDENTIFIER","isGTUnindexedSelectElement","TYPE","SKELETON_TYPE","VAR_IDENTIFIER","TYPE","traverseIcu","isGTIndexedSelectElement"],"sources":["../src/settings/plurals.ts","../src/locales/getPluralForm.ts","../src/utils/minify.ts","../src/derive/indexVars.ts","../src/derive/extractVars.ts","../src/derive/utils/printIcuAst.ts","../src/derive/condenseVars.ts"],"sourcesContent":["export const pluralForms = [\n 'singular',\n 'plural',\n 'dual',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n 'other',\n] as const;\nexport type PluralType = (typeof pluralForms)[number];\nexport function isAcceptedPluralForm(form: string): form is PluralType {\n return pluralForms.includes(form as (typeof pluralForms)[number]);\n}\n","import { getCachedPluralRules } from '@generaltranslation/format/internal';\n\nimport { pluralForms, PluralType } from '../settings/plurals';\nimport { libraryDefaultLocale } from '../settings/settings';\n\n/**\n * Given a number and a list of allowed plural forms, return the plural form that best fits the number.\n *\n * @param {number} n - The number to determine the plural form for.\n * @param {PluralType[]} forms - The allowed plural forms.\n * @returns {PluralType} The determined plural form, or an empty string if none fit.\n */\nexport function _getPluralForm(\n n: number,\n forms: readonly PluralType[] = pluralForms,\n locales: string[] = [libraryDefaultLocale]\n): PluralType | '' {\n const pluralRules = getCachedPluralRules(locales);\n const provisionalBranchName = pluralRules.select(n);\n // aliases\n const absN = Math.abs(n);\n // 0\n if (absN === 0 && forms.includes('zero')) return 'zero'; // override\n // 1\n if (absN === 1) {\n if (forms.includes('singular')) return 'singular'; // override\n if (forms.includes('one')) return 'one'; // override\n }\n if (provisionalBranchName === 'one' && forms.includes('singular'))\n return 'singular';\n // 2\n if (absN === 2) {\n if (forms.includes('dual')) return 'dual'; // override\n if (forms.includes('two')) return 'two'; // override\n }\n if (provisionalBranchName === 'two' && forms.includes('dual')) return 'dual';\n // fallbacks\n if (forms.includes(provisionalBranchName)) return provisionalBranchName;\n // two\n if (provisionalBranchName === 'two' && forms.includes('dual')) return 'dual';\n if (provisionalBranchName === 'two' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'two' && forms.includes('other'))\n return 'other';\n // few\n if (provisionalBranchName === 'few' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'few' && forms.includes('other'))\n return 'other';\n // many\n if (provisionalBranchName === 'many' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'many' && forms.includes('other'))\n return 'other';\n // other\n if (provisionalBranchName === 'other' && forms.includes('plural'))\n return 'plural';\n return '';\n}\n","import { VariableTransformationSuffix, VariableType } from '../types';\n\nconst VARIABLE_TRANSFORMATION_SUFFIXES_TO_MINIFIED_NAMES = {\n variable: 'v',\n number: 'n',\n datetime: 'd',\n currency: 'c',\n 'relative-time': 'rt',\n} as const;\n\nexport function minifyVariableType(\n variableType: VariableTransformationSuffix\n): VariableType {\n return VARIABLE_TRANSFORMATION_SUFFIXES_TO_MINIFIED_NAMES[variableType];\n}\n","import { VAR_IDENTIFIER } from './utils/constants';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { GTUnindexedSelectElement } from './utils/types';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\nimport type { IcuMessage } from '@generaltranslation/format/types';\n\ntype Location = {\n start: number;\n end: number;\n otherStart: number;\n otherEnd: number;\n};\n\n/**\n * Given an ICU string adds identifiers to each _gt_ placeholder\n * indexVars('Hello {_gt_} {_gt_} World') => 'Hello {_gt_1_} {_gt_2_} World'\n */\nexport function indexVars(icuString: IcuMessage): string {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return icuString;\n }\n\n // Record the location of the variable\n const variableLocations: Location[] = [];\n function visitor(child: GTUnindexedSelectElement): void {\n variableLocations.push({\n start: child.location?.start.offset ?? 0,\n end: child.location?.end.offset ?? 0,\n otherStart: child.options.other.location?.start.offset ?? 0,\n otherEnd: child.options.other.location?.end.offset ?? 0,\n });\n }\n\n // Find all variable identifiers.\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false, captureLocation: true },\n });\n\n // Index each variable and collapse the other option.\n const result = [];\n let current = 0;\n for (let i = 0; i < variableLocations.length; i++) {\n const { start, end, otherStart, otherEnd } = variableLocations[i];\n // Before the variable\n result.push(icuString.slice(current, start));\n // Replace the variable with the new identifier (+1 is for the curly brace)\n result.push(icuString.slice(start, start + VAR_IDENTIFIER.length + 1));\n\n // Add the new identifier.\n result.push(String(i + 1));\n // After the variable\n result.push(icuString.slice(start + VAR_IDENTIFIER.length + 1, otherStart));\n // Before the other option\n result.push('{}');\n // The other option\n result.push(icuString.slice(otherEnd, end));\n current = end;\n }\n result.push(icuString.slice(current, icuString.length));\n\n return result.join('');\n}\n","import { VAR_IDENTIFIER } from './utils/constants';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { GTUnindexedSelectElement } from './utils/types';\n/**\n * Given an unindexed ICU string, extracts all the _gt_ variables and an indexed mapping of the variable to the values\n *\n * extractVars('Hello {_gt_, select, other {World}}') => { _gt_1: 'World' }\n *\n * @param {string} icuString - The ICU string to extract variables from.\n * @returns {Record<string, string>} A mapping of the variable to the value.\n */\nexport function extractVars(icuString: string): Record<string, string> {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return {};\n }\n\n // Extract all the _gt_# variables\n let index = 1;\n const variables: Record<string, string> = {};\n function visitor(child: GTUnindexedSelectElement): void {\n variables[child.value + index] = child.options.other.value.length\n ? child.options.other.value[0]?.value\n : '';\n index += 1;\n }\n\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false },\n });\n\n return variables;\n}\n","// The code in this file is adapted from the FormatJS printer,\n// https://github.com/formatjs/formatjs/blob/main/packages/icu-messageformat-parser/printer.ts\n// (published as `@formatjs/icu-messageformat-parser/printer.js`)\n// And is therefore MIT licensed\n\n/*!\nMIT License\n\nCopyright (c) 2023 FormatJS\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\nimport { SKELETON_TYPE, TYPE } from '@formatjs/icu-messageformat-parser';\nimport type {\n DateElement,\n LiteralElement,\n MessageFormatElement,\n NumberElement,\n NumberSkeleton,\n PluralElement,\n SelectElement,\n TagElement,\n TimeElement,\n} from '@formatjs/icu-messageformat-parser';\n\ntype SimpleFormatStyle = NonNullable<\n (DateElement | TimeElement | NumberElement)['style']\n>;\n\n/**\n * Local copy of FormatJS `printAST` (see the license header above). The\n * published printer subpath is CommonJS-only, which browsers and Vite-based\n * dev servers (e.g. TanStack Start) cannot load from our ESM build, and the\n * package's ESM variant uses extensionless relative imports that fail Node\n * resolution.\n *\n * Output must stay byte-identical to FormatJS `printAST` because condensed\n * ICU strings feed into hashing.\n */\nexport function printIcuAst(ast: MessageFormatElement[]): string {\n return doPrintAst(ast, false);\n}\n\nfunction doPrintAst(ast: MessageFormatElement[], isInPlural: boolean): string {\n const printedNodes = ast.map((el, i) => {\n switch (el.type) {\n case TYPE.literal:\n return printLiteralElement(\n el,\n isInPlural,\n i === 0,\n i === ast.length - 1\n );\n case TYPE.argument:\n return `{${el.value}}`;\n case TYPE.date:\n case TYPE.time:\n case TYPE.number:\n return printSimpleFormatElement(el);\n case TYPE.plural:\n return printPluralElement(el);\n case TYPE.select:\n return printSelectElement(el);\n case TYPE.pound:\n return '#';\n case TYPE.tag:\n return printTagElement(el);\n }\n });\n return printedNodes.join('');\n}\n\nfunction printTagElement(el: TagElement): string {\n return `<${el.value}>${printIcuAst(el.children)}</${el.value}>`;\n}\n\nfunction printEscapedMessage(message: string): string {\n return message.replace(/([{}](?:[\\s\\S]*[{}])?)/, \"'$1'\");\n}\n\nfunction printLiteralElement(\n { value }: LiteralElement,\n isInPlural: boolean,\n isFirstEl: boolean,\n isLastEl: boolean\n): string {\n let escaped = value;\n // If this literal starts with a ' and it's not the 1st node, the node\n // before it is non-literal and the `'` needs to be re-escaped\n if (!isFirstEl && escaped[0] === \"'\") {\n escaped = `''${escaped.slice(1)}`;\n }\n // Same logic but for last el\n if (!isLastEl && escaped[escaped.length - 1] === \"'\") {\n escaped = `${escaped.slice(0, escaped.length - 1)}''`;\n }\n escaped = printEscapedMessage(escaped);\n // Upstream escapes only the first `#` (String#replace with a string\n // pattern); keep the quirk so output stays byte-identical\n return isInPlural ? escaped.replace('#', \"'#'\") : escaped;\n}\n\nfunction printSimpleFormatElement(\n el: DateElement | TimeElement | NumberElement\n): string {\n return `{${el.value}, ${TYPE[el.type]}${\n el.style ? `, ${printArgumentStyle(el.style)}` : ''\n }}`;\n}\n\nfunction printNumberSkeletonToken(\n token: NumberSkeleton['tokens'][number]\n): string {\n const { stem, options } = token;\n return options.length === 0\n ? stem\n : `${stem}${options.map((o) => `/${o}`).join('')}`;\n}\n\nfunction printArgumentStyle(style: SimpleFormatStyle): string {\n if (typeof style === 'string') {\n return printEscapedMessage(style);\n } else if (style.type === SKELETON_TYPE.dateTime) {\n return `::${style.pattern}`;\n } else {\n return `::${style.tokens.map(printNumberSkeletonToken).join(' ')}`;\n }\n}\n\nfunction printSelectElement(el: SelectElement): string {\n const msg = [\n el.value,\n 'select',\n Object.keys(el.options)\n .map((id) => `${id}{${doPrintAst(el.options[id].value, false)}}`)\n .join(' '),\n ].join(',');\n return `{${msg}}`;\n}\n\nfunction printPluralElement(el: PluralElement): string {\n const type = el.pluralType === 'cardinal' ? 'plural' : 'selectordinal';\n const msg = [\n el.value,\n type,\n [\n el.offset ? `offset:${el.offset}` : '',\n ...Object.keys(el.options).map(\n (id) => `${id}{${doPrintAst(el.options[id].value, true)}}`\n ),\n ]\n .filter(Boolean)\n .join(' '),\n ].join(',');\n return `{${msg}}`;\n}\n","import { TYPE } from '@formatjs/icu-messageformat-parser';\nimport type { ArgumentElement } from '@formatjs/icu-messageformat-parser/types.js';\nimport { printIcuAst } from './utils/printIcuAst';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { VAR_IDENTIFIER } from './utils/constants';\nimport { GTIndexedSelectElement } from './utils/types';\nimport { isGTIndexedSelectElement } from './utils/traverseHelpers';\ninterface GTIndexedArgumentElement extends ArgumentElement {\n value: `${typeof VAR_IDENTIFIER}${number}`;\n}\n\nconst CONTAINS_INDEXED_GT_REGEX = new RegExp(`${VAR_IDENTIFIER}\\\\d+`);\n\n/**\n * Given an indexed ICU string, condenses any select to an argument\n * Unindexed _gt_ source strings and indexed _gt_# translation strings\n * are mutually exclusive.\n * indexVars('Hello {_gt_1, select, other {World}}') => 'Hello {_gt_1}'\n * @param {string} icuString - The ICU string to condense.\n * @returns {string} The condensed ICU string.\n */\nexport function condenseVars(icuString: string): string {\n // Check if the string contains an indexed _gt_ identifier.\n if (!CONTAINS_INDEXED_GT_REGEX.test(icuString)) {\n return icuString;\n }\n\n // Replace with argument\n function visitor(child: GTIndexedSelectElement): void {\n (child as unknown as GTIndexedArgumentElement).type = TYPE.argument;\n Reflect.deleteProperty(child, 'options');\n }\n\n const ast = traverseIcu({\n icuString,\n shouldVisit: isGTIndexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false },\n });\n\n // Serialize\n return printIcuAst(ast);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.cjs","names":["isGTUnindexedSelectElement","VAR_IDENTIFIER","isGTUnindexedSelectElement","VAR_IDENTIFIER","TYPE","traverseIcu","isGTIndexedSelectElement"],"sources":["../src/settings/plurals.ts","../src/locales/getPluralForm.ts","../src/utils/minify.ts","../src/derive/indexVars.ts","../src/derive/extractVars.ts","../src/derive/condenseVars.ts"],"sourcesContent":["export const pluralForms = [\n 'singular',\n 'plural',\n 'dual',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n 'other',\n] as const;\nexport type PluralType = (typeof pluralForms)[number];\nexport function isAcceptedPluralForm(form: string): form is PluralType {\n return pluralForms.includes(form as (typeof pluralForms)[number]);\n}\n","import { getCachedPluralRules } from '@generaltranslation/format/internal';\n\nimport { pluralForms, PluralType } from '../settings/plurals';\nimport { libraryDefaultLocale } from '../settings/settings';\n\n/**\n * Given a number and a list of allowed plural forms, return the plural form that best fits the number.\n *\n * @param {number} n - The number to determine the plural form for.\n * @param {PluralType[]} forms - The allowed plural forms.\n * @returns {PluralType} The determined plural form, or an empty string if none fit.\n */\nexport function _getPluralForm(\n n: number,\n forms: readonly PluralType[] = pluralForms,\n locales: string[] = [libraryDefaultLocale]\n): PluralType | '' {\n const pluralRules = getCachedPluralRules(locales);\n const provisionalBranchName = pluralRules.select(n);\n // aliases\n const absN = Math.abs(n);\n // 0\n if (absN === 0 && forms.includes('zero')) return 'zero'; // override\n // 1\n if (absN === 1) {\n if (forms.includes('singular')) return 'singular'; // override\n if (forms.includes('one')) return 'one'; // override\n }\n if (provisionalBranchName === 'one' && forms.includes('singular'))\n return 'singular';\n // 2\n if (absN === 2) {\n if (forms.includes('dual')) return 'dual'; // override\n if (forms.includes('two')) return 'two'; // override\n }\n if (provisionalBranchName === 'two' && forms.includes('dual')) return 'dual';\n // fallbacks\n if (forms.includes(provisionalBranchName)) return provisionalBranchName;\n // two\n if (provisionalBranchName === 'two' && forms.includes('dual')) return 'dual';\n if (provisionalBranchName === 'two' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'two' && forms.includes('other'))\n return 'other';\n // few\n if (provisionalBranchName === 'few' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'few' && forms.includes('other'))\n return 'other';\n // many\n if (provisionalBranchName === 'many' && forms.includes('plural'))\n return 'plural';\n if (provisionalBranchName === 'many' && forms.includes('other'))\n return 'other';\n // other\n if (provisionalBranchName === 'other' && forms.includes('plural'))\n return 'plural';\n return '';\n}\n","import { VariableTransformationSuffix, VariableType } from '../types';\n\nconst VARIABLE_TRANSFORMATION_SUFFIXES_TO_MINIFIED_NAMES = {\n variable: 'v',\n number: 'n',\n datetime: 'd',\n currency: 'c',\n 'relative-time': 'rt',\n} as const;\n\nexport function minifyVariableType(\n variableType: VariableTransformationSuffix\n): VariableType {\n return VARIABLE_TRANSFORMATION_SUFFIXES_TO_MINIFIED_NAMES[variableType];\n}\n","import { VAR_IDENTIFIER } from './utils/constants';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { GTUnindexedSelectElement } from './utils/types';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\nimport type { IcuMessage } from '@generaltranslation/format/types';\n\ntype Location = {\n start: number;\n end: number;\n otherStart: number;\n otherEnd: number;\n};\n\n/**\n * Given an ICU string adds identifiers to each _gt_ placeholder\n * indexVars('Hello {_gt_} {_gt_} World') => 'Hello {_gt_1_} {_gt_2_} World'\n */\nexport function indexVars(icuString: IcuMessage): string {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return icuString;\n }\n\n // Record the location of the variable\n const variableLocations: Location[] = [];\n function visitor(child: GTUnindexedSelectElement): void {\n variableLocations.push({\n start: child.location?.start.offset ?? 0,\n end: child.location?.end.offset ?? 0,\n otherStart: child.options.other.location?.start.offset ?? 0,\n otherEnd: child.options.other.location?.end.offset ?? 0,\n });\n }\n\n // Find all variable identifiers.\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false, captureLocation: true },\n });\n\n // Index each variable and collapse the other option.\n const result = [];\n let current = 0;\n for (let i = 0; i < variableLocations.length; i++) {\n const { start, end, otherStart, otherEnd } = variableLocations[i];\n // Before the variable\n result.push(icuString.slice(current, start));\n // Replace the variable with the new identifier (+1 is for the curly brace)\n result.push(icuString.slice(start, start + VAR_IDENTIFIER.length + 1));\n\n // Add the new identifier.\n result.push(String(i + 1));\n // After the variable\n result.push(icuString.slice(start + VAR_IDENTIFIER.length + 1, otherStart));\n // Before the other option\n result.push('{}');\n // The other option\n result.push(icuString.slice(otherEnd, end));\n current = end;\n }\n result.push(icuString.slice(current, icuString.length));\n\n return result.join('');\n}\n","import { VAR_IDENTIFIER } from './utils/constants';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { GTUnindexedSelectElement } from './utils/types';\n/**\n * Given an unindexed ICU string, extracts all the _gt_ variables and an indexed mapping of the variable to the values\n *\n * extractVars('Hello {_gt_, select, other {World}}') => { _gt_1: 'World' }\n *\n * @param {string} icuString - The ICU string to extract variables from.\n * @returns {Record<string, string>} A mapping of the variable to the value.\n */\nexport function extractVars(icuString: string): Record<string, string> {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return {};\n }\n\n // Extract all the _gt_# variables\n let index = 1;\n const variables: Record<string, string> = {};\n function visitor(child: GTUnindexedSelectElement): void {\n variables[child.value + index] = child.options.other.value.length\n ? child.options.other.value[0]?.value\n : '';\n index += 1;\n }\n\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false },\n });\n\n return variables;\n}\n","import { printAST, TYPE, type ArgumentElement } from '@generaltranslation/icu';\nimport { traverseIcu } from './utils/traverseIcu';\nimport { VAR_IDENTIFIER } from './utils/constants';\nimport { GTIndexedSelectElement } from './utils/types';\nimport { isGTIndexedSelectElement } from './utils/traverseHelpers';\ninterface GTIndexedArgumentElement extends ArgumentElement {\n value: `${typeof VAR_IDENTIFIER}${number}`;\n}\n\nconst CONTAINS_INDEXED_GT_REGEX = new RegExp(`${VAR_IDENTIFIER}\\\\d+`);\n\n/**\n * Given an indexed ICU string, condenses any select to an argument\n * Unindexed _gt_ source strings and indexed _gt_# translation strings\n * are mutually exclusive.\n * indexVars('Hello {_gt_1, select, other {World}}') => 'Hello {_gt_1}'\n * @param {string} icuString - The ICU string to condense.\n * @returns {string} The condensed ICU string.\n */\nexport function condenseVars(icuString: string): string {\n // Check if the string contains an indexed _gt_ identifier.\n if (!CONTAINS_INDEXED_GT_REGEX.test(icuString)) {\n return icuString;\n }\n\n // Replace with argument\n function visitor(child: GTIndexedSelectElement): void {\n (child as unknown as GTIndexedArgumentElement).type = TYPE.argument;\n Reflect.deleteProperty(child, 'options');\n }\n\n const ast = traverseIcu({\n icuString,\n shouldVisit: isGTIndexedSelectElement,\n visitor,\n options: { recurseIntoVisited: false },\n });\n\n // Serialize\n return printAST(ast);\n}\n"],"mappings":"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"}
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as RuntimeTranslateManyOptions, C as VariableType, D as VariableTransformationSuffix, S as Variable, dt as FileFormat, g as LocaleProperties, h as JsxElement, m as JsxChildren, p as JsxChild } from "./types-
|
|
1
|
+
import { At as RuntimeTranslateManyOptions, C as VariableType, D as VariableTransformationSuffix, S as Variable, dt as FileFormat, g as LocaleProperties, h as JsxElement, m as JsxChildren, p as JsxChild } from "./types-wj-Dtih8.cjs";
|
|
2
2
|
import { n as declareVar, r as decodeVars, t as derive } from "./derive-DBCCXTmL.cjs";
|
|
3
3
|
import { IcuMessage } from "@generaltranslation/format/types";
|
|
4
4
|
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as RuntimeTranslateManyOptions, C as VariableType, D as VariableTransformationSuffix, S as Variable, dt as FileFormat, g as LocaleProperties, h as JsxElement, m as JsxChildren, p as JsxChild } from "./types-
|
|
1
|
+
import { At as RuntimeTranslateManyOptions, C as VariableType, D as VariableTransformationSuffix, S as Variable, dt as FileFormat, g as LocaleProperties, h as JsxElement, m as JsxChildren, p as JsxChild } from "./types-iO493WgK.mjs";
|
|
2
2
|
import { n as declareVar, r as decodeVars, t as derive } from "./derive-VfZjYfIU.mjs";
|
|
3
3
|
import { IcuMessage } from "@generaltranslation/format/types";
|
|
4
4
|
|