mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-11 09:18:26 +00:00
156 lines
5.0 KiB
TypeScript
156 lines
5.0 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { logger } from "@trigger.dev/sdk/v3";
|
|
|
|
import * as fs from "fs";
|
|
import * as path from "path";
|
|
|
|
import { prisma } from "./prisma";
|
|
|
|
export const fetchAndSaveStdioIntegrations = async () => {
|
|
try {
|
|
logger.info("Starting stdio integrations fetch and save process");
|
|
|
|
// Get all integration definitions
|
|
const integrationDefinitions =
|
|
await prisma.integrationDefinitionV2.findMany({
|
|
where: {
|
|
deleted: null, // Only active integrations
|
|
},
|
|
});
|
|
|
|
logger.info(
|
|
`Found ${integrationDefinitions.length} integration definitions`,
|
|
);
|
|
|
|
for (const integration of integrationDefinitions) {
|
|
try {
|
|
const spec = integration.spec as any;
|
|
|
|
// Check if this integration has MCP config and is stdio type
|
|
if (spec?.mcp?.type === "stdio" && spec?.mcp?.url) {
|
|
logger.info(`Processing stdio integration: ${integration.slug}`);
|
|
|
|
const integrationDir = path.join(
|
|
process.cwd(),
|
|
"integrations",
|
|
integration.slug,
|
|
);
|
|
const targetFile = path.join(integrationDir, "main");
|
|
|
|
// Create directory if it doesn't exist
|
|
if (!fs.existsSync(integrationDir)) {
|
|
fs.mkdirSync(integrationDir, { recursive: true });
|
|
logger.info(`Created directory: ${integrationDir}`);
|
|
}
|
|
|
|
// Skip if file already exists
|
|
if (fs.existsSync(targetFile)) {
|
|
logger.info(
|
|
`Integration ${integration.slug} already exists, skipping`,
|
|
);
|
|
continue;
|
|
}
|
|
|
|
const urlOrPath = spec.mcp.url;
|
|
|
|
// If urlOrPath looks like a URL, use fetch, otherwise treat as local path
|
|
let isUrl = false;
|
|
try {
|
|
// Try to parse as URL
|
|
const parsed = new URL(urlOrPath);
|
|
isUrl = ["http:", "https:"].includes(parsed.protocol);
|
|
} catch {
|
|
isUrl = false;
|
|
}
|
|
|
|
if (isUrl) {
|
|
// Fetch the URL content
|
|
logger.info(`Fetching content from URL: ${urlOrPath}`);
|
|
const response = await fetch(urlOrPath);
|
|
|
|
if (!response.ok) {
|
|
logger.error(
|
|
`Failed to fetch ${urlOrPath}: ${response.status} ${response.statusText}`,
|
|
);
|
|
continue;
|
|
}
|
|
|
|
// Check if the response is binary (executable) or text
|
|
const contentType = response.headers.get("content-type");
|
|
const isBinary =
|
|
contentType &&
|
|
(contentType.includes("application/octet-stream") ||
|
|
contentType.includes("application/executable") ||
|
|
contentType.includes("application/x-executable") ||
|
|
contentType.includes("binary") ||
|
|
!contentType.includes("text/"));
|
|
|
|
let content: string | Buffer;
|
|
|
|
if (isBinary) {
|
|
// Handle binary files
|
|
const arrayBuffer = await response.arrayBuffer();
|
|
content = Buffer.from(arrayBuffer);
|
|
} else {
|
|
// Handle text files
|
|
content = await response.text();
|
|
}
|
|
|
|
// Save the content to the target file
|
|
if (typeof content === "string") {
|
|
fs.writeFileSync(targetFile, content);
|
|
} else {
|
|
fs.writeFileSync(targetFile, content);
|
|
}
|
|
|
|
// Make the file executable if it's a script
|
|
if (process.platform !== "win32") {
|
|
fs.chmodSync(targetFile, "755");
|
|
}
|
|
|
|
logger.info(
|
|
`Successfully saved stdio integration: ${integration.slug} to ${targetFile}`,
|
|
);
|
|
} else {
|
|
// Treat as local file path
|
|
const sourcePath = path.isAbsolute(urlOrPath)
|
|
? urlOrPath
|
|
: path.join(process.cwd(), urlOrPath);
|
|
|
|
logger.info(`Copying content from local path: ${sourcePath}`);
|
|
|
|
if (!fs.existsSync(sourcePath)) {
|
|
logger.error(`Source file does not exist: ${sourcePath}`);
|
|
continue;
|
|
}
|
|
|
|
fs.copyFileSync(sourcePath, targetFile);
|
|
|
|
// Make the file executable if it's a script
|
|
if (process.platform !== "win32") {
|
|
fs.chmodSync(targetFile, "755");
|
|
}
|
|
|
|
logger.info(
|
|
`Successfully copied stdio integration: ${integration.slug} to ${targetFile}`,
|
|
);
|
|
}
|
|
} else {
|
|
logger.debug(
|
|
`Skipping integration ${integration.slug}: not a stdio type or missing URL`,
|
|
);
|
|
}
|
|
} catch (error) {
|
|
logger.error(`Error processing integration ${integration.slug}:`, {
|
|
error,
|
|
});
|
|
}
|
|
}
|
|
|
|
logger.info("Completed stdio integrations fetch and save process");
|
|
} catch (error) {
|
|
logger.error("Failed to fetch and save stdio integrations:", { error });
|
|
throw error;
|
|
}
|
|
};
|