Skip to content

Commit fc687ab

Browse files
authored
Merge pull request #5 from internxt/feat/type-definitions
[_]: chore/type-definitions
2 parents bbba057 + 041d24d commit fc687ab

File tree

4 files changed

+280
-1
lines changed

4 files changed

+280
-1
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
22
"name": "@internxt/scan",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"author": "Kyle Farris <[email protected]> (https://infotechinc.com)",
55
"description": "Use Node JS to scan files on your server with ClamAV's clamscan/clamdscan binary or via TCP to a remote server or local UNIX Domain socket. This is especially useful for scanning uploaded files provided by un-trusted sources.",
66
"main": "index.js",
7+
"types": "types/index.d.ts",
78
"contributors": [
89
"dietervds",
910
"nicolaspeixoto",
@@ -37,6 +38,7 @@
3738
},
3839
"devDependencies": {
3940
"@babel/eslint-parser": "^7.19.1",
41+
"@types/node": "^22.13.8",
4042
"axios": "^1.2.0",
4143
"chai": "^4.4.1",
4244
"chai-as-promised": "^7.1.1",

tsconfig.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2018",
4+
"module": "commonjs",
5+
"allowJs": true,
6+
"declaration": true,
7+
"emitDeclarationOnly": false,
8+
"outDir": "./dist",
9+
"strict": false,
10+
"esModuleInterop": true,
11+
"skipLibCheck": true,
12+
"forceConsistentCasingInFileNames": true
13+
},
14+
"include": [
15+
"index.js",
16+
"lib/**/*.js"
17+
],
18+
"exclude": [
19+
"node_modules"
20+
]
21+
}

types/index.d.ts

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/// <reference types="node" />
2+
3+
import { Socket } from 'dgram';
4+
import { Readable } from 'stream';
5+
6+
declare namespace NodeClam {
7+
interface ClamScanSettings {
8+
/** If true, removes infected files */
9+
removeInfected?: boolean;
10+
/** False: Don't quarantine, Path: Moves files to this place. */
11+
quarantineInfected?: boolean | string;
12+
/** Path to a writeable log file to write scan results into */
13+
scanLog?: string | null;
14+
/** Whether to log info/debug/error msg to the console */
15+
debugMode?: boolean;
16+
/** path to file containing list of files to scan (for scanFiles method) */
17+
fileList?: string | null;
18+
/** If true, deep scan folders recursively */
19+
scanRecursively?: boolean;
20+
clamscan?: {
21+
/** Path to clamscan binary on your server */
22+
path?: string;
23+
/** Path to a custom virus definition database */
24+
db?: string | null;
25+
/** If true, scan archives (ex. zip, rar, tar, dmg, iso, etc...) */
26+
scanArchives?: boolean;
27+
/** If true, this module will consider using the clamscan binary */
28+
active?: boolean;
29+
};
30+
clamdscan?: {
31+
/** Socket file for connecting via TCP */
32+
socket?: string | boolean;
33+
/** IP of host to connect to TCP interface */
34+
host?: string | boolean;
35+
/** Port of host to use when connecting via TCP interface */
36+
port?: number | boolean;
37+
/** Timeout for scanning files */
38+
timeout?: number;
39+
/** Do not fail over to binary-method of scanning */
40+
localFallback?: boolean;
41+
/** Path to the clamdscan binary on your server */
42+
path?: string;
43+
/** Specify config file if it's in an unusual place */
44+
configFile?: string | null;
45+
/** Scan using all available cores! Yay! */
46+
multiscan?: boolean;
47+
/** If true, will re-load the DB on every call (slow) */
48+
reloadDb?: boolean;
49+
/** If true, this module will consider using the clamdscan binary */
50+
active?: boolean;
51+
/** Check to see if socket is available when applicable */
52+
bypassTest?: boolean;
53+
/** If true, connect to a TLS-Termination proxy in front of ClamAV */
54+
tls?: boolean;
55+
};
56+
/** If clamdscan is found and active, it will be used by default */
57+
preference?: any;
58+
}
59+
60+
interface ScanResult {
61+
file: string;
62+
isInfected: boolean;
63+
viruses: string[];
64+
resultString?: string;
65+
timeout?: boolean;
66+
}
67+
68+
interface ScanFileResult extends ScanResult {
69+
viruses: string[];
70+
file: string;
71+
isInfected: boolean;
72+
}
73+
74+
interface FileScanResult {
75+
[filePath: string]: {
76+
isInfected: boolean;
77+
viruses: string[];
78+
};
79+
}
80+
81+
interface ScanDirResult {
82+
path: string;
83+
isInfected: boolean;
84+
goodFiles: string[];
85+
goodFileCount: number;
86+
infectedFiles: FileScanResult;
87+
infectedFileCount: number;
88+
error: Error | null;
89+
errorFiles: string[];
90+
errorFileCount: number;
91+
files: FileScanResult;
92+
fileCount: number;
93+
}
94+
95+
interface ScanBufferResult extends ScanResult {
96+
isInfected: boolean;
97+
viruses: string[];
98+
}
99+
100+
interface ScanStreamResult extends ScanResult {
101+
isInfected: boolean;
102+
viruses: string[];
103+
}
104+
105+
// Create a union type that combines ClamScanner and NodeClam functionality
106+
interface ClamScanner {
107+
scanFile: (filePath: string) => Promise<ScanFileResult>;
108+
scanDir: (
109+
directoryPath: string,
110+
endCallback?: (err: Error | null, goodFiles?: string[], badFiles?: string[], viruses?: string[]) => void,
111+
fileCallback?: (err: Error | null, file?: string, isInfected?: boolean, viruses?: string[], scannedCount?: number, progress?: string) => void
112+
) => Promise<ScanDirResult>;
113+
scanFiles: (
114+
files: string[] | string,
115+
endCallback?: (err: Error | null, goodFiles?: string[], badFiles?: string[], errors?: object, viruses?: string[]) => void,
116+
fileCallback?: (err: Error | null, file?: string, isInfected?: boolean, viruses?: string[], scannedCount?: number, progress?: string) => void
117+
) => Promise<{goodFiles: string[], badFiles: string[], errors: object, viruses: string[]}>;
118+
scanStream: (stream: Readable) => Promise<ScanStreamResult>;
119+
getVersion: (cb?: (err: Error | null, version: string) => void) => Promise<string>;
120+
isInfected: (file: string) => Promise<ScanFileResult>;
121+
passthrough: () => ClamScanner;
122+
/**
123+
* Closes all active socket connections tracked by the scanner
124+
* @returns A promise that resolves when all sockets have been closed
125+
*/
126+
closeAllSockets: () => Promise<string>;
127+
128+
/**
129+
* Quick check to see if the remote/local socket is working
130+
* @param cb - Optional callback function to handle the result
131+
* @returns A Promise that resolves with a Socket client instance
132+
*/
133+
ping: (cb?: (err: Error | null, client: Socket | null) => void) => Promise<Socket>;
134+
135+
/**
136+
* Initialize the NodeClam instance
137+
* @param settings - Configuration settings
138+
* @param cb - Optional callback function
139+
* @returns The initialized NodeClam instance
140+
*/
141+
init: (settings?: ClamScanSettings, cb?: (err: Error | null, instance: any) => void) => Promise<ClamScanner>;
142+
143+
/**
144+
* Reset and reinitialize the NodeClam instance with new options
145+
* @param options - New configuration settings
146+
* @param cb - Optional callback function
147+
* @returns The reset NodeClam instance
148+
*/
149+
reset: (options?: ClamScanSettings, cb?: (err: Error | null, instance: any) => void) => Promise<ClamScanner>;
150+
}
151+
}
152+
153+
declare class NodeClam {
154+
/**
155+
* Initialize the NodeClam instance
156+
* @param settings - Configuration settings
157+
* @param cb - Optional callback function
158+
* @returns The initialized NodeClam instance with all scanning capabilities
159+
*/
160+
init(settings?: NodeClam.ClamScanSettings, cb?: (err: Error | null, instance: NodeClam) => void): Promise<NodeClam.ClamScanner>;
161+
162+
/**
163+
* Reset and reinitialize the NodeClam instance with new options
164+
* @param options - New configuration settings
165+
* @param cb - Optional callback function
166+
* @returns The reset NodeClam instance
167+
*/
168+
reset(options?: NodeClam.ClamScanSettings, cb?: (err: Error | null, instance: NodeClam) => void): Promise<NodeClam.ClamScanner>;
169+
170+
/**
171+
* Scan a file for viruses
172+
* @param filePath - The path to the file to be scanned
173+
* @returns Scan results
174+
*/
175+
scanFile(filePath: string): Promise<NodeClam.ScanFileResult>;
176+
177+
/**
178+
* Scan a directory for viruses
179+
* @param directoryPath - The path to the directory to be scanned
180+
* @param endCallback - Optional callback function for when scanning is complete
181+
* @param fileCallback - Optional callback function for each scanned file
182+
* @returns Scan results
183+
*/
184+
scanDir(
185+
directoryPath: string,
186+
endCallback?: (err: Error | null, goodFiles?: string[], badFiles?: string[], viruses?: string[]) => void,
187+
fileCallback?: (err: Error | null, file?: string, isInfected?: boolean, viruses?: string[], scannedCount?: number, progress?: string) => void
188+
): Promise<NodeClam.ScanDirResult>;
189+
190+
/**
191+
* Scan multiple files for viruses
192+
* @param files - Array of file paths to scan
193+
* @param endCallback - Optional callback function for when scanning is complete
194+
* @param fileCallback - Optional callback function for each scanned file
195+
* @returns Scan results
196+
*/
197+
scanFiles(
198+
files: string[] | string,
199+
endCallback?: (err: Error | null, goodFiles?: string[], badFiles?: string[], errors?: object, viruses?: string[]) => void,
200+
fileCallback?: (err: Error | null, file?: string, isInfected?: boolean, viruses?: string[], scannedCount?: number, progress?: string) => void
201+
): Promise<{goodFiles: string[], badFiles: string[], errors: object, viruses: string[]}>;
202+
203+
/**
204+
* Scan a stream for viruses
205+
* @param stream - The readable stream to be scanned
206+
* @returns Scan results
207+
*/
208+
scanStream(stream: Readable): Promise<NodeClam.ScanStreamResult>;
209+
210+
/**
211+
* Get the version information
212+
* @param cb - Optional callback function
213+
* @returns Version information
214+
*/
215+
getVersion(cb?: (err: Error | null, version: string) => void): Promise<string>;
216+
217+
/**
218+
* Check if a file is infected
219+
* @param file - Path to the file to check
220+
* @returns Scan results
221+
*/
222+
isInfected(file: string): Promise<NodeClam.ScanFileResult>;
223+
224+
/**
225+
* Quick check to see if the remote/local socket is working
226+
* @param cb - Optional callback function
227+
* @returns A Promise that resolves with a Socket client instance
228+
*/
229+
ping(cb?: (err: Error | null, client: Socket | null) => void): Promise<Socket>;
230+
231+
/**
232+
* Passthrough method to directly access the raw scanner
233+
* @returns The raw scanner object
234+
*/
235+
passthrough(): NodeClam.ClamScanner;
236+
237+
/**
238+
* Closes all active socket connections tracked by the scanner
239+
* @returns A promise that resolves when all sockets have been closed
240+
*/
241+
closeAllSockets(): Promise<string>;
242+
}
243+
244+
export = NodeClam;

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@
164164
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd"
165165
integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==
166166

167+
"@types/node@^22.13.8":
168+
version "22.13.8"
169+
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.8.tgz#57e2450295b33a6518d6fd4f65f47236d3e41d8d"
170+
integrity sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==
171+
dependencies:
172+
undici-types "~6.20.0"
173+
167174
"@ungap/structured-clone@^1.2.0":
168175
version "1.2.1"
169176
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.1.tgz#28fa185f67daaf7b7a1a8c1d445132c5d979f8bd"
@@ -2543,6 +2550,11 @@ underscore@~1.13.2:
25432550
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.7.tgz#970e33963af9a7dda228f17ebe8399e5fbe63a10"
25442551
integrity sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==
25452552

2553+
undici-types@~6.20.0:
2554+
version "6.20.0"
2555+
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
2556+
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
2557+
25462558
uri-js@^4.2.2:
25472559
version "4.4.1"
25482560
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"

0 commit comments

Comments
 (0)