Skip to content

Commit 9e32854

Browse files
committed
chore: fix lint and compile errors
1 parent 891d409 commit 9e32854

9 files changed

Lines changed: 1375 additions & 76 deletions

File tree

package-lock.json

Lines changed: 1306 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"dev": "tsx src/index.ts",
88
"start": "node dist/src",
99
"test": "c8 tsx --test tests/basic.ts",
10-
"build:ui": "esbuild --bundle src/modules/http-gui/frontend/index.tsx --outfile=src/modules/http-gui/frontend/dist/index.min.js --loader:.ts=ts --loader:.tsx=tsx && cp src/modules/http-gui/frontend/index.html src/modules/http-gui/frontend/dist"
10+
"build": "tsc",
11+
"build:ui": "esbuild --bundle src/modules/http-gui/frontend/index.tsx --outfile=src/modules/http-gui/frontend/dist/index.min.js --loader:.ts=ts --loader:.tsx=tsx && cp src/modules/http-gui/frontend/index.html src/modules/http-gui/frontend/dist",
12+
"lint": "eslint"
1113
},
1214
"keywords": [],
1315
"author": {
@@ -25,11 +27,17 @@
2527
"uuid": "^10.0.0"
2628
},
2729
"devDependencies": {
30+
"@eslint/js": "^9.8.0",
31+
"@types/mime-types": "^2.1.4",
2832
"@types/node": "^20.14.12",
33+
"@types/uuid": "^10.0.0",
2934
"c8": "^10.1.2",
3035
"esbuild": "^0.23.0",
36+
"eslint": "^9.8.0",
37+
"globals": "^15.9.0",
3138
"test": "^3.3.0",
3239
"tsx": "^4.16.2",
33-
"typescript": "^5.5.4"
40+
"typescript": "^5.5.4",
41+
"typescript-eslint": "^8.0.0"
3442
}
3543
}

src/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export type Context = {
5858
/** JetStream client */
5959
js: JetStreamClient;
6060
}
61-
/** Array of cleanup functions */
61+
/** Functions added to this array will be executed when the server is closed */
6262
cleanups: Array<() => Promise<void>>;
6363
}
6464

@@ -88,7 +88,7 @@ export function createContext (config: Config): Context {
8888
systemCollections: {
8989
collections: []
9090
},
91-
// @ts-ignore
91+
// @ts-expect-error TS2739
9292
jetStream : {},
9393
cleanups: []
9494
};

src/modules/events/applyEvent.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Context, Event, Collection } from "../../context.js";
1+
import { Context, Event } from "../../context.js";
22

