@crowdin/app-project-module
Version:
Module that generates for you all common endpoints for serving standalone Crowdin App
838 lines (837 loc) • 40.6 kB
JavaScript
"use strict";
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.D1Storage = void 0;
const types_1 = require("../modules/integration/util/types");
const crypto_1 = require("crypto");
class D1Storage {
constructor(config) {
this.migrated = false;
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_1.JobStatus.CREATED}',
payload varchar null,
info varchar null,
data varchar null,
attempt varchar DEFAULT 0,
errors varchar null,
processed_entities varchar null,
initiated_by varchar null,
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.db = config.database;
}
ensureMigrated() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.migrated) {
yield this.migrate();
this.migrated = true;
}
});
}
addColumn(tableName, column, defaultValue) {
return __awaiter(this, void 0, void 0, function* () {
const tableInfo = yield this.db.prepare(`PRAGMA table_info(${tableName})`).all();
const columns = tableInfo.results || [];
const exists = columns.some((columnInfo) => columnInfo.name === column);
if (!exists) {
yield this.db.prepare(`ALTER TABLE ${tableName} ADD COLUMN ${column} varchar ${defaultValue}`).run();
}
});
}
updateTables() {
return __awaiter(this, void 0, void 0, function* () {
yield this.addColumn('job', 'processed_entities', 'null');
yield this.addColumn('job', 'initiated_by', 'null');
});
}
migrate(skipOnboarding) {
return __awaiter(this, void 0, void 0, function* () {
if (!skipOnboarding) {
try {
// Create all tables
const statements = [];
const tableEntries = Object.keys(this.tables).map((key) => [
key,
this.tables[key],
]);
for (const [tableName, tableSchema] of tableEntries) {
statements.push(this.db.prepare(`CREATE TABLE IF NOT EXISTS ${tableName} ${tableSchema}`));
}
// Execute all table creation in batch
yield this.db.batch(statements);
// Update tables with new columns if needed
yield this.updateTables();
}
catch (e) {
console.error(e);
}
}
});
}
saveCrowdinCredentials(credentials) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
yield this.db
.prepare('INSERT INTO crowdin_credentials(id, app_secret, domain, user_id, agent_id, organization_id, base_url, access_token, refresh_token, expire, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
.bind(...this.sanitizeBindValues(credentials.id, credentials.appSecret, credentials.domain, (_a = credentials.userId) === null || _a === void 0 ? void 0 : _a.toString(), (_b = credentials.agentId) === null || _b === void 0 ? void 0 : _b.toString(), (_c = credentials.organizationId) === null || _c === void 0 ? void 0 : _c.toString(), credentials.baseUrl, credentials.accessToken, credentials.refreshToken, credentials.expire, credentials.type))
.run();
});
}
updateCrowdinCredentials(credentials) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
yield this.db
.prepare('UPDATE crowdin_credentials SET app_secret = ?, domain = ?, user_id = ?, agent_id = ?, organization_id = ?, base_url = ?, access_token = ?, refresh_token = ?, expire = ? WHERE id = ?')
.bind(...this.sanitizeBindValues(credentials.appSecret, credentials.domain, (_a = credentials.userId) === null || _a === void 0 ? void 0 : _a.toString(), (_b = credentials.agentId) === null || _b === void 0 ? void 0 : _b.toString(), (_c = credentials.organizationId) === null || _c === void 0 ? void 0 : _c.toString(), credentials.baseUrl, credentials.accessToken, credentials.refreshToken, credentials.expire, credentials.id))
.run();
});
}
getCrowdinCredentials(id) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('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 = ?')
.bind(id)
.first();
if (row) {
return Object.assign(Object.assign({}, row), { userId: row.userId ? parseInt(row.userId, 10) : row.userId, agentId: row.agentId ? parseInt(row.agentId, 10) : row.agentId, organizationId: row.organizationId ? parseInt(row.organizationId, 10) : row.organizationId });
}
});
}
getAllCrowdinCredentials() {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare('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')
.all();
return (result.results || []).map((row) => (Object.assign(Object.assign({}, row), { userId: row.userId ? parseInt(row.userId, 10) : row.userId, agentId: row.agentId ? parseInt(row.agentId, 10) : row.agentId, organizationId: row.organizationId ? parseInt(row.organizationId, 10) : row.organizationId })));
});
}
deleteCrowdinCredentials(id) {
return __awaiter(this, void 0, void 0, function* () {
const statements = [
this.db.prepare('DELETE FROM crowdin_credentials WHERE id = ?').bind(id),
this.db.prepare('DELETE FROM integration_credentials WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM sync_settings WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM app_metadata WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM files_snapshot WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM webhooks WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM user_errors WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM integration_settings WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM job WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM translation_file_cache WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM unsynced_files WHERE crowdin_id = ?').bind(id),
this.db.prepare('DELETE FROM synced_data WHERE crowdin_id = ?').bind(id),
];
yield this.db.batch(statements);
});
}
saveIntegrationCredentials(id, credentials, crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO integration_credentials(id, credentials, crowdin_id) VALUES (?, ?, ?)')
.bind(id, credentials, crowdinId)
.run();
});
}
updateIntegrationCredentials(id, credentials) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE integration_credentials SET credentials = ? WHERE id = ?')
.bind(credentials, id)
.run();
});
}
updateIntegrationManagers(id, managers) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db.prepare('UPDATE integration_credentials SET managers = ? WHERE id = ?').bind(managers, id).run();
});
}
getIntegrationCredentials(id) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('SELECT id, credentials, crowdin_id as crowdinId, managers FROM integration_credentials WHERE id = ?')
.bind(id)
.first();
if (row) {
return row;
}
});
}
getAllIntegrationCredentials(crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare('SELECT id, credentials, crowdin_id as crowdinId, managers FROM integration_credentials WHERE crowdin_id = ?')
.bind(crowdinId)
.all();
return result.results || [];
});
}
deleteIntegrationCredentials(id) {
return __awaiter(this, void 0, void 0, function* () {
const statements = [
this.db.prepare('DELETE FROM integration_credentials WHERE id = ?').bind(id),
this.db.prepare('DELETE FROM sync_settings WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM files_snapshot WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM webhooks WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM user_errors WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM integration_settings WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM job WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM translation_file_cache WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM unsynced_files WHERE integration_id = ?').bind(id),
this.db.prepare('DELETE FROM synced_data WHERE integration_id = ?').bind(id),
];
yield this.db.batch(statements);
});
}
deleteAllIntegrationCredentials(crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
const statements = [
this.db.prepare('DELETE FROM integration_credentials WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM sync_settings WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM files_snapshot WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM webhooks WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM user_errors WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM job WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM unsynced_files WHERE crowdin_id = ?').bind(crowdinId),
this.db.prepare('DELETE FROM synced_data WHERE crowdin_id = ?').bind(crowdinId),
];
yield this.db.batch(statements);
});
}
saveMetadata(id, metadata, crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO app_metadata(id, data, crowdin_id) VALUES (?, ?, ?)')
.bind(id, JSON.stringify(metadata), crowdinId)
.run();
});
}
updateMetadata(id, metadata, crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE app_metadata SET data = ?, crowdin_id = ? WHERE id = ?')
.bind(JSON.stringify(metadata), crowdinId, id)
.run();
});
}
getMetadata(id) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db.prepare('SELECT data FROM app_metadata WHERE id = ?').bind(id).first();
return (result === null || result === void 0 ? void 0 : result.data) ? JSON.parse(result.data) : undefined;
});
}
getAllMetadata() {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db.prepare('SELECT * FROM app_metadata').all();
return result.results || [];
});
}
deleteMetadata(id) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db.prepare('DELETE FROM app_metadata WHERE id = ?').bind(id).run();
});
}
getSyncSettingsByProvider(integrationId, provider) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, type, provider FROM sync_settings WHERE integration_id = ? AND provider = ?')
.bind(integrationId, provider)
.first();
if (row) {
return row;
}
});
}
getSyncSettingsBySchedule(type, schedule) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare(`
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
`)
.bind(type, schedule)
.all();
return result.results || [];
});
}
saveSyncSettings(files, integrationId, crowdinId, type, provider) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO sync_settings(files, integration_id, crowdin_id, type, provider) VALUES (?, ?, ?, ?, ?)')
.bind(files, integrationId, crowdinId, type, provider)
.run();
});
}
updateSyncSettings(files, integrationId, crowdinId, type, provider) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE sync_settings SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ? AND provider = ?')
.bind(files, integrationId, crowdinId, type, provider)
.run();
});
}
getSyncSettings(integrationId, crowdinId, type, provider) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('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 = ?')
.bind(integrationId, crowdinId, type, provider)
.first();
if (row) {
return row;
}
});
}
saveFilesSnapshot(files, integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO files_snapshot(files, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)')
.bind(files, integrationId, crowdinId, provider)
.run();
});
}
updateFilesSnapshot(files, integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE files_snapshot SET files = ? WHERE integration_id = ? AND crowdin_id = ? AND provider = ? ')
.bind(files, integrationId, crowdinId, provider)
.run();
});
}
getFilesSnapshot(integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('SELECT id, files, integration_id as integrationId, crowdin_id as crowdinId, provider FROM files_snapshot WHERE integration_id = ? AND crowdin_id = ? AND provider = ?')
.bind(integrationId, crowdinId, provider)
.first();
if (row) {
return row;
}
});
}
getAllWebhooks(integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare('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 = ?')
.bind(integrationId, crowdinId, provider)
.all();
return result.results || [];
});
}
getWebhooks(fileId, integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('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 = ?')
.bind(fileId, integrationId, crowdinId, provider)
.first();
if (row) {
return row;
}
});
}
saveWebhooks(fileId, integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO webhooks(file_id, integration_id, crowdin_id, provider) VALUES (?, ?, ?, ?)')
.bind(fileId, integrationId, crowdinId, provider)
.run();
});
}
deleteWebhooks(fileIds, integrationId, crowdinId, provider) {
return __awaiter(this, void 0, void 0, function* () {
if (fileIds.length === 0) {
return;
}
const placeholders = fileIds.map(() => '?').join(',');
yield this.db
.prepare(`DELETE FROM webhooks WHERE file_id IN (${placeholders}) AND integration_id = ? AND crowdin_id = ? AND provider = ?`)
.bind(...fileIds, integrationId, crowdinId, provider)
.run();
});
}
getAllUserErrors(crowdinId, integrationId) {
return __awaiter(this, void 0, void 0, function* () {
let whereIntegrationCondition = 'integration_id is NULL';
const params = [crowdinId];
if (integrationId) {
whereIntegrationCondition = 'integration_id = ?';
params.push(integrationId);
}
const result = yield this.db
.prepare(`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}`)
.bind(...this.sanitizeBindValues(...params))
.all();
return result.results || [];
});
}
saveUserError(action, message, data, createdAt, crowdinId, integrationId) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO user_errors(action, message, data, created_at, integration_id, crowdin_id) VALUES (?, ?, ?, ?, ?, ?)')
.bind(...this.sanitizeBindValues(action, message, data, createdAt, integrationId, crowdinId))
.run();
});
}
deleteUserErrors(date, crowdinId, integrationId) {
return __awaiter(this, void 0, void 0, function* () {
let whereIntegrationCondition = 'integration_id is NULL';
const params = [date, crowdinId];
if (integrationId) {
whereIntegrationCondition = 'integration_id = ?';
params.push(integrationId);
}
yield this.db
.prepare(`DELETE FROM user_errors WHERE created_at < ? AND crowdin_id = ? AND ${whereIntegrationCondition}`)
.bind(...this.sanitizeBindValues(...params))
.run();
});
}
deleteAllUsersErrorsOlderThan(date) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db.prepare('DELETE FROM user_errors WHERE created_at < ?').bind(date).run();
});
}
saveIntegrationConfig(integrationId, crowdinId, config) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO integration_settings(integration_id, crowdin_id, config) VALUES (?, ?, ?)')
.bind(integrationId, crowdinId, config)
.run();
});
}
getAllIntegrationConfigs(crowdinId) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare('SELECT config, integration_id as integrationId FROM integration_settings WHERE crowdin_id = ?')
.bind(crowdinId)
.all();
return result.results || [];
});
}
getIntegrationConfig(integrationId) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('SELECT config FROM integration_settings WHERE integration_id = ?')
.bind(integrationId)
.first();
if (row) {
return row;
}
});
}
updateIntegrationConfig(integrationId, config) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE integration_settings SET config = ? WHERE integration_id = ?')
.bind(config, integrationId)
.run();
});
}
createJob(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const id = (0, crypto_1.randomUUID)();
yield this.db
.prepare('INSERT INTO job(id, integration_id, crowdin_id, type, payload, title, initiated_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)')
.bind(id, params.integrationId, params.crowdinId, params.type, params.payload, params.title, (_a = params.initiatedBy) !== null && _a !== void 0 ? _a : null, Date.now().toString())
.run();
return id;
});
}
updateJob(params) {
return __awaiter(this, void 0, void 0, function* () {
const updateFields = ['updated_at = ?'];
const updateParams = [Date.now().toString()];
if (params.progress) {
updateFields.push('progress = ?');
updateParams.push(Math.round(params.progress));
if (params.progress >= 100) {
updateFields.push('finished_at = ?');
updateParams.push(Date.now().toString());
}
}
if (params.status) {
updateFields.push('status = ?');
updateParams.push(params.status);
if (!updateFields.includes('finished_at = ?') &&
[types_1.JobStatus.FAILED, types_1.JobStatus.CANCELED].includes(params.status)) {
updateFields.push('finished_at = ?');
updateParams.push(Date.now().toString());
}
}
if (params.data) {
updateFields.push('data = ?');
updateParams.push(params.data);
}
if (params.info) {
updateFields.push('info = ?');
updateParams.push(params.info);
}
if (params.attempt) {
updateFields.push('attempt = ?');
updateParams.push(params.attempt);
}
if (params.errors) {
updateFields.push('errors = ?');
updateParams.push(JSON.stringify(params.errors));
}
if (params.processedEntities) {
updateFields.push('processed_entities = ?');
updateParams.push(params.processedEntities);
}
updateParams.push(params.id);
const query = `UPDATE job SET ${updateFields.join(', ')} WHERE id = ?`;
yield this.db
.prepare(query)
.bind(...updateParams)
.run();
});
}
getJob(params) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare(`
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status,
title, info, data, attempt, errors, processed_entities as processedEntities, initiated_by as initiatedBy, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
FROM job
WHERE id = ?
`)
.bind(params.id)
.first();
if (row) {
return row;
}
});
}
getActiveJobs(params) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare(`
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, errors, processed_entities as processedEntities, initiated_by as initiatedBy, 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
`)
.bind(params.integrationId, params.crowdinId)
.all();
return result.results || [];
});
}
deleteFinishedJobs() {
return __awaiter(this, void 0, void 0, function* () {
yield this.db.prepare('DELETE FROM job WHERE finished_at IS NOT NULL').run();
});
}
getAllInProgressJobs() {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare(`
SELECT id, integration_id as integrationId, crowdin_id as crowdinId, type, payload, progress, status, title, info, data, attempt, errors, processed_entities as processedEntities, initiated_by as initiatedBy, created_at as createdAt, updated_at as updatedAt, finished_at as finishedAt
FROM job
WHERE status IN (?,?) AND finished_at is NULL
`)
.bind(types_1.JobStatus.IN_PROGRESS, types_1.JobStatus.CREATED)
.all();
return result.results || [];
});
}
getAllJobs(params) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare(`
SELECT
id,
integration_id as integrationId,
crowdin_id as crowdinId,
type,
payload,
progress,
status,
title,
info,
data,
attempt,
initiated_by as initiatedBy,
created_at as createdAt,
updated_at as updatedAt,
finished_at as finishedAt
FROM job
WHERE integration_id = ? AND crowdin_id = ?
ORDER BY created_at DESC
LIMIT ? OFFSET ?
`)
.bind(params.integrationId, params.crowdinId, params.limit, params.offset)
.all();
return result.results || [];
});
}
saveTranslationCache(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO translation_file_cache(integration_id, crowdin_id, file_id, language_id, etag) VALUES (?, ?, ?, ?, ?)')
.bind(params.integrationId, params.crowdinId, params.fileId, params.languageId, params.etag)
.run();
});
}
getFileTranslationCache(params) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.db
.prepare(`
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 = ?
`)
.bind(params.integrationId, params.crowdinId, params.fileId)
.all();
return result.results || [];
});
}
getFileTranslationCacheByLanguage(params) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare(`
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 = ?
`)
.bind(params.integrationId, params.crowdinId, params.fileId, params.languageId)
.first();
if (row) {
return row;
}
});
}
updateTranslationCache(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE translation_file_cache SET etag = ? WHERE integration_id = ? AND crowdin_id = ? AND file_id = ? AND language_id = ?')
.bind(params.etag, params.integrationId, params.crowdinId, params.fileId, params.languageId)
.run();
});
}
saveUnsyncedFiles(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO unsynced_files(integration_id, crowdin_id, files) VALUES (?, ?, ?)')
.bind(params.integrationId, params.crowdinId, params.files)
.run();
});
}
updateUnsyncedFiles(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE unsynced_files SET files = ? WHERE integration_id = ? AND crowdin_id = ?')
.bind(params.files, params.integrationId, params.crowdinId)
.run();
});
}
getUnsyncedFiles(params) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('SELECT files FROM unsynced_files WHERE integration_id = ? AND crowdin_id = ?')
.bind(params.integrationId, params.crowdinId)
.first();
if (row) {
return row;
}
});
}
registerCustomTable(tableName, schema) {
return __awaiter(this, void 0, void 0, function* () {
const schemaKeys = Object.keys(schema);
const columns = schemaKeys.map((name) => `${name} ${schema[name]}`).join(', ');
yield this.db.prepare(`CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`).run();
});
}
insertRecord(tableName, data) {
return __awaiter(this, void 0, void 0, function* () {
const keys = Object.keys(data);
const columns = keys.join(', ');
const placeholders = keys.map(() => '?').join(', ');
const values = keys.map((key) => data[key]);
yield this.db
.prepare(`INSERT INTO ${tableName} (${columns}) VALUES (${placeholders})`)
.bind(...this.sanitizeBindValues(...values))
.run();
});
}
selectRecords(tableName_1) {
return __awaiter(this, arguments, void 0, function* (tableName, options = {}, params = []) {
var _a;
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 offsetClause = options.offset ? ` OFFSET ${options.offset}` : '';
const query = `SELECT ${distinctKeyword}${columns} FROM ${tableName}${whereClause}${orderByClause}${limitClause}${offsetClause};`;
const stmt = this.db.prepare(query);
const result = params.length > 0 ? yield stmt.bind(...this.sanitizeBindValues(...params)).all() : yield stmt.all();
return result.results || [];
});
}
updateRecord(tableName_1, data_1, whereClause_1) {
return __awaiter(this, arguments, void 0, function* (tableName, data, whereClause, params = []) {
const setClause = Object.keys(data)
.map((key) => `${key} = ?`)
.join(', ');
const values = Object.values(data);
const query = `UPDATE ${tableName} SET ${setClause} ${whereClause};`;
yield this.db
.prepare(query)
.bind(...this.sanitizeBindValues(...values, ...params))
.run();
});
}
deleteRecord(tableName_1, whereClause_1) {
return __awaiter(this, arguments, void 0, function* (tableName, whereClause, params = []) {
const query = `DELETE FROM ${tableName} ${whereClause};`;
const stmt = this.db.prepare(query);
if (params.length > 0) {
yield stmt.bind(...this.sanitizeBindValues(...params)).run();
}
else {
yield stmt.run();
}
});
}
saveSyncedData(files, integrationId, crowdinId, type) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('INSERT INTO synced_data(files, integration_id, crowdin_id, type, updated_at) VALUES (?, ?, ?, ?, ?)')
.bind(files, integrationId, crowdinId, type, Date.now().toString())
.run();
});
}
updateSyncedData(files, integrationId, crowdinId, type) {
return __awaiter(this, void 0, void 0, function* () {
yield this.db
.prepare('UPDATE synced_data SET files = ?, updated_at = ? WHERE integration_id = ? AND crowdin_id = ? AND type = ?')
.bind(files, Date.now().toString(), integrationId, crowdinId, type)
.run();
});
}
getSyncedData(integrationId, crowdinId, type) {
return __awaiter(this, void 0, void 0, function* () {
const row = yield this.db
.prepare('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 = ?')
.bind(integrationId, crowdinId, type)
.first();
if (row) {
return row;
}
});
}
/**
* Converts undefined values to null for D1 compatibility
* D1 does not support undefined values, so we convert them to null
*/
sanitizeBindValues(...values) {
return values.map((v) => (v === undefined ? null : v));
}
}
exports.D1Storage = D1Storage;