stubsmith 0.2.0 → 0.2.1
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/README.md +8 -1
- package/dist/cli.js +33 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +49 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +49 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -348,7 +348,7 @@ declare function install(options?: StubsmithOptions): StubsmithClient;
|
|
|
348
348
|
/** True while an installed client exists and is not stopped. */
|
|
349
349
|
declare function isInstalled(): boolean;
|
|
350
350
|
|
|
351
|
-
declare const VERSION = "0.2.
|
|
351
|
+
declare const VERSION = "0.2.1";
|
|
352
352
|
|
|
353
353
|
interface FixturesOptions {
|
|
354
354
|
/** Only `"status"`: at most one fixture per distinct HTTP status, newest first. */
|
package/dist/index.d.ts
CHANGED
|
@@ -348,7 +348,7 @@ declare function install(options?: StubsmithOptions): StubsmithClient;
|
|
|
348
348
|
/** True while an installed client exists and is not stopped. */
|
|
349
349
|
declare function isInstalled(): boolean;
|
|
350
350
|
|
|
351
|
-
declare const VERSION = "0.2.
|
|
351
|
+
declare const VERSION = "0.2.1";
|
|
352
352
|
|
|
353
353
|
interface FixturesOptions {
|
|
354
354
|
/** Only `"status"`: at most one fixture per distinct HTTP status, newest first. */
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/_version.ts
|
|
2
|
-
var VERSION = "0.2.
|
|
2
|
+
var VERSION = "0.2.1";
|
|
3
3
|
|
|
4
4
|
// src/instrument.ts
|
|
5
5
|
import http2 from "http";
|
|
@@ -86,6 +86,31 @@ function truncateUtf8Bytes(s, n) {
|
|
|
86
86
|
// src/client.ts
|
|
87
87
|
import { gzipSync } from "zlib";
|
|
88
88
|
|
|
89
|
+
// src/endpoint.ts
|
|
90
|
+
var LOCAL_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
91
|
+
var InsecureEndpointError = class extends Error {
|
|
92
|
+
constructor(message) {
|
|
93
|
+
super(message);
|
|
94
|
+
this.name = "InsecureEndpointError";
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
function checkEndpoint(url) {
|
|
98
|
+
let u;
|
|
99
|
+
try {
|
|
100
|
+
u = new URL(url);
|
|
101
|
+
} catch {
|
|
102
|
+
throw new InsecureEndpointError(
|
|
103
|
+
"stubsmith: the Stubsmith URL is not a valid URL; the SDK sends only to an https URL."
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (u.protocol === "https:" && u.hostname !== "") return;
|
|
107
|
+
if (u.protocol === "http:" && LOCAL_HOSTS.has(u.hostname)) return;
|
|
108
|
+
const shown = u.hostname ? `${u.protocol}//${u.hostname}` : u.protocol;
|
|
109
|
+
throw new InsecureEndpointError(
|
|
110
|
+
`stubsmith: refusing to send to ${shown}. The SDK sends only over https; plain http is allowed only for localhost, 127.0.0.1 and ::1.`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
89
114
|
// src/internal/codepoint.ts
|
|
90
115
|
function compareCodePoints(a, b) {
|
|
91
116
|
const la = a.length;
|
|
@@ -2621,6 +2646,12 @@ function sendRequest(url, opts) {
|
|
|
2621
2646
|
fail(err);
|
|
2622
2647
|
return;
|
|
2623
2648
|
}
|
|
2649
|
+
try {
|
|
2650
|
+
checkEndpoint(url);
|
|
2651
|
+
} catch (err) {
|
|
2652
|
+
fail(err);
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2624
2655
|
const request = u.protocol === "https:" ? ORIGINAL_REQUEST.https : u.protocol === "http:" ? ORIGINAL_REQUEST.http : null;
|
|
2625
2656
|
if (request === null) {
|
|
2626
2657
|
fail(new Error(`unsupported protocol ${u.protocol}`));
|
|
@@ -2888,9 +2919,22 @@ var StubsmithClient = class _StubsmithClient {
|
|
|
2888
2919
|
counters.set(this, this.counts);
|
|
2889
2920
|
const env2 = readEnv();
|
|
2890
2921
|
this.apiKey = options.apiKey || env2.apiKey;
|
|
2891
|
-
this.enabled = Boolean(this.apiKey);
|
|
2892
2922
|
this.url = options.url || env2.url || DEFAULT_URL;
|
|
2893
2923
|
this.backendUrl = options.backendUrl || env2.backendUrl || DEFAULT_BACKEND_URL;
|
|
2924
|
+
let secure = true;
|
|
2925
|
+
if (this.apiKey) {
|
|
2926
|
+
try {
|
|
2927
|
+
checkEndpoint(this.url);
|
|
2928
|
+
checkEndpoint(this.backendUrl);
|
|
2929
|
+
} catch (err) {
|
|
2930
|
+
secure = false;
|
|
2931
|
+
try {
|
|
2932
|
+
console.warn(`${err instanceof Error ? err.message : String(err)} Capture is off.`);
|
|
2933
|
+
} catch {
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
this.enabled = Boolean(this.apiKey) && secure;
|
|
2894
2938
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
2895
2939
|
const sr = options.sampleRate ?? 1;
|
|
2896
2940
|
this.sampleRate = Number.isNaN(sr) ? 1 : Math.max(0, Math.min(1, sr));
|
|
@@ -3136,7 +3180,7 @@ var StubsmithClient = class _StubsmithClient {
|
|
|
3136
3180
|
if (this.inflight === t) this.inflight = null;
|
|
3137
3181
|
}
|
|
3138
3182
|
reportIngestRefusal(res.body, res.status, this.debug);
|
|
3139
|
-
if (res.status >=
|
|
3183
|
+
if (res.status >= 300) {
|
|
3140
3184
|
this.sendFailures++;
|
|
3141
3185
|
debugLog(`send failed - status=${res.status} url=${this.url}`);
|
|
3142
3186
|
}
|
|
@@ -3854,6 +3898,7 @@ async function fixturesBundle(spec, opts = {}) {
|
|
|
3854
3898
|
const params = new URLSearchParams({ method: method.toUpperCase(), path: path3 });
|
|
3855
3899
|
if (opts.distinct !== void 0) params.set("distinct", opts.distinct);
|
|
3856
3900
|
if (opts.limit !== void 0) params.set("limit", String(opts.limit));
|
|
3901
|
+
checkEndpoint(base);
|
|
3857
3902
|
const url = `${base.replace(/\/+$/, "")}/v1/fixtures?${params.toString()}`;
|
|
3858
3903
|
let res;
|
|
3859
3904
|
try {
|
|
@@ -3928,6 +3973,7 @@ async function fetchOne(apiUrl, apiKey, method, p, samples) {
|
|
|
3928
3973
|
if (method) params.set("method", method);
|
|
3929
3974
|
if (p) params.set("path", p);
|
|
3930
3975
|
if (samples !== null) params.set("samples", samples);
|
|
3976
|
+
checkEndpoint(apiUrl);
|
|
3931
3977
|
const qs = [...params].length > 0 ? `?${params.toString()}` : "";
|
|
3932
3978
|
const url = `${apiUrl.replace(/\/+$/, "")}/v1/replay/bundle${qs}`;
|
|
3933
3979
|
let res;
|