33
export function applyEvent(context : Context, event: Event) {
4-
const { inMemoryDB, systemCollections } = context;
4+
const { inMemoryDB } = context;
55

66
const { eventType, collection, documentId, payload } = event;
77
if (!inMemoryDB[collection]) {

src/modules/http-api/setup.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,49 @@ export default async function setupHttpApi(context: Context) {
1111
cert: await fs.readFile(config.tls.cert)
1212
};
1313

14-
const server = https.createServer(options, async (req, res) => {
15-
if (!req.url) {
16-
res.writeHead(400, { 'Content-Type': 'application/json' });
17-
res.end(JSON.stringify({ error: 'Invalid URL' }));
14+
const server = https.createServer(options, async (request, response) => {
15+
if (!request.url) {
16+
response.writeHead(400, { 'Content-Type': 'application/json' });
17+
response.end(JSON.stringify({ error: 'Invalid URL' }));
1818
return;
1919
}
2020

21-
const parsedUrl = url.parse(req.url, true);
21+
const parsedUrl = url.parse(request.url, true);
2222
if (!parsedUrl.pathname) {
23-
res.writeHead(400, { 'Content-Type': 'application/json' });
24-
res.end(JSON.stringify({ error: 'Invalid pathname' }));
23+
response.writeHead(400, { 'Content-Type': 'application/json' });
24+
response.end(JSON.stringify({ error: 'Invalid pathname' }));
2525
return;
2626
}
2727

2828
const path = parsedUrl.pathname.split('/').filter(Boolean);
2929
const [collection, documentId] = path;
3030

3131
if (!collection) {
32-
res.writeHead(400, { 'Content-Type': 'application/json' });
33-
res.end(JSON.stringify({ error: 'Collection name is required' }));
32+
response.writeHead(400, { 'Content-Type': 'application/json' });
33+
response.end(JSON.stringify({ error: 'Collection name is required' }));
3434
return;
3535
}
3636

3737
let body = '';
38-
req.on('data', chunk => {
38+
request.on('data', chunk => {
3939
body += chunk.toString();
4040
});
4141

42-
req.on('end', async () => {
42+
request.on('end', async () => {
4343
try {
4444
const payload = body ? JSON.parse(body) : null;
4545

46-
if ((req.method === 'PUT' || req.method === 'PATCH') && payload && 'id' in payload) {
46+
if ((request.method === 'PUT' || request.method === 'PATCH') && payload && 'id' in payload) {
4747
delete payload.id;
4848
}
4949

50-
const result = await handleDatabaseOperation(context, config.jetstream.streamName, req.method || 'GET', collection, documentId, payload);
51-
res.writeHead(200, { 'Content-Type': 'application/json' });
52-
res.end(JSON.stringify(result));
50+
const result = await handleDatabaseOperation(context, config.jetstream.streamName, request.method || 'GET', collection, documentId, payload);
51+
response.writeHead(200, { 'Content-Type': 'application/json' });
52+
response.end(JSON.stringify(result));
5353
} catch (error) {
5454
console.error('Error:', error);
55-
res.writeHead(500, { 'Content-Type': 'application/json' });
56-
res.end(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }));
55+
response.writeHead(500, { 'Content-Type': 'application/json' });
56+
response.end(JSON.stringify({ error: error instanceof Error ? error.message : 'Unknown error' }));
5757
}
5858
});
5959
});

src/modules/http-gui/frontend/App.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { useState, useEffect } from 'react';
22

33
function App() {
4-
const [darkMode, setDarkMode] = useState(false);
54
const [collection, setCollection] = useState('');
65
const [documentId, setDocumentId] = useState('');
76
const [queryResult, setQueryResult] = useState(null);

src/modules/http-gui/setup.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import https from 'node:https';
22
import fs from 'node:fs/promises';
33
import path from 'node:path';
4-
import { Context } from "../../context.js";
54
import mime from 'mime-types';
5+
import { Context } from '../../context.js';
66

77
export default async function setupHttpGui(context: Context) {
88
const { config } = context;
@@ -13,36 +13,36 @@ export default async function setupHttpGui(context: Context) {
1313

1414
const staticDir = path.join(import.meta.dirname, 'frontend/dist');
1515

16-
const server = https.createServer(options, async (req, res) => {
17-
if (req.url?.startsWith('/api/')) {
16+
const server = https.createServer(options, async (request, response) => {
17+
if (request.url?.startsWith('/api/')) {
1818
// Proxy request to the API server
1919
const apiReq = https.request({
2020
hostname: 'localhost',
2121
port: config.ports.gui,
22-
path: req.url.replace('/api', ''),
23-
method: req.method,
24-
headers: req.headers,
22+
path: request.url.replace('/api', ''),
23+
method: request.method,
24+
headers: request.headers,
2525
rejectUnauthorized: false // Only for development, remove in production
2626
}, (apiRes) => {
27-
res.writeHead(apiRes.statusCode || 500, apiRes.headers);
28-
apiRes.pipe(res);
27+
response.writeHead(apiRes.statusCode || 500, apiRes.headers);
28+
apiRes.pipe(response);
2929
});
3030

3131
apiReq.on('error', (error) => {
3232
console.error('Error proxying to API:', error);
33-
res.writeHead(500, { 'Content-Type': 'text/plain' });
34-
res.end('Internal Server Error');
33+
response.writeHead(500, { 'Content-Type': 'text/plain' });
34+
response.end('Internal Server Error');
3535
});
3636

37-
req.pipe(apiReq);
37+
request.pipe(apiReq);
3838
} else {
3939
try {
4040
let filePath;
41-
if (req.url === '/' || req.url === '/index.html') {
41+
if (request.url === '/' || request.url === '/index.html') {
4242
filePath = path.join(staticDir, 'index.html');
4343
} else {
4444
// Normalize the path to prevent directory traversal
45-
const normalizedPath = path.normalize(req.url || '').replace(/^(\.\.[\/\\])+/, '');
45+
const normalizedPath = path.normalize(request.url || '').replace(/^(\.\.[/\\])+/, '');
4646
filePath = path.join(staticDir, normalizedPath);
4747
}
4848

@@ -58,16 +58,16 @@ export default async function setupHttpGui(context: Context) {
5858

5959
const content = await fs.readFile(filePath);
6060
const contentType = mime.lookup(filePath) || 'application/octet-stream';
61-
res.writeHead(200, { 'Content-Type': contentType });
62-
res.end(content);
63-
} catch (error) {
61+
response.writeHead(200, { 'Content-Type': contentType });
62+
response.end(content);
63+
} catch (error: any) {
6464
console.error('Error serving file:', error);
6565
if (error.code === 'ENOENT') {
66-
res.writeHead(404, { 'Content-Type': 'text/plain' });
67-
res.end('Not Found');
66+
response.writeHead(404, { 'Content-Type': 'text/plain' });
67+
response.end('Not Found');
6868
} else {
69-
res.writeHead(500, { 'Content-Type': 'text/plain' });
70-
res.end('Internal Server Error');
69+
response.writeHead(500, { 'Content-Type': 'text/plain' });
70+
response.end('Internal Server Error');
7171
}
7272
}
7373
}

tests/basic.ts

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,21 @@ interface Response {
2323

2424
async function makeRequest(options: RequestOptions, data: any = null): Promise<Response> {
2525
const url = `https://${options.hostname}:${options.port}${options.path}`;
26-
const fetchOptions: any = {
26+
const fetchOptions: RequestInit = { // Changed from any to RequestInit
27+
method: options.method, // Explicitly set the method
2728
headers: {
2829
'Content-Type': 'application/json'
2930
},
3031
body: data ? JSON.stringify(data) : undefined,
31-
...options
3232
};
3333

34-
try {
35-
const res = await fetch(url, fetchOptions);
36-
const responseBody = await res.json();
37-
return {
38-
statusCode: res.status,
39-
headers: res.headers,
40-
body: responseBody
41-
};
42-
} catch (error) {
43-
// console.log(error);
44-
throw error;
45-
}
34+
const response = await fetch(url, fetchOptions);
35+
const responseBody = await response.json();
36+
return {
37+
statusCode: response.status,
38+
headers: response.headers as Headers,
39+
body: responseBody
40+
};
4641
}
4742

4843
const testConfig: Config = {
@@ -81,8 +76,7 @@ describe('CanhazDB Server Tests', async () => {
8176
hostname: 'localhost',
8277
port: 3000,
8378
path: '/users',
84-
method: 'POST',
85-
rejectUnauthorized: false
79+
method: 'POST'
8680
}, { name: 'John Doe', age: 30 });
8781

8882
assert.equal(response.statusCode, 200);
@@ -97,8 +91,7 @@ describe('CanhazDB Server Tests', async () => {
9791
hostname: 'localhost',
9892
port: 3000,
9993
path: '/users',
100-
method: 'POST',
101-
rejectUnauthorized: false
94+
method: 'POST'
10295
}, { name: 'Jane Doe', age: 25 });
10396

10497
const documentId = createResponse.body.documentId;
@@ -144,8 +137,7 @@ describe('CanhazDB Server Tests', async () => {
144137
hostname: 'localhost',
145138
port: 3000,
146139
path: `/users/${documentId}`,
147-
method: 'GET',
148-
rejectUnauthorized: false
140+
method: 'GET'
149141
});
150142

151143
assert.equal(getResponse.body.name, 'Bob Smith');
@@ -158,8 +150,7 @@ describe('CanhazDB Server Tests', async () => {
158150
hostname: 'localhost',
159151
port: 3000,
160152
path: '/users',
161-
method: 'POST',
162-
rejectUnauthorized: false
153+
method: 'POST'
163154
}, { name: 'Alice Johnson', age: 35 });
164155

165156
const documentId = createResponse.body.documentId;
@@ -169,8 +160,7 @@ describe('CanhazDB Server Tests', async () => {
169160
hostname: 'localhost',
170161
port: 3000,
171162
path: `/users/${documentId}`,
172-
method: 'DELETE',
173-
rejectUnauthorized: false
163+
method: 'DELETE'
174164
});
175165

176166
assert.equal(response.statusCode, 200);
@@ -182,8 +172,7 @@ describe('CanhazDB Server Tests', async () => {
182172
hostname: 'localhost',
183173
port: 3000,
184174
path: `/users/${documentId}`,
185-
method: 'GET',
186-
rejectUnauthorized: false
175+
method: 'GET'
187176
});
188177

189178
assert.deepEqual(getResponse.body, { error: 'Document not found' });
@@ -237,8 +226,7 @@ describe('CanhazDB Server Tests', async () => {
237226
hostname: 'localhost',
238227
port: 3000,
239228
path: '',
240-
method: 'GET',
241-
rejectUnauthorized: false
229+
method: 'GET'
242230
});
243231
assert.equal(response.statusCode, 400);
244232
assert.equal(response.body.error, 'Collection name is required');
@@ -249,8 +237,7 @@ describe('CanhazDB Server Tests', async () => {
249237
hostname: 'localhost',
250238
port: 3000,
251239
path: '/',
252-
method: 'GET',
253-
rejectUnauthorized: false
240+
method: 'GET'
254241
});
255242
assert.equal(response.statusCode, 400);
256243
assert.equal(response.body.error, 'Collection name is required');

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
"checkJs": true
2121
},
2222
"include": ["tests/**/*", "src/**/*"],
23-
"exclude": ["node_modules", "dist"]
23+
"exclude": ["node_modules", "dist", "src/modules/http-gui/frontend/**/*"]
2424
}

0 commit comments

Comments
 (0)