@apifuse/provider-sdk 2.2.0-beta.11 → 2.2.0-beta.13
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/AUTHORING.md +238 -0
- package/CHANGELOG.md +14 -0
- package/README.md +44 -2
- package/bin/apifuse-pack-smoke.ts +14 -0
- package/bin/apifuse-pack-types.ts +40 -1
- package/bin/apifuse-record.ts +622 -57
- package/bin/apifuse-submit-check.ts +43 -10
- package/dist/config/loader.d.ts +9 -1
- package/dist/config/loader.js +9 -0
- package/dist/define.d.ts +2 -1
- package/dist/define.js +61 -3
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +15 -0
- package/dist/fixture-sanitization.d.ts +26 -0
- package/dist/fixture-sanitization.js +216 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/provider.d.ts +2 -1
- package/dist/provider.js +1 -0
- package/dist/runtime/http.js +86 -32
- package/dist/runtime/instrumentation.js +295 -9
- package/dist/runtime/native-network.d.ts +53 -0
- package/dist/runtime/native-network.js +477 -0
- package/dist/runtime/proxy-nodemaven.d.ts +14 -0
- package/dist/runtime/proxy-nodemaven.js +20 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/stealth.d.ts +3 -1
- package/dist/runtime/stealth.js +352 -86
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +451 -19
- package/dist/types.d.ts +201 -7
- package/package.json +3 -1
- package/src/config/loader.ts +22 -1
- package/src/define.ts +81 -3
- package/src/errors.ts +15 -0
- package/src/fixture-sanitization.ts +247 -0
- package/src/index.ts +45 -1
- package/src/provider.ts +37 -0
- package/src/runtime/http.ts +144 -38
- package/src/runtime/instrumentation.ts +424 -8
- package/src/runtime/native-network.ts +600 -0
- package/src/runtime/proxy-nodemaven.ts +37 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/stealth.ts +420 -88
- package/src/server/index.ts +4 -1
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/stream-evidence.ts +988 -0
- package/src/testing/index.ts +9 -1
- package/src/testing/run.ts +608 -12
- package/src/types.ts +235 -7
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Relative
|
|
3
|
-
*
|
|
4
|
-
* so
|
|
2
|
+
* Relative date-token resolution for health-check case inputs and fixture
|
|
3
|
+
* requests. The calendar defaults to KST; callers that need UTC must opt in
|
|
4
|
+
* explicitly so UTC and KST do not silently disagree from 15:00–23:59 UTC.
|
|
5
5
|
*
|
|
6
|
-
* Supported token: `+<days>d` or `+<days>d:YYYYMMDD` (1..365 days ahead
|
|
6
|
+
* Supported token: `+<days>d` or `+<days>d:YYYYMMDD` (1..365 days ahead).
|
|
7
7
|
*/
|
|
8
|
-
const
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
const date = new Date(Date.UTC(
|
|
8
|
+
const RELATIVE_DATE_TOKEN = /^\+(\d{1,3})d(?::(YYYYMMDD))?$/i;
|
|
9
|
+
function dateFromDaysAhead(daysAhead, now = new Date(), format = "YYYY-MM-DD", calendar = "KST") {
|
|
10
|
+
const calendarNow = new Date(now.getTime() + (calendar === "KST" ? 9 * 60 * 60 * 1000 : 0));
|
|
11
|
+
const date = new Date(Date.UTC(calendarNow.getUTCFullYear(), calendarNow.getUTCMonth(), calendarNow.getUTCDate() + daysAhead));
|
|
12
12
|
const isoDate = date.toISOString().slice(0, 10);
|
|
13
13
|
return format === "YYYYMMDD" ? isoDate.replace(/-/g, "") : isoDate;
|
|
14
14
|
}
|
|
15
|
-
export function resolveHealthCheckInputDateTokens(value, now = new Date()) {
|
|
15
|
+
export function resolveHealthCheckInputDateTokens(value, now = new Date(), calendar = "KST") {
|
|
16
16
|
if (typeof value === "string") {
|
|
17
|
-
const relative = value.match(
|
|
17
|
+
const relative = value.match(RELATIVE_DATE_TOKEN);
|
|
18
18
|
if (!relative)
|
|
19
19
|
return value;
|
|
20
20
|
const daysAhead = Number(relative[1]);
|
|
@@ -22,16 +22,20 @@ export function resolveHealthCheckInputDateTokens(value, now = new Date()) {
|
|
|
22
22
|
return value;
|
|
23
23
|
}
|
|
24
24
|
const format = relative[2]?.toUpperCase() === "YYYYMMDD" ? "YYYYMMDD" : "YYYY-MM-DD";
|
|
25
|
-
return
|
|
25
|
+
return dateFromDaysAhead(daysAhead, now, format, calendar);
|
|
26
26
|
}
|
|
27
27
|
if (Array.isArray(value)) {
|
|
28
|
-
|
|
28
|
+
const resolved = value.map((entry) => resolveHealthCheckInputDateTokens(entry, now, calendar));
|
|
29
|
+
return resolved.some((entry, index) => entry !== value[index]) ? resolved : value;
|
|
29
30
|
}
|
|
30
31
|
if (value && typeof value === "object") {
|
|
31
|
-
|
|
32
|
+
const resolved = Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
32
33
|
key,
|
|
33
|
-
resolveHealthCheckInputDateTokens(entry, now),
|
|
34
|
+
resolveHealthCheckInputDateTokens(entry, now, calendar),
|
|
34
35
|
]));
|
|
36
|
+
return Object.entries(resolved).some(([key, entry]) => entry !== Reflect.get(value, key))
|
|
37
|
+
? resolved
|
|
38
|
+
: value;
|
|
35
39
|
}
|
|
36
40
|
return value;
|
|
37
41
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type JsonValue } from "./contract-json.js";
|
|
2
|
+
import type { HttpStreamResponse } from "./types.js";
|
|
3
|
+
export declare const STREAM_PREVIEW_BYTES = 4096;
|
|
4
|
+
export declare const STREAM_FINALIZE_TIMEOUT_MS = 30000;
|
|
5
|
+
declare const STREAM_EVIDENCE_HEADER_NAMES: readonly ["content-disposition", "content-length", "content-type"];
|
|
6
|
+
type StreamEvidenceHeaderName = (typeof STREAM_EVIDENCE_HEADER_NAMES)[number];
|
|
7
|
+
export type StreamEvidenceHeaders = Partial<Record<StreamEvidenceHeaderName, string>>;
|
|
8
|
+
export interface StreamEvidenceRequest {
|
|
9
|
+
ordinal: number;
|
|
10
|
+
method: string;
|
|
11
|
+
path: string;
|
|
12
|
+
}
|
|
13
|
+
declare const STREAM_EVIDENCE_REDACTION_REASONS: readonly ["high-entropy-token", "malformed-json", "pem-private-key", "sanitized-preview-too-large", "sanitizer-output-invalid", "sensitive-delimited-column", "textual-xml", "truncated-form", "truncated-json", "undecodable-text"];
|
|
14
|
+
export type StreamEvidenceRedactionReason = (typeof STREAM_EVIDENCE_REDACTION_REASONS)[number];
|
|
15
|
+
export interface StreamEvidenceRecord {
|
|
16
|
+
__apifuse_stream__: true;
|
|
17
|
+
status: number;
|
|
18
|
+
ok: boolean;
|
|
19
|
+
headers: StreamEvidenceHeaders;
|
|
20
|
+
body_sha256: string;
|
|
21
|
+
body_bytes: number;
|
|
22
|
+
body_preview_base64: string;
|
|
23
|
+
request?: StreamEvidenceRequest;
|
|
24
|
+
preview_sanitized?: true;
|
|
25
|
+
preview_redaction_reason?: StreamEvidenceRedactionReason;
|
|
26
|
+
}
|
|
27
|
+
export type StreamEvidenceReplayResponse = HttpStreamResponse & {
|
|
28
|
+
evidence_only: true;
|
|
29
|
+
body_sha256: string;
|
|
30
|
+
body_bytes: number;
|
|
31
|
+
preview_sanitized?: true;
|
|
32
|
+
preview_redaction_reason?: StreamEvidenceRedactionReason;
|
|
33
|
+
};
|
|
34
|
+
export interface StreamEvidenceCapture {
|
|
35
|
+
response: HttpStreamResponse;
|
|
36
|
+
getEvidence(): Promise<StreamEvidenceRecord>;
|
|
37
|
+
}
|
|
38
|
+
export type StreamCaptureGroupItem = {
|
|
39
|
+
kind: "stream";
|
|
40
|
+
evidence: StreamEvidenceRecord;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "response";
|
|
43
|
+
value: JsonValue;
|
|
44
|
+
};
|
|
45
|
+
export interface StreamCaptureGroup {
|
|
46
|
+
items: StreamCaptureGroupItem[];
|
|
47
|
+
}
|
|
48
|
+
export interface StreamCaptureEnvelope {
|
|
49
|
+
__apifuse_capture__: true;
|
|
50
|
+
items: StreamCaptureGroupItem[];
|
|
51
|
+
}
|
|
52
|
+
export type StreamEvidenceCaptureOptions = {
|
|
53
|
+
requestUrl: string;
|
|
54
|
+
sanitizeFixture?: (value: JsonValue) => JsonValue;
|
|
55
|
+
request?: StreamEvidenceRequest;
|
|
56
|
+
finalizeTimeoutMs?: number;
|
|
57
|
+
};
|
|
58
|
+
export declare function parseStreamEvidenceRecord(value: unknown): StreamEvidenceRecord;
|
|
59
|
+
export declare function isStreamEvidenceRecord(value: unknown): value is StreamEvidenceRecord;
|
|
60
|
+
export declare function findStreamEvidenceRecord(value: unknown): StreamEvidenceRecord | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Selects every stream captured by the latest recording invocation, in stream call order.
|
|
63
|
+
* Evidence without request ordinals uses the legacy latest-record-only behavior.
|
|
64
|
+
*/
|
|
65
|
+
export declare function findStreamEvidenceRecords(value: unknown): StreamEvidenceRecord[];
|
|
66
|
+
/** Returns a tagged latest mixed response group used by evidence-only snapshot replay. */
|
|
67
|
+
export declare function findStreamCaptureGroup(value: unknown): StreamCaptureGroup | undefined;
|
|
68
|
+
/** Creates a discriminated invocation envelope so ordinary arrays cannot mimic capture timelines. */
|
|
69
|
+
export declare function createStreamCaptureEnvelope(items: StreamCaptureGroupItem[]): StreamCaptureEnvelope;
|
|
70
|
+
export declare function isStreamEvidenceReplayResponse(response: HttpStreamResponse): response is StreamEvidenceReplayResponse;
|
|
71
|
+
export declare function captureStreamEvidence(response: HttpStreamResponse, options: StreamEvidenceCaptureOptions): StreamEvidenceCapture;
|
|
72
|
+
export declare function replayStreamEvidence(evidence: StreamEvidenceRecord): StreamEvidenceReplayResponse;
|
|
73
|
+
export declare function hasStreamEvidenceMarker(value: unknown): boolean;
|
|
74
|
+
export {};
|