mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
import ts from 'typescript-api'
|
|
import { literalString, propertyName, unwrap } from './static-module-specifiers.mjs'
|
|
|
|
const INDIRECT_NAME =
|
|
/^(?:readFile\w*|readdir\w*|glob(?:Sync|Stream|Iterate|SyncIterate|StreamSync)?|spawn(?:Sync)?|execFile(?:Sync)?|execSync|runProcess\w*|fork|Worker|createRequire|getBuiltinModule|create(?:Incremental|Watch|EmitAndSemanticDiagnosticsBuilder|SemanticDiagnosticsBuilder)?Program|createSolutionBuilder(?:WithWatch)?|createLanguageService|getParsedCommandLineOfConfigFile|parseJson(?:SourceFile)?ConfigFileContent|readConfigFile|resolveModuleName|resolveTypeReferenceDirective|readDirectory|eval|Function)$/
|
|
const INDIRECT_CANDIDATE = new RegExp(
|
|
`\\b${INDIRECT_NAME.source.slice(1, -1)}\\b|\\b(?:import|require)\\s*\\(|\\bURL\\b`
|
|
)
|
|
const INDIRECT_MODULES = new Set([
|
|
'fs',
|
|
'node:fs',
|
|
'fs/promises',
|
|
'node:fs/promises',
|
|
'module',
|
|
'node:module',
|
|
'child_process',
|
|
'node:child_process',
|
|
'worker_threads',
|
|
'node:worker_threads',
|
|
'vm',
|
|
'node:vm',
|
|
'glob',
|
|
'fast-glob',
|
|
'globby',
|
|
'tinyglobby'
|
|
])
|
|
|
|
export function hasIndirectUnitInputs(file, contents, imports) {
|
|
if (file.endsWith('.json')) {
|
|
return false
|
|
}
|
|
if (imports.some(({ fileName }) => INDIRECT_MODULES.has(fileName))) {
|
|
return true
|
|
}
|
|
if (!INDIRECT_CANDIDATE.test(contents)) {
|
|
return false
|
|
}
|
|
const source = ts.createSourceFile(file, contents, ts.ScriptTarget.Latest, false)
|
|
if (source.parseDiagnostics.length > 0) {
|
|
return true
|
|
}
|
|
function visit(node) {
|
|
if (
|
|
ts.isTypeNode(node) ||
|
|
ts.isInterfaceDeclaration(node) ||
|
|
ts.isTypeAliasDeclaration(node) ||
|
|
((ts.isImportClause(node) ||
|
|
ts.isImportSpecifier(node) ||
|
|
ts.isExportDeclaration(node) ||
|
|
ts.isExportSpecifier(node)) &&
|
|
node.isTypeOnly)
|
|
) {
|
|
return false
|
|
}
|
|
if (ts.isIdentifier(node) && INDIRECT_NAME.test(node.text)) {
|
|
return true
|
|
}
|
|
if (ts.isElementAccessExpression(node) && INDIRECT_NAME.test(propertyName(node) ?? '')) {
|
|
return true
|
|
}
|
|
if (ts.isCallExpression(node)) {
|
|
const callee = unwrap(node.expression)
|
|
if (
|
|
(callee.kind === ts.SyntaxKind.ImportKeyword ||
|
|
(ts.isIdentifier(callee) && callee.text === 'require')) &&
|
|
literalString(node.arguments[0]) === null
|
|
) {
|
|
return true
|
|
}
|
|
}
|
|
if (
|
|
ts.isNewExpression(node) &&
|
|
ts.isIdentifier(node.expression) &&
|
|
node.expression.text === 'URL'
|
|
) {
|
|
const url = literalString(node.arguments?.[0])
|
|
if (url === null || !/^(?:https?|wss?):/.test(url)) {
|
|
return true
|
|
}
|
|
}
|
|
return ts.forEachChild(node, visit) ?? false
|
|
}
|
|
return visit(source)
|
|
}
|