mirror of
https://github.com/gnmyt/myspeed.git
synced 2026-02-11 08:08:49 -06:00
131 lines
4.2 KiB
JavaScript
131 lines
4.2 KiB
JavaScript
import IntegrationData from '../models/IntegrationData.js';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const integrations = {};
|
|
|
|
const events = {};
|
|
|
|
const registerEvent = (module) => (name, callback) => {
|
|
if (!events[name]) events[name] = [];
|
|
events[name].push({module, callback});
|
|
}
|
|
|
|
const getActiveByName = async (name) => {
|
|
const data = await IntegrationData.findAll({where: {name: name}});
|
|
if (!data) return null;
|
|
|
|
return data.map((item) => ({...item, data: JSON.parse(item.data)}));
|
|
}
|
|
|
|
const triggerActivity = async (id, error = false) => {
|
|
await IntegrationData.update({lastActivity: new Date().toISOString(), activityFailed: error}, {where: {id: id}});
|
|
}
|
|
|
|
export const triggerEvent = async (name, data) => {
|
|
if (!events[name]) return;
|
|
|
|
for (const module of events[name]) {
|
|
const active = await getActiveByName(module.module);
|
|
for (const integration of active)
|
|
await module.callback(integration, data, (error = false) => triggerActivity(integration.id, error));
|
|
}
|
|
}
|
|
|
|
export const initialize = async () => {
|
|
const integrationsDir = path.join(__dirname, '..', 'integrations');
|
|
|
|
for await (const entry of Deno.readDir(integrationsDir)) {
|
|
if (!entry.isFile || !entry.name.endsWith('.js')) continue;
|
|
|
|
const integrationName = entry.name.replace('.js', '');
|
|
const filePath = path.join(integrationsDir, entry.name);
|
|
|
|
const module = await import(`file://${filePath}`);
|
|
integrations[integrationName] = module.default(registerEvent(integrationName));
|
|
console.log(`Integration "${integrationName}" loaded successfully`);
|
|
}
|
|
};
|
|
|
|
export const getActive = async () => {
|
|
const data = await IntegrationData.findAll();
|
|
if (!data) return null;
|
|
|
|
return data.map((item) => ({...item, data: JSON.parse(item.data)}));
|
|
}
|
|
|
|
export const getIntegrationById = (id) => IntegrationData.findOne({where: {id: id}});
|
|
|
|
export const deleteIntegration = async (id) => {
|
|
const data = await IntegrationData.findOne({where: {id}});
|
|
if (!data) return null;
|
|
|
|
await IntegrationData.destroy({where: {id}});
|
|
return true;
|
|
}
|
|
|
|
export const create = async (name, data) => {
|
|
const integration = integrations[name];
|
|
if (!integration) return null;
|
|
|
|
const displayName = data.integration_name;
|
|
delete data.integration_name;
|
|
|
|
const created = await IntegrationData.create({name: name, data: data, displayName});
|
|
|
|
return created.id;
|
|
}
|
|
|
|
export const patch = async (id, data) => {
|
|
const item = await IntegrationData.findOne({where: {id: id}});
|
|
if (!item) return null;
|
|
|
|
const displayName = data.integration_name;
|
|
delete data.integration_name;
|
|
|
|
IntegrationData.update({data: {...JSON.parse(item.data), ...data}, displayName}, {where: {id: id}});
|
|
return true;
|
|
}
|
|
|
|
export const getIntegrations = () => {
|
|
const result = {};
|
|
|
|
for (const [name, integration] of Object.entries(integrations)) {
|
|
const updatedIntegration = {...integration};
|
|
|
|
updatedIntegration.fields = updatedIntegration.fields.map((field) => ({
|
|
...field, regex: field.regex ? field.regex.source : undefined
|
|
}));
|
|
|
|
result[name] = {name, ...updatedIntegration};
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
export const getIntegration = (name) => integrations[name];
|
|
|
|
export const validateInput = (module, data) => {
|
|
const integration = integrations[module];
|
|
if (!integration) return false;
|
|
|
|
for (const field of integration.fields) {
|
|
if (field.required && (!data[field.name] || data[field.name] === "")) return false;
|
|
|
|
if (data[field.name] !== undefined) {
|
|
if (field.regex && !new RegExp(field.regex).test(data[field.name])) return false;
|
|
if (field.type === "text" && data[field.name].length > 250) return false;
|
|
if (field.type === "textarea" && data[field.name].length > 2000) return false;
|
|
if (field.type === "boolean" && typeof data[field.name] !== "boolean") return false;
|
|
}
|
|
}
|
|
|
|
const result = {};
|
|
for (const field of integration.fields) result[field.name] = data[field.name];
|
|
result["integration_name"] = data["integration_name"];
|
|
|
|
return result;
|
|
} |