112 lines
4.3 KiB
JavaScript
112 lines
4.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createIntegrationsRouter = createIntegrationsRouter;
|
|
const express_1 = require("express");
|
|
const Integration_1 = require("../../domain/entities/Integration");
|
|
const WebhookEndpoint_1 = require("../../domain/entities/WebhookEndpoint");
|
|
const IntegrationType_1 = require("../../domain/value-objects/IntegrationType");
|
|
function createIntegrationsRouter(deps) {
|
|
const router = (0, express_1.Router)();
|
|
const { integrationRepo, webhookRepo } = deps;
|
|
// ─── Integrations CRUD ──────────────────────────────────────────────────────
|
|
router.get('/', async (_req, res) => {
|
|
const items = await integrationRepo.findAll();
|
|
res.json(items.map(serializeIntegration));
|
|
});
|
|
router.post('/', async (req, res) => {
|
|
const { name, type, config } = req.body;
|
|
if (!name || !type) {
|
|
res.status(400).json({ error: 'name and type are required' });
|
|
return;
|
|
}
|
|
let intType;
|
|
try {
|
|
intType = IntegrationType_1.IntegrationType.fromString(type);
|
|
}
|
|
catch {
|
|
res.status(400).json({ error: `Invalid integration type: ${type}` });
|
|
return;
|
|
}
|
|
const integration = Integration_1.Integration.create({ name, type: intType, config: config ?? {} });
|
|
await integrationRepo.save(integration);
|
|
res.status(201).json(serializeIntegration(integration));
|
|
});
|
|
router.get('/:id', async (req, res) => {
|
|
const item = await integrationRepo.findById(req.params['id']);
|
|
if (!item) {
|
|
res.status(404).json({ error: 'Integration not found' });
|
|
return;
|
|
}
|
|
res.json(serializeIntegration(item));
|
|
});
|
|
router.patch('/:id', async (req, res) => {
|
|
const item = await integrationRepo.findById(req.params['id']);
|
|
if (!item) {
|
|
res.status(404).json({ error: 'Integration not found' });
|
|
return;
|
|
}
|
|
const { enabled, config } = req.body;
|
|
if (enabled === true)
|
|
item.enable();
|
|
else if (enabled === false)
|
|
item.disable();
|
|
if (config)
|
|
item.updateConfig(config);
|
|
await integrationRepo.update(item);
|
|
res.json(serializeIntegration(item));
|
|
});
|
|
router.delete('/:id', async (req, res) => {
|
|
await integrationRepo.delete(req.params['id']);
|
|
res.status(204).end();
|
|
});
|
|
// ─── Webhook Endpoints ───────────────────────────────────────────────────────
|
|
router.get('/webhooks/endpoints', async (_req, res) => {
|
|
const endpoints = await webhookRepo.findAll();
|
|
res.json(endpoints.map(serializeWebhook));
|
|
});
|
|
router.post('/webhooks/endpoints', async (req, res) => {
|
|
const { url } = req.body;
|
|
if (!url) {
|
|
res.status(400).json({ error: 'url is required' });
|
|
return;
|
|
}
|
|
const endpoint = WebhookEndpoint_1.WebhookEndpoint.create({ url });
|
|
await webhookRepo.save(endpoint);
|
|
res.status(201).json(serializeWebhook(endpoint));
|
|
});
|
|
router.delete('/webhooks/endpoints/:id', async (req, res) => {
|
|
await webhookRepo.delete(req.params['id']);
|
|
res.status(204).end();
|
|
});
|
|
return router;
|
|
}
|
|
function serializeIntegration(i) {
|
|
return {
|
|
id: i.id.toString(),
|
|
name: i.name,
|
|
type: i.type.value,
|
|
enabled: i.enabled,
|
|
config: maskSecrets(i.config),
|
|
createdAt: i.createdAt.toISOString(),
|
|
};
|
|
}
|
|
function serializeWebhook(ep) {
|
|
return {
|
|
id: ep.id.toString(),
|
|
url: ep.url,
|
|
enabled: ep.enabled,
|
|
createdAt: ep.createdAt.toISOString(),
|
|
lastDeliveredAt: ep.lastDeliveredAt?.toISOString() ?? null,
|
|
lastStatus: ep.lastStatus ?? null,
|
|
// Return the secret only once at creation (caller can see it from the first POST)
|
|
};
|
|
}
|
|
function maskSecrets(config) {
|
|
const masked = { ...config };
|
|
for (const key of ['token', 'secret', 'password', 'apiKey']) {
|
|
if (masked[key])
|
|
masked[key] = '***';
|
|
}
|
|
return masked;
|
|
}
|