Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions backend/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { readdir, readFile, writeFile, mkdir } from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';

const nodeDir = dirname(process.execPath);
const tsPath = resolve(nodeDir, '..', 'lib', 'node_modules', 'typescript', 'lib', 'typescript.js');
const ts = await import(tsPath);

async function getFiles(dir) {
const entries = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(entries.map(async (entry) => {
const res = path.join(dir, entry.name);
return entry.isDirectory() ? await getFiles(res) : res;
}));
return files.flat();
}

const srcFiles = await getFiles('src');
const testFiles = await getFiles('test');
const allFiles = srcFiles.concat(testFiles).filter((f) => f.endsWith('.ts'));

for (const file of allFiles) {
const source = await readFile(file, 'utf8');
const { outputText } = ts.transpileModule(source, {
compilerOptions: {
module: ts.ModuleKind.ESNext,
target: ts.ScriptTarget.ESNext,
esModuleInterop: true,
},
fileName: file,
});
const outPath = path.join('dist', file.replace(/\.ts$/, '.js'));
await mkdir(path.dirname(outPath), { recursive: true });
await writeFile(outPath, outputText);
}
4 changes: 4 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"module": "index.ts",
"type": "module",
"private": true,
"scripts": {
"build": "node build.mjs",
"test": "npm run build && node --test \"dist/test/**/*.js\""
},
"devDependencies": {
"@types/bun": "latest",
"@types/express": "^5.0.2"
Expand Down
9 changes: 6 additions & 3 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ app.use("/containers", containerRoutes);
app.use("/chat", chatRoutes);

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Docker Container API running on port ${PORT}`);
});

if (process.env.NODE_ENV !== "test") {
app.listen(PORT, () => {
console.log(`Docker Container API running on port ${PORT}`);
});
}

export default app;
27 changes: 27 additions & 0 deletions backend/test/chat.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import test from 'node:test';
import assert from 'node:assert/strict';

process.env.NODE_ENV = 'test';
const { default: app } = await import('../src/index.js');

function getPort(server: any): number {
const address = server.address();
if (typeof address === 'string' || !address) {
throw new Error('Invalid server address');
}
return address.port;
}

test('GET /chat/:id/messages returns session data', async (t) => {
const server = app.listen(0);
t.after(() => server.close());
const port = getPort(server);

const response = await fetch(`http://localhost:${port}/chat/test/messages`);
const body = await response.json();

assert.equal(response.status, 200);
assert.equal(body.success, true);
assert.ok(Array.isArray(body.messages));
assert.equal(typeof body.sessionId, 'string');
});
8 changes: 8 additions & 0 deletions backend/test/docker.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { getDockerfile } from '../src/services/docker.js';

test('getDockerfile reads Dockerfile content', async () => {
const content = await getDockerfile();
assert.ok(content.includes('FROM node:18-alpine'));
});