|
import { Scanner, ScannerComponent } from 'scanoss'; |
|
|
|
interface ScanOSSScanner{ |
|
scanContents: <T extends string>(options: { content: string; key: T}) => Promise<{[K in `/${T}`]: ScannerComponent[]} | null>; |
|
} |
|
|
|
export interface ScanOSSResultClean { |
|
type: 'clean'; |
|
} |
|
export interface ScanOSSResultMatch { |
|
type: 'match'; |
|
matched: string; // e.g. "75%" |
|
url: string; // e.g. a Github link |
|
raw: unknown; // treat remaining results as a block box for now |
|
} |
|
export interface ScanOSSResultError { |
|
type: 'error'; |
|
message: string; |
|
} |
|
export type ScanOSSResult = ScanOSSResultClean | ScanOSSResultMatch | ScanOSSResultError; |
|
|
|
async function scanContent(content: string, apiKey?: string): Promise<ScanOSSResult> { |
|
// Partial 'ScannerCfg' does not seem to work, so I need to hand over a full default object? |
|
const scanner = new Scanner(/* { |
|
API_KEY: apiKey || process.env.SCANOSS_API_KEY || undefined, |
|
MAX_RESPONSES_IN_BUFFER: 1, |
|
} as ScannerCfg*/); |
|
// Adjusted type as the real ScanOSS Scanner types return the nested type instead. The type should be adjusted in the library. |
|
const results = await (scanner as unknown as ScanOSSScanner).scanContents({ |
|
content, |
|
key: 'content_scanning', |
|
}); |
|
|
|
// I'm assuming that 'null' means error. Is this correct? What is returned in case limits are exceeded? |
|
if (!results) { |
|
return { |
|
type: 'error', |
|
message: 'ScanOSS request unsuccessful' |
|
}; |
|
} |
|
|
|
// Is the first result always the "best" (i.e. highest match) result? |
|
// I only ever get one result, which is fine, but when to expect more? |
|
const firstEntry = results['/content_scanning'][0]; |
|
// Is this the correct check for no match found? |
|
if (firstEntry.id === 'none') { |
|
return { |
|
type: 'clean' |
|
}; |
|
} |
|
|
|
// Will 'matched' and 'url' always exist? |
|
// Some of the other properties of 'ScannedComponent' seem to be optional although they are not typed as such, e.g. 'dependencies', 'copyrights', 'server.flags' |
|
// Also some of the returned properties are not typed, e.g. 'url_stats' |
|
return { |
|
type: 'match', |
|
matched: firstEntry.matched, |
|
url: firstEntry.url, |
|
raw: firstEntry |
|
}; |
|
} |
|
|
|
|
|
async function main() { |
|
const result = await scanContent( |
|
`// Compare words in given command against known command\n for (int j = 1; j <= limit; j++)\n {\n char *cword = ldb_extract_word(j, command);\n char *kword = ldb_extract_word(j, ldb_commands[i]);\n bool fulfilled = false;\n if (!strcmp(kword, "{hex}")) fulfilled = ldb_valid_hex(cword);\n else if (!strcmp(kword, "{ascii}")) fulfilled = ldb_valid_ascii(cword);\n else if (!strcmp(kword, cword)) fulfilled = true;\n free(cword);\n free(kword);\n\n if (!fulfilled) break;\n else if (j > hits)\n {\n closest = i;\n hits = j;\n *word_nr = hits;\n *command_nr = closest;\n }\n }\n if ((hits > 0) && (hits == known_words)) return true;\n }\n\n return false;` |
|
); |
|
// In the UI I currently highlight 'matched' and 'url' and pretty print the whole remaining result as JSON in a preformatted block |
|
// Is there already a built-in mechanism to get a nicer textual overview? Ideally I would like to avoid printing a raw JSON in the UI with reasonable effort. |
|
console.log(JSON.stringify(result, null, 2)); |
|
} |
|
|
|
main(); |
Hi Stefan, I'll add comments below to your questions:
1 - Partial 'ScannerCfg' does not seem to work, so I need to hand over a full default object?
2 - Adjusted type as the real ScanOSS Scanner types return the nested type instead. The type should be adjusted in the library.
3 - I'm assuming that 'null' means error. Is this correct? What is returned in case limits are exceeded?
4 - Is the first result always the "best" (i.e. highest match) result? I only ever get one result, which is fine, but when to expect more?
5 - Is this the correct check for no match found?
6 - Will 'matched' and 'url' always exist?. Some of the other properties of 'ScannedComponent' seem to be optional although they are not typed as such, e.g. 'dependencies', 'copyrights', 'server.flags'. Also some of the returned properties are not typed, e.g. 'url_stats'
7 - In the UI I currently highlight 'matched' and 'url' and pretty print the whole remaining result as JSON in a preformatted block. Is there already a built-in mechanism to get a nicer textual overview? Ideally I would like to avoid printing a raw JSON in the UI with reasonable effort.