import { SMARTLING_BASE_URL, SMARTLING_AUTH_PATH, SMARTLING_API_USER, SMARTLING_API_SECRET, } from '../constants.js'; import { execSync } from 'node:child_process'; import { argv } from 'node:process'; import { MalformedSmartlingResponseError } from '../pull/errors/malformed-smartling-response-error.js'; export function getRepoRoot(): string { try { return execSync('git rev-parse --show-toplevel').toString().trim(); } catch { throw new Error("Couldn't get Git root dir."); } } export async function getAuthToken(): Promise { const data = { userIdentifier: SMARTLING_API_USER, userSecret: SMARTLING_API_SECRET, }; const result = await doFetch(`${SMARTLING_BASE_URL}${SMARTLING_AUTH_PATH}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }); if (!result.response.data.accessToken) { throw new MalformedSmartlingResponseError('The access token is missing'); } return result.response.data.accessToken; } const args = argv.slice(2); const useFtlFlowIndex = args.indexOf('--use-ftl-flow'); const skipUnavailableLocalesIndex = args.indexOf('--skip-unavailable-locales'); /** * This flag indicates if the `skipUnavailableLocales` behavior should be used. * * The reasons behind the existence of this flag are the following: * * a) When having a locale that requires a manual translation (or a different process in general), i.e. jp-JP, and this pulling * happens before that process is completed, you will get an error, preventing the whole process from happening. * This way you will have the flexibility of pulling all the others but that one. * * b) Let's say that you do have another file that you previously upload to Smartling (either intentionally or a residual file) * if that file have not been translated yet, (or will never been translated), in this case if you do not skip those locales, * pulling the other existing files will get you an error preventing the whole pulling process from happening * */ export const skipUnavailableLocales = Boolean( skipUnavailableLocalesIndex !== -1 ? toBoolean(args[skipUnavailableLocalesIndex + 1]) : undefined, ); /** * This indicates if the FTL flow should be used. */ export const useFTLFlow = Boolean( useFtlFlowIndex !== -1 ? toBoolean(args[useFtlFlowIndex + 1]) : undefined, ); function toBoolean(value: string): boolean { return value === 'true'; } export const fileExtensionToUse = useFTLFlow ? '.ftl' : '.csv'; // any is the type that .json() returns :-/ export async function doFetch( endpoint: string, opts: Record, // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Promise { const response = await fetch(endpoint, opts); if (!response.ok) { const jsonResp = await response.json(); const errorMessages = jsonResp.response.errors; throw new Error( `Error! Status code ${ response.status } from Smartling when fetching to ${endpoint}: ${JSON.stringify( errorMessages, )}`, ); } const result = await response.json(); return result; }