@google/gemini-cli-core 0.34.0-preview.2 → 0.35.0-nightly.20260313.bb060d7a9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/changelogs/index.md +19 -0
- package/dist/docs/changelogs/latest.md +214 -191
- package/dist/docs/changelogs/preview.md +447 -184
- package/dist/docs/cli/model-routing.md +18 -1
- package/dist/docs/cli/model-steering.md +79 -0
- package/dist/docs/cli/plan-mode.md +99 -14
- package/dist/docs/cli/settings.md +14 -12
- package/dist/docs/cli/telemetry.md +45 -0
- package/dist/docs/cli/tutorials/plan-mode-steering.md +89 -0
- package/dist/docs/core/index.md +2 -0
- package/dist/docs/core/local-model-routing.md +193 -0
- package/dist/docs/reference/configuration.md +27 -3
- package/dist/docs/reference/keyboard-shortcuts.md +168 -90
- package/dist/docs/reference/policy-engine.md +30 -6
- package/dist/docs/resources/troubleshooting.md +15 -0
- package/dist/docs/sidebar.json +10 -0
- package/dist/docs/tools/shell.md +8 -0
- package/dist/google-gemini-cli-core-0.35.0-nightly.20260311.657f19c1f.tgz +0 -0
- package/dist/src/agents/a2a-client-manager.d.ts +11 -4
- package/dist/src/agents/a2a-client-manager.js +61 -34
- package/dist/src/agents/a2a-client-manager.js.map +1 -1
- package/dist/src/agents/a2a-client-manager.test.js +178 -115
- package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
- package/dist/src/agents/a2aUtils.d.ts +4 -28
- package/dist/src/agents/a2aUtils.js +20 -181
- package/dist/src/agents/a2aUtils.js.map +1 -1
- package/dist/src/agents/a2aUtils.test.js +19 -106
- package/dist/src/agents/a2aUtils.test.js.map +1 -1
- package/dist/src/agents/agent-scheduler.d.ts +2 -0
- package/dist/src/agents/agent-scheduler.js +3 -2
- package/dist/src/agents/agent-scheduler.js.map +1 -1
- package/dist/src/agents/agent-scheduler.test.js +12 -3
- package/dist/src/agents/agent-scheduler.test.js.map +1 -1
- package/dist/src/agents/agentLoader.d.ts +2 -2
- package/dist/src/agents/agentLoader.js +15 -0
- package/dist/src/agents/agentLoader.js.map +1 -1
- package/dist/src/agents/auth-provider/factory.d.ts +2 -0
- package/dist/src/agents/auth-provider/factory.js +6 -3
- package/dist/src/agents/auth-provider/factory.js.map +1 -1
- package/dist/src/agents/auth-provider/google-credentials-provider.d.ts +26 -0
- package/dist/src/agents/auth-provider/google-credentials-provider.js +117 -0
- package/dist/src/agents/auth-provider/google-credentials-provider.js.map +1 -0
- package/dist/src/agents/auth-provider/google-credentials-provider.test.d.ts +6 -0
- package/dist/src/agents/auth-provider/google-credentials-provider.test.js +126 -0
- package/dist/src/agents/auth-provider/google-credentials-provider.test.js.map +1 -0
- package/dist/src/agents/browser/browserAgentFactory.js +11 -2
- package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.d.ts +4 -3
- package/dist/src/agents/browser/browserAgentInvocation.js +10 -4
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.test.js +1 -0
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
- package/dist/src/agents/browser/browserManager.d.ts +10 -0
- package/dist/src/agents/browser/browserManager.js +53 -8
- package/dist/src/agents/browser/browserManager.js.map +1 -1
- package/dist/src/agents/browser/inputBlocker.d.ts +51 -0
- package/dist/src/agents/browser/inputBlocker.js +234 -0
- package/dist/src/agents/browser/inputBlocker.js.map +1 -0
- package/dist/src/agents/browser/inputBlocker.test.d.ts +6 -0
- package/dist/src/agents/browser/inputBlocker.test.js +82 -0
- package/dist/src/agents/browser/inputBlocker.test.js.map +1 -0
- package/dist/src/agents/browser/mcpToolWrapper.d.ts +3 -2
- package/dist/src/agents/browser/mcpToolWrapper.js +49 -8
- package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.test.js +51 -0
- package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
- package/dist/src/agents/local-executor.d.ts +5 -4
- package/dist/src/agents/local-executor.js +30 -25
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +269 -3
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.d.ts +4 -4
- package/dist/src/agents/local-invocation.js +12 -9
- package/dist/src/agents/local-invocation.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +19 -3
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/registry.js +3 -2
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +1 -0
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.d.ts +0 -9
- package/dist/src/agents/remote-invocation.js +1 -28
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +1 -0
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.d.ts +5 -4
- package/dist/src/agents/subagent-tool-wrapper.js +9 -5
- package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +15 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
- package/dist/src/agents/subagent-tool.d.ts +3 -3
- package/dist/src/agents/subagent-tool.js +16 -12
- package/dist/src/agents/subagent-tool.js.map +1 -1
- package/dist/src/agents/subagent-tool.test.js +13 -3
- package/dist/src/agents/subagent-tool.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.js +0 -1
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/server.js +2 -2
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +5 -1
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/telemetry.d.ts +2 -2
- package/dist/src/code_assist/telemetry.js +5 -3
- package/dist/src/code_assist/telemetry.js.map +1 -1
- package/dist/src/code_assist/telemetry.test.js +14 -12
- package/dist/src/code_assist/telemetry.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +14 -12
- package/dist/src/code_assist/types.js.map +1 -1
- package/dist/src/config/agent-loop-context.d.ts +3 -0
- package/dist/src/config/config.d.ts +75 -2
- package/dist/src/config/config.js +78 -11
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +170 -10
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +14 -0
- package/dist/src/config/models.js +37 -0
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +51 -1
- package/dist/src/config/models.test.js.map +1 -1
- package/dist/src/config/storage.d.ts +1 -0
- package/dist/src/config/storage.js +3 -0
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/core/baseLlmClient.js +19 -3
- package/dist/src/core/baseLlmClient.js.map +1 -1
- package/dist/src/core/baseLlmClient.test.js +2 -0
- package/dist/src/core/baseLlmClient.test.js.map +1 -1
- package/dist/src/core/client.d.ts +4 -3
- package/dist/src/core/client.js +42 -17
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +8 -0
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +1 -0
- package/dist/src/core/contentGenerator.js +35 -3
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +137 -2
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.d.ts +2 -3
- package/dist/src/core/coreToolHookTriggers.js +5 -11
- package/dist/src/core/coreToolHookTriggers.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.test.js +24 -0
- package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.js +1 -1
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/geminiChat.js +31 -21
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +6 -4
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChat_network_retry.test.js +21 -11
- package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
- package/dist/src/fallback/handler.js +0 -4
- package/dist/src/fallback/handler.js.map +1 -1
- package/dist/src/fallback/handler.test.js +0 -6
- package/dist/src/fallback/handler.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/ide/detect-ide.d.ts +8 -0
- package/dist/src/ide/detect-ide.js +12 -1
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.js +12 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -1
- package/dist/src/ide/ide-installer.js +20 -8
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +60 -4
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/mcp/oauth-provider.js +0 -2
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-utils.js +0 -2
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/policy/config.d.ts +14 -2
- package/dist/src/policy/config.js +94 -49
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/config.test.js +208 -488
- package/dist/src/policy/config.test.js.map +1 -1
- package/dist/src/policy/policies/plan.toml +1 -1
- package/dist/src/policy/stable-stringify.js +15 -5
- package/dist/src/policy/stable-stringify.js.map +1 -1
- package/dist/src/policy/types.d.ts +1 -0
- package/dist/src/policy/types.js.map +1 -1
- package/dist/src/policy/utils.d.ts +17 -0
- package/dist/src/policy/utils.js +27 -7
- package/dist/src/policy/utils.js.map +1 -1
- package/dist/src/prompts/snippets.js +2 -1
- package/dist/src/prompts/snippets.js.map +1 -1
- package/dist/src/prompts/utils.test.d.ts +6 -0
- package/dist/src/prompts/utils.test.js +225 -0
- package/dist/src/prompts/utils.test.js.map +1 -0
- package/dist/src/routing/modelRouterService.js +2 -2
- package/dist/src/routing/modelRouterService.js.map +1 -1
- package/dist/src/routing/modelRouterService.test.js +4 -3
- package/dist/src/routing/modelRouterService.test.js.map +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.js +6 -40
- package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +29 -64
- package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -1
- package/dist/src/scheduler/policy.d.ts +3 -7
- package/dist/src/scheduler/policy.js +4 -3
- package/dist/src/scheduler/policy.js.map +1 -1
- package/dist/src/scheduler/policy.test.js +51 -31
- package/dist/src/scheduler/policy.test.js.map +1 -1
- package/dist/src/scheduler/scheduler.d.ts +4 -2
- package/dist/src/scheduler/scheduler.js +19 -16
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/scheduler/scheduler.test.js +33 -10
- package/dist/src/scheduler/scheduler.test.js.map +1 -1
- package/dist/src/scheduler/scheduler_parallel.test.js +40 -2
- package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -1
- package/dist/src/scheduler/scheduler_waiting_callback.test.js +1 -1
- package/dist/src/scheduler/scheduler_waiting_callback.test.js.map +1 -1
- package/dist/src/scheduler/tool-executor.d.ts +3 -3
- package/dist/src/scheduler/tool-executor.js +15 -21
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/scheduler/tool-executor.test.js +43 -8
- package/dist/src/scheduler/tool-executor.test.js.map +1 -1
- package/dist/src/services/chatRecordingService.js +2 -1
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +21 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/executionLifecycleService.d.ts +83 -0
- package/dist/src/services/executionLifecycleService.js +271 -0
- package/dist/src/services/executionLifecycleService.js.map +1 -0
- package/dist/src/services/executionLifecycleService.test.d.ts +6 -0
- package/dist/src/services/executionLifecycleService.test.js +227 -0
- package/dist/src/services/executionLifecycleService.test.js.map +1 -0
- package/dist/src/services/sandboxManager.d.ts +54 -0
- package/dist/src/services/sandboxManager.js +30 -0
- package/dist/src/services/sandboxManager.js.map +1 -0
- package/dist/src/services/sandboxManager.test.d.ts +6 -0
- package/dist/src/services/sandboxManager.test.js +95 -0
- package/dist/src/services/sandboxManager.test.js.map +1 -0
- package/dist/src/services/shellExecutionService.d.ts +4 -52
- package/dist/src/services/shellExecutionService.js +437 -498
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +10 -21
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +13 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +91 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +77 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +10 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +25 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +3 -3
- package/dist/src/telemetry/index.js +3 -3
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +2 -1
- package/dist/src/telemetry/loggers.js +32 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +37 -2
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +13 -0
- package/dist/src/telemetry/metrics.js +17 -0
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/startupProfiler.js +4 -4
- package/dist/src/telemetry/startupProfiler.js.map +1 -1
- package/dist/src/telemetry/startupProfiler.test.js +19 -0
- package/dist/src/telemetry/startupProfiler.test.js.map +1 -1
- package/dist/src/telemetry/telemetry-utils.test.js +3 -3
- package/dist/src/telemetry/types.d.ts +16 -2
- package/dist/src/telemetry/types.js +34 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +7 -0
- package/dist/src/telemetry/uiTelemetry.js +78 -0
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +101 -0
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.js +10 -2
- package/dist/src/tools/exit-plan-mode.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.test.js +15 -0
- package/dist/src/tools/exit-plan-mode.test.js.map +1 -1
- package/dist/src/tools/ls.js +2 -2
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client.js +0 -1
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +4 -0
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +10 -1
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/read-many-files.js +2 -4
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/shell.d.ts +1 -1
- package/dist/src/tools/shell.js +3 -3
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +4 -0
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +34 -1
- package/dist/src/tools/tools.js +47 -1
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.d.ts +5 -0
- package/dist/src/tools/web-fetch.js +177 -100
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +130 -26
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.test.js +2 -0
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/utils/fetch.d.ts +0 -29
- package/dist/src/utils/fetch.js +10 -123
- package/dist/src/utils/fetch.js.map +1 -1
- package/dist/src/utils/fetch.test.js +1 -103
- package/dist/src/utils/fetch.test.js.map +1 -1
- package/dist/src/utils/language-detection.js +96 -89
- package/dist/src/utils/language-detection.js.map +1 -1
- package/dist/src/utils/language-detection.test.d.ts +6 -0
- package/dist/src/utils/language-detection.test.js +39 -0
- package/dist/src/utils/language-detection.test.js.map +1 -0
- package/dist/src/utils/oauth-flow.js +0 -2
- package/dist/src/utils/oauth-flow.js.map +1 -1
- package/dist/src/utils/paths.js +5 -2
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +11 -0
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/process-utils.js +18 -4
- package/dist/src/utils/process-utils.js.map +1 -1
- package/dist/src/utils/process-utils.test.js +32 -10
- package/dist/src/utils/process-utils.test.js.map +1 -1
- package/dist/src/utils/retry.d.ts +7 -0
- package/dist/src/utils/retry.js +40 -3
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +13 -0
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/summarizer.test.js +5 -0
- package/dist/src/utils/summarizer.test.js.map +1 -1
- package/dist/src/utils/surface.d.ts +18 -0
- package/dist/src/utils/surface.js +46 -0
- package/dist/src/utils/surface.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.34.0-preview.1.tgz +0 -0
package/dist/src/utils/fetch.js
CHANGED
|
@@ -5,26 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { getErrorMessage, isNodeError } from './errors.js';
|
|
7
7
|
import { URL } from 'node:url';
|
|
8
|
-
import * as dns from 'node:dns';
|
|
9
|
-
import { lookup } from 'node:dns/promises';
|
|
10
8
|
import { Agent, ProxyAgent, setGlobalDispatcher } from 'undici';
|
|
11
9
|
import ipaddr from 'ipaddr.js';
|
|
12
10
|
const DEFAULT_HEADERS_TIMEOUT = 300000; // 5 minutes
|
|
13
11
|
const DEFAULT_BODY_TIMEOUT = 300000; // 5 minutes
|
|
14
|
-
// Configure default global dispatcher with higher timeouts
|
|
15
|
-
setGlobalDispatcher(new Agent({
|
|
16
|
-
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
|
17
|
-
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
|
18
|
-
}));
|
|
19
|
-
/**
|
|
20
|
-
* Error thrown when a connection to a private IP address is blocked for security reasons.
|
|
21
|
-
*/
|
|
22
|
-
export class PrivateIpError extends Error {
|
|
23
|
-
constructor(message = 'Refusing to connect to private IP address') {
|
|
24
|
-
super(message);
|
|
25
|
-
this.name = 'PrivateIpError';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
12
|
export class FetchError extends Error {
|
|
29
13
|
code;
|
|
30
14
|
constructor(message, code, options) {
|
|
@@ -33,6 +17,11 @@ export class FetchError extends Error {
|
|
|
33
17
|
this.name = 'FetchError';
|
|
34
18
|
}
|
|
35
19
|
}
|
|
20
|
+
// Configure default global dispatcher with higher timeouts
|
|
21
|
+
setGlobalDispatcher(new Agent({
|
|
22
|
+
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
|
23
|
+
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
|
24
|
+
}));
|
|
36
25
|
/**
|
|
37
26
|
* Sanitizes a hostname by stripping IPv6 brackets if present.
|
|
38
27
|
*/
|
|
@@ -50,37 +39,6 @@ export function isLoopbackHost(hostname) {
|
|
|
50
39
|
sanitized === '127.0.0.1' ||
|
|
51
40
|
sanitized === '::1');
|
|
52
41
|
}
|
|
53
|
-
/**
|
|
54
|
-
* A custom DNS lookup implementation for undici agents that prevents
|
|
55
|
-
* connection to private IP ranges (SSRF protection).
|
|
56
|
-
*/
|
|
57
|
-
export function safeLookup(hostname, options, callback) {
|
|
58
|
-
// Use the callback-based dns.lookup to match undici's expected signature.
|
|
59
|
-
// We explicitly handle the 'all' option to ensure we get an array of addresses.
|
|
60
|
-
const lookupOptions = typeof options === 'number' ? { family: options } : { ...options };
|
|
61
|
-
const finalOptions = { ...lookupOptions, all: true };
|
|
62
|
-
dns.lookup(hostname, finalOptions, (err, addresses) => {
|
|
63
|
-
if (err) {
|
|
64
|
-
callback(err, []);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const addressArray = Array.isArray(addresses) ? addresses : [];
|
|
68
|
-
const filtered = addressArray.filter((addr) => !isAddressPrivate(addr.address) || isLoopbackHost(hostname));
|
|
69
|
-
if (filtered.length === 0 && addressArray.length > 0) {
|
|
70
|
-
callback(new PrivateIpError(), []);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
callback(null, filtered);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
// Dedicated dispatcher with connection-level SSRF protection (safeLookup)
|
|
77
|
-
const safeDispatcher = new Agent({
|
|
78
|
-
headersTimeout: DEFAULT_HEADERS_TIMEOUT,
|
|
79
|
-
bodyTimeout: DEFAULT_BODY_TIMEOUT,
|
|
80
|
-
connect: {
|
|
81
|
-
lookup: safeLookup,
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
42
|
export function isPrivateIp(url) {
|
|
85
43
|
try {
|
|
86
44
|
const hostname = new URL(url).hostname;
|
|
@@ -90,33 +48,6 @@ export function isPrivateIp(url) {
|
|
|
90
48
|
return false;
|
|
91
49
|
}
|
|
92
50
|
}
|
|
93
|
-
/**
|
|
94
|
-
* Checks if a URL resolves to a private IP address.
|
|
95
|
-
* Performs DNS resolution to prevent DNS rebinding/SSRF bypasses.
|
|
96
|
-
*/
|
|
97
|
-
export async function isPrivateIpAsync(url) {
|
|
98
|
-
try {
|
|
99
|
-
const parsed = new URL(url);
|
|
100
|
-
const hostname = parsed.hostname;
|
|
101
|
-
// Fast check for literal IPs or localhost
|
|
102
|
-
if (isAddressPrivate(hostname)) {
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
// Resolve DNS to check the actual target IP
|
|
106
|
-
const addresses = await lookup(hostname, { all: true });
|
|
107
|
-
return addresses.some((addr) => isAddressPrivate(addr.address));
|
|
108
|
-
}
|
|
109
|
-
catch (e) {
|
|
110
|
-
if (e instanceof Error &&
|
|
111
|
-
e.name === 'TypeError' &&
|
|
112
|
-
e.message.includes('Invalid URL')) {
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
throw new Error(`Failed to verify if URL resolves to private IP: ${url}`, {
|
|
116
|
-
cause: e,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
51
|
/**
|
|
121
52
|
* IANA Benchmark Testing Range (198.18.0.0/15).
|
|
122
53
|
* Classified as 'unicast' by ipaddr.js but is reserved and should not be
|
|
@@ -161,55 +92,14 @@ export function isAddressPrivate(address) {
|
|
|
161
92
|
return true;
|
|
162
93
|
}
|
|
163
94
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Internal helper to map varied fetch errors to a standardized FetchError.
|
|
166
|
-
* Centralizes security-related error mapping (e.g. PrivateIpError).
|
|
167
|
-
*/
|
|
168
|
-
function handleFetchError(error, url) {
|
|
169
|
-
if (error instanceof PrivateIpError) {
|
|
170
|
-
throw new FetchError(`Access to private network is blocked: ${url}`, 'ERR_PRIVATE_NETWORK', { cause: error });
|
|
171
|
-
}
|
|
172
|
-
if (error instanceof FetchError) {
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
175
|
-
throw new FetchError(getErrorMessage(error), isNodeError(error) ? error.code : undefined, { cause: error });
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Enhanced fetch with SSRF protection.
|
|
179
|
-
* Prevents access to private/internal networks at the connection level.
|
|
180
|
-
*/
|
|
181
|
-
export async function safeFetch(input, init) {
|
|
182
|
-
const nodeInit = {
|
|
183
|
-
...init,
|
|
184
|
-
dispatcher: safeDispatcher,
|
|
185
|
-
};
|
|
186
|
-
try {
|
|
187
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
188
|
-
return await fetch(input, nodeInit);
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
const url = input instanceof Request
|
|
192
|
-
? input.url
|
|
193
|
-
: typeof input === 'string'
|
|
194
|
-
? input
|
|
195
|
-
: input.toString();
|
|
196
|
-
handleFetchError(error, url);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
95
|
/**
|
|
200
96
|
* Creates an undici ProxyAgent that incorporates safe DNS lookup.
|
|
201
97
|
*/
|
|
202
98
|
export function createSafeProxyAgent(proxyUrl) {
|
|
203
99
|
return new ProxyAgent({
|
|
204
100
|
uri: proxyUrl,
|
|
205
|
-
connect: {
|
|
206
|
-
lookup: safeLookup,
|
|
207
|
-
},
|
|
208
101
|
});
|
|
209
102
|
}
|
|
210
|
-
/**
|
|
211
|
-
* Performs a fetch with a specified timeout and connection-level SSRF protection.
|
|
212
|
-
*/
|
|
213
103
|
export async function fetchWithTimeout(url, timeout, options) {
|
|
214
104
|
const controller = new AbortController();
|
|
215
105
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
@@ -223,21 +113,18 @@ export async function fetchWithTimeout(url, timeout, options) {
|
|
|
223
113
|
});
|
|
224
114
|
}
|
|
225
115
|
}
|
|
226
|
-
const nodeInit = {
|
|
227
|
-
...options,
|
|
228
|
-
signal: controller.signal,
|
|
229
|
-
dispatcher: safeDispatcher,
|
|
230
|
-
};
|
|
231
116
|
try {
|
|
232
|
-
|
|
233
|
-
|
|
117
|
+
const response = await fetch(url, {
|
|
118
|
+
...options,
|
|
119
|
+
signal: controller.signal,
|
|
120
|
+
});
|
|
234
121
|
return response;
|
|
235
122
|
}
|
|
236
123
|
catch (error) {
|
|
237
124
|
if (isNodeError(error) && error.code === 'ABORT_ERR') {
|
|
238
125
|
throw new FetchError(`Request timed out after ${timeout}ms`, 'ETIMEDOUT');
|
|
239
126
|
}
|
|
240
|
-
|
|
127
|
+
throw new FetchError(getErrorMessage(error), undefined, { cause: error });
|
|
241
128
|
}
|
|
242
129
|
finally {
|
|
243
130
|
clearTimeout(timeoutId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B,MAAM,uBAAuB,GAAG,MAAM,CAAC,CAAC,YAAY;AACpD,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,YAAY;AAEjD,MAAM,OAAO,UAAW,SAAQ,KAAK;IAG1B;IAFT,YACE,OAAe,EACR,IAAa,EACpB,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAHjB,SAAI,GAAJ,IAAI,CAAS;QAIpB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,2DAA2D;AAC3D,mBAAmB,CACjB,IAAI,KAAK,CAAC;IACR,cAAc,EAAE,uBAAuB;IACvC,WAAW,EAAE,oBAAoB;CAClC,CAAC,CACH,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7C,OAAO,CACL,SAAS,KAAK,WAAW;QACzB,SAAS,KAAK,WAAW;QACzB,SAAS,KAAK,KAAK,CACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACvC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;AAE/D;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAA+B;IACzD,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,oBAAoB,CAAC;IACpD,OAAO,CACL,IAAI,YAAY,MAAM,CAAC,IAAI;QAC3B,SAAS,YAAY,MAAM,CAAC,IAAI;QAChC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CACjC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAErC,yDAAyD;QACzD,qDAAqD;QACrD,IAAI,IAAI,YAAY,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;YAC9D,OAAO,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,iDAAiD;QACjD,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,SAAS,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,IAAI,UAAU,CAAC;QACpB,GAAG,EAAE,QAAQ;KACd,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,OAAe,EACf,OAAqB;IAErB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE;gBACjE,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,GAAG,OAAO;YACV,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACrD,MAAM,IAAI,UAAU,CAAC,2BAA2B,OAAO,IAAI,EAAE,WAAW,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,mBAAmB,CACjB,IAAI,UAAU,CAAC;QACb,GAAG,EAAE,KAAK;QACV,cAAc,EAAE,uBAAuB;QACvC,WAAW,EAAE,oBAAoB;KAClC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -4,16 +4,10 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { describe, it, expect, vi, beforeEach, afterAll } from 'vitest';
|
|
7
|
-
import { isPrivateIp,
|
|
8
|
-
import * as dnsPromises from 'node:dns/promises';
|
|
9
|
-
import * as dns from 'node:dns';
|
|
7
|
+
import { isPrivateIp, isAddressPrivate, fetchWithTimeout } from './fetch.js';
|
|
10
8
|
vi.mock('node:dns/promises', () => ({
|
|
11
9
|
lookup: vi.fn(),
|
|
12
10
|
}));
|
|
13
|
-
// We need to mock node:dns for safeLookup since it uses the callback API
|
|
14
|
-
vi.mock('node:dns', () => ({
|
|
15
|
-
lookup: vi.fn(),
|
|
16
|
-
}));
|
|
17
11
|
// Mock global fetch
|
|
18
12
|
const originalFetch = global.fetch;
|
|
19
13
|
global.fetch = vi.fn();
|
|
@@ -90,98 +84,6 @@ describe('fetch utils', () => {
|
|
|
90
84
|
expect(isPrivateIp('https://google.com/')).toBe(false);
|
|
91
85
|
});
|
|
92
86
|
});
|
|
93
|
-
describe('isPrivateIpAsync', () => {
|
|
94
|
-
it('should identify private IPs directly', async () => {
|
|
95
|
-
expect(await isPrivateIpAsync('http://10.0.0.1/')).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
it('should identify domains resolving to private IPs', async () => {
|
|
98
|
-
vi.mocked(dnsPromises.lookup).mockImplementation(async () =>
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
-
[{ address: '10.0.0.1', family: 4 }]);
|
|
101
|
-
expect(await isPrivateIpAsync('http://malicious.com/')).toBe(true);
|
|
102
|
-
});
|
|
103
|
-
it('should identify domains resolving to public IPs as non-private', async () => {
|
|
104
|
-
vi.mocked(dnsPromises.lookup).mockImplementation(async () =>
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
|
-
[{ address: '8.8.8.8', family: 4 }]);
|
|
107
|
-
expect(await isPrivateIpAsync('http://google.com/')).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
it('should throw error if DNS resolution fails (fail closed)', async () => {
|
|
110
|
-
vi.mocked(dnsPromises.lookup).mockRejectedValue(new Error('DNS Error'));
|
|
111
|
-
await expect(isPrivateIpAsync('http://unreachable.com/')).rejects.toThrow('Failed to verify if URL resolves to private IP');
|
|
112
|
-
});
|
|
113
|
-
it('should return false for invalid URLs instead of throwing verification error', async () => {
|
|
114
|
-
expect(await isPrivateIpAsync('not-a-url')).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe('safeLookup', () => {
|
|
118
|
-
it('should filter out private IPs', async () => {
|
|
119
|
-
const addresses = [
|
|
120
|
-
{ address: '8.8.8.8', family: 4 },
|
|
121
|
-
{ address: '10.0.0.1', family: 4 },
|
|
122
|
-
];
|
|
123
|
-
vi.mocked(dns.lookup).mockImplementation(((_h, _o, cb) => {
|
|
124
|
-
cb(null, addresses);
|
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
126
|
-
}));
|
|
127
|
-
const result = await new Promise((resolve, reject) => {
|
|
128
|
-
safeLookup('example.com', { all: true }, (err, filtered) => {
|
|
129
|
-
if (err)
|
|
130
|
-
reject(err);
|
|
131
|
-
else
|
|
132
|
-
resolve(filtered);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
expect(result).toHaveLength(1);
|
|
136
|
-
expect(result[0].address).toBe('8.8.8.8');
|
|
137
|
-
});
|
|
138
|
-
it('should allow explicit localhost', async () => {
|
|
139
|
-
const addresses = [{ address: '127.0.0.1', family: 4 }];
|
|
140
|
-
vi.mocked(dns.lookup).mockImplementation(((_h, _o, cb) => {
|
|
141
|
-
cb(null, addresses);
|
|
142
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
-
}));
|
|
144
|
-
const result = await new Promise((resolve, reject) => {
|
|
145
|
-
safeLookup('localhost', { all: true }, (err, filtered) => {
|
|
146
|
-
if (err)
|
|
147
|
-
reject(err);
|
|
148
|
-
else
|
|
149
|
-
resolve(filtered);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
expect(result).toHaveLength(1);
|
|
153
|
-
expect(result[0].address).toBe('127.0.0.1');
|
|
154
|
-
});
|
|
155
|
-
it('should error if all resolved IPs are private', async () => {
|
|
156
|
-
const addresses = [{ address: '10.0.0.1', family: 4 }];
|
|
157
|
-
vi.mocked(dns.lookup).mockImplementation(((_h, _o, cb) => {
|
|
158
|
-
cb(null, addresses);
|
|
159
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
160
|
-
}));
|
|
161
|
-
await expect(new Promise((resolve, reject) => {
|
|
162
|
-
safeLookup('malicious.com', { all: true }, (err, filtered) => {
|
|
163
|
-
if (err)
|
|
164
|
-
reject(err);
|
|
165
|
-
else
|
|
166
|
-
resolve(filtered);
|
|
167
|
-
});
|
|
168
|
-
})).rejects.toThrow(PrivateIpError);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
describe('safeFetch', () => {
|
|
172
|
-
it('should forward to fetch with dispatcher', async () => {
|
|
173
|
-
vi.mocked(global.fetch).mockResolvedValue(new Response('ok'));
|
|
174
|
-
const response = await safeFetch('https://example.com');
|
|
175
|
-
expect(response.status).toBe(200);
|
|
176
|
-
expect(global.fetch).toHaveBeenCalledWith('https://example.com', expect.objectContaining({
|
|
177
|
-
dispatcher: expect.any(Object),
|
|
178
|
-
}));
|
|
179
|
-
});
|
|
180
|
-
it('should handle Refusing to connect errors', async () => {
|
|
181
|
-
vi.mocked(global.fetch).mockRejectedValue(new PrivateIpError());
|
|
182
|
-
await expect(safeFetch('http://10.0.0.1')).rejects.toThrow('Access to private network is blocked');
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
87
|
describe('fetchWithTimeout', () => {
|
|
186
88
|
it('should handle timeouts', async () => {
|
|
187
89
|
vi.mocked(global.fetch).mockImplementation((_input, init) => new Promise((_resolve, reject) => {
|
|
@@ -197,10 +99,6 @@ describe('fetch utils', () => {
|
|
|
197
99
|
}));
|
|
198
100
|
await expect(fetchWithTimeout('http://example.com', 50)).rejects.toThrow('Request timed out after 50ms');
|
|
199
101
|
});
|
|
200
|
-
it('should handle private IP errors via handleFetchError', async () => {
|
|
201
|
-
vi.mocked(global.fetch).mockRejectedValue(new PrivateIpError());
|
|
202
|
-
await expect(fetchWithTimeout('http://10.0.0.1', 1000)).rejects.toThrow('Access to private network is blocked: http://10.0.0.1');
|
|
203
|
-
});
|
|
204
102
|
});
|
|
205
103
|
});
|
|
206
104
|
//# sourceMappingURL=fetch.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.test.js","sourceRoot":"","sources":["../../../src/utils/fetch.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACxE,OAAO,
|
|
1
|
+
{"version":3,"file":"fetch.test.js","sourceRoot":"","sources":["../../../src/utils/fetch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,98 +4,105 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import * as path from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Maps file extensions or filenames to LSP 3.18 language identifiers.
|
|
9
|
+
* See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocumentItem
|
|
10
|
+
*/
|
|
7
11
|
const extensionToLanguageMap = {
|
|
8
|
-
'.ts': '
|
|
9
|
-
'.js': '
|
|
10
|
-
'.mjs': '
|
|
11
|
-
'.cjs': '
|
|
12
|
-
'.jsx': '
|
|
13
|
-
'.tsx': '
|
|
14
|
-
'.py': '
|
|
15
|
-
'.java': '
|
|
16
|
-
'.go': '
|
|
17
|
-
'.rb': '
|
|
18
|
-
'.php': '
|
|
19
|
-
'.phtml': '
|
|
20
|
-
'.cs': '
|
|
21
|
-
'.cpp': '
|
|
22
|
-
'.cxx': '
|
|
23
|
-
'.cc': '
|
|
24
|
-
'.c': '
|
|
25
|
-
'.h': '
|
|
26
|
-
'.hpp': '
|
|
27
|
-
'.swift': '
|
|
28
|
-
'.kt': '
|
|
29
|
-
'.rs': '
|
|
30
|
-
'.m': '
|
|
31
|
-
'.mm': '
|
|
32
|
-
'.pl': '
|
|
33
|
-
'.pm': '
|
|
34
|
-
'.lua': '
|
|
35
|
-
'.r': '
|
|
36
|
-
'.scala': '
|
|
37
|
-
'.sc': '
|
|
38
|
-
'.sh': '
|
|
39
|
-
'.ps1': '
|
|
40
|
-
'.bat': '
|
|
41
|
-
'.cmd': '
|
|
42
|
-
'.sql': '
|
|
43
|
-
'.html': '
|
|
44
|
-
'.htm': '
|
|
45
|
-
'.css': '
|
|
46
|
-
'.less': '
|
|
47
|
-
'.sass': '
|
|
48
|
-
'.scss': '
|
|
49
|
-
'.json': '
|
|
50
|
-
'.xml': '
|
|
51
|
-
'.yaml': '
|
|
52
|
-
'.yml': '
|
|
53
|
-
'.md': '
|
|
54
|
-
'.markdown': '
|
|
55
|
-
'.dockerfile': '
|
|
56
|
-
'.vim': '
|
|
57
|
-
'.vb': '
|
|
58
|
-
'.fs': '
|
|
59
|
-
'.clj': '
|
|
60
|
-
'.cljs': '
|
|
61
|
-
'.dart': '
|
|
62
|
-
'.ex': '
|
|
63
|
-
'.erl': '
|
|
64
|
-
'.hs': '
|
|
65
|
-
'.lisp': '
|
|
66
|
-
'.rkt': '
|
|
67
|
-
'.groovy': '
|
|
68
|
-
'.jl': '
|
|
69
|
-
'.tex': '
|
|
70
|
-
'.ino': '
|
|
71
|
-
'.asm': '
|
|
72
|
-
'.s': '
|
|
73
|
-
'.toml': '
|
|
74
|
-
'.vue': '
|
|
75
|
-
'.svelte': '
|
|
76
|
-
'.gohtml': '
|
|
77
|
-
'.hbs': '
|
|
78
|
-
'.ejs': '
|
|
79
|
-
'.erb': '
|
|
80
|
-
'.jsp': '
|
|
81
|
-
'.dockerignore': '
|
|
82
|
-
'.gitignore': '
|
|
83
|
-
'.npmignore': '
|
|
84
|
-
'.editorconfig': '
|
|
85
|
-
'.prettierrc': '
|
|
86
|
-
'.eslintrc': '
|
|
87
|
-
'.babelrc': '
|
|
88
|
-
'.tsconfig': '
|
|
89
|
-
'.flow': '
|
|
90
|
-
'.graphql': '
|
|
91
|
-
'.proto': '
|
|
12
|
+
'.ts': 'typescript',
|
|
13
|
+
'.js': 'javascript',
|
|
14
|
+
'.mjs': 'javascript',
|
|
15
|
+
'.cjs': 'javascript',
|
|
16
|
+
'.jsx': 'javascriptreact',
|
|
17
|
+
'.tsx': 'typescriptreact',
|
|
18
|
+
'.py': 'python',
|
|
19
|
+
'.java': 'java',
|
|
20
|
+
'.go': 'go',
|
|
21
|
+
'.rb': 'ruby',
|
|
22
|
+
'.php': 'php',
|
|
23
|
+
'.phtml': 'php',
|
|
24
|
+
'.cs': 'csharp',
|
|
25
|
+
'.cpp': 'cpp',
|
|
26
|
+
'.cxx': 'cpp',
|
|
27
|
+
'.cc': 'cpp',
|
|
28
|
+
'.c': 'c',
|
|
29
|
+
'.h': 'c',
|
|
30
|
+
'.hpp': 'cpp',
|
|
31
|
+
'.swift': 'swift',
|
|
32
|
+
'.kt': 'kotlin',
|
|
33
|
+
'.rs': 'rust',
|
|
34
|
+
'.m': 'objective-c',
|
|
35
|
+
'.mm': 'objective-cpp',
|
|
36
|
+
'.pl': 'perl',
|
|
37
|
+
'.pm': 'perl',
|
|
38
|
+
'.lua': 'lua',
|
|
39
|
+
'.r': 'r',
|
|
40
|
+
'.scala': 'scala',
|
|
41
|
+
'.sc': 'scala',
|
|
42
|
+
'.sh': 'shellscript',
|
|
43
|
+
'.ps1': 'powershell',
|
|
44
|
+
'.bat': 'bat',
|
|
45
|
+
'.cmd': 'bat',
|
|
46
|
+
'.sql': 'sql',
|
|
47
|
+
'.html': 'html',
|
|
48
|
+
'.htm': 'html',
|
|
49
|
+
'.css': 'css',
|
|
50
|
+
'.less': 'less',
|
|
51
|
+
'.sass': 'sass',
|
|
52
|
+
'.scss': 'scss',
|
|
53
|
+
'.json': 'json',
|
|
54
|
+
'.xml': 'xml',
|
|
55
|
+
'.yaml': 'yaml',
|
|
56
|
+
'.yml': 'yaml',
|
|
57
|
+
'.md': 'markdown',
|
|
58
|
+
'.markdown': 'markdown',
|
|
59
|
+
'.dockerfile': 'dockerfile',
|
|
60
|
+
'.vim': 'vim',
|
|
61
|
+
'.vb': 'vb',
|
|
62
|
+
'.fs': 'fsharp',
|
|
63
|
+
'.clj': 'clojure',
|
|
64
|
+
'.cljs': 'clojure',
|
|
65
|
+
'.dart': 'dart',
|
|
66
|
+
'.ex': 'elixir',
|
|
67
|
+
'.erl': 'erlang',
|
|
68
|
+
'.hs': 'haskell',
|
|
69
|
+
'.lisp': 'lisp',
|
|
70
|
+
'.rkt': 'racket',
|
|
71
|
+
'.groovy': 'groovy',
|
|
72
|
+
'.jl': 'julia',
|
|
73
|
+
'.tex': 'latex',
|
|
74
|
+
'.ino': 'arduino',
|
|
75
|
+
'.asm': 'assembly',
|
|
76
|
+
'.s': 'assembly',
|
|
77
|
+
'.toml': 'toml',
|
|
78
|
+
'.vue': 'vue',
|
|
79
|
+
'.svelte': 'svelte',
|
|
80
|
+
'.gohtml': 'gohtml', // Not in standard LSP well-known list but kept for compatibility
|
|
81
|
+
'.hbs': 'handlebars',
|
|
82
|
+
'.ejs': 'ejs',
|
|
83
|
+
'.erb': 'erb',
|
|
84
|
+
'.jsp': 'jsp',
|
|
85
|
+
'.dockerignore': 'ignore',
|
|
86
|
+
'.gitignore': 'ignore',
|
|
87
|
+
'.npmignore': 'ignore',
|
|
88
|
+
'.editorconfig': 'properties',
|
|
89
|
+
'.prettierrc': 'json',
|
|
90
|
+
'.eslintrc': 'json',
|
|
91
|
+
'.babelrc': 'json',
|
|
92
|
+
'.tsconfig': 'json',
|
|
93
|
+
'.flow': 'javascript',
|
|
94
|
+
'.graphql': 'graphql',
|
|
95
|
+
'.proto': 'proto',
|
|
92
96
|
};
|
|
93
97
|
export function getLanguageFromFilePath(filePath) {
|
|
94
|
-
const extension = path.extname(filePath).toLowerCase();
|
|
95
|
-
if (extension) {
|
|
96
|
-
return extensionToLanguageMap[extension];
|
|
97
|
-
}
|
|
98
98
|
const filename = path.basename(filePath).toLowerCase();
|
|
99
|
-
|
|
99
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
100
|
+
const candidates = [
|
|
101
|
+
extension, // 1. Standard extension (e.g., '.js')
|
|
102
|
+
filename, // 2. Exact filename (e.g., 'dockerfile')
|
|
103
|
+
`.${filename}`, // 3. Dot-prefixed filename (e.g., '.gitignore')
|
|
104
|
+
];
|
|
105
|
+
const match = candidates.find((key) => key in extensionToLanguageMap);
|
|
106
|
+
return match ? extensionToLanguageMap[match] : undefined;
|
|
100
107
|
}
|
|
101
108
|
//# sourceMappingURL=language-detection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language-detection.js","sourceRoot":"","sources":["../../../src/utils/language-detection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,sBAAsB,GAA8B;IACxD,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"language-detection.js","sourceRoot":"","sources":["../../../src/utils/language-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import { getLanguageFromFilePath } from './language-detection.js';
|
|
8
|
+
describe('language-detection', () => {
|
|
9
|
+
it('should return correct LSP identifiers for various extensions', () => {
|
|
10
|
+
expect(getLanguageFromFilePath('test.ts')).toBe('typescript');
|
|
11
|
+
expect(getLanguageFromFilePath('test.js')).toBe('javascript');
|
|
12
|
+
expect(getLanguageFromFilePath('test.py')).toBe('python');
|
|
13
|
+
expect(getLanguageFromFilePath('test.java')).toBe('java');
|
|
14
|
+
expect(getLanguageFromFilePath('test.go')).toBe('go');
|
|
15
|
+
expect(getLanguageFromFilePath('test.cs')).toBe('csharp');
|
|
16
|
+
expect(getLanguageFromFilePath('test.cpp')).toBe('cpp');
|
|
17
|
+
expect(getLanguageFromFilePath('test.sh')).toBe('shellscript');
|
|
18
|
+
expect(getLanguageFromFilePath('test.bat')).toBe('bat');
|
|
19
|
+
expect(getLanguageFromFilePath('test.json')).toBe('json');
|
|
20
|
+
expect(getLanguageFromFilePath('test.md')).toBe('markdown');
|
|
21
|
+
expect(getLanguageFromFilePath('test.tsx')).toBe('typescriptreact');
|
|
22
|
+
expect(getLanguageFromFilePath('test.jsx')).toBe('javascriptreact');
|
|
23
|
+
});
|
|
24
|
+
it('should handle uppercase extensions', () => {
|
|
25
|
+
expect(getLanguageFromFilePath('TEST.TS')).toBe('typescript');
|
|
26
|
+
});
|
|
27
|
+
it('should handle filenames without extensions but in map', () => {
|
|
28
|
+
expect(getLanguageFromFilePath('.gitignore')).toBe('ignore');
|
|
29
|
+
expect(getLanguageFromFilePath('.dockerfile')).toBe('dockerfile');
|
|
30
|
+
expect(getLanguageFromFilePath('Dockerfile')).toBe('dockerfile');
|
|
31
|
+
});
|
|
32
|
+
it('should return undefined for unknown extensions', () => {
|
|
33
|
+
expect(getLanguageFromFilePath('test.unknown')).toBeUndefined();
|
|
34
|
+
});
|
|
35
|
+
it('should return undefined for files without extension or known filename', () => {
|
|
36
|
+
expect(getLanguageFromFilePath('just_a_file')).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=language-detection.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-detection.test.js","sourceRoot":"","sources":["../../../src/utils/language-detection.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC/D,MAAM,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACpE,MAAM,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,MAAM,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClE,MAAM,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|