{"version":3,"file":"index.cjs","names":["apiRequest","isSupportedFileFormatTransform","apiRequest","apiRequest","apiRequest","decode","apiRequest","apiRequest","encode","apiRequest","encode","apiRequest","defaultTimeout","fetchWithTimeout","generateRequestHeaders","validateResponse","apiRequest","apiRequest","apiRequest","apiRequest","apiRequest","apiRequest","apiRequest","apiRequest","GTRuntime","noSourceLocaleProvidedError","noTargetLocaleProvidedError"],"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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"}