npm / rolldown / 1.2.15

rolldown 1.2.15

Source
https://github.com/rolldown/rolldown
Artifact scanned
rolldown-1.2.15.tgz (npm tarball · 198.3 KB · SHA-256 0f4e689f37f1…)
Compared with
rolldown-1.2.14.tgz (2 signals introduced since)
Files
50 scanned, 2 skipped (binary, oversized, or unrecognised)
Signals
1 critical · 0 warn · 23 info
Scan time
16.2 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 15 of 15 warn and critical signals; 14 demoted to info.
Disclude version
4.3.0
Scanned (UTC)
2026-10-24 00:15

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. critical dynamic-execution dist/utils-index.mjs:2348:9

    `Function(...)` called with a non-literal body (ast pass, confidence 0.75)

    	args.push(body);
    	return new Function(...args);
    }
    const mergers = [
    likely benign LLM, confidence 0.60 A utility that builds a function from a dynamic body string, bundled alongside merger definitions.
    Reasoning

    The snippet shows a helper that pushes a body string onto an args array and calls new Function(...args), followed by a mergers array. That pattern matches a configuration-merging or schema-compilation utility bundled from a dependency rather than a dropper. Dynamic Function construction with a non-literal body is still risky, and the snippet does not show where body comes from, so the call-site input is unverified.

  2. info long-line dist/experimental-index.d.mts:1:1 new in this release

    line length 674 characters (raw pass, confidence 0.50)

    import { $ as resetNativeMemoryStats, B as NapiResolveOptions, E as BindingViteManifestPluginConfig, F as IsolatedDeclarationsResult, G as ResolverFactory, P as IsolatedDeclarationsOptions, Q as moduleRunnerTransform, W as ResolveResult, X as isolatedDeclaration, Y as getNativeMemoryStats, Z as isolatedDeclarationSync,
  3. info warn → info by review long-line dist/index.d.mts:3:1 new in this release

    line length 2504 characters (raw pass, confidence 0.65)

    import { $t as SourceMap, A as ResolvedId, At as ChunkFileNamesFunction, B as ExistingRawSourceMap, Bt as ManglePropertiesOptions, C as ParallelPluginHooks, Ct as RolldownBuild, D as ResolveFileUrlArgs, Dt as AdvancedChunksGroup, E as PluginMeta, Et as AddonFunction, Ft as CommentsOptions, G as EmittedAsset, H as Outpu
    likely benign LLM, confidence 0.97 Generated .d.mts re-export list of type names.
    Reasoning

    A long line in a generated TypeScript declaration file is a re-export list of type names. Long generated export lines are normal for bundler output and show no obfuscation.

  4. line length 847 characters (raw pass, confidence 0.50)

    export { type BindingClientHmrUpdate, type BindingNativeMemoryStats, BindingRebuildStrategy, type DevOptions, type DevWatchOptions, type IsolatedDeclarationsOptions, type IsolatedDeclarationsResult, type NapiResolveOptions as ResolveOptions, type ResolveResult, ResolverFactory, defineParallelPlugin, viteDynamicImportVa
  5. line length 806 characters (raw pass, confidence 0.50)

    export { BindingRebuildStrategy, DevEngine, ResolverFactory, TsconfigCache, bundleAnalyzerPlugin, defineParallelPlugin, dev, viteDynamicImportVarsPlugin as dynamicImportVarsPlugin, viteDynamicImportVarsPlugin, freeExternalMemory, getNativeMemoryStats, viteImportGlobPlugin as importGlobPlugin, viteImportGlobPlugin, isol
  6. info warn → info by review long-line dist/index.d.mts:4:1

    line length 2639 characters (raw pass, confidence 0.65)

    export { type AddonFunction, type AdvancedChunksGroup, type AdvancedChunksOptions, type AsyncPluginHooks, type BufferEncoding, type BuildOptions, type BuiltinModuleTag, type BundleError, type ChecksOptions, type ChunkFileNamesFunction, type ChunkOptimizationOptions, type ChunkingContext, type CodeSplittingGroup, type C
    likely benign LLM, confidence 0.97 Generated .d.mts export statement listing many public types.
    Reasoning

    The line is a long export type list in a generated declaration file, consistent with bundler build output. No encoded or hidden content is present.

  7. info warn → info by review dynamic-import dist/parallel-plugin-worker.mjs:10:36

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    		const plugins = await Promise.all(pluginInfos.map(async (pluginInfo) => {
    			const definePluginImpl = (await import(pluginInfo.fileUrl)).default;
    			const plugin = await definePluginImpl(pluginInfo.options, { threadNumber });
    			return {
    likely benign LLM, confidence 0.85 Worker loads configured plugin modules via dynamic import of their file URLs.
    Reasoning

    Rolldown's parallel plugin worker dynamically imports user plugin modules by their file URL and then calls their define function. Loading configured plugins this way is the documented purpose of the worker, and the snippet shows no decoding or hidden behaviour.

  8. line length 1664 characters (raw pass, confidence 0.50)

    export { resetNativeMemoryStats as $, BindingViteResolvePluginConfig as A, NapiResolveOptions as B, BindingViteDynamicImportVarsPluginConfig as C, BindingViteModulePreloadPolyfillPluginConfig as D, BindingViteManifestPluginConfig as E, IsolatedDeclarationsResult as F, ResolverFactory as G, ParserOptions as H, JsxOption
  9. line length 639 characters (raw pass, confidence 0.50)

    export { LOG_LEVEL_WARN as C, version as D, package_default as E, LOG_LEVEL_INFO as S, VERSION as T, getParallelPluginInfo as _, measureIfFunction as a, LOG_LEVEL_DEBUG as b, PluginContextData as c, transformRenderedChunk as d, __decorate as f, MinimalPluginContextImpl as g, PlainObjectLike as h, measureHookCost as i, 
  10. line length 1611 characters (raw pass, confidence 0.50)

    ENUMERATED_PLUGIN_HOOK_NAMES[0], ENUMERATED_PLUGIN_HOOK_NAMES[0], ENUMERATED_PLUGIN_HOOK_NAMES[1], ENUMERATED_PLUGIN_HOOK_NAMES[1], ENUMERATED_PLUGIN_HOOK_NAMES[2], ENUMERATED_PLUGIN_HOOK_NAMES[2], ENUMERATED_PLUGIN_HOOK_NAMES[3], ENUMERATED_PLUGIN_HOOK_NAMES[3], ENUMERATED_PLUGIN_HOOK_NAMES[4], ENUMERATED_PLUGIN_HOOK_
  11. line length 741 characters (raw pass, confidence 0.50)

    	devtools: /* @__PURE__ */ pipe(/* @__PURE__ */ optional(/* @__PURE__ */ object({ sessionId: /* @__PURE__ */ pipe(/* @__PURE__ */ optional(/* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ check((id) => id !== "" && id !== "." && id !== ".." && !/[/\\\0]/.test(id), "Expected one path segment: not empty, no
  12. info warn → info by review long-line dist/shared/create-bundler-option-DzNR1xQS.mjs:2718:1

    line length 3680 characters (raw pass, confidence 0.65)

    	return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 
    likely benign LLM, confidence 0.95 Long character-code range check, likely a Unicode East Asian width lookup.
    Reasoning

    The line is a chain of integer range comparisons over code points, matching East Asian width tables used for terminal string width. This is ordinary generated lookup code.

  13. info warn → info by review long-line dist/shared/create-bundler-option-DzNR1xQS.mjs:2724:1

    line length 3090 characters (raw pass, confidence 0.65)

    	return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || 
    likely benign LLM, confidence 0.95 Long code-point range check in a character width function.
    Reasoning

    The line is another code point range table, consistent with a wide-character width function for terminal output. The content is data, not executable payload.

  14. info warn → info by review long-line dist/shared/create-bundler-option-DzNR1xQS.mjs:2735:1

    line length 12819 characters (raw pass, confidence 0.65)

    	return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u265
    likely benign LLM, confidence 0.95 Very long emoji-matching regular expression literal.
    Reasoning

    The snippet is a regex built from emoji and symbol code point escapes, used to measure or strip emoji width. Long regex literals of this kind are common in generated Unicode tables and do not execute anything.

  15. line length 522 characters (raw pass, confidence 0.50)

    	const { dir, charset, format, exports, hashCharacters, sourcemap, sourcemapBaseUrl, sourcemapDebugIds, sourcemapFileNames, sourcemapExcludeSources, sourcemapIgnoreList, sourcemapPathTransform, name, assetFileNames, entryFileNames, chunkFileNames, banner, footer, postBanner, postFooter, intro, outro, esModule, globals,
  16. info warn → info by review long-line dist/shared/define-config-BoIay7tU.d.mts:4154:1

    line length 2593 characters (raw pass, confidence 0.65)

    export { defineParallelPlugin as $, SourceMap as $t, ResolvedId as A, ChunkFileNamesFunction as At, ExistingRawSourceMap as B, ManglePropertiesOptions as Bt, ParallelPluginHooks as C, RolldownBuild as Ct, ResolveFileUrlArgs as D, AdvancedChunksGroup as Dt, PluginMeta as E, AddonFunction as Et, withFilter as F, Comments
    likely benign LLM, confidence 0.97 Generated .d.mts re-export list.
    Reasoning

    This is a generated declaration re-export line of type and value names from the bundler's public API. It is normal build output.

  17. info warn → info by review dynamic-import dist/shared/dist-BHJd_fmG.mjs:84:25

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    		try {
    			const result = await import(specifier + formatTrackingQuery(queryName, id, specifier));
    			await new Promise((resolve) => setImmediate(resolve));
    			return {
    likely benign LLM, confidence 0.75 Dynamic import of a module specifier with an appended tracking query.
    Reasoning

    The module loader imports a specifier concatenated with a tracking query string, which is a cache-busting or module-tracking pattern used in bundler config and plugin loading. The specifier comes from the module graph, not from an untrusted network source, and no decoding or process spawning appears.

  18. info warn → info by review dynamic-import dist/shared/dist-BHJd_fmG.mjs:116:19

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    			return {
    				result: await import(specifier + formatTrackingQuery(queryName, id, specifier)),
    				dependencies: [...depsList].filter((url) => url.startsWith("file:")).map((url) => fileURLToPath(url))
    			};
    likely benign LLM, confidence 0.75 Dynamic import in a module loader that records file dependencies.
    Reasoning

    The same loader returns the imported module and collects file dependencies for watch mode. The specifier is resolved module-graph data plus a tracking query, a legitimate reload mechanism. No malicious behaviour is visible.

  19. info warn → info by review dynamic-import dist/shared/load-config-Bn62HMqQ.mjs:70:17

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    	try {
    		return (await import(pathToFileURL(file).href)).default;
    	} finally {
    		fs.unlink(file, () => {});
    likely benign LLM, confidence 0.80 Imports a transpiled temporary config file and deletes it afterwards.
    Reasoning

    The config loader imports a temporary file URL, then deletes that file in a finally block. This is the standard way bundlers load a transpiled config file, so the import target is the bundler's own output.

  20. info warn → info by review dynamic-import dist/shared/load-config-Bn62HMqQ.mjs:109:16

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.80)

    	}
    	return (await import(url + "?t=" + Date.now())).default;
    }
    /**
    likely benign LLM, confidence 0.80 Re-imports the config file with a cache-busting timestamp query.
    Reasoning

    The loader re-imports a config URL with a timestamp query to bypass the module cache when reloading. This is a common hot-reload pattern for user configuration files.

  21. info warn → info by review dynamic-import dist/shared/load-config-Bn62HMqQ.mjs:125:163

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    		if (SUPPORTED_JS_CONFIG_FORMATS.includes(ext) || process.env.NODE_OPTIONS?.includes("--import=tsx") && SUPPORTED_TS_CONFIG_FORMATS.includes(ext)) return (await import(pathToFileURL(configPath).href)).default;
    		else if (SUPPORTED_TS_CONFIG_FORMATS.includes(ext)) return await loadTsConfig(path.resolve(configPath));
    likely benign LLM, confidence 0.80 Imports a local config file by file URL based on its extension.
    Reasoning

    The line imports the config file by its file URL when its extension is a supported JavaScript format, and otherwise falls back to a TypeScript loader. This is the normal config resolution path and the specifier is a local config path.

  22. info warn → info by review long-line dist/shared/prompt-DkftHXS7.mjs:155:1

    line length 4990 characters (raw pass, confidence 0.65)

    		return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65
    likely benign LLM, confidence 0.95 Minified bundled Unicode character-width classification code in a CLI prompt chunk.
    Reasoning

    The line is a minified bundle chunk containing Unicode code-point classification logic (surrogate pair handling and East Asian width ranges). Long lines are ordinary in minified output, and nothing in the visible snippet is decoding, executing or reaching the network. The raw-pass long-line signal has a high false-positive rate.

  23. info warn → info by review long-line dist/shared/prompt-DkftHXS7.mjs:180:1

    line length 15657 characters (raw pass, confidence 0.65)

    	return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uD
    likely benign LLM, confidence 0.95 Minified bundled emoji and grapheme-cluster regex table.
    Reasoning

    The line is a large minified regex of emoji and grapheme-cluster sequences (ZWJ sequences, flag tags, skin-tone modifiers). This is a standard Unicode-width or string-segmentation table compiled into a bundle, with no execution or exfiltration behaviour.

  24. line length 518 characters (raw pass, confidence 0.50)

    		if (this.state === "error" && (this.state = "active"), F?.name && (!this._track && c.aliases.has(F.name) && this.emit("cursor", c.aliases.get(F.name)), c.actions.has(F.name) && this.emit("cursor", F.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u =

Reproduce This Scan

Run disclude locally to verify. These commands scan the published file; the "new in this release" marks come from comparing it with the previous release's file, which they don't repeat. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.3.0
curl -fsSL -o rolldown-1.2.15.tgz https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz
printf '%s  %s\n' 0f4e689f37f168b87605f3b9756b150c63bd1cb52bd04ba5d90e156794625067 rolldown-1.2.15.tgz | shasum -a 256 -c -
mkdir pkg && tar -xzf rolldown-1.2.15.tgz -C pkg --strip-components 1
disclude scan --untrusted --severity info pkg