@apifuse/provider-sdk 2.1.0-beta.6 → 2.1.0-beta.9
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 +15 -0
- package/bin/apifuse-perf.ts +18 -9
- package/dist/ceremonies/index.d.ts +41 -0
- package/dist/ceremonies/index.js +490 -0
- package/dist/choice-token.d.ts +24 -0
- package/dist/choice-token.js +74 -0
- package/dist/cli/commands.d.ts +10 -0
- package/dist/cli/commands.js +80 -0
- package/dist/cli/create.d.ts +47 -0
- package/dist/cli/create.js +762 -0
- package/dist/config/loader.d.ts +107 -0
- package/dist/config/loader.js +935 -0
- package/dist/contract-json.d.ts +9 -0
- package/dist/contract-json.js +51 -0
- package/dist/contract-serialization.d.ts +4 -0
- package/dist/contract-serialization.js +78 -0
- package/dist/contract-types.d.ts +49 -0
- package/dist/contract-types.js +1 -0
- package/dist/contract.d.ts +6 -0
- package/dist/contract.js +155 -0
- package/dist/define.d.ts +97 -0
- package/dist/define.js +1320 -0
- package/dist/dev.d.ts +9 -0
- package/dist/dev.js +15 -0
- package/dist/errors.d.ts +59 -0
- package/dist/errors.js +97 -0
- package/dist/i18n/catalog.d.ts +29 -0
- package/dist/i18n/catalog.js +159 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/keys.d.ts +10 -0
- package/dist/i18n/keys.js +34 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +37 -0
- package/dist/lint.d.ts +73 -0
- package/dist/lint.js +702 -0
- package/dist/observability.d.ts +5 -0
- package/dist/observability.js +39 -0
- package/dist/provider.d.ts +9 -0
- package/dist/provider.js +8 -0
- package/dist/public-schema-field-lint.d.ts +2 -0
- package/dist/public-schema-field-lint.js +158 -0
- package/dist/recipes/gov-api.d.ts +19 -0
- package/dist/recipes/gov-api.js +72 -0
- package/dist/recipes/rest-api.d.ts +21 -0
- package/dist/recipes/rest-api.js +115 -0
- package/dist/runtime/auth-flow.d.ts +14 -0
- package/dist/runtime/auth-flow.js +44 -0
- package/dist/runtime/browser.d.ts +25 -0
- package/dist/runtime/browser.js +1034 -0
- package/dist/runtime/cache.d.ts +10 -0
- package/dist/runtime/cache.js +372 -0
- package/dist/runtime/choice.d.ts +15 -0
- package/dist/runtime/choice.js +435 -0
- package/dist/runtime/credential.d.ts +8 -0
- package/dist/runtime/credential.js +61 -0
- package/dist/runtime/env.d.ts +2 -0
- package/dist/runtime/env.js +10 -0
- package/dist/runtime/executor.d.ts +16 -0
- package/dist/runtime/executor.js +51 -0
- package/dist/runtime/http.d.ts +8 -0
- package/dist/runtime/http.js +706 -0
- package/dist/runtime/insights.d.ts +9 -0
- package/dist/runtime/insights.js +324 -0
- package/dist/runtime/instrumentation.d.ts +8 -0
- package/dist/runtime/instrumentation.js +269 -0
- package/dist/runtime/key-derivation.d.ts +24 -0
- package/dist/runtime/key-derivation.js +73 -0
- package/dist/runtime/keyring.d.ts +25 -0
- package/dist/runtime/keyring.js +93 -0
- package/dist/runtime/namespace.d.ts +9 -0
- package/dist/runtime/namespace.js +19 -0
- package/dist/runtime/otlp.d.ts +39 -0
- package/dist/runtime/otlp.js +103 -0
- package/dist/runtime/perf.d.ts +12 -0
- package/dist/runtime/perf.js +52 -0
- package/dist/runtime/prevalidate.d.ts +12 -0
- package/dist/runtime/prevalidate.js +173 -0
- package/dist/runtime/provider.d.ts +2 -0
- package/dist/runtime/provider.js +11 -0
- package/dist/runtime/proxy-errors.d.ts +21 -0
- package/dist/runtime/proxy-errors.js +83 -0
- package/dist/runtime/proxy-telemetry.d.ts +8 -0
- package/dist/runtime/proxy-telemetry.js +174 -0
- package/dist/runtime/redis.d.ts +17 -0
- package/dist/runtime/redis.js +82 -0
- package/dist/runtime/request-options.d.ts +3 -0
- package/dist/runtime/request-options.js +42 -0
- package/dist/runtime/state.d.ts +17 -0
- package/dist/runtime/state.js +344 -0
- package/dist/runtime/stealth.d.ts +18 -0
- package/dist/runtime/stealth.js +834 -0
- package/dist/runtime/stt.d.ts +22 -0
- package/dist/runtime/stt.js +480 -0
- package/dist/runtime/trace.d.ts +26 -0
- package/dist/runtime/trace.js +142 -0
- package/dist/runtime/waterfall.d.ts +12 -0
- package/dist/runtime/waterfall.js +147 -0
- package/dist/schema.d.ts +74 -0
- package/dist/schema.js +243 -0
- package/dist/serve.d.ts +1 -0
- package/dist/serve.js +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +2 -0
- package/dist/server/serve.d.ts +64 -0
- package/dist/server/serve.js +1110 -0
- package/dist/server/types.d.ts +136 -0
- package/dist/server/types.js +86 -0
- package/dist/stealth/profiles.d.ts +4 -0
- package/dist/stealth/profiles.js +259 -0
- package/dist/stream.d.ts +44 -0
- package/dist/stream.js +151 -0
- package/dist/testing/helpers.d.ts +23 -0
- package/dist/testing/helpers.js +95 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/run.d.ts +34 -0
- package/dist/testing/run.js +303 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.js +61 -0
- package/dist/utils/date.d.ts +6 -0
- package/dist/utils/date.js +101 -0
- package/dist/utils/parse.d.ts +16 -0
- package/dist/utils/parse.js +51 -0
- package/dist/utils/text.d.ts +4 -0
- package/dist/utils/text.js +14 -0
- package/dist/utils/transform.d.ts +8 -0
- package/dist/utils/transform.js +48 -0
- package/package.json +109 -107
- package/src/runtime/stealth.ts +8 -1
- package/src/types.ts +2 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ConnectionModeSchema: z.ZodEnum<{
|
|
3
|
+
credentials: "credentials";
|
|
4
|
+
none: "none";
|
|
5
|
+
oauth2: "oauth2";
|
|
6
|
+
"platform-managed": "platform-managed";
|
|
7
|
+
}>;
|
|
8
|
+
export declare const OperationConnectionSchema: z.ZodObject<{
|
|
9
|
+
id: z.ZodString;
|
|
10
|
+
mode: z.ZodEnum<{
|
|
11
|
+
credentials: "credentials";
|
|
12
|
+
none: "none";
|
|
13
|
+
oauth2: "oauth2";
|
|
14
|
+
"platform-managed": "platform-managed";
|
|
15
|
+
}>;
|
|
16
|
+
secrets: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
17
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
18
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
19
|
+
externalRef: z.ZodString;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
export declare const OperationRequestSchema: z.ZodObject<{
|
|
22
|
+
requestId: z.ZodString;
|
|
23
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
24
|
+
connection: z.ZodOptional<z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
mode: z.ZodEnum<{
|
|
27
|
+
credentials: "credentials";
|
|
28
|
+
none: "none";
|
|
29
|
+
oauth2: "oauth2";
|
|
30
|
+
"platform-managed": "platform-managed";
|
|
31
|
+
}>;
|
|
32
|
+
secrets: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
33
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
35
|
+
externalRef: z.ZodString;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
38
|
+
trace: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export declare const ErrorEnvelopeSchema: z.ZodObject<{
|
|
41
|
+
code: z.ZodString;
|
|
42
|
+
message: z.ZodString;
|
|
43
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
44
|
+
fix: z.ZodOptional<z.ZodString>;
|
|
45
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export declare const OperationSuccessResponseSchema: z.ZodObject<{
|
|
48
|
+
data: z.ZodUnknown;
|
|
49
|
+
meta: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
cached: z.ZodOptional<z.ZodBoolean>;
|
|
51
|
+
stale: z.ZodOptional<z.ZodBoolean>;
|
|
52
|
+
cache: z.ZodOptional<z.ZodObject<{
|
|
53
|
+
hit: z.ZodBoolean;
|
|
54
|
+
stale: z.ZodBoolean;
|
|
55
|
+
keys: z.ZodArray<z.ZodString>;
|
|
56
|
+
source: z.ZodOptional<z.ZodEnum<{
|
|
57
|
+
loader: "loader";
|
|
58
|
+
memory: "memory";
|
|
59
|
+
mixed: "mixed";
|
|
60
|
+
redis: "redis";
|
|
61
|
+
}>>;
|
|
62
|
+
}, z.core.$strip>>;
|
|
63
|
+
retry: z.ZodOptional<z.ZodObject<{
|
|
64
|
+
attempts: z.ZodNumber;
|
|
65
|
+
retries: z.ZodNumber;
|
|
66
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
67
|
+
aggressive_read: "aggressive_read";
|
|
68
|
+
off: "off";
|
|
69
|
+
rate_limit_aware: "rate_limit_aware";
|
|
70
|
+
safe_read: "safe_read";
|
|
71
|
+
transport_transient: "transport_transient";
|
|
72
|
+
}>>;
|
|
73
|
+
transport: z.ZodEnum<{
|
|
74
|
+
native: "native";
|
|
75
|
+
}>;
|
|
76
|
+
lastErrorCode: z.ZodOptional<z.ZodString>;
|
|
77
|
+
lastStatus: z.ZodOptional<z.ZodNumber>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
}, z.core.$loose>>;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
export declare const OperationErrorResponseSchema: z.ZodObject<{
|
|
82
|
+
error: z.ZodObject<{
|
|
83
|
+
code: z.ZodString;
|
|
84
|
+
message: z.ZodString;
|
|
85
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
86
|
+
fix: z.ZodOptional<z.ZodString>;
|
|
87
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
88
|
+
}, z.core.$strip>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
export declare const AuthFlowRequestSchema: z.ZodObject<{
|
|
91
|
+
requestId: z.ZodString;
|
|
92
|
+
flowId: z.ZodString;
|
|
93
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
94
|
+
externalRef: z.ZodOptional<z.ZodString>;
|
|
95
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
96
|
+
providerId: z.ZodOptional<z.ZodString>;
|
|
97
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
98
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
99
|
+
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
100
|
+
connection: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
id: z.ZodString;
|
|
102
|
+
mode: z.ZodEnum<{
|
|
103
|
+
credentials: "credentials";
|
|
104
|
+
none: "none";
|
|
105
|
+
oauth2: "oauth2";
|
|
106
|
+
"platform-managed": "platform-managed";
|
|
107
|
+
}>;
|
|
108
|
+
secrets: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
109
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
110
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
111
|
+
externalRef: z.ZodString;
|
|
112
|
+
}, z.core.$strip>>;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
export declare const AuthFlowSuccessResponseSchema: z.ZodObject<{
|
|
115
|
+
data: z.ZodUnknown;
|
|
116
|
+
contextPatch: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnknown>>>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
export declare const AuthFlowErrorResponseSchema: z.ZodObject<{
|
|
119
|
+
error: z.ZodObject<{
|
|
120
|
+
code: z.ZodString;
|
|
121
|
+
message: z.ZodString;
|
|
122
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
123
|
+
fix: z.ZodOptional<z.ZodString>;
|
|
124
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
}, z.core.$strip>;
|
|
127
|
+
export type ConnectionMode = z.infer<typeof ConnectionModeSchema>;
|
|
128
|
+
export type OperationConnection = z.infer<typeof OperationConnectionSchema>;
|
|
129
|
+
export type OperationRequest = z.infer<typeof OperationRequestSchema>;
|
|
130
|
+
export type OperationSuccessResponse = z.infer<typeof OperationSuccessResponseSchema>;
|
|
131
|
+
export type OperationErrorResponse = z.infer<typeof OperationErrorResponseSchema>;
|
|
132
|
+
export type OperationResponse = OperationSuccessResponse | OperationErrorResponse;
|
|
133
|
+
export type AuthFlowRequest = z.infer<typeof AuthFlowRequestSchema>;
|
|
134
|
+
export type AuthFlowSuccessResponse = z.infer<typeof AuthFlowSuccessResponseSchema>;
|
|
135
|
+
export type AuthFlowErrorResponse = z.infer<typeof AuthFlowErrorResponseSchema>;
|
|
136
|
+
export type AuthFlowResponse = AuthFlowSuccessResponse | AuthFlowErrorResponse;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { HttpRetryPreset } from "../types";
|
|
3
|
+
export const ConnectionModeSchema = z.enum([
|
|
4
|
+
"oauth2",
|
|
5
|
+
"credentials",
|
|
6
|
+
"platform-managed",
|
|
7
|
+
"none",
|
|
8
|
+
]);
|
|
9
|
+
export const OperationConnectionSchema = z.object({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
mode: ConnectionModeSchema,
|
|
12
|
+
secrets: z.record(z.string(), z.string()),
|
|
13
|
+
scopes: z.array(z.string()).optional(),
|
|
14
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
15
|
+
externalRef: z.string(),
|
|
16
|
+
});
|
|
17
|
+
export const OperationRequestSchema = z.object({
|
|
18
|
+
requestId: z.string(),
|
|
19
|
+
input: z.record(z.string(), z.unknown()),
|
|
20
|
+
connection: OperationConnectionSchema.optional(),
|
|
21
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
22
|
+
trace: z.record(z.string(), z.string()).optional(),
|
|
23
|
+
});
|
|
24
|
+
export const ErrorEnvelopeSchema = z.object({
|
|
25
|
+
code: z.string(),
|
|
26
|
+
message: z.string(),
|
|
27
|
+
requestId: z.string().optional(),
|
|
28
|
+
fix: z.string().optional(),
|
|
29
|
+
details: z.unknown().optional(),
|
|
30
|
+
});
|
|
31
|
+
export const OperationSuccessResponseSchema = z.object({
|
|
32
|
+
data: z.unknown(),
|
|
33
|
+
meta: z
|
|
34
|
+
.object({
|
|
35
|
+
cached: z.boolean().optional(),
|
|
36
|
+
stale: z.boolean().optional(),
|
|
37
|
+
cache: z
|
|
38
|
+
.object({
|
|
39
|
+
hit: z.boolean(),
|
|
40
|
+
stale: z.boolean(),
|
|
41
|
+
keys: z.array(z.string()),
|
|
42
|
+
source: z.enum(["redis", "memory", "loader", "mixed"]).optional(),
|
|
43
|
+
})
|
|
44
|
+
.optional(),
|
|
45
|
+
retry: z
|
|
46
|
+
.object({
|
|
47
|
+
attempts: z.number().int().min(1),
|
|
48
|
+
retries: z.number().int().min(0),
|
|
49
|
+
preset: z
|
|
50
|
+
.enum([
|
|
51
|
+
HttpRetryPreset.Off,
|
|
52
|
+
HttpRetryPreset.TransportTransient,
|
|
53
|
+
HttpRetryPreset.SafeRead,
|
|
54
|
+
HttpRetryPreset.AggressiveRead,
|
|
55
|
+
HttpRetryPreset.RateLimitAware,
|
|
56
|
+
])
|
|
57
|
+
.optional(),
|
|
58
|
+
transport: z.enum(["native"]),
|
|
59
|
+
lastErrorCode: z.string().optional(),
|
|
60
|
+
lastStatus: z.number().int().optional(),
|
|
61
|
+
})
|
|
62
|
+
.optional(),
|
|
63
|
+
})
|
|
64
|
+
.passthrough()
|
|
65
|
+
.optional(),
|
|
66
|
+
});
|
|
67
|
+
export const OperationErrorResponseSchema = z.object({
|
|
68
|
+
error: ErrorEnvelopeSchema,
|
|
69
|
+
});
|
|
70
|
+
export const AuthFlowRequestSchema = z.object({
|
|
71
|
+
requestId: z.string(),
|
|
72
|
+
flowId: z.string(),
|
|
73
|
+
connectionId: z.string().optional(),
|
|
74
|
+
externalRef: z.string().optional(),
|
|
75
|
+
tenantId: z.string().optional(),
|
|
76
|
+
providerId: z.string().optional(),
|
|
77
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
78
|
+
input: z.record(z.string(), z.unknown()).optional(),
|
|
79
|
+
context: z.record(z.string(), z.unknown()).optional(),
|
|
80
|
+
connection: OperationConnectionSchema.optional(),
|
|
81
|
+
});
|
|
82
|
+
export const AuthFlowSuccessResponseSchema = z.object({
|
|
83
|
+
data: z.unknown(),
|
|
84
|
+
contextPatch: z.record(z.string(), z.unknown().nullable()).optional(),
|
|
85
|
+
});
|
|
86
|
+
export const AuthFlowErrorResponseSchema = OperationErrorResponseSchema;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { StealthProfile } from "../types";
|
|
2
|
+
export declare function generateLayer2Headers(profile: StealthProfile): Record<string, string>;
|
|
3
|
+
export declare function getStealthProfile(name: string): StealthProfile;
|
|
4
|
+
export declare function listStealthProfiles(): string[];
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { SDKError } from "../errors";
|
|
2
|
+
const CHROMIUM_HEADER_ORDER = [
|
|
3
|
+
":method",
|
|
4
|
+
":authority",
|
|
5
|
+
":scheme",
|
|
6
|
+
":path",
|
|
7
|
+
"user-agent",
|
|
8
|
+
"accept",
|
|
9
|
+
"accept-encoding",
|
|
10
|
+
"accept-language",
|
|
11
|
+
"cache-control",
|
|
12
|
+
"pragma",
|
|
13
|
+
"cookie",
|
|
14
|
+
"sec-ch-ua",
|
|
15
|
+
"sec-ch-ua-mobile",
|
|
16
|
+
"sec-ch-ua-platform",
|
|
17
|
+
];
|
|
18
|
+
const FIREFOX_HEADER_ORDER = [
|
|
19
|
+
":method",
|
|
20
|
+
":path",
|
|
21
|
+
":authority",
|
|
22
|
+
":scheme",
|
|
23
|
+
"user-agent",
|
|
24
|
+
"accept",
|
|
25
|
+
"accept-language",
|
|
26
|
+
"accept-encoding",
|
|
27
|
+
"referer",
|
|
28
|
+
"cookie",
|
|
29
|
+
"upgrade-insecure-requests",
|
|
30
|
+
"sec-fetch-dest",
|
|
31
|
+
"sec-fetch-mode",
|
|
32
|
+
"sec-fetch-site",
|
|
33
|
+
"sec-fetch-user",
|
|
34
|
+
];
|
|
35
|
+
const SAFARI_HEADER_ORDER = [
|
|
36
|
+
":method",
|
|
37
|
+
":scheme",
|
|
38
|
+
":path",
|
|
39
|
+
":authority",
|
|
40
|
+
"accept",
|
|
41
|
+
"user-agent",
|
|
42
|
+
"accept-language",
|
|
43
|
+
"accept-encoding",
|
|
44
|
+
"cookie",
|
|
45
|
+
"upgrade-insecure-requests",
|
|
46
|
+
];
|
|
47
|
+
const CHROMIUM_H2_SETTINGS = {
|
|
48
|
+
HEADER_TABLE_SIZE: 65536,
|
|
49
|
+
ENABLE_PUSH: 0,
|
|
50
|
+
INITIAL_WINDOW_SIZE: 6291456,
|
|
51
|
+
MAX_HEADER_LIST_SIZE: 262144,
|
|
52
|
+
};
|
|
53
|
+
const FIREFOX_H2_SETTINGS = {
|
|
54
|
+
HEADER_TABLE_SIZE: 65536,
|
|
55
|
+
INITIAL_WINDOW_SIZE: 131072,
|
|
56
|
+
MAX_FRAME_SIZE: 16384,
|
|
57
|
+
MAX_HEADER_LIST_SIZE: 65536,
|
|
58
|
+
};
|
|
59
|
+
const SAFARI_H2_SETTINGS = {
|
|
60
|
+
HEADER_TABLE_SIZE: 4096,
|
|
61
|
+
ENABLE_PUSH: 0,
|
|
62
|
+
INITIAL_WINDOW_SIZE: 4194304,
|
|
63
|
+
MAX_CONCURRENT_STREAMS: 100,
|
|
64
|
+
};
|
|
65
|
+
const CHROMIUM_JA3 = "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-65037,29-23-24,0";
|
|
66
|
+
const FIREFOX_JA3 = "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-28-27-43-45-51,29-23-24-25,0";
|
|
67
|
+
const SAFARI_JA3 = "771,4865-4866-4867-49196-49195-52393-49200-49199-49188-49192-159-158-107-103-57-51-157-156-61-60-53-47-255,0-23-65281-10-11-16-5-13-18-51-45-43-27,29-23-24-25,0";
|
|
68
|
+
function createProfile(name, definition) {
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
platform: definition.platform,
|
|
72
|
+
version: definition.version,
|
|
73
|
+
userAgent: definition.userAgent,
|
|
74
|
+
tlsClientIdentifier: definition.tlsClientIdentifier,
|
|
75
|
+
ja3: definition.ja3,
|
|
76
|
+
ja4: definition.ja4,
|
|
77
|
+
h2Settings: definition.h2Settings
|
|
78
|
+
? { ...definition.h2Settings }
|
|
79
|
+
: undefined,
|
|
80
|
+
headerOrder: definition.headerOrder
|
|
81
|
+
? [...definition.headerOrder]
|
|
82
|
+
: undefined,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function extractBrowserMajorVersion(profile) {
|
|
86
|
+
const chromeVersion = profile.userAgent.match(/Chrome\/(\d+)/)?.[1];
|
|
87
|
+
if (chromeVersion) {
|
|
88
|
+
return chromeVersion;
|
|
89
|
+
}
|
|
90
|
+
const identifierVersion = profile.tlsClientIdentifier?.match(/(\d+)(?!.*\d)/)?.[1];
|
|
91
|
+
if (identifierVersion) {
|
|
92
|
+
return identifierVersion;
|
|
93
|
+
}
|
|
94
|
+
return profile.version.split(".")[0] ?? profile.version;
|
|
95
|
+
}
|
|
96
|
+
function toPlatformHeaderValue(platform) {
|
|
97
|
+
switch (platform) {
|
|
98
|
+
case "macos":
|
|
99
|
+
return '"macOS"';
|
|
100
|
+
case "windows":
|
|
101
|
+
return '"Windows"';
|
|
102
|
+
case "linux":
|
|
103
|
+
return '"Linux"';
|
|
104
|
+
case "android":
|
|
105
|
+
return '"Android"';
|
|
106
|
+
case "ios":
|
|
107
|
+
return '"iOS"';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function generateLayer2Headers(profile) {
|
|
111
|
+
const headers = {
|
|
112
|
+
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8",
|
|
113
|
+
};
|
|
114
|
+
const identifier = profile.tlsClientIdentifier?.toLowerCase() ?? "";
|
|
115
|
+
const majorVersion = extractBrowserMajorVersion(profile);
|
|
116
|
+
if (identifier.startsWith("chrome_") || identifier.startsWith("edge_")) {
|
|
117
|
+
const isEdge = identifier.startsWith("edge_") || /\bEdg\//.test(profile.userAgent);
|
|
118
|
+
headers["Sec-Ch-Ua"] = isEdge
|
|
119
|
+
? `"Chromium";v="${majorVersion}", "Microsoft Edge";v="${majorVersion}", "Not)A;Brand";v="99"`
|
|
120
|
+
: `"Chromium";v="${majorVersion}", "Google Chrome";v="${majorVersion}", "Not)A;Brand";v="99"`;
|
|
121
|
+
headers["Sec-Ch-Ua-Platform"] = toPlatformHeaderValue(profile.platform);
|
|
122
|
+
headers["Sec-Ch-Ua-Mobile"] =
|
|
123
|
+
profile.platform === "android" || profile.platform === "ios"
|
|
124
|
+
? "?1"
|
|
125
|
+
: "?0";
|
|
126
|
+
}
|
|
127
|
+
return headers;
|
|
128
|
+
}
|
|
129
|
+
const STEALTH_PROFILE_ALIASES = {
|
|
130
|
+
"chrome-desktop": "chrome-146",
|
|
131
|
+
};
|
|
132
|
+
const STEALTH_PROFILES = {
|
|
133
|
+
"chrome-146": createProfile("chrome-146", {
|
|
134
|
+
platform: "macos",
|
|
135
|
+
version: "146.0.0.0",
|
|
136
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
|
|
137
|
+
tlsClientIdentifier: "chrome_146",
|
|
138
|
+
ja3: CHROMIUM_JA3,
|
|
139
|
+
h2Settings: CHROMIUM_H2_SETTINGS,
|
|
140
|
+
headerOrder: CHROMIUM_HEADER_ORDER,
|
|
141
|
+
}),
|
|
142
|
+
"firefox-147": createProfile("firefox-147", {
|
|
143
|
+
platform: "macos",
|
|
144
|
+
version: "147.0",
|
|
145
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0",
|
|
146
|
+
tlsClientIdentifier: "firefox_147",
|
|
147
|
+
ja3: FIREFOX_JA3,
|
|
148
|
+
h2Settings: FIREFOX_H2_SETTINGS,
|
|
149
|
+
headerOrder: FIREFOX_HEADER_ORDER,
|
|
150
|
+
}),
|
|
151
|
+
"firefox-135": createProfile("firefox-135", {
|
|
152
|
+
platform: "macos",
|
|
153
|
+
version: "135.0",
|
|
154
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0",
|
|
155
|
+
tlsClientIdentifier: "firefox_135",
|
|
156
|
+
ja3: FIREFOX_JA3,
|
|
157
|
+
h2Settings: FIREFOX_H2_SETTINGS,
|
|
158
|
+
headerOrder: FIREFOX_HEADER_ORDER,
|
|
159
|
+
}),
|
|
160
|
+
"firefox-133": createProfile("firefox-133", {
|
|
161
|
+
platform: "macos",
|
|
162
|
+
version: "133.0",
|
|
163
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0",
|
|
164
|
+
tlsClientIdentifier: "firefox_133",
|
|
165
|
+
ja3: FIREFOX_JA3,
|
|
166
|
+
h2Settings: FIREFOX_H2_SETTINGS,
|
|
167
|
+
headerOrder: FIREFOX_HEADER_ORDER,
|
|
168
|
+
}),
|
|
169
|
+
"firefox-132": createProfile("firefox-132", {
|
|
170
|
+
platform: "macos",
|
|
171
|
+
version: "132.0",
|
|
172
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:132.0) Gecko/20100101 Firefox/132.0",
|
|
173
|
+
tlsClientIdentifier: "firefox_132",
|
|
174
|
+
ja3: FIREFOX_JA3,
|
|
175
|
+
h2Settings: FIREFOX_H2_SETTINGS,
|
|
176
|
+
headerOrder: FIREFOX_HEADER_ORDER,
|
|
177
|
+
}),
|
|
178
|
+
"safari-16": createProfile("safari-16", {
|
|
179
|
+
platform: "macos",
|
|
180
|
+
version: "16.0",
|
|
181
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
|
|
182
|
+
tlsClientIdentifier: "safari_16_0",
|
|
183
|
+
ja3: SAFARI_JA3,
|
|
184
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
185
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
186
|
+
}),
|
|
187
|
+
"safari-15": createProfile("safari-15", {
|
|
188
|
+
platform: "macos",
|
|
189
|
+
version: "15.6.1",
|
|
190
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15",
|
|
191
|
+
tlsClientIdentifier: "safari_15_6_1",
|
|
192
|
+
ja3: SAFARI_JA3,
|
|
193
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
194
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
195
|
+
}),
|
|
196
|
+
"ios-safari-26": createProfile("ios-safari-26", {
|
|
197
|
+
platform: "ios",
|
|
198
|
+
version: "26.0",
|
|
199
|
+
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1",
|
|
200
|
+
tlsClientIdentifier: "safari_ios_26_0",
|
|
201
|
+
ja3: SAFARI_JA3,
|
|
202
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
203
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
204
|
+
}),
|
|
205
|
+
"ios-safari-18": createProfile("ios-safari-18", {
|
|
206
|
+
platform: "ios",
|
|
207
|
+
version: "18.0",
|
|
208
|
+
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
|
|
209
|
+
tlsClientIdentifier: "safari_ios_18_0",
|
|
210
|
+
ja3: SAFARI_JA3,
|
|
211
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
212
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
213
|
+
}),
|
|
214
|
+
"ios-safari-17": createProfile("ios-safari-17", {
|
|
215
|
+
platform: "ios",
|
|
216
|
+
version: "17.0",
|
|
217
|
+
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
|
218
|
+
tlsClientIdentifier: "safari_ios_17_0",
|
|
219
|
+
ja3: SAFARI_JA3,
|
|
220
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
221
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
222
|
+
}),
|
|
223
|
+
"generic-desktop": createProfile("generic-desktop", {
|
|
224
|
+
platform: "macos",
|
|
225
|
+
version: "146.0.0.0",
|
|
226
|
+
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
|
|
227
|
+
tlsClientIdentifier: "chrome_146",
|
|
228
|
+
ja3: CHROMIUM_JA3,
|
|
229
|
+
h2Settings: CHROMIUM_H2_SETTINGS,
|
|
230
|
+
headerOrder: CHROMIUM_HEADER_ORDER,
|
|
231
|
+
}),
|
|
232
|
+
"generic-mobile": createProfile("generic-mobile", {
|
|
233
|
+
platform: "ios",
|
|
234
|
+
version: "26.0",
|
|
235
|
+
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1",
|
|
236
|
+
tlsClientIdentifier: "safari_ios_26_0",
|
|
237
|
+
ja3: SAFARI_JA3,
|
|
238
|
+
h2Settings: SAFARI_H2_SETTINGS,
|
|
239
|
+
headerOrder: SAFARI_HEADER_ORDER,
|
|
240
|
+
}),
|
|
241
|
+
};
|
|
242
|
+
export function getStealthProfile(name) {
|
|
243
|
+
const canonicalName = STEALTH_PROFILE_ALIASES[name] ?? name;
|
|
244
|
+
const profile = STEALTH_PROFILES[canonicalName];
|
|
245
|
+
if (!profile) {
|
|
246
|
+
throw new SDKError(`Unknown stealth profile: ${name}`);
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
...profile,
|
|
250
|
+
h2Settings: profile.h2Settings ? { ...profile.h2Settings } : undefined,
|
|
251
|
+
headerOrder: profile.headerOrder ? [...profile.headerOrder] : undefined,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export function listStealthProfiles() {
|
|
255
|
+
return [
|
|
256
|
+
...Object.keys(STEALTH_PROFILES),
|
|
257
|
+
...Object.keys(STEALTH_PROFILE_ALIASES),
|
|
258
|
+
];
|
|
259
|
+
}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SseMessage } from "./types";
|
|
2
|
+
export interface SseEvent<TData = unknown> {
|
|
3
|
+
event: string;
|
|
4
|
+
data: TData;
|
|
5
|
+
id?: string;
|
|
6
|
+
retry?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SseErrorData {
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
requestId?: string;
|
|
12
|
+
retryable?: boolean;
|
|
13
|
+
details?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export declare const APIFUSE_STREAM_ERROR_EVENT = "apifuse.error";
|
|
16
|
+
export declare const APIFUSE_STREAM_DONE_EVENT = "apifuse.done";
|
|
17
|
+
export declare function event<TData>(eventName: string, data: TData, options?: {
|
|
18
|
+
id?: string;
|
|
19
|
+
retry?: number;
|
|
20
|
+
}): SseEvent<TData>;
|
|
21
|
+
export declare function error(code: string, message: string, options?: Omit<SseErrorData, "code" | "message"> & {
|
|
22
|
+
id?: string;
|
|
23
|
+
retry?: number;
|
|
24
|
+
}): SseEvent<SseErrorData>;
|
|
25
|
+
export declare function done(): SseEvent<Record<string, never>>;
|
|
26
|
+
export declare function done<TData>(data: TData, options?: {
|
|
27
|
+
id?: string;
|
|
28
|
+
retry?: number;
|
|
29
|
+
}): SseEvent<TData>;
|
|
30
|
+
export declare function encodeSseEvent(input: SseEvent): string;
|
|
31
|
+
export declare function readableBytes(body: ReadableStream<Uint8Array>): AsyncIterable<Uint8Array>;
|
|
32
|
+
export declare function readableTextChunks(body: ReadableStream<Uint8Array>): AsyncIterable<string>;
|
|
33
|
+
export declare function readableLines(body: ReadableStream<Uint8Array>): AsyncIterable<string>;
|
|
34
|
+
export declare function parseSseStream(body: ReadableStream<Uint8Array>): AsyncIterable<SseMessage>;
|
|
35
|
+
export declare const stream: {
|
|
36
|
+
event: typeof event;
|
|
37
|
+
error: typeof error;
|
|
38
|
+
done: typeof done;
|
|
39
|
+
encodeSseEvent: typeof encodeSseEvent;
|
|
40
|
+
parseSseStream: typeof parseSseStream;
|
|
41
|
+
readableBytes: typeof readableBytes;
|
|
42
|
+
readableTextChunks: typeof readableTextChunks;
|
|
43
|
+
readableLines: typeof readableLines;
|
|
44
|
+
};
|
package/dist/stream.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
export const APIFUSE_STREAM_ERROR_EVENT = "apifuse.error";
|
|
2
|
+
export const APIFUSE_STREAM_DONE_EVENT = "apifuse.done";
|
|
3
|
+
export function event(eventName, data, options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
event: eventName,
|
|
6
|
+
data,
|
|
7
|
+
...(options.id ? { id: options.id } : {}),
|
|
8
|
+
...(options.retry !== undefined ? { retry: options.retry } : {}),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function error(code, message, options = {}) {
|
|
12
|
+
const { id, retry, ...dataOptions } = options;
|
|
13
|
+
return event(APIFUSE_STREAM_ERROR_EVENT, { code, message, ...dataOptions }, { ...(id ? { id } : {}), ...(retry !== undefined ? { retry } : {}) });
|
|
14
|
+
}
|
|
15
|
+
export function done(data, options = {}) {
|
|
16
|
+
return event(APIFUSE_STREAM_DONE_EVENT, data ?? {}, options);
|
|
17
|
+
}
|
|
18
|
+
export function encodeSseEvent(input) {
|
|
19
|
+
const lines = [];
|
|
20
|
+
if (input.id !== undefined)
|
|
21
|
+
lines.push(`id: ${sseFieldValue(input.id, "id")}`);
|
|
22
|
+
if (input.event)
|
|
23
|
+
lines.push(`event: ${sseFieldValue(input.event, "event")}`);
|
|
24
|
+
if (input.retry !== undefined) {
|
|
25
|
+
if (!Number.isInteger(input.retry) || input.retry < 0) {
|
|
26
|
+
throw new TypeError("SSE retry must be a non-negative integer.");
|
|
27
|
+
}
|
|
28
|
+
lines.push(`retry: ${input.retry}`);
|
|
29
|
+
}
|
|
30
|
+
const data = typeof input.data === "string" ? input.data : JSON.stringify(input.data);
|
|
31
|
+
for (const line of data.split(/\r?\n/)) {
|
|
32
|
+
lines.push(`data: ${line}`);
|
|
33
|
+
}
|
|
34
|
+
return `${lines.join("\n")}\n\n`;
|
|
35
|
+
}
|
|
36
|
+
function sseFieldValue(value, field) {
|
|
37
|
+
if (/[\r\n]/.test(value)) {
|
|
38
|
+
throw new TypeError(`SSE ${field} must not contain CR or LF.`);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
export async function* readableBytes(body) {
|
|
43
|
+
const reader = body.getReader();
|
|
44
|
+
try {
|
|
45
|
+
for (;;) {
|
|
46
|
+
const { value, done } = await reader.read();
|
|
47
|
+
if (done)
|
|
48
|
+
return;
|
|
49
|
+
if (value)
|
|
50
|
+
yield value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
reader.releaseLock();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function* readableTextChunks(body) {
|
|
58
|
+
const decoder = new TextDecoder();
|
|
59
|
+
for await (const chunk of readableBytes(body)) {
|
|
60
|
+
yield decoder.decode(chunk, { stream: true });
|
|
61
|
+
}
|
|
62
|
+
const tail = decoder.decode();
|
|
63
|
+
if (tail)
|
|
64
|
+
yield tail;
|
|
65
|
+
}
|
|
66
|
+
export async function* readableLines(body) {
|
|
67
|
+
let buffer = "";
|
|
68
|
+
for await (const chunk of readableTextChunks(body)) {
|
|
69
|
+
buffer += chunk;
|
|
70
|
+
for (;;) {
|
|
71
|
+
const index = buffer.search(/\r?\n/);
|
|
72
|
+
if (index < 0)
|
|
73
|
+
break;
|
|
74
|
+
const line = buffer.slice(0, index);
|
|
75
|
+
const newlineLength = buffer[index] === "\r" && buffer[index + 1] === "\n" ? 2 : 1;
|
|
76
|
+
buffer = buffer.slice(index + newlineLength);
|
|
77
|
+
yield line;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (buffer)
|
|
81
|
+
yield buffer;
|
|
82
|
+
}
|
|
83
|
+
function createSseMessage(eventName, data, options) {
|
|
84
|
+
return {
|
|
85
|
+
event: eventName || "message",
|
|
86
|
+
data,
|
|
87
|
+
...(options.id !== undefined ? { id: options.id } : {}),
|
|
88
|
+
...(options.retry !== undefined ? { retry: options.retry } : {}),
|
|
89
|
+
json() {
|
|
90
|
+
return parseJson(data);
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function parseJson(data) {
|
|
95
|
+
return JSON.parse(data);
|
|
96
|
+
}
|
|
97
|
+
export async function* parseSseStream(body) {
|
|
98
|
+
let eventName = "message";
|
|
99
|
+
let dataLines = [];
|
|
100
|
+
let id;
|
|
101
|
+
let retry;
|
|
102
|
+
const dispatch = function* () {
|
|
103
|
+
if (dataLines.length === 0 && id === undefined && retry === undefined) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
yield createSseMessage(eventName, dataLines.join("\n"), { id, retry });
|
|
107
|
+
eventName = "message";
|
|
108
|
+
dataLines = [];
|
|
109
|
+
retry = undefined;
|
|
110
|
+
};
|
|
111
|
+
for await (const line of readableLines(body)) {
|
|
112
|
+
if (line === "") {
|
|
113
|
+
yield* dispatch();
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (line.startsWith(":"))
|
|
117
|
+
continue;
|
|
118
|
+
const separator = line.indexOf(":");
|
|
119
|
+
const field = separator < 0 ? line : line.slice(0, separator);
|
|
120
|
+
const rawValue = separator < 0 ? "" : line.slice(separator + 1);
|
|
121
|
+
const value = rawValue.startsWith(" ") ? rawValue.slice(1) : rawValue;
|
|
122
|
+
switch (field) {
|
|
123
|
+
case "event":
|
|
124
|
+
eventName = value;
|
|
125
|
+
break;
|
|
126
|
+
case "data":
|
|
127
|
+
dataLines.push(value);
|
|
128
|
+
break;
|
|
129
|
+
case "id":
|
|
130
|
+
id = value;
|
|
131
|
+
break;
|
|
132
|
+
case "retry": {
|
|
133
|
+
const parsed = Number(value);
|
|
134
|
+
if (Number.isInteger(parsed) && parsed >= 0)
|
|
135
|
+
retry = parsed;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
yield* dispatch();
|
|
141
|
+
}
|
|
142
|
+
export const stream = {
|
|
143
|
+
event,
|
|
144
|
+
error,
|
|
145
|
+
done,
|
|
146
|
+
encodeSseEvent,
|
|
147
|
+
parseSseStream,
|
|
148
|
+
readableBytes,
|
|
149
|
+
readableTextChunks,
|
|
150
|
+
readableLines,
|
|
151
|
+
};
|