Files FIles Files

This commit is contained in:
2026-02-20 04:28:02 +00:00
parent 1f7eb64eb3
commit d7503ca56b
20 changed files with 2195 additions and 633 deletions
+33 -8
View File
@@ -2,7 +2,7 @@ import { readdir, mkdir } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { createRouter } from '../../create-router';
import { getResourcesDir } from '../../data-path';
import { DATA_PATH, getResourcesDir } from '../../data-path';
type ResourceCredentials = {
apiKey?: string;
@@ -10,7 +10,7 @@ type ResourceCredentials = {
password?: string;
};
type ResourceConnectionConfig = {
export type ResourceConnectionConfig = {
url: string;
credentials?: ResourceCredentials;
};
@@ -37,6 +37,10 @@ type Resource = {
const stripBackticks = (value: string) => value.replace(/^`(.+)`$/, '$1');
const resolveCommand = (command: string): string => {
return command.replace(/\$DATA_PATH/g, DATA_PATH);
};
function parseResourceFile(
filename: string,
content: string,
@@ -70,11 +74,11 @@ function parseResourceFile(
port,
path: rawPath ? stripBackticks(rawPath) : null,
description: field('Description') ?? '',
installCommand: field('Install') ? stripBackticks(field('Install')!) : null,
uninstallCommand: field('Uninstall') ? stripBackticks(field('Uninstall')!) : null,
manageCommand: field('Manage') ? stripBackticks(field('Manage')!) : null,
verifyCommand: field('Verify') ? stripBackticks(field('Verify')!) : null,
updateCommand: field('Update') ? stripBackticks(field('Update')!) : null,
installCommand: field('Install') ? resolveCommand(stripBackticks(field('Install')!)) : null,
uninstallCommand: field('Uninstall') ? resolveCommand(stripBackticks(field('Uninstall')!)) : null,
manageCommand: field('Manage') ? resolveCommand(stripBackticks(field('Manage')!)) : null,
verifyCommand: field('Verify') ? resolveCommand(stripBackticks(field('Verify')!)) : null,
updateCommand: field('Update') ? resolveCommand(stripBackticks(field('Update')!)) : null,
};
}
@@ -82,7 +86,7 @@ const CONFIG_FILENAME = 'resources-config.json';
const getConfigPath = () => join(getResourcesDir(), CONFIG_FILENAME);
async function readConfig(): Promise<ResourcesConfig> {
export async function readConfig(): Promise<ResourcesConfig> {
const path = getConfigPath();
if (!existsSync(path)) return {};
const text = await Bun.file(path).text();
@@ -265,6 +269,27 @@ resourcesRouter.post('/:id/ping', async (ctx) => {
}
});
resourcesRouter.post('/error-log', async (ctx) => {
const body = await ctx.req.json<{ command: string; output: string; exitCode: number }>();
const timestamp = Date.now();
const filePath = `/tmp/officer-error-${timestamp}.md`;
const md = [
`# Command Failed (exit code ${body.exitCode})`,
'',
'```',
body.command,
'```',
'',
'## Output',
'',
'```',
body.output,
'```',
].join('\n');
await Bun.write(filePath, md);
return ctx.json({ filePath });
});
resourcesRouter.get('/:id', async (ctx) => {
const resources = await loadResources();
const resource = resources.find((r) => r.id === ctx.req.param('id'));