@crowdin/app-project-module
Version:
Module that generates for you all common endpoints for serving standalone Crowdin App
636 lines (635 loc) • 33.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.runJob = runJob;
exports.runUpdateProviderJob = runUpdateProviderJob;
exports.filesCron = filesCron;
exports.filterFilesFromIntegrationRequest = filterFilesFromIntegrationRequest;
exports.createOrUpdateSyncSettings = createOrUpdateSyncSettings;
exports.removeFinishedJobs = removeFinishedJobs;
const storage_1 = require("../../../storage");
const token_1 = require("../../../util/app-functions/token");
const connection_1 = require("../../../util/connection");
const logger_1 = require("../../../util/logger");
const subscription_1 = require("../../../util/subscription");
const types_1 = require("../types");
const defaults_1 = require("./defaults");
const files_1 = require("./files");
const job_1 = require("./job");
const snapshot_1 = require("./snapshot");
const types_2 = require("./types");
function runJob(_a) {
return __awaiter(this, arguments, void 0, function* ({ config, integration, job, }) {
(0, logger_1.log)(`Starting cron job with expression [${job.expression}]`);
const crowdinCredentialsList = yield (0, storage_1.getStorage)().getAllCrowdinCredentials();
yield Promise.all(crowdinCredentialsList.map((crowdinCredentials) => __awaiter(this, void 0, void 0, function* () {
const { token, client: crowdinClient } = yield (0, connection_1.prepareCrowdinClient)({
config,
credentials: crowdinCredentials,
autoRenew: true,
});
const { expired } = yield (0, subscription_1.checkSubscription)({
config,
token,
organization: crowdinCredentials.id,
accountType: crowdinCredentials.type,
});
if (expired) {
(0, logger_1.log)(`Subscription expired. Skipping job [${job.expression}] for organization ${crowdinCredentials.id}`);
return;
}
const integrationCredentialsList = yield (0, storage_1.getStorage)().getAllIntegrationCredentials(crowdinCredentials.id);
const allIntegrationConfigs = yield (0, storage_1.getStorage)().getAllIntegrationConfigs(crowdinCredentials.id);
for (const integrationCredentials of integrationCredentialsList) {
const integrationConfig = allIntegrationConfigs.find(({ integrationId }) => integrationId === integrationCredentials.id);
const projectId = (0, token_1.getProjectId)(integrationCredentials.id);
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config) ? JSON.parse(integrationConfig.config) : undefined;
(0, logger_1.log)(`Executing task for cron job with expression [${job.expression}] for project ${projectId}`);
yield job.task({
projectId,
client: crowdinClient,
credentials,
rootFolder,
settings: intConfig,
});
(0, logger_1.log)(`Task for cron job with expression [${job.expression}] for project ${projectId} completed`);
}
})));
(0, logger_1.log)(`Cron job with expression [${job.expression}] completed`);
});
}
function runUpdateProviderJob(_a) {
return __awaiter(this, arguments, void 0, function* ({ integrationId, crowdinId, type, title, payload, jobType, projectId, client, integration, context, credentials, rootFolder, settings, reRunJobId, initiatedBy, }) {
try {
yield (0, job_1.runAsJob)({
integrationId,
crowdinId,
type,
title,
payload,
jobType,
projectId,
client,
reRunJobId,
initiatedBy,
jobStoreType: integration.jobStoreType,
jobCallback: (job) => __awaiter(this, void 0, void 0, function* () {
if (type === types_2.JobType.UPDATE_TO_CROWDIN) {
yield integration.updateCrowdin({
projectId,
client,
credentials,
request: payload,
rootFolder,
settings,
job,
});
try {
yield (0, files_1.updateSyncedData)(integrationId, crowdinId, payload, types_1.Provider.INTEGRATION);
}
catch (e) {
(0, logger_1.logError)(e, context);
}
}
else if (type === types_2.JobType.UPDATE_TO_INTEGRATION) {
yield integration.updateIntegration({
projectId,
client,
credentials,
request: payload,
rootFolder,
settings,
job,
});
}
}),
});
}
catch (e) {
const action = type === types_2.JobType.UPDATE_TO_CROWDIN ? 'Auto sync files to Crowdin' : 'Auto sync files to External Service';
yield (0, logger_1.handleUserError)({
action,
error: e,
crowdinId: crowdinId,
clientId: integrationId,
});
(0, logger_1.logError)(e, context);
throw e;
}
});
}
function filesCron(_a) {
return __awaiter(this, arguments, void 0, function* ({ config, integration, period, }) {
(0, logger_1.log)(`Starting files cron job with period [${period}]`);
const syncSettingsList = yield (0, storage_1.getStorage)().getSyncSettingsBySchedule('schedule', period);
const crowdinSyncSettings = syncSettingsList.filter((syncSettings) => syncSettings.provider === types_1.Provider.CROWDIN);
const integrationSyncSettings = syncSettingsList.filter((syncSettings) => syncSettings.provider === types_1.Provider.INTEGRATION);
const crowdinResults = yield Promise.allSettled(crowdinSyncSettings.map((syncSettings) => processSyncSettings({ config, integration, period, syncSettings })));
crowdinResults.forEach((result) => {
if (result.status === 'rejected') {
(0, logger_1.logError)(result.reason);
}
});
const integrationResults = yield Promise.allSettled(integrationSyncSettings.map((syncSettings) => processSyncSettings({ config, integration, period, syncSettings })));
integrationResults.forEach((result) => {
if (result.status === 'rejected') {
(0, logger_1.logError)(result.reason);
}
});
(0, logger_1.log)(`Files cron job with period [${period}] completed`);
});
}
function processSyncSettings(_a) {
return __awaiter(this, arguments, void 0, function* ({ config, integration, period, syncSettings, }) {
var _b, _c, _d, _e;
let projectData;
let crowdinClient;
let token;
let files = (0, files_1.prepareSyncFiles)(JSON.parse(syncSettings.files));
let newFiles = [];
const crowdinCredentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(syncSettings.crowdinId);
const integrationCredentials = yield (0, storage_1.getStorage)().getIntegrationCredentials(syncSettings.integrationId);
const integrationConfig = yield (0, storage_1.getStorage)().getIntegrationConfig(syncSettings.integrationId);
if (!crowdinCredentials || !integrationCredentials) {
return;
}
const intConfig = (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.config)
? JSON.parse(integrationConfig.config)
: { schedule: '0', condition: '0' };
if (period !== intConfig.schedule) {
return;
}
const projectId = (0, token_1.getProjectId)(integrationCredentials.id);
const context = {
jwtPayload: {
context: {
project_id: projectId,
organization_id: crowdinCredentials.organizationId,
organization_domain: crowdinCredentials.domain,
user_id: crowdinCredentials.userId,
},
},
crowdinId: crowdinCredentials.id,
clientId: integrationCredentials.id,
};
const logInfo = (0, logger_1.withContext)(context);
try {
const preparedCrowdinClient = yield (0, connection_1.prepareCrowdinClient)({
config,
credentials: crowdinCredentials,
autoRenew: true,
context,
});
token = preparedCrowdinClient.token;
crowdinClient = preparedCrowdinClient.client;
}
catch (e) {
intConfig.schedule = '0';
yield (0, storage_1.getStorage)().updateIntegrationConfig(syncSettings.integrationId, JSON.stringify(intConfig));
logInfo(`Auto-sync has been disabled for organization '${crowdinCredentials.id}'.`);
(0, logger_1.logError)(e, context);
return;
}
const { expired } = yield (0, subscription_1.checkSubscription)({
config,
token,
organization: crowdinCredentials.id,
accountType: crowdinCredentials.type,
});
if (expired) {
(0, logger_1.log)(`Subscription expired. Skipping job [${period}] for organization ${crowdinCredentials.id}`);
return;
}
try {
projectData = (yield crowdinClient.projectsGroupsApi.getProject(projectId))
.data;
}
catch (e) {
(0, logger_1.logError)(e, context);
return;
}
context.jwtPayload.context.project_identifier = projectData.identifier;
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
let currentFileSnapshot = [];
let needsSnapshotForNewFiles = !integration.webhooks &&
((_b = integration.syncNewElements) === null || _b === void 0 ? void 0 : _b[syncSettings.provider]) &&
(intConfig[`new-${syncSettings.provider}-files`] || (0, files_1.hasFolders)(files));
if (!needsSnapshotForNewFiles &&
!integration.webhooks &&
((_c = integration.syncNewElements) === null || _c === void 0 ? void 0 : _c[syncSettings.provider]) &&
syncSettings.provider === types_1.Provider.CROWDIN) {
currentFileSnapshot = yield (0, snapshot_1.getCrowdinSnapshot)(config, integration, crowdinClient, projectData.id, intConfig);
const syncedFileIds = Object.keys(files);
const hasSyncedFolders = currentFileSnapshot.some((file) => !('type' in file) && syncedFileIds.includes(String(file.id)));
if (hasSyncedFolders) {
needsSnapshotForNewFiles = true;
}
}
const needsIntegrationSnapshot = needsSnapshotForNewFiles && syncSettings.provider !== types_1.Provider.CROWDIN;
const needsCrowdinSnapshot = needsSnapshotForNewFiles && syncSettings.provider === types_1.Provider.CROWDIN && currentFileSnapshot.length === 0;
if (needsIntegrationSnapshot) {
currentFileSnapshot = yield (0, snapshot_1.getIntegrationSnapshot)({
integration,
integrationCredentials: credentials,
integrationSettings: intConfig,
client: crowdinClient,
projectId: projectData.id,
});
}
else if (needsCrowdinSnapshot) {
currentFileSnapshot = yield (0, snapshot_1.getCrowdinSnapshot)(config, integration, crowdinClient, projectData.id, intConfig);
}
if (needsSnapshotForNewFiles) {
try {
newFiles = yield getAllNewFiles({
crowdinId: crowdinCredentials.id,
integrationId: integrationCredentials.id,
projectData,
integrationSettings: intConfig,
syncSettings,
currentFileSnapshot,
});
}
catch (e) {
(0, logger_1.logError)(e, context);
return;
}
}
if (integration.webhooks) {
const webhooks = yield (0, storage_1.getStorage)().getAllWebhooks(syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
const webhooksFileIds = (webhooks || []).map((webhook) => webhook.fileId);
if (syncSettings.provider === types_1.Provider.CROWDIN) {
files = webhooksFileIds.reduce((acc, fileId) => {
if (files[fileId]) {
acc[fileId] = files[fileId];
}
return acc;
}, {});
}
else {
files = files.filter((file) => webhooksFileIds.includes(file.id));
}
yield (0, storage_1.getStorage)().deleteWebhooks(webhooksFileIds, syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
}
if (syncSettings.provider === types_1.Provider.CROWDIN) {
const crowdinFiles = yield filterFilesFromIntegrationRequest({
config,
integration,
projectId,
crowdinFiles: Object.assign(Object.assign({}, files), newFiles),
crowdinClient,
});
const onlyTranslated = +intConfig.condition === types_1.SyncCondition.TRANSLATED;
const onlyApproved = +intConfig.condition === types_1.SyncCondition.APPROVED;
const all = +intConfig.condition === types_1.SyncCondition.ALL || intConfig.condition === undefined;
let filesToProcess;
let deletedFileIds = [];
if (all) {
filesToProcess = crowdinFiles;
}
else {
const result = yield getOnlyTranslatedOrApprovedFiles({
projectId,
crowdinFiles,
crowdinClient,
onlyApproved,
onlyTranslated,
context,
integration,
});
filesToProcess = result.filteredFiles;
deletedFileIds = result.deletedFiles;
}
if (deletedFileIds.length > 0) {
(0, logger_1.log)(`Removing ${deletedFileIds.length} deleted files from sync settings`);
const updatedFiles = Object.assign({}, files);
for (const fileId of deletedFileIds) {
delete updatedFiles[fileId];
}
yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(updatedFiles), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', types_1.Provider.CROWDIN);
files = updatedFiles;
}
if (Object.keys(filesToProcess).length <= 0) {
return;
}
(0, logger_1.log)(`Executing updateIntegration task for files cron job with period [${period}] for project ${projectId}.Files ${Object.keys(filesToProcess).length}`);
if (!all) {
if (Object.keys(filesToProcess).length === 0) {
(0, logger_1.log)(`There is no ${onlyApproved ? 'approved' : 'translated'} file`);
return;
}
}
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
if (!(intConfig === null || intConfig === void 0 ? void 0 : intConfig.inContext)) {
removeInContextLanguage(filesToProcess, projectData);
}
try {
yield runUpdateProviderJob({
integrationId: syncSettings.integrationId,
crowdinId: syncSettings.crowdinId,
type: types_2.JobType.UPDATE_TO_INTEGRATION,
title: `Sync files to ${config.name} [scheduled]`,
payload: filesToProcess,
jobType: types_2.JobClientType.CRON,
projectId: projectId,
client: crowdinClient,
integration,
context,
credentials,
rootFolder,
settings: intConfig,
initiatedBy: 'autosync',
});
}
catch (e) {
return;
}
if (Object.keys(newFiles).length) {
yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(Object.assign(Object.assign({}, files), newFiles)), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
const currentFileSnapshot = yield (0, snapshot_1.getCrowdinSnapshot)(config, integration, crowdinClient, projectId, intConfig);
yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
}
(0, logger_1.log)(`updateIntegration task for files cron job with period [${period}] for project ${projectId} completed`);
}
else {
const allIntFiles = [...files, ...newFiles].map((file) => (Object.assign({ id: file.id, name: file.name, parentId: file.parent_id || file.parentId, parent_id: file.parent_id || file.parentId, node_type: file.nodeType || file.node_type }, (file.type ? { type: file.type } : {}))));
let intFiles = allIntFiles.filter((file) => 'type' in file);
if (integration.forcePushSources === true && currentFileSnapshot.length > 0) {
const snapshotMap = new Map(currentFileSnapshot.map((f) => [f.id, f]));
intFiles = intFiles.map((file) => {
const snapshotFile = snapshotMap.get(file.id);
if (snapshotFile) {
return Object.assign(Object.assign({}, file), { updatedAt: snapshotFile.updatedAt, createdAt: snapshotFile.createdAt });
}
return file;
});
intFiles = yield (0, files_1.attachFileStatus)(intFiles, syncSettings.integrationId, syncSettings.crowdinId, integration);
intFiles = intFiles.filter((file) => file.isUpdated !== false);
}
if (intFiles.length <= 0) {
return;
}
(0, logger_1.log)(`Executing updateCrowdin task for files cron job with period [${period}] for project ${projectId}. Files ${intFiles.length}`);
const credentials = yield (0, connection_1.prepareIntegrationCredentials)(config, integration, integrationCredentials);
if (integration.filterByPathIntegrationFiles) {
const includePatterns = (_d = intConfig === null || intConfig === void 0 ? void 0 : intConfig.includeByFilePath) === null || _d === void 0 ? void 0 : _d.split('\n').filter(Boolean);
const excludePatterns = (_e = intConfig === null || intConfig === void 0 ? void 0 : intConfig.excludeByFilePath) === null || _e === void 0 ? void 0 : _e.split('\n').filter(Boolean);
try {
const fullTreeResult = yield integration.getIntegrationFiles({
credentials,
client: crowdinClient,
projectId: projectId,
settings: intConfig,
});
const fullTree = (0, files_1.isExtendedResultType)(fullTreeResult) ? fullTreeResult.data || [] : fullTreeResult;
const filteredFiles = (0, files_1.filterFilesByPath)(fullTree, includePatterns, excludePatterns);
const filteredFileIds = new Set(filteredFiles.map((f) => f.id));
const filteredIntFiles = intFiles.filter((file) => filteredFileIds.has(file.id));
(0, logger_1.log)(`Path filtering applied: ${intFiles.length} -> ${filteredIntFiles.length} files`);
if (filteredIntFiles.length === 0) {
(0, logger_1.log)('No files passed path filtering, skipping sync');
return;
}
intFiles = filteredIntFiles;
}
catch (e) {
(0, logger_1.logError)(e, context);
}
}
try {
yield runUpdateProviderJob({
integrationId: syncSettings.integrationId,
crowdinId: syncSettings.crowdinId,
type: types_2.JobType.UPDATE_TO_CROWDIN,
title: 'Sync files to Crowdin [scheduled]',
payload: intFiles,
jobType: types_2.JobClientType.CRON,
projectId: projectId,
client: crowdinClient,
integration,
context,
credentials,
rootFolder,
settings: intConfig,
initiatedBy: 'autosync',
});
}
catch (e) {
return;
}
if (Object.keys(newFiles).length) {
const newSyncSettingsFields = allIntFiles.map((file) => (Object.assign(Object.assign({}, file), { schedule: true, sync: false })));
yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(newSyncSettingsFields), syncSettings.integrationId, syncSettings.crowdinId, 'schedule', syncSettings.provider);
const currentFileSnapshot = yield (0, snapshot_1.getIntegrationSnapshot)({
integration,
integrationCredentials: credentials,
integrationSettings: intConfig,
client: crowdinClient,
projectId,
});
yield (0, storage_1.getStorage)().updateFilesSnapshot(JSON.stringify(currentFileSnapshot), syncSettings.integrationId, syncSettings.crowdinId, syncSettings.provider);
}
(0, logger_1.log)(`updateCrowdin task for files cron job with period [${period}] for project ${projectId} completed`);
}
});
}
function getFileDiff(currentFiles, savedFiles) {
return currentFiles.filter((x) => !savedFiles.some((x2) => x2.id === x.id));
}
function getAllNewFiles(_a) {
return __awaiter(this, arguments, void 0, function* ({ crowdinId, integrationId, projectData, integrationSettings, syncSettings, currentFileSnapshot, }) {
const fileSnapshotData = yield (0, storage_1.getStorage)().getFilesSnapshot(integrationId, crowdinId, syncSettings.provider);
const snapshotFiles = (fileSnapshotData === null || fileSnapshotData === void 0 ? void 0 : fileSnapshotData.files) ? JSON.parse(fileSnapshotData.files) : [];
const difference = getFileDiff(currentFileSnapshot, snapshotFiles);
const onlyFiles = difference.filter((file) => 'type' in file);
const synFiles = (0, files_1.prepareSyncFiles)(JSON.parse(syncSettings.files));
if (syncSettings.provider === types_1.Provider.INTEGRATION) {
if (integrationSettings[`new-${syncSettings.provider}-files`]) {
return onlyFiles;
}
const syncFolders = synFiles.filter((file) => !('type' in file));
return getNewFoldersFile(syncFolders, difference);
}
else {
const files = {};
const targetLanguages = projectData.targetLanguageIds;
if (projectData.inContext) {
targetLanguages.push(projectData.inContextPseudoLanguageId);
}
if (integrationSettings[`new-${syncSettings.provider}-files`]) {
for (const file of onlyFiles) {
files[file.id] = targetLanguages;
}
}
else {
const syncFolders = currentFileSnapshot.filter((file) => !('type' in file) && Object.keys(synFiles).includes(file.id));
const newFiles = getNewFoldersFile(syncFolders, difference);
for (const file of newFiles) {
files[file.id] = targetLanguages;
}
}
return files;
}
});
}
function getNewFoldersFile(folders, snapshotFiles) {
let files = [];
for (const folder of folders) {
const folderFiles = snapshotFiles.filter((file) => Number(file.parentId) === Number(folder.id));
if (folderFiles.length) {
files = files.concat(folderFiles);
}
}
files = files.filter((file) => 'type' in file);
return files;
}
function getOnlyTranslatedOrApprovedFiles(_a) {
return __awaiter(this, arguments, void 0, function* ({ projectId, crowdinFiles, crowdinClient, onlyApproved, onlyTranslated, context, integration, }) {
const deletedFiles = [];
(0, logger_1.log)(`Filtering files to process only ${onlyApproved ? 'approved' : 'translated'} files`);
const filesInfo = yield Promise.all(Object.keys(crowdinFiles).map((fileId) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
try {
let info;
if (integration.getFileProgress) {
const progress = yield integration.getFileProgress({
projectId,
client: crowdinClient,
fileId: Number(fileId),
});
info = (_b = (_a = progress[Number(fileId)]) !== null && _a !== void 0 ? _a : progress[fileId]) !== null && _b !== void 0 ? _b : [];
}
else {
const res = yield crowdinClient.translationStatusApi
.withFetchAll()
.getFileProgress(projectId, Number(fileId));
info = res.data.map((e) => e.data);
}
return {
id: fileId,
info,
};
}
catch (e) {
delete crowdinFiles[fileId];
const status = (_e = (_d = (_c = e === null || e === void 0 ? void 0 : e.response) === null || _c === void 0 ? void 0 : _c.status) !== null && _d !== void 0 ? _d : e === null || e === void 0 ? void 0 : e.status) !== null && _e !== void 0 ? _e : e === null || e === void 0 ? void 0 : e.code;
if (status === 404) {
(0, logger_1.log)(`File ${fileId} not found in Crowdin (404), marking for removal from sync settings`);
deletedFiles.push(Number(fileId));
}
else {
(0, logger_1.logError)(e, context);
}
}
})));
const filteredFiles = {};
Object.keys(crowdinFiles).forEach((fileId) => {
const fileInfo = filesInfo.find((info) => (info === null || info === void 0 ? void 0 : info.id) === fileId);
if (!fileInfo) {
return;
}
const languages = crowdinFiles[fileId];
languages.forEach((language) => {
const languageInfo = fileInfo.info.find((info) => info.languageId === language);
if (!languageInfo) {
return;
}
if (onlyTranslated) {
if (languageInfo.translationProgress === 100) {
(0, logger_1.log)(`File ${fileId} is fully translated for language ${language}`);
if (!filteredFiles[fileId]) {
filteredFiles[fileId] = [];
}
filteredFiles[fileId].push(language);
}
else {
(0, logger_1.log)(`File ${fileId} is not fully translated for language ${language}, progress ${languageInfo.translationProgress}`);
}
}
if (onlyApproved) {
if (languageInfo.approvalProgress === 100) {
(0, logger_1.log)(`File ${fileId} is fully approved for language ${language}`);
if (!filteredFiles[fileId]) {
filteredFiles[fileId] = [];
}
filteredFiles[fileId].push(language);
}
else {
(0, logger_1.log)(`File ${fileId} is not fully approved for language ${language}, progress ${languageInfo.approvalProgress}`);
}
}
});
});
return { filteredFiles, deletedFiles };
});
}
function filterFilesFromIntegrationRequest(_a) {
return __awaiter(this, arguments, void 0, function* ({ config, integration, projectId, crowdinClient, crowdinFiles, }) {
var _b;
if (integration.skipAutoSyncFoldersFilter) {
return crowdinFiles;
}
let folders;
if ((_b = config.projectIntegration) === null || _b === void 0 ? void 0 : _b.withRootFolder) {
const rootFolder = yield (0, defaults_1.getRootFolder)(config, integration, crowdinClient, projectId);
if (rootFolder) {
folders = (yield crowdinClient.sourceFilesApi.withFetchAll().listProjectDirectories(projectId, {
directoryId: rootFolder.id,
recursion: 'true',
})).data;
}
}
else {
folders = (yield crowdinClient.sourceFilesApi.withFetchAll().listProjectDirectories(projectId, { recursion: 'true' })).data;
}
if (folders) {
for (const fileId of Object.keys(crowdinFiles)) {
if (folders.find((folder) => folder.data.id === +fileId)) {
delete crowdinFiles[fileId];
}
}
}
return crowdinFiles;
});
}
function createOrUpdateSyncSettings(_a) {
return __awaiter(this, arguments, void 0, function* ({ req, files, provider, onlyCreate = false, }) {
const existingSettings = yield (0, storage_1.getStorage)().getSyncSettings(req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
if (!existingSettings) {
(0, logger_1.log)(`Saving sync settings for type schedule and provider ${provider} ${JSON.stringify(files, null, 2)}`);
yield (0, storage_1.getStorage)().saveSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
}
else if (!onlyCreate) {
(0, logger_1.log)(`Updating sync settings for type schedule and provider ${provider} ${JSON.stringify(files, null, 2)}`);
yield (0, storage_1.getStorage)().updateSyncSettings(JSON.stringify(files), req.crowdinContext.clientId, req.crowdinContext.crowdinId, 'schedule', provider);
}
});
}
function removeFinishedJobs() {
return __awaiter(this, void 0, void 0, function* () {
(0, logger_1.log)('Removing all finished jobs');
yield (0, storage_1.getStorage)().deleteFinishedJobs();
(0, logger_1.log)('Removed all finished jobs');
});
}
function removeInContextLanguage(filesToProcess, projectData) {
(0, logger_1.log)('Removing in-context language from files to process');
if (!projectData.inContext) {
return;
}
for (const fileId in filesToProcess) {
filesToProcess[fileId] = filesToProcess[fileId].filter((language) => language !== projectData.inContextPseudoLanguageId);
}
(0, logger_1.log)('In-context language(' + projectData.inContextPseudoLanguageId + ') removed from files to process');
}