fix(client,testing,build): improve TypeScript compatibility for DNS client parsing and test suite

This commit is contained in:
2026-04-30 12:48:49 +00:00
parent 510801b109
commit 199dfe7ba3
18 changed files with 1944 additions and 3435 deletions
+27 -19
View File
@@ -1,6 +1,6 @@
import * as plugins from '../ts_server/plugins.js';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import { tapNodeTools } from '@git.zone/tstest/tapbundle_serverside';
import { TapNodeTools } from '@git.zone/tstest/tapbundle_serverside';
import { execSync } from 'child_process';
import * as dnsPacket from 'dns-packet';
@@ -12,6 +12,8 @@ import * as os from 'os';
import * as smartdns from '../ts_server/index.js';
const tapNodeTools = new TapNodeTools(tap);
// Generate a real self-signed certificate using OpenSSL
function generateSelfSignedCert() {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cert-'));
@@ -48,7 +50,7 @@ function generateSelfSignedCert() {
}
// Cache the generated certificate for performance
let cachedCert = null;
let cachedCert: { key: string; cert: string } | null = null;
// Helper function to get certificate
function getTestCertificate() {
@@ -108,7 +110,7 @@ const acmeClientMock = {
},
forge: {
createCsr({commonName, altNames}) {
createCsr({ commonName, altNames }: { commonName: string; altNames: string[] }) {
return Promise.resolve({
csr: Buffer.from('mock-csr-data')
});
@@ -125,7 +127,7 @@ const acmeClientMock = {
// Override generateKeyPairSync to use our test key for certificate generation in tests
const originalGenerateKeyPairSync = plugins.crypto.generateKeyPairSync;
plugins.crypto.generateKeyPairSync = function(type, options) {
(plugins.crypto.generateKeyPairSync as any) = function(this: any, type: string, options?: any) {
if (type === 'rsa' &&
options?.modulusLength === 2048 &&
options?.privateKeyEncoding?.type === 'pkcs8') {
@@ -143,10 +145,10 @@ plugins.crypto.generateKeyPairSync = function(type, options) {
}
// Use the original function for other cases
return originalGenerateKeyPairSync.apply(this, arguments);
return (originalGenerateKeyPairSync as any).apply(this, arguments);
};
let dnsServer: smartdns.DnsServer;
let dnsServer: smartdns.DnsServer | null;
const testCertDir = path.join(process.cwd(), 'test-certs');
// Helper to clean up test certificate directory
@@ -187,7 +189,7 @@ async function stopServer(server: smartdns.DnsServer | null | undefined) {
await Promise.race([stopPromise, timeoutPromise]);
} catch (e) {
console.log('Handled error when stopping server:', e.message || e);
console.log('Handled error when stopping server:', e instanceof Error ? e.message : e);
// Force close if normal stop fails
try {
@@ -202,7 +204,7 @@ async function stopServer(server: smartdns.DnsServer | null | undefined) {
(server as any).udpServer = null;
}
} catch (forceError) {
console.log('Force cleanup error:', forceError.message || forceError);
console.log('Force cleanup error:', forceError instanceof Error ? forceError.message : forceError);
}
}
}
@@ -400,7 +402,7 @@ tap.test('lets query over https', async () => {
const response = await fetch(`https://localhost:${httpsPort}/dns-query`, {
method: 'POST',
body: query,
body: query as unknown as BodyInit,
headers: {
'Content-Type': 'application/dns-message',
}
@@ -411,9 +413,9 @@ tap.test('lets query over https', async () => {
const responseData = await response.arrayBuffer();
const dnsResponse = dnsPacket.decode(Buffer.from(responseData));
console.log(dnsResponse.answers[0]);
console.log(dnsResponse.answers![0]);
expect(dnsResponse.answers[0]).toEqual({
expect(dnsResponse.answers![0]).toEqual({
name: 'dnsly_a.bleu.de',
type: 'A',
class: 'IN',
@@ -494,9 +496,9 @@ tap.test('lets query over udp', async () => {
const dnsResponse = await responsePromise;
console.log(dnsResponse.answers[0]);
console.log(dnsResponse.answers![0]);
expect(dnsResponse.answers[0]).toEqual({
expect(dnsResponse.answers![0]).toEqual({
name: 'dnsly_a.bleu.de',
type: 'A',
class: 'IN',
@@ -674,14 +676,17 @@ tap.test('should reject invalid IP addresses', async () => {
udpBindInterface: 'invalid-ip',
});
let error1 = null;
let error1: Error | null = null;
try {
await dnsServer.start();
} catch (err) {
error1 = err;
error1 = err instanceof Error ? err : new Error(String(err));
}
expect(error1).toBeDefined();
if (!error1) {
throw new Error('Expected invalid UDP bind interface to throw');
}
expect(error1.message).toContain('Invalid UDP bind interface');
// Test invalid HTTPS interface
@@ -694,14 +699,17 @@ tap.test('should reject invalid IP addresses', async () => {
httpsBindInterface: '999.999.999.999',
});
let error2 = null;
let error2: Error | null = null;
try {
await dnsServer.start();
} catch (err) {
error2 = err;
error2 = err instanceof Error ? err : new Error(String(err));
}
expect(error2).toBeDefined();
if (!error2) {
throw new Error('Expected invalid HTTPS bind interface to throw');
}
expect(error2.message).toContain('Invalid HTTPS bind interface');
dnsServer = null;
@@ -740,7 +748,7 @@ tap.test('should work with IPv6 localhost if available', async () => {
await stopServer(dnsServer);
} catch (err) {
console.log('IPv6 binding failed:', err.message);
console.log('IPv6 binding failed:', err instanceof Error ? err.message : err);
await stopServer(dnsServer);
throw err;
}
@@ -771,4 +779,4 @@ tap.test('should stop the server', async () => {
dnsServer = null;
});
export default tap.start();
export default tap.start();