UNPKG

@crowdin/app-project-module

Version:

Module that generates for you all common endpoints for serving standalone Crowdin App

778 lines (777 loc) 36.1 kB
"use strict"; /* eslint-disable @typescript-eslint/camelcase */ /* eslint-disable @typescript-eslint/ban-ts-ignore */ /* eslint-disable no-unused-expressions */ /* eslint-disable @typescript-eslint/no-var-requires */ 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.SQLiteStorage = void 0; const path_1 = require("path"); const uuid_1 = require("uuid"); const types_1 = require("../types"); const types_2 = require("../modules/integration/util/types"); class SQLiteStorage { constructor(config) { this.dbPromise = new Promise((res, rej) => { this._res = res; this._rej = rej; }); this.tables = { crowdin_credentials: `( id varchar not null primary key, app_secret varchar null, domain varchar null, user_id varchar null, agent_id varchar null, organization_id varchar null, base_url varchar null, access_token varchar not null, refresh_token varchar not null, expire varchar not null, type varchar not null )`, integration_credentials: `( id varchar not null primary key, credentials varchar not null, crowdin_id varchar not null, managers varchar null )`, sync_settings: `( id integer not null primary key autoincrement, files varchar null, integration_id varchar not null, crowdin_id varchar not null, type varchar not null, provider varchar not null )`, app_metadata: `( id varchar not null primary key, data varchar null, crowdin_id varchar null )`, files_snapshot: `( id integer not null primary key autoincrement, integration_id varchar not null, crowdin_id varchar not null, files varchar null, provider varchar not null )`, webhooks: `( id integer not null primary key autoincrement, file_id varchar not null, integration_id varchar not null, crowdin_id varchar not null, provider varchar not null )`, user_errors: `( id integer not null primary key autoincrement, action varchar not null, message varchar not null, data varchar null, created_at varchar not null, crowdin_id varchar not null, integration_id varchar null )`, integration_settings: `( id integer not null primary key autoincrement, integration_id varchar not null, crowdin_id varchar not null, config varchar null )`, job: `( id varchar not null primary key, integration_id varchar not null, crowdin_id varchar not null, type varchar not null, title varchar null, progress integer DEFAULT 0, status varchar DEFAULT '${types_2.JobStatus.CREATED}', payload varchar null, info varchar null, data varchar null, attempt varchar DEFAULT 0, created_at varchar not null, updated_at varchar null, finished_at varchar null )`, translation_file_cache: `( id integer not null primary key autoincrement, integration_id varchar not null, crowdin_id varchar not null, file_id integer not null, language_id varchar not null, etag varchar )`, unsynced_files: `( id integer not null primary key autoincrement, integration_id varchar not null, crowdin_id varchar not null, files varchar null )`, synced_data: `( id integer not null primary key autoincrement, files varchar null, integration_id varchar not null, crowdin_id varchar not null, type varchar not null, updated_at varchar null )`, }; this.config = config; } _run(query, params) { return __awaiter(this, void 0, void 0, function* () { yield new Promise((res, rej) => { var _a; //@ts-ignore (_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, (err) => { if (err) { rej(err); } else { res(); } }); }); }); } run(query, params) { return __awaiter(this, void 0, void 0, function* () { yield this.dbPromise; yield new Promise((res, rej) => { var _a; //@ts-ignore (_a = this.db) === null || _a === void 0 ? void 0 : _a.run(query, params, (err) => { if (err) { rej(err); } else { res(); } }); }); }); } get(query, params) { return __awaiter(this, void 0, void 0, function* () { yield this.dbPromise; return new Promise((res, rej) => { var _a; //@ts-ignore (_a = this.db) === null || _a === void 0 ? void 0 : _a.get(query, params, (err, row) => { if (err) { rej(err); } else { res(row); } }); }); }); } each(query, params) { return __awaiter(this, void 0, void 0, function* () { yield this.dbPromise; return new Promise((res, rej) => { var _a; const result = []; (_a = this.db) === null || _a === void 0 ? void 0 : _a.each(query, params, //@ts-ignore (err, row) => { if (err) { rej(err); } else { result.push(row); } }, () => res(result)); }); }); } removeColumns(column, tableName) { return __awaiter(this, void 0, void 0, function* () { const tableInfo = yield this.each(`PRAGMA table_info(${tableName});`, []); const exists = tableInfo.some((columnInfo) => columnInfo.name === column); if (exists) { yield this.run(`ALTER TABLE ${tableName} DROP COLUMN ${column};`, []); } }); } addColumns(columns, tableName) { return __awaiter(this, void 0, void 0, function* () { const tableInfo = yield this.each(`PRAGMA table_info(${tableName});`, []); //@ts-ignore tableInfo.map((columnInfo) => __awaiter(this, void 0, void 0, function* () { const index = columns.indexOf(columnInfo.name); if (~index) { columns.splice(index, 1); } })); for (const column of columns) { yield this.run(`ALTER TABLE ${tableName} ADD COLUMN ${column} varchar null;`, []); } }); } addColumn(tableName, column, defaultValue) { return __awaiter(this, void 0, void 0, function* () { const tableInfo = yield this.each(`PRAGMA table_info(${tableName});`, []); const exists = tableInfo.some((columnInfo) => columnInfo.name === column); if (!exists) { yield this.run(`ALTER TABLE ${tableName} ADD COLUMN ${column} varchar ${defaultValue};`, []); } }); } updateTables() { return __awaiter(this, void 0, void 0, function* () { yield this.addColumns(['app_secret', 'domain', 'user_id', 'agent_id', 'organization_id', 'base_url'], 'crowdin_credentials'); yield this.addColumns(['crowdin_id'], 'app_metadata'); yield this.addColumn('job', 'attempt', 'DEFAULT 0'); yield this.addColumn('integration_credentials', 'managers', 'null'); }); } moveIntegrationSettings() { return __awaiter(this, void 0, void 0, function* () { const integrationCredentials = yield this.each('SELECT * FROM integration_credentials', []); for (const credentials of integrationCredentials) { if (credentials.config) { yield this.saveIntegrationConfig(credentials.id, credentials.crowdin_id, credentials.config); } } yield this.removeColumns('config', 'integration_credentials'); }); } migrateManagers() { return __awaiter(this, void 0, void 0, function* () { const tableInfo = yield this.each('PRAGMA table_info(integration_credentials);', []); const exists = tableInfo.some((columnInfo) => columnInfo.name === 'managers'); if (exists) { return; } yield this.addColumn('integration_credentials', 'managers', 'null'); const integrationSettings = yield this.each('SELECT integration_id, config FROM integration_settings', []); for (const settings of integrationSettings) { const config = JSON.parse(settings.config); if (config.managers) { yield this.run('UPDATE integration_credentials SET managers = ? WHERE id = ?', [ JSON.stringify(config.managers), settings.integration_id, ]); } } }); } migrate() { return __awaiter(this, void 0, void 0, function* () { let _connection_res; let _connection_rej; const connectionPromise = new Promise((res, rej) => { _connection_res = res; _connection_rej = rej; }); const sqlite = require('sqlite3'); //@ts-ignore this.db = new sqlite.Database((0, path_1.join)(this.config.dbFolder, types_1.storageFiles.SQLITE), (error) => { if (error) { _connection_rej(error); } else { _connection_res(); } }); try { yield connectionPromise; for (const [tableName, tableSchema] of Object.entries(this.tables)) { yield this._run(`create table if not exists ${tableName} ${tableSchema};`, []); } this._res && this._res(); // TODO: temporary code yield this.updateTables(); yield this.moveIntegrationSettings(); yield this.migrateManagers(); } catch (e) { this._rej && this._rej(e); } }); } saveCrowdinCredentials(credentials) { return this.run('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, agent_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [ credentials.id, credentials.appSecret, credentials.domain, credentials.userId, credentials.agentId, credentials.organizationId, credentials.baseUrl, credentials.accessToken, credentials.refreshToken, credentials.expire, credentials.type, ]); } updateCrowdinCredentials(credentials) { return this.run('UPDATE crowdin_credentials SET app_secret = ?, domain = ?, user_id = ?, agent_id = ?, organization_id = ?, base_url = ?, access_token = ?, refresh_token = ?, expire = ? WHERE id = ?', [ credentials.appSecret, credentials.domain, credentials.userId, credentials.agentId, credentials.organizationId, credentials.baseUrl, credentials.accessToken, credentials.refreshToken, credentials.expire, credentials.id, ]); } getCrowdinCredentials(id) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, app_secret as appSecret, domain, user_id as userId, agent_id as agentId, organization_id as organizationId, base_url as baseUrl, access_token as accessToken, refresh_token as refreshToken, expire, type FROM crowdin_credentials WHERE id = ?', [id]); if (row) { return row; } }); } getAllCrowdinCredentials() { return this.each('SELECT id, app_secret as appSecret, domain, user_id as userId, agent_id as agentId, organization_id as organizationId, base_url as baseUrl, access_token as accessToken, refresh_token as refreshToken, expire, type FROM crowdin_credentials', []); } deleteCrowdinCredentials(id) { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM crowdin_credentials where id = ?', [id]); yield this.run('DELETE FROM integration_credentials where crowdin_id = ?', [id]); yield this.run('DELETE FROM sync_settings WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM app_metadata WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM files_snapshot WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM webhooks WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM user_errors WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM integration_settings WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM job WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM translation_file_cache WHERE crowdin_id = ?', [id]); yield this.run('DELETE FROM unsynced_files WHERE crowdin_id = ?', [id]); }); } saveIntegrationCredentials(id, credentials, crowdinId) { return this.run('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES (?, ?, ?)', [ id, credentials, crowdinId, ]); } updateIntegrationCredentials(id, credentials) { return this.run('UPDATE integration_credentials SET credentials = ? WHERE id = ?', [credentials, id]); } updateIntegrationManagers(id, managers) { return this.run('UPDATE integration_credentials SET managers = ? WHERE id = ?', [managers, id]); } getIntegrationCredentials(id) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, credentials, crowdin_id as crowdinId, managers FROM integration_credentials WHERE id = ?', [id]); if (row) { return row; } }); } getAllIntegrationCredentials(crowdinId) { return this.each('SELECT id, credentials, crowdin_id as crowdinId, managers FROM integration_credentials WHERE crowdin_id = ?', [crowdinId]); } deleteIntegrationCredentials(id) { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM integration_credentials where id = ?', [id]); yield this.run('DELETE FROM sync_settings where integration_id = ?', [id]); yield this.run('DELETE FROM files_snapshot where integration_id = ?', [id]); yield this.run('DELETE FROM webhooks where integration_id = ?', [id]); yield this.run('DELETE FROM job where integration_id = ?', [id]); yield this.run('DELETE FROM unsynced_files where integration_id = ?', [id]); }); } deleteAllIntegrationCredentials(crowdinId) { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM integration_credentials where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM sync_settings where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM files_snapshot where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM webhooks where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM user_errors where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM job where crowdin_id = ?', [crowdinId]); yield this.run('DELETE FROM unsynced_files where crowdin_id = ?', [crowdinId]); }); } saveMetadata(id, metadata, crowdinId) { return this.run('INSERT INTO app_metadata(id, data, crowdin_id) VALUES (?, ?, ?)', [ id, JSON.stringify(metadata), crowdinId, ]); } updateMetadata(id, metadata, crowdinId) { return this.run('UPDATE app_metadata SET data = ?, crowdin_id = ? WHERE id = ?', [ JSON.stringify(metadata), crowdinId, id, ]); } getMetadata(id) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT data FROM app_metadata WHERE id = ?', [id]); if (row) { return JSON.parse(row.data); } }); } getAllMetadata() { return this.each('SELECT * FROM app_metadata', []); } deleteMetadata(id) { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM app_metadata where id = ?', [id]); }); } getSyncSettingsByProvider(integrationId, provider) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE integration_id = ? AND provider = ?', [integrationId, provider]); if (row) { return row; } }); } getSyncSettingsBySchedule(type, schedule) { return this.each(` SELECT s.id, s.files, s.integration_id as integrationId, s.crowdin_id as crowdinId, s.type, s.provider FROM sync_settings s INNER JOIN integration_settings i ON s.integration_id = i.integration_id WHERE s.type = ? AND CASE WHEN i.config IS NULL THEN 0 ELSE json_extract(i.config, '$.schedule') = ? END `, [type, schedule]); } saveSyncSettings(files, integrationId, crowdinId, type, provider) { return this.run('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES (?, ?, ?, ?, ?)', [files, integrationId, crowdinId, type, provider]); } updateSyncSettings(files, integrationId, crowdinId, type, provider) { return this.run('UPDATE sync_settings SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [files, integrationId, crowdinId, type, provider]); } getSyncSettings(integrationId, crowdinId, type, provider) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?', [integrationId, crowdinId, type, provider]); if (row) { return row; } }); } saveFilesSnapshot(files, integrationId, crowdinId, provider) { return this.run('INSERT INTO files_snapshot(files, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [ files, integrationId, crowdinId, provider, ]); } updateFilesSnapshot(files, integrationId, crowdinId, provider) { return this.run('UPDATE files_snapshot SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND provider = ? ', [files, integrationId, crowdinId, provider]); } getFilesSnapshot(integrationId, crowdinId, provider) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, provider FROM files_snapshot WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]); if (row) { return row; } }); } getAllWebhooks(integrationId, crowdinId, provider) { return this.each('SELECT id, file_id as fileId, integration_id as integrationId, crowdin_id as crowdinId, provider FROM webhooks WHERE integration_id = ? AND crowdin_id = ? AND provider = ?', [integrationId, crowdinId, provider]); } getWebhooks(fileId, integrationId, crowdinId, provider) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, file_id as fileId, integration_id as integrationId, crowdin_id as crowdinId, provider FROM webhooks WHERE file_id = ? AND integration_id = ? AND crowdin_id = ? AND provider = ?', [fileId, integrationId, crowdinId, provider]); if (row) { return row; } }); } saveWebhooks(fileId, integrationId, crowdinId, provider) { return this.run('INSERT INTO webhooks(file_id, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)', [ fileId, integrationId, crowdinId, provider, ]); } deleteWebhooks(fileIds, integrationId, crowdinId, provider) { return __awaiter(this, void 0, void 0, function* () { if (!fileIds.length) { return; } const placeholders = fileIds.map(() => '?').join(','); return this.run(`DELETE FROM webhooks WHERE file_id IN (${placeholders}) AND integration_id = ? AND crowdin_id = ? AND provider = ?`, [...fileIds, integrationId, crowdinId, provider]); }); } getAllUserErrors(crowdinId, integrationId) { let whereIntegrationCondition = 'integration_id is NULL'; const params = [crowdinId]; if (integrationId) { whereIntegrationCondition = 'integration_id = ?'; params.push(integrationId); } return this.each(`SELECT id, action, message, data, created_at as createdAt, integration_id as integrationId, crowdin_id as crowdinId FROM user_errors WHERE crowdin_id = ? AND ${whereIntegrationCondition}`, params); } saveUserError(action, message, data, createdAt, crowdinId, integrationId) { return this.run('INSERT INTO user_errors(action, message, data, created_at, integration_id, crowdin_id) VALUES (?, ?, ?, ?, ?, ?)', [action, message, data, createdAt, integrationId, crowdinId]); } deleteUserErrors(createAt, crowdinId, integrationId) { return __awaiter(this, void 0, void 0, function* () { let whereIntegrationCondition = 'integration_id is NULL'; const params = [createAt, crowdinId]; if (integrationId) { whereIntegrationCondition = 'integration_id = ?'; params.push(integrationId); } return this.run(`DELETE FROM user_errors WHERE created_at < ? AND crowdin_id = ? AND ${whereIntegrationCondition}`, params); }); } deleteAllUsersErrorsOlderThan(createAt) { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM user_errors where created_at < ?', [createAt]); }); } saveIntegrationConfig(integrationId, crowdinId, config) { return this.run('INSERT INTO integration_settings(integration_id, crowdin_id, config) VALUES (?, ?, ?)', [ integrationId, crowdinId, config, ]); } getAllIntegrationConfigs(crowdinId) { return this.each('SELECT config, integration_id as integrationId FROM integration_settings WHERE crowdin_id = ?', [crowdinId]); } getIntegrationConfig(integrationId) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT config FROM integration_settings WHERE integration_id = ?', [ integrationId, ]); if (row) { return row; } }); } updateIntegrationConfig(integrationId, config) { return this.run('UPDATE integration_settings SET config = ? WHERE integration_id = ?', [config, integrationId]); } createJob({ integrationId, crowdinId, type, title, payload }) { return __awaiter(this, void 0, void 0, function* () { const id = (0, uuid_1.v4)(); yield this.run(` INSERT INTO job(id, integration_id, crowdin_id, type, payload, title, created_at) VALUES (?, ?, ?, ?, ?, ?, ?) `, [id, integrationId, crowdinId, type, payload, title, Date.now().toString()]); return id; }); } updateJob({ id, progress, status, info, data, attempt }) { const updateFields = ['updated_at = ?']; const updateParams = [Date.now().toString()]; if (progress) { updateFields.push('progress = ?'); updateParams.push(Math.round(progress)); if (progress >= 100) { updateFields.push('finished_at = ?'); updateParams.push(Date.now().toString()); } } if (status) { updateFields.push('status = ?'); updateParams.push(status); if (!updateFields.includes('finished_at = ?') && [types_2.JobStatus.FAILED, types_2.JobStatus.CANCELED].includes(status)) { updateFields.push('finished_at = ?'); updateParams.push(Date.now().toString()); } } if (data) { updateFields.push('data = ?'); updateParams.push(data); } if (info) { updateFields.push('info = ?'); updateParams.push(info); } if (attempt) { updateFields.push('attempt = ?'); updateParams.push(attempt); } updateParams.push(id); const query = ` UPDATE job SET ${updateFields.join(', ')} WHERE id = ? `; return this.run(query, updateParams); } getJob({ id }) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get(` SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt FROM job WHERE id = ? `, [id]); if (row) { return row; } }); } getActiveJobs({ integrationId, crowdinId }) { return __awaiter(this, void 0, void 0, function* () { return this.each(` SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt FROM job WHERE integration_id = ? AND crowdin_id = ? AND finished_at is NULL `, [integrationId, crowdinId]); }); } deleteFinishedJobs() { return __awaiter(this, void 0, void 0, function* () { yield this.run('DELETE FROM job WHERE finished_at is not NULL', []); }); } getAllInProgressJobs() { return __awaiter(this, void 0, void 0, function* () { return this.each(` SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt FROM job WHERE status IN (?,?) AND finished_at is NULL `, [types_2.JobStatus.IN_PROGRESS, types_2.JobStatus.CREATED]); }); } saveTranslationCache({ integrationId, crowdinId, fileId, languageId, etag }) { return this.run(` INSERT INTO translation_file_cache(integration_id, crowdin_id, file_id, language_id, etag) VALUES (?, ?, ?, ?, ?) `, [integrationId, crowdinId, fileId, languageId, etag]); } getFileTranslationCache({ integrationId, crowdinId, fileId, }) { return __awaiter(this, void 0, void 0, function* () { return this.each(` SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag FROM translation_file_cache WHERE integration_id = ? AND crowdin_id = ? AND file_id = ? `, [integrationId, crowdinId, fileId]); }); } getFileTranslationCacheByLanguage({ integrationId, crowdinId, fileId, languageId, }) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get(` SELECT integration_id as integrationId, crowdin_id as crowdinId, file_id as fileId, language_id as languageId, etag FROM translation_file_cache WHERE integration_id = ? AND crowdin_id = ? AND file_id = ? AND language_id = ? `, [integrationId, crowdinId, fileId, languageId]); if (row) { return row; } }); } updateTranslationCache({ integrationId, crowdinId, fileId, languageId, etag, }) { return this.run(` UPDATE translation_file_cache SET etag = ? WHERE integration_id = ? AND crowdin_id = ? AND file_id = ? AND language_id = ? `, [etag, integrationId, crowdinId, fileId, languageId]); } saveUnsyncedFiles({ integrationId, crowdinId, files }) { return this.run(` INSERT INTO unsynced_files(integration_id, crowdin_id, files) VALUES (?, ?, ?) `, [integrationId, crowdinId, files]); } updateUnsyncedFiles({ integrationId, crowdinId, files }) { return this.run(` UPDATE unsynced_files SET files = ? WHERE integration_id = ? AND crowdin_id = ? `, [files, integrationId, crowdinId]); } getUnsyncedFiles({ integrationId, crowdinId }) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get(` SELECT files FROM unsynced_files WHERE integration_id = ? AND crowdin_id = ? `, [integrationId, crowdinId]); if (row) { return row; } }); } registerCustomTable(tableName, schema) { return __awaiter(this, void 0, void 0, function* () { const columns = Object.entries(schema) .map(([col, def]) => `${col} ${def}`) .join(', '); const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns});`; yield this.run(query, []); }); } insertRecord(tableName, data) { return __awaiter(this, void 0, void 0, function* () { const columns = Object.keys(data).join(', '); const placeholders = Object.keys(data) .map(() => '?') .join(', '); const values = Object.values(data); const query = `INSERT INTO ${tableName} (${columns}) VALUES (${placeholders});`; return this.run(query, values); }); } selectRecords(tableName, options = {}, params = []) { var _a; return __awaiter(this, void 0, void 0, function* () { const columns = ((_a = options.columns) === null || _a === void 0 ? void 0 : _a.length) ? options.columns.join(', ') : '*'; const distinctKeyword = options.distinct ? 'DISTINCT ' : ''; const whereClause = options.whereClause ? ` ${options.whereClause}` : ''; const orderByClause = options.orderBy ? ` ORDER BY ${options.orderBy}` : ''; const limitClause = options.limit ? ` LIMIT ${options.limit}` : ''; const query = `SELECT ${distinctKeyword}${columns} FROM ${tableName}${whereClause}${orderByClause}${limitClause};`; return this.each(query, params); }); } updateRecord(tableName, data, whereClause, params = []) { return __awaiter(this, void 0, void 0, function* () { const setClause = Object.keys(data) .map((key) => `${key} = ?`) .join(', '); const values = Object.values(data); const query = `UPDATE ${tableName} SET ${setClause} ${whereClause};`; yield this.run(query, [...values, ...params]); }); } deleteRecord(tableName, whereClause, params = []) { return __awaiter(this, void 0, void 0, function* () { const query = `DELETE FROM ${tableName} ${whereClause};`; yield this.run(query, params); }); } saveSyncedData(files, integrationId, crowdinId, type) { return this.run('INSERT INTO synced_data(files, integration_id, crowdin_id, type, updated_at) VALUES (?, ?, ?, ?, ?)', [files, integrationId, crowdinId, type, Date.now().toString()]); } updateSyncedData(files, integrationId, crowdinId, type) { return this.run('UPDATE synced_data SET files = ?, updated_at = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ?', [files, Date.now().toString(), integrationId, crowdinId, type]); } getSyncedData(integrationId, crowdinId, type) { return __awaiter(this, void 0, void 0, function* () { const row = yield this.get('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, updated_at as updatedAt FROM synced_data WHERE integration_id = ? AND crowdin_id = ? AND type = ?', [integrationId, crowdinId, type]); if (row) { return row; } }); } } exports.SQLiteStorage = SQLiteStorage;