@dotsetlabs/bellwether 0.10.0
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/CHANGELOG.md +291 -0
- package/LICENSE +21 -0
- package/README.md +739 -0
- package/dist/auth/credentials.d.ts +64 -0
- package/dist/auth/credentials.js +218 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/keychain.d.ts +64 -0
- package/dist/auth/keychain.js +268 -0
- package/dist/baseline/ab-testing.d.ts +80 -0
- package/dist/baseline/ab-testing.js +236 -0
- package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
- package/dist/baseline/ai-compatibility-scorer.js +606 -0
- package/dist/baseline/calibration.d.ts +77 -0
- package/dist/baseline/calibration.js +136 -0
- package/dist/baseline/category-matching.d.ts +85 -0
- package/dist/baseline/category-matching.js +289 -0
- package/dist/baseline/change-impact-analyzer.d.ts +98 -0
- package/dist/baseline/change-impact-analyzer.js +592 -0
- package/dist/baseline/comparator.d.ts +64 -0
- package/dist/baseline/comparator.js +916 -0
- package/dist/baseline/confidence.d.ts +55 -0
- package/dist/baseline/confidence.js +122 -0
- package/dist/baseline/converter.d.ts +61 -0
- package/dist/baseline/converter.js +585 -0
- package/dist/baseline/dependency-analyzer.d.ts +89 -0
- package/dist/baseline/dependency-analyzer.js +567 -0
- package/dist/baseline/deprecation-tracker.d.ts +133 -0
- package/dist/baseline/deprecation-tracker.js +322 -0
- package/dist/baseline/diff.d.ts +55 -0
- package/dist/baseline/diff.js +1584 -0
- package/dist/baseline/documentation-scorer.d.ts +205 -0
- package/dist/baseline/documentation-scorer.js +466 -0
- package/dist/baseline/embeddings.d.ts +118 -0
- package/dist/baseline/embeddings.js +251 -0
- package/dist/baseline/error-analyzer.d.ts +198 -0
- package/dist/baseline/error-analyzer.js +721 -0
- package/dist/baseline/evaluation/evaluator.d.ts +42 -0
- package/dist/baseline/evaluation/evaluator.js +323 -0
- package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
- package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
- package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
- package/dist/baseline/evaluation/golden-dataset.js +717 -0
- package/dist/baseline/evaluation/index.d.ts +15 -0
- package/dist/baseline/evaluation/index.js +15 -0
- package/dist/baseline/evaluation/types.d.ts +186 -0
- package/dist/baseline/evaluation/types.js +8 -0
- package/dist/baseline/external-dependency-detector.d.ts +181 -0
- package/dist/baseline/external-dependency-detector.js +524 -0
- package/dist/baseline/golden-output.d.ts +162 -0
- package/dist/baseline/golden-output.js +636 -0
- package/dist/baseline/health-scorer.d.ts +174 -0
- package/dist/baseline/health-scorer.js +451 -0
- package/dist/baseline/incremental-checker.d.ts +97 -0
- package/dist/baseline/incremental-checker.js +174 -0
- package/dist/baseline/index.d.ts +31 -0
- package/dist/baseline/index.js +42 -0
- package/dist/baseline/migration-generator.d.ts +137 -0
- package/dist/baseline/migration-generator.js +554 -0
- package/dist/baseline/migrations.d.ts +60 -0
- package/dist/baseline/migrations.js +197 -0
- package/dist/baseline/performance-tracker.d.ts +214 -0
- package/dist/baseline/performance-tracker.js +577 -0
- package/dist/baseline/pr-comment-generator.d.ts +117 -0
- package/dist/baseline/pr-comment-generator.js +546 -0
- package/dist/baseline/response-fingerprint.d.ts +127 -0
- package/dist/baseline/response-fingerprint.js +728 -0
- package/dist/baseline/response-schema-tracker.d.ts +129 -0
- package/dist/baseline/response-schema-tracker.js +420 -0
- package/dist/baseline/risk-scorer.d.ts +54 -0
- package/dist/baseline/risk-scorer.js +434 -0
- package/dist/baseline/saver.d.ts +89 -0
- package/dist/baseline/saver.js +554 -0
- package/dist/baseline/scenario-generator.d.ts +151 -0
- package/dist/baseline/scenario-generator.js +905 -0
- package/dist/baseline/schema-compare.d.ts +86 -0
- package/dist/baseline/schema-compare.js +557 -0
- package/dist/baseline/schema-evolution.d.ts +189 -0
- package/dist/baseline/schema-evolution.js +467 -0
- package/dist/baseline/semantic.d.ts +203 -0
- package/dist/baseline/semantic.js +908 -0
- package/dist/baseline/synonyms.d.ts +60 -0
- package/dist/baseline/synonyms.js +386 -0
- package/dist/baseline/telemetry.d.ts +165 -0
- package/dist/baseline/telemetry.js +294 -0
- package/dist/baseline/test-pruner.d.ts +120 -0
- package/dist/baseline/test-pruner.js +387 -0
- package/dist/baseline/types.d.ts +449 -0
- package/dist/baseline/types.js +5 -0
- package/dist/baseline/version.d.ts +138 -0
- package/dist/baseline/version.js +206 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/response-cache.d.ts +151 -0
- package/dist/cache/response-cache.js +287 -0
- package/dist/ci/index.d.ts +60 -0
- package/dist/ci/index.js +342 -0
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.js +352 -0
- package/dist/cli/commands/badge.d.ts +3 -0
- package/dist/cli/commands/badge.js +74 -0
- package/dist/cli/commands/baseline-accept.d.ts +15 -0
- package/dist/cli/commands/baseline-accept.js +178 -0
- package/dist/cli/commands/baseline-migrate.d.ts +12 -0
- package/dist/cli/commands/baseline-migrate.js +164 -0
- package/dist/cli/commands/baseline.d.ts +14 -0
- package/dist/cli/commands/baseline.js +449 -0
- package/dist/cli/commands/beta.d.ts +10 -0
- package/dist/cli/commands/beta.js +231 -0
- package/dist/cli/commands/check.d.ts +11 -0
- package/dist/cli/commands/check.js +820 -0
- package/dist/cli/commands/cloud/badge.d.ts +3 -0
- package/dist/cli/commands/cloud/badge.js +74 -0
- package/dist/cli/commands/cloud/diff.d.ts +6 -0
- package/dist/cli/commands/cloud/diff.js +79 -0
- package/dist/cli/commands/cloud/history.d.ts +6 -0
- package/dist/cli/commands/cloud/history.js +102 -0
- package/dist/cli/commands/cloud/link.d.ts +9 -0
- package/dist/cli/commands/cloud/link.js +119 -0
- package/dist/cli/commands/cloud/login.d.ts +7 -0
- package/dist/cli/commands/cloud/login.js +499 -0
- package/dist/cli/commands/cloud/projects.d.ts +6 -0
- package/dist/cli/commands/cloud/projects.js +44 -0
- package/dist/cli/commands/cloud/shared.d.ts +7 -0
- package/dist/cli/commands/cloud/shared.js +42 -0
- package/dist/cli/commands/cloud/teams.d.ts +8 -0
- package/dist/cli/commands/cloud/teams.js +169 -0
- package/dist/cli/commands/cloud/upload.d.ts +8 -0
- package/dist/cli/commands/cloud/upload.js +181 -0
- package/dist/cli/commands/contract.d.ts +11 -0
- package/dist/cli/commands/contract.js +280 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.js +82 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.js +187 -0
- package/dist/cli/commands/explore.d.ts +11 -0
- package/dist/cli/commands/explore.js +437 -0
- package/dist/cli/commands/feedback.d.ts +9 -0
- package/dist/cli/commands/feedback.js +174 -0
- package/dist/cli/commands/golden.d.ts +12 -0
- package/dist/cli/commands/golden.js +407 -0
- package/dist/cli/commands/history.d.ts +10 -0
- package/dist/cli/commands/history.js +202 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +219 -0
- package/dist/cli/commands/interview.d.ts +3 -0
- package/dist/cli/commands/interview.js +903 -0
- package/dist/cli/commands/link.d.ts +10 -0
- package/dist/cli/commands/link.js +169 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +499 -0
- package/dist/cli/commands/preset.d.ts +33 -0
- package/dist/cli/commands/preset.js +297 -0
- package/dist/cli/commands/profile.d.ts +33 -0
- package/dist/cli/commands/profile.js +286 -0
- package/dist/cli/commands/registry.d.ts +11 -0
- package/dist/cli/commands/registry.js +146 -0
- package/dist/cli/commands/shared.d.ts +79 -0
- package/dist/cli/commands/shared.js +196 -0
- package/dist/cli/commands/teams.d.ts +8 -0
- package/dist/cli/commands/teams.js +169 -0
- package/dist/cli/commands/test.d.ts +9 -0
- package/dist/cli/commands/test.js +500 -0
- package/dist/cli/commands/upload.d.ts +8 -0
- package/dist/cli/commands/upload.js +223 -0
- package/dist/cli/commands/validate-config.d.ts +6 -0
- package/dist/cli/commands/validate-config.js +35 -0
- package/dist/cli/commands/verify.d.ts +11 -0
- package/dist/cli/commands/verify.js +283 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.js +253 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +178 -0
- package/dist/cli/interactive.d.ts +47 -0
- package/dist/cli/interactive.js +216 -0
- package/dist/cli/output/terminal-reporter.d.ts +19 -0
- package/dist/cli/output/terminal-reporter.js +104 -0
- package/dist/cli/output.d.ts +226 -0
- package/dist/cli/output.js +438 -0
- package/dist/cli/utils/env.d.ts +5 -0
- package/dist/cli/utils/env.js +14 -0
- package/dist/cli/utils/progress.d.ts +59 -0
- package/dist/cli/utils/progress.js +206 -0
- package/dist/cli/utils/server-context.d.ts +10 -0
- package/dist/cli/utils/server-context.js +36 -0
- package/dist/cloud/auth.d.ts +144 -0
- package/dist/cloud/auth.js +374 -0
- package/dist/cloud/client.d.ts +24 -0
- package/dist/cloud/client.js +65 -0
- package/dist/cloud/http-client.d.ts +38 -0
- package/dist/cloud/http-client.js +215 -0
- package/dist/cloud/index.d.ts +23 -0
- package/dist/cloud/index.js +25 -0
- package/dist/cloud/mock-client.d.ts +107 -0
- package/dist/cloud/mock-client.js +545 -0
- package/dist/cloud/types.d.ts +515 -0
- package/dist/cloud/types.js +15 -0
- package/dist/config/defaults.d.ts +160 -0
- package/dist/config/defaults.js +169 -0
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.js +122 -0
- package/dist/config/template.d.ts +42 -0
- package/dist/config/template.js +647 -0
- package/dist/config/validator.d.ts +2112 -0
- package/dist/config/validator.js +658 -0
- package/dist/constants/cloud.d.ts +107 -0
- package/dist/constants/cloud.js +110 -0
- package/dist/constants/core.d.ts +521 -0
- package/dist/constants/core.js +556 -0
- package/dist/constants/testing.d.ts +1283 -0
- package/dist/constants/testing.js +1568 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/contract/index.js +5 -0
- package/dist/contract/validator.d.ts +177 -0
- package/dist/contract/validator.js +574 -0
- package/dist/cost/index.d.ts +6 -0
- package/dist/cost/index.js +5 -0
- package/dist/cost/tracker.d.ts +134 -0
- package/dist/cost/tracker.js +313 -0
- package/dist/discovery/discovery.d.ts +16 -0
- package/dist/discovery/discovery.js +173 -0
- package/dist/discovery/types.d.ts +51 -0
- package/dist/discovery/types.js +2 -0
- package/dist/docs/agents.d.ts +3 -0
- package/dist/docs/agents.js +995 -0
- package/dist/docs/contract.d.ts +51 -0
- package/dist/docs/contract.js +1681 -0
- package/dist/docs/generator.d.ts +4 -0
- package/dist/docs/generator.js +4 -0
- package/dist/docs/html-reporter.d.ts +9 -0
- package/dist/docs/html-reporter.js +757 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +11 -0
- package/dist/docs/junit-reporter.d.ts +18 -0
- package/dist/docs/junit-reporter.js +210 -0
- package/dist/docs/report.d.ts +14 -0
- package/dist/docs/report.js +44 -0
- package/dist/docs/sarif-reporter.d.ts +19 -0
- package/dist/docs/sarif-reporter.js +335 -0
- package/dist/docs/shared.d.ts +35 -0
- package/dist/docs/shared.js +162 -0
- package/dist/docs/templates.d.ts +12 -0
- package/dist/docs/templates.js +76 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/retry.d.ts +92 -0
- package/dist/errors/retry.js +323 -0
- package/dist/errors/types.d.ts +321 -0
- package/dist/errors/types.js +584 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/interview/dependency-resolver.d.ts +11 -0
- package/dist/interview/dependency-resolver.js +32 -0
- package/dist/interview/interviewer.d.ts +232 -0
- package/dist/interview/interviewer.js +1939 -0
- package/dist/interview/mock-response-generator.d.ts +7 -0
- package/dist/interview/mock-response-generator.js +102 -0
- package/dist/interview/orchestrator.d.ts +237 -0
- package/dist/interview/orchestrator.js +1296 -0
- package/dist/interview/rate-limiter.d.ts +15 -0
- package/dist/interview/rate-limiter.js +55 -0
- package/dist/interview/response-validator.d.ts +10 -0
- package/dist/interview/response-validator.js +132 -0
- package/dist/interview/schema-inferrer.d.ts +8 -0
- package/dist/interview/schema-inferrer.js +71 -0
- package/dist/interview/schema-test-generator.d.ts +71 -0
- package/dist/interview/schema-test-generator.js +834 -0
- package/dist/interview/smart-value-generator.d.ts +155 -0
- package/dist/interview/smart-value-generator.js +554 -0
- package/dist/interview/stateful-test-runner.d.ts +19 -0
- package/dist/interview/stateful-test-runner.js +106 -0
- package/dist/interview/types.d.ts +561 -0
- package/dist/interview/types.js +2 -0
- package/dist/llm/anthropic.d.ts +41 -0
- package/dist/llm/anthropic.js +355 -0
- package/dist/llm/client.d.ts +123 -0
- package/dist/llm/client.js +42 -0
- package/dist/llm/factory.d.ts +38 -0
- package/dist/llm/factory.js +145 -0
- package/dist/llm/fallback.d.ts +140 -0
- package/dist/llm/fallback.js +379 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.js +15 -0
- package/dist/llm/ollama.d.ts +37 -0
- package/dist/llm/ollama.js +330 -0
- package/dist/llm/openai.d.ts +25 -0
- package/dist/llm/openai.js +320 -0
- package/dist/llm/token-budget.d.ts +161 -0
- package/dist/llm/token-budget.js +395 -0
- package/dist/logging/logger.d.ts +70 -0
- package/dist/logging/logger.js +130 -0
- package/dist/metrics/collector.d.ts +106 -0
- package/dist/metrics/collector.js +547 -0
- package/dist/metrics/index.d.ts +7 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/prometheus.d.ts +20 -0
- package/dist/metrics/prometheus.js +241 -0
- package/dist/metrics/types.d.ts +209 -0
- package/dist/metrics/types.js +5 -0
- package/dist/persona/builtins.d.ts +54 -0
- package/dist/persona/builtins.js +219 -0
- package/dist/persona/index.d.ts +8 -0
- package/dist/persona/index.js +8 -0
- package/dist/persona/loader.d.ts +30 -0
- package/dist/persona/loader.js +190 -0
- package/dist/persona/types.d.ts +144 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/validation.d.ts +94 -0
- package/dist/persona/validation.js +332 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/templates.d.ts +180 -0
- package/dist/prompts/templates.js +431 -0
- package/dist/registry/client.d.ts +49 -0
- package/dist/registry/client.js +191 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/types.d.ts +140 -0
- package/dist/registry/types.js +6 -0
- package/dist/scenarios/evaluator.d.ts +43 -0
- package/dist/scenarios/evaluator.js +206 -0
- package/dist/scenarios/index.d.ts +10 -0
- package/dist/scenarios/index.js +9 -0
- package/dist/scenarios/loader.d.ts +20 -0
- package/dist/scenarios/loader.js +285 -0
- package/dist/scenarios/types.d.ts +153 -0
- package/dist/scenarios/types.js +8 -0
- package/dist/security/index.d.ts +17 -0
- package/dist/security/index.js +18 -0
- package/dist/security/payloads.d.ts +61 -0
- package/dist/security/payloads.js +268 -0
- package/dist/security/security-tester.d.ts +42 -0
- package/dist/security/security-tester.js +582 -0
- package/dist/security/types.d.ts +166 -0
- package/dist/security/types.js +8 -0
- package/dist/transport/base-transport.d.ts +59 -0
- package/dist/transport/base-transport.js +38 -0
- package/dist/transport/http-transport.d.ts +67 -0
- package/dist/transport/http-transport.js +238 -0
- package/dist/transport/mcp-client.d.ts +141 -0
- package/dist/transport/mcp-client.js +496 -0
- package/dist/transport/sse-transport.d.ts +88 -0
- package/dist/transport/sse-transport.js +316 -0
- package/dist/transport/stdio-transport.d.ts +43 -0
- package/dist/transport/stdio-transport.js +238 -0
- package/dist/transport/types.d.ts +125 -0
- package/dist/transport/types.js +16 -0
- package/dist/utils/concurrency.d.ts +123 -0
- package/dist/utils/concurrency.js +213 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +37 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jsonpath.d.ts +87 -0
- package/dist/utils/jsonpath.js +326 -0
- package/dist/utils/markdown.d.ts +113 -0
- package/dist/utils/markdown.js +265 -0
- package/dist/utils/network.d.ts +14 -0
- package/dist/utils/network.js +17 -0
- package/dist/utils/sanitize.d.ts +92 -0
- package/dist/utils/sanitize.js +191 -0
- package/dist/utils/semantic.d.ts +194 -0
- package/dist/utils/semantic.js +1051 -0
- package/dist/utils/smart-truncate.d.ts +94 -0
- package/dist/utils/smart-truncate.js +361 -0
- package/dist/utils/timeout.d.ts +153 -0
- package/dist/utils/timeout.js +205 -0
- package/dist/utils/yaml-parser.d.ts +58 -0
- package/dist/utils/yaml-parser.js +86 -0
- package/dist/validation/index.d.ts +32 -0
- package/dist/validation/index.js +32 -0
- package/dist/validation/semantic-test-generator.d.ts +50 -0
- package/dist/validation/semantic-test-generator.js +176 -0
- package/dist/validation/semantic-types.d.ts +66 -0
- package/dist/validation/semantic-types.js +94 -0
- package/dist/validation/semantic-validator.d.ts +38 -0
- package/dist/validation/semantic-validator.js +340 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.js +5 -0
- package/dist/verification/types.d.ts +133 -0
- package/dist/verification/types.js +5 -0
- package/dist/verification/verifier.d.ts +30 -0
- package/dist/verification/verifier.js +309 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +48 -0
- package/dist/workflow/auto-generator.d.ts +27 -0
- package/dist/workflow/auto-generator.js +513 -0
- package/dist/workflow/discovery.d.ts +40 -0
- package/dist/workflow/discovery.js +195 -0
- package/dist/workflow/executor.d.ts +82 -0
- package/dist/workflow/executor.js +611 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/loader.d.ts +24 -0
- package/dist/workflow/loader.js +194 -0
- package/dist/workflow/state-tracker.d.ts +98 -0
- package/dist/workflow/state-tracker.js +424 -0
- package/dist/workflow/types.d.ts +337 -0
- package/dist/workflow/types.js +5 -0
- package/package.json +94 -0
- package/schemas/bellwether-check.schema.json +651 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication module for Bellwether Cloud.
|
|
3
|
+
*
|
|
4
|
+
* Handles session storage, retrieval, and management.
|
|
5
|
+
* Sessions are stored in ~/.bellwether/session.json with restricted permissions.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, statSync, chmodSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir, platform } from 'os';
|
|
10
|
+
import { URLS, PATHS, PATTERNS, CLI_SECURITY } from '../constants.js';
|
|
11
|
+
import { isLocalhost } from '../utils/index.js';
|
|
12
|
+
import * as output from '../cli/output.js';
|
|
13
|
+
/**
|
|
14
|
+
* Directory for bellwether configuration.
|
|
15
|
+
*/
|
|
16
|
+
export const CONFIG_DIR = join(homedir(), PATHS.CONFIG_DIR);
|
|
17
|
+
/**
|
|
18
|
+
* Path to session file.
|
|
19
|
+
*/
|
|
20
|
+
export const SESSION_FILE = join(CONFIG_DIR, PATHS.SESSION_FILE);
|
|
21
|
+
/**
|
|
22
|
+
* Environment variable name for session token.
|
|
23
|
+
*/
|
|
24
|
+
export const SESSION_ENV_VAR = 'BELLWETHER_SESSION';
|
|
25
|
+
/**
|
|
26
|
+
* Environment variable name for API base URL.
|
|
27
|
+
*/
|
|
28
|
+
export const BASE_URL_ENV_VAR = 'BELLWETHER_API_URL';
|
|
29
|
+
/**
|
|
30
|
+
* Environment variable name for team ID override.
|
|
31
|
+
*/
|
|
32
|
+
export const TEAM_ID_ENV_VAR = 'BELLWETHER_TEAM_ID';
|
|
33
|
+
/**
|
|
34
|
+
* Session token prefix for validation.
|
|
35
|
+
*/
|
|
36
|
+
export const SESSION_PREFIX = CLI_SECURITY.SESSION_PREFIX;
|
|
37
|
+
/**
|
|
38
|
+
* Mock session prefix for development.
|
|
39
|
+
*/
|
|
40
|
+
export const MOCK_SESSION_PREFIX = CLI_SECURITY.MOCK_SESSION_PREFIX;
|
|
41
|
+
/**
|
|
42
|
+
* Session token pattern: sess_ followed by 64 hex characters.
|
|
43
|
+
* Mock sessions use sess_mock_ prefix with username and hex characters.
|
|
44
|
+
* Format: sess_mock_<username>_<hex>
|
|
45
|
+
*/
|
|
46
|
+
const SESSION_TOKEN_PATTERN = PATTERNS.SESSION_TOKEN;
|
|
47
|
+
const MOCK_SESSION_TOKEN_PATTERN = PATTERNS.MOCK_SESSION_TOKEN;
|
|
48
|
+
/**
|
|
49
|
+
* Ensure the config directory exists.
|
|
50
|
+
*/
|
|
51
|
+
export function ensureConfigDir() {
|
|
52
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
53
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Verify and fix session file permissions.
|
|
58
|
+
* On Unix systems, ensures file is only readable by owner (0600).
|
|
59
|
+
* Returns false if permissions could not be verified/fixed.
|
|
60
|
+
*/
|
|
61
|
+
function verifySessionPermissions() {
|
|
62
|
+
// Skip permission checks on Windows (Windows has different ACL system)
|
|
63
|
+
if (platform() === 'win32') {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
if (!existsSync(SESSION_FILE)) {
|
|
68
|
+
return true; // No file to check
|
|
69
|
+
}
|
|
70
|
+
const stats = statSync(SESSION_FILE);
|
|
71
|
+
const mode = stats.mode & 0o777;
|
|
72
|
+
// Check if permissions are too permissive (anyone other than owner can read)
|
|
73
|
+
if (mode & 0o077) {
|
|
74
|
+
// Try to fix permissions
|
|
75
|
+
try {
|
|
76
|
+
chmodSync(SESSION_FILE, 0o600);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Could not fix permissions
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
// If we can't stat the file, there's a real problem
|
|
88
|
+
output.warn(`Warning: Could not verify session file permissions: ${error instanceof Error ? error.message : error}`);
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the stored session.
|
|
94
|
+
* Returns null if no session exists, session is expired, or file is corrupted.
|
|
95
|
+
*/
|
|
96
|
+
export function getStoredSession() {
|
|
97
|
+
if (!existsSync(SESSION_FILE)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
// Verify file permissions before reading sensitive data
|
|
101
|
+
const permissionsOk = verifySessionPermissions();
|
|
102
|
+
if (!permissionsOk) {
|
|
103
|
+
// Permissions are insecure and couldn't be fixed - refuse to use session
|
|
104
|
+
output.error('Error: Session file has insecure permissions. Please fix with:');
|
|
105
|
+
output.error(` chmod 600 ${SESSION_FILE}`);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const content = readFileSync(SESSION_FILE, 'utf-8');
|
|
110
|
+
const session = JSON.parse(content);
|
|
111
|
+
// Validate and check if session is expired
|
|
112
|
+
if (!session.expiresAt) {
|
|
113
|
+
output.warn('Warning: Session file missing expiration date, clearing it.');
|
|
114
|
+
clearSession();
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const expirationDate = new Date(session.expiresAt);
|
|
118
|
+
if (isNaN(expirationDate.getTime())) {
|
|
119
|
+
output.warn('Warning: Session file has invalid expiration date, clearing it.');
|
|
120
|
+
clearSession();
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
if (expirationDate <= new Date()) {
|
|
124
|
+
// Session expired, clear it
|
|
125
|
+
clearSession();
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return session;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// If file is corrupted, log and return null
|
|
132
|
+
output.warn('Warning: Session file is corrupted, clearing it.');
|
|
133
|
+
clearSession();
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Save session to disk.
|
|
139
|
+
* File is created with 0600 permissions (owner read/write only).
|
|
140
|
+
*/
|
|
141
|
+
export function saveSession(session) {
|
|
142
|
+
ensureConfigDir();
|
|
143
|
+
writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2), { mode: 0o600 });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Clear the stored session.
|
|
147
|
+
*/
|
|
148
|
+
export function clearSession() {
|
|
149
|
+
if (existsSync(SESSION_FILE)) {
|
|
150
|
+
try {
|
|
151
|
+
unlinkSync(SESSION_FILE);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Ignore errors
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get the session token.
|
|
160
|
+
*
|
|
161
|
+
* Priority:
|
|
162
|
+
* 1. BELLWETHER_SESSION environment variable
|
|
163
|
+
* 2. Stored session in ~/.bellwether/session.json
|
|
164
|
+
*/
|
|
165
|
+
export function getSessionToken() {
|
|
166
|
+
// Check environment variable first
|
|
167
|
+
const envSession = process.env[SESSION_ENV_VAR];
|
|
168
|
+
if (envSession) {
|
|
169
|
+
return envSession;
|
|
170
|
+
}
|
|
171
|
+
// Fall back to stored session
|
|
172
|
+
const session = getStoredSession();
|
|
173
|
+
return session?.sessionToken;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the API base URL.
|
|
177
|
+
*
|
|
178
|
+
* Priority:
|
|
179
|
+
* 1. BELLWETHER_API_URL environment variable
|
|
180
|
+
* 2. Default: https://api.bellwether.sh
|
|
181
|
+
*
|
|
182
|
+
* Security: Validates that custom URLs use HTTPS (except localhost for development).
|
|
183
|
+
*/
|
|
184
|
+
export function getBaseUrl() {
|
|
185
|
+
// Check environment variable first
|
|
186
|
+
const envUrl = process.env[BASE_URL_ENV_VAR];
|
|
187
|
+
if (envUrl) {
|
|
188
|
+
// Validate URL format and security
|
|
189
|
+
try {
|
|
190
|
+
const url = new URL(envUrl);
|
|
191
|
+
// Allow HTTP only for localhost (development)
|
|
192
|
+
if (url.protocol !== 'https:' && !isLocalhost(url.hostname)) {
|
|
193
|
+
output.warn(`Warning: ${BASE_URL_ENV_VAR} uses insecure HTTP protocol.`);
|
|
194
|
+
output.warn('HTTPS is required for production use to protect authentication tokens.');
|
|
195
|
+
output.warn('Use HTTPS or localhost for secure communication.\n');
|
|
196
|
+
}
|
|
197
|
+
return envUrl;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
output.warn(`Warning: Invalid URL in ${BASE_URL_ENV_VAR}: ${envUrl}`);
|
|
201
|
+
output.warn('Falling back to default API URL.\n');
|
|
202
|
+
return URLS.CLOUD_API;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Return default
|
|
206
|
+
return URLS.CLOUD_API;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Check if a session token appears valid (strict format check).
|
|
210
|
+
* Validates against exact patterns to prevent injection.
|
|
211
|
+
*/
|
|
212
|
+
export function isValidSessionFormat(token) {
|
|
213
|
+
return SESSION_TOKEN_PATTERN.test(token) || MOCK_SESSION_TOKEN_PATTERN.test(token);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Check if a session token is a mock session (for development).
|
|
217
|
+
*/
|
|
218
|
+
export function isMockSession(token) {
|
|
219
|
+
return token.startsWith(MOCK_SESSION_PREFIX);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Check if currently authenticated.
|
|
223
|
+
*/
|
|
224
|
+
export function isAuthenticated() {
|
|
225
|
+
const token = getSessionToken();
|
|
226
|
+
return token !== undefined && isValidSessionFormat(token);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get the active team ID.
|
|
230
|
+
*
|
|
231
|
+
* Priority:
|
|
232
|
+
* 1. BELLWETHER_TEAM_ID environment variable
|
|
233
|
+
* 2. Team ID from project link (if in a linked project directory)
|
|
234
|
+
* 3. Active team ID from stored session
|
|
235
|
+
*/
|
|
236
|
+
export function getTeamId(projectDir = process.cwd()) {
|
|
237
|
+
// Check environment variable first (for CI/CD)
|
|
238
|
+
const envTeamId = process.env[TEAM_ID_ENV_VAR];
|
|
239
|
+
if (envTeamId) {
|
|
240
|
+
return envTeamId;
|
|
241
|
+
}
|
|
242
|
+
// Check project link for project-specific team
|
|
243
|
+
const projectLink = getLinkedProject(projectDir);
|
|
244
|
+
if (projectLink?.teamId) {
|
|
245
|
+
return projectLink.teamId;
|
|
246
|
+
}
|
|
247
|
+
// Fall back to session's active team
|
|
248
|
+
const session = getStoredSession();
|
|
249
|
+
return session?.activeTeamId;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get the active team details.
|
|
253
|
+
* Returns the full team object if available.
|
|
254
|
+
*/
|
|
255
|
+
export function getActiveTeam(projectDir = process.cwd()) {
|
|
256
|
+
const teamId = getTeamId(projectDir);
|
|
257
|
+
if (!teamId) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
const session = getStoredSession();
|
|
261
|
+
return session?.teams?.find(t => t.id === teamId);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get all teams from the stored session.
|
|
265
|
+
*/
|
|
266
|
+
export function getSessionTeams() {
|
|
267
|
+
const session = getStoredSession();
|
|
268
|
+
return session?.teams ?? [];
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Set the active team in the stored session.
|
|
272
|
+
* Returns true if successful, false if team not found in session.
|
|
273
|
+
*/
|
|
274
|
+
export function setActiveTeam(teamId) {
|
|
275
|
+
const session = getStoredSession();
|
|
276
|
+
if (!session) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
// Verify the team exists in the session
|
|
280
|
+
const teamExists = session.teams?.some(t => t.id === teamId);
|
|
281
|
+
if (!teamExists) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
// Update the active team
|
|
285
|
+
session.activeTeamId = teamId;
|
|
286
|
+
saveSession(session);
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Update the session token in the stored session.
|
|
291
|
+
* Called when the server rotates the token and returns a new one.
|
|
292
|
+
*
|
|
293
|
+
* @param newToken - The new session token from the server
|
|
294
|
+
* @returns Promise that resolves when the session is updated
|
|
295
|
+
*/
|
|
296
|
+
export async function updateSessionToken(newToken) {
|
|
297
|
+
const session = getStoredSession();
|
|
298
|
+
if (!session) {
|
|
299
|
+
// No session to update - this shouldn't happen in normal flow
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// Validate the new token format
|
|
303
|
+
if (!isValidSessionFormat(newToken)) {
|
|
304
|
+
throw new Error('Invalid session token format received from server');
|
|
305
|
+
}
|
|
306
|
+
// Update the token and record when it was rotated
|
|
307
|
+
session.sessionToken = newToken;
|
|
308
|
+
session.tokenRotatedAt = new Date().toISOString();
|
|
309
|
+
saveSession(session);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Directory name for per-project bellwether config.
|
|
313
|
+
*/
|
|
314
|
+
export const PROJECT_CONFIG_DIR = '.bellwether';
|
|
315
|
+
/**
|
|
316
|
+
* File name for project link configuration.
|
|
317
|
+
*/
|
|
318
|
+
export const LINK_FILE = 'link.json';
|
|
319
|
+
/**
|
|
320
|
+
* Get the project link file path for a given directory.
|
|
321
|
+
*/
|
|
322
|
+
export function getLinkFilePath(projectDir = process.cwd()) {
|
|
323
|
+
return join(projectDir, PROJECT_CONFIG_DIR, LINK_FILE);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get the linked project for the current directory.
|
|
327
|
+
*/
|
|
328
|
+
export function getLinkedProject(projectDir = process.cwd()) {
|
|
329
|
+
const linkFile = getLinkFilePath(projectDir);
|
|
330
|
+
if (!existsSync(linkFile)) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
const content = readFileSync(linkFile, 'utf-8');
|
|
335
|
+
return JSON.parse(content);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Save a project link for the current directory.
|
|
343
|
+
*/
|
|
344
|
+
export function saveProjectLink(link, projectDir = process.cwd()) {
|
|
345
|
+
const configDir = join(projectDir, PROJECT_CONFIG_DIR);
|
|
346
|
+
if (!existsSync(configDir)) {
|
|
347
|
+
mkdirSync(configDir, { recursive: true });
|
|
348
|
+
}
|
|
349
|
+
const linkFile = getLinkFilePath(projectDir);
|
|
350
|
+
writeFileSync(linkFile, JSON.stringify(link, null, 2));
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Remove the project link for the current directory.
|
|
354
|
+
*/
|
|
355
|
+
export function removeProjectLink(projectDir = process.cwd()) {
|
|
356
|
+
const linkFile = getLinkFilePath(projectDir);
|
|
357
|
+
if (!existsSync(linkFile)) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
unlinkSync(linkFile);
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Check if the current directory is linked to a project.
|
|
370
|
+
*/
|
|
371
|
+
export function isLinked(projectDir = process.cwd()) {
|
|
372
|
+
return getLinkedProject(projectDir) !== null;
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud client factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates the appropriate cloud client implementation based on configuration.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - MockCloudClient (local development/testing)
|
|
7
|
+
* - HttpCloudClient (production API)
|
|
8
|
+
*/
|
|
9
|
+
import type { BellwetherCloudClient, CloudConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Create a cloud client with the given configuration.
|
|
12
|
+
*
|
|
13
|
+
* If no session token is provided, attempts to get one from environment/storage.
|
|
14
|
+
* Automatically selects mock client for development or HTTP client for production.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createCloudClient(config?: Partial<CloudConfig>): BellwetherCloudClient;
|
|
17
|
+
/**
|
|
18
|
+
* Create a cloud client with explicit session token.
|
|
19
|
+
*
|
|
20
|
+
* Convenience function for when you already have a session token.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createCloudClientWithSession(sessionToken: string): BellwetherCloudClient;
|
|
23
|
+
export type { BellwetherCloudClient, CloudConfig } from './types.js';
|
|
24
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud client factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates the appropriate cloud client implementation based on configuration.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - MockCloudClient (local development/testing)
|
|
7
|
+
* - HttpCloudClient (production API)
|
|
8
|
+
*/
|
|
9
|
+
import { MockCloudClient } from './mock-client.js';
|
|
10
|
+
import { HttpCloudClient } from './http-client.js';
|
|
11
|
+
import { getSessionToken, getBaseUrl, isMockSession, getTeamId } from './auth.js';
|
|
12
|
+
import { TIMEOUTS } from '../constants.js';
|
|
13
|
+
/**
|
|
14
|
+
* Create a cloud client with the given configuration.
|
|
15
|
+
*
|
|
16
|
+
* If no session token is provided, attempts to get one from environment/storage.
|
|
17
|
+
* Automatically selects mock client for development or HTTP client for production.
|
|
18
|
+
*/
|
|
19
|
+
export function createCloudClient(config) {
|
|
20
|
+
const sessionToken = config?.sessionToken ?? getSessionToken();
|
|
21
|
+
const baseUrl = config?.baseUrl ?? getBaseUrl();
|
|
22
|
+
const timeout = config?.timeout ?? TIMEOUTS.CLOUD_API;
|
|
23
|
+
// Determine which client to use
|
|
24
|
+
const useMock = shouldUseMockClient(sessionToken);
|
|
25
|
+
if (useMock) {
|
|
26
|
+
return new MockCloudClient(sessionToken);
|
|
27
|
+
}
|
|
28
|
+
// Use HTTP client for production
|
|
29
|
+
if (!sessionToken) {
|
|
30
|
+
throw new Error('Session required for HTTP client. Run `bellwether login` first.');
|
|
31
|
+
}
|
|
32
|
+
const teamId = getTeamId();
|
|
33
|
+
return new HttpCloudClient(baseUrl, sessionToken, timeout, teamId);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Determine if we should use the mock client.
|
|
37
|
+
*
|
|
38
|
+
* Uses mock client when:
|
|
39
|
+
* - Session is a mock session (sess_mock_*)
|
|
40
|
+
* - No session is provided (unauthenticated mode)
|
|
41
|
+
*
|
|
42
|
+
* Uses HTTP client when:
|
|
43
|
+
* - A real session is provided (even for localhost - allows local server testing)
|
|
44
|
+
*/
|
|
45
|
+
function shouldUseMockClient(sessionToken) {
|
|
46
|
+
// Use mock if session is a mock session
|
|
47
|
+
if (sessionToken && isMockSession(sessionToken)) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Use mock if no session (unauthenticated mock mode)
|
|
51
|
+
if (!sessionToken) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// Use HTTP client for real sessions (works with localhost or production)
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a cloud client with explicit session token.
|
|
59
|
+
*
|
|
60
|
+
* Convenience function for when you already have a session token.
|
|
61
|
+
*/
|
|
62
|
+
export function createCloudClientWithSession(sessionToken) {
|
|
63
|
+
return createCloudClient({ sessionToken });
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP cloud client for production API.
|
|
3
|
+
*
|
|
4
|
+
* Makes real HTTP requests to the Bellwether Cloud API.
|
|
5
|
+
* Handles automatic session token rotation when the server returns
|
|
6
|
+
* a new token via the X-Rotated-Session-Token header.
|
|
7
|
+
*/
|
|
8
|
+
import type { BellwetherCloudClient, CloudUser, Project, BaselineVersion, UploadResult, DiffSummary, BellwetherBaseline, BadgeInfo, CloudVerificationResult, VerificationSubmissionResult } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* HTTP cloud client implementation.
|
|
11
|
+
*/
|
|
12
|
+
export declare class HttpCloudClient implements BellwetherCloudClient {
|
|
13
|
+
private baseUrl;
|
|
14
|
+
private sessionToken;
|
|
15
|
+
private teamId?;
|
|
16
|
+
private timeout;
|
|
17
|
+
constructor(baseUrl: string, sessionToken: string, timeout?: number, teamId?: string);
|
|
18
|
+
/**
|
|
19
|
+
* Make an authenticated request.
|
|
20
|
+
* Handles automatic session token rotation when the server returns
|
|
21
|
+
* a new token via the X-Rotated-Session-Token header.
|
|
22
|
+
*/
|
|
23
|
+
private request;
|
|
24
|
+
isAuthenticated(): boolean;
|
|
25
|
+
whoami(): Promise<CloudUser | null>;
|
|
26
|
+
listProjects(): Promise<Project[]>;
|
|
27
|
+
createProject(name: string, serverCommand: string): Promise<Project>;
|
|
28
|
+
getProject(projectId: string): Promise<Project | null>;
|
|
29
|
+
deleteProject(projectId: string): Promise<void>;
|
|
30
|
+
uploadBaseline(projectId: string, baseline: BellwetherBaseline): Promise<UploadResult>;
|
|
31
|
+
getHistory(projectId: string, limit?: number): Promise<BaselineVersion[]>;
|
|
32
|
+
getBaseline(baselineId: string): Promise<BellwetherBaseline | null>;
|
|
33
|
+
getDiff(projectId: string, fromVersion: number, toVersion: number): Promise<DiffSummary>;
|
|
34
|
+
getLatestDiff(projectId: string): Promise<DiffSummary | null>;
|
|
35
|
+
getBadgeInfo(projectId: string): Promise<BadgeInfo | null>;
|
|
36
|
+
submitVerification(projectId: string, result: CloudVerificationResult, report?: Record<string, unknown>): Promise<VerificationSubmissionResult>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=http-client.d.ts.map
|