@apifuse/provider-sdk 2.0.0-beta.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.
Files changed (67) hide show
  1. package/README.md +44 -0
  2. package/bin/apifuse-check.ts +406 -0
  3. package/bin/apifuse-dev.ts +222 -0
  4. package/bin/apifuse-init.ts +387 -0
  5. package/bin/apifuse-perf.ts +1099 -0
  6. package/bin/apifuse-record.ts +444 -0
  7. package/bin/apifuse-test.ts +688 -0
  8. package/bin/apifuse.ts +51 -0
  9. package/package.json +64 -0
  10. package/src/__tests__/auth.test.ts +396 -0
  11. package/src/__tests__/browser-auth.test.ts +180 -0
  12. package/src/__tests__/browser.test.ts +632 -0
  13. package/src/__tests__/define.test.ts +225 -0
  14. package/src/__tests__/errors.test.ts +69 -0
  15. package/src/__tests__/executor.test.ts +214 -0
  16. package/src/__tests__/http.test.ts +238 -0
  17. package/src/__tests__/insights.test.ts +210 -0
  18. package/src/__tests__/instrumentation.test.ts +290 -0
  19. package/src/__tests__/otlp.test.ts +141 -0
  20. package/src/__tests__/perf.test.ts +60 -0
  21. package/src/__tests__/providers-yaml.test.ts +135 -0
  22. package/src/__tests__/proxy.test.ts +359 -0
  23. package/src/__tests__/recipes.test.ts +36 -0
  24. package/src/__tests__/serve.test.ts +233 -0
  25. package/src/__tests__/session.test.ts +231 -0
  26. package/src/__tests__/state.test.ts +100 -0
  27. package/src/__tests__/stealth.test.ts +57 -0
  28. package/src/__tests__/testing.test.ts +97 -0
  29. package/src/__tests__/tls.test.ts +345 -0
  30. package/src/__tests__/types.test.ts +142 -0
  31. package/src/__tests__/utils.test.ts +62 -0
  32. package/src/__tests__/waterfall.test.ts +270 -0
  33. package/src/config/loader.ts +122 -0
  34. package/src/config/providers-yaml.ts +370 -0
  35. package/src/define.ts +137 -0
  36. package/src/dev.ts +38 -0
  37. package/src/errors.ts +68 -0
  38. package/src/index.test.ts +1 -0
  39. package/src/index.ts +100 -0
  40. package/src/protocol.ts +183 -0
  41. package/src/recipes/gov-api.ts +97 -0
  42. package/src/recipes/rest-api.ts +152 -0
  43. package/src/runtime/auth.ts +245 -0
  44. package/src/runtime/browser.ts +724 -0
  45. package/src/runtime/executor.ts +54 -0
  46. package/src/runtime/http.ts +248 -0
  47. package/src/runtime/insights.ts +456 -0
  48. package/src/runtime/instrumentation.ts +424 -0
  49. package/src/runtime/otlp.ts +171 -0
  50. package/src/runtime/perf.ts +73 -0
  51. package/src/runtime/provider.ts +20 -0
  52. package/src/runtime/session.ts +573 -0
  53. package/src/runtime/state.ts +124 -0
  54. package/src/runtime/tls.ts +410 -0
  55. package/src/runtime/trace.ts +261 -0
  56. package/src/runtime/waterfall.ts +245 -0
  57. package/src/serve.ts +664 -0
  58. package/src/stealth/profiles.ts +391 -0
  59. package/src/testing/helpers.ts +144 -0
  60. package/src/testing/index.ts +2 -0
  61. package/src/testing/run.ts +88 -0
  62. package/src/types/playwright-stealth.d.ts +9 -0
  63. package/src/types.ts +243 -0
  64. package/src/utils/date.ts +163 -0
  65. package/src/utils/parse.ts +66 -0
  66. package/src/utils/text.ts +20 -0
  67. package/src/utils/transform.ts +62 -0
@@ -0,0 +1,370 @@
1
+ import { readFile } from "node:fs/promises";
2
+
3
+ import { z } from "zod";
4
+
5
+ import { SDKError, ValidationError } from "../errors";
6
+
7
+ type YamlObject = Record<string, unknown>;
8
+
9
+ function stripInlineComment(line: string): string {
10
+ let inSingleQuote = false;
11
+ let inDoubleQuote = false;
12
+
13
+ for (let index = 0; index < line.length; index += 1) {
14
+ const char = line[index];
15
+
16
+ if (char === "'" && !inDoubleQuote) {
17
+ inSingleQuote = !inSingleQuote;
18
+ continue;
19
+ }
20
+
21
+ if (char === '"' && !inSingleQuote) {
22
+ inDoubleQuote = !inDoubleQuote;
23
+ continue;
24
+ }
25
+
26
+ if (char === "#" && !inSingleQuote && !inDoubleQuote) {
27
+ return line.slice(0, index).trimEnd();
28
+ }
29
+ }
30
+
31
+ return line;
32
+ }
33
+
34
+ function parseQuotedString(value: string): string {
35
+ if (
36
+ (value.startsWith('"') && value.endsWith('"')) ||
37
+ (value.startsWith("'") && value.endsWith("'"))
38
+ ) {
39
+ return value.slice(1, -1);
40
+ }
41
+
42
+ return value;
43
+ }
44
+
45
+ function splitFlowArrayItems(value: string): string[] {
46
+ const items: string[] = [];
47
+ let current = "";
48
+ let inSingleQuote = false;
49
+ let inDoubleQuote = false;
50
+
51
+ for (let index = 0; index < value.length; index += 1) {
52
+ const char = value[index];
53
+
54
+ if (char === "'" && !inDoubleQuote) {
55
+ inSingleQuote = !inSingleQuote;
56
+ current += char;
57
+ continue;
58
+ }
59
+
60
+ if (char === '"' && !inSingleQuote) {
61
+ inDoubleQuote = !inDoubleQuote;
62
+ current += char;
63
+ continue;
64
+ }
65
+
66
+ if (char === "," && !inSingleQuote && !inDoubleQuote) {
67
+ items.push(current.trim());
68
+ current = "";
69
+ continue;
70
+ }
71
+
72
+ current += char;
73
+ }
74
+
75
+ if (current.trim()) {
76
+ items.push(current.trim());
77
+ }
78
+
79
+ return items;
80
+ }
81
+
82
+ function parseYamlScalar(value: string): unknown {
83
+ if (value === "{}") {
84
+ return {};
85
+ }
86
+
87
+ if (value === "[]") {
88
+ return [];
89
+ }
90
+
91
+ if (value.startsWith("[") && value.endsWith("]")) {
92
+ const inner = value.slice(1, -1).trim();
93
+ if (!inner) {
94
+ return [];
95
+ }
96
+
97
+ return splitFlowArrayItems(inner).map((item) => parseYamlScalar(item));
98
+ }
99
+
100
+ if (value === "true") {
101
+ return true;
102
+ }
103
+
104
+ if (value === "false") {
105
+ return false;
106
+ }
107
+
108
+ if (/^-?\d+$/.test(value)) {
109
+ return Number.parseInt(value, 10);
110
+ }
111
+
112
+ return parseQuotedString(value);
113
+ }
114
+
115
+ function parseYamlObject(yamlContent: string): YamlObject {
116
+ const root: YamlObject = {};
117
+ const stack: Array<{ container: YamlObject; indent: number }> = [
118
+ { container: root, indent: -1 },
119
+ ];
120
+
121
+ for (const rawLine of yamlContent.split(/\r?\n/u)) {
122
+ const withoutComment = stripInlineComment(rawLine);
123
+ if (!withoutComment.trim()) {
124
+ continue;
125
+ }
126
+
127
+ const indent = withoutComment.match(/^\s*/u)?.[0].length ?? 0;
128
+ const line = withoutComment.trim();
129
+ const separatorIndex = line.indexOf(":");
130
+
131
+ if (separatorIndex === -1) {
132
+ throw new Error(`Invalid YAML line: ${rawLine}`);
133
+ }
134
+
135
+ const key = line.slice(0, separatorIndex).trim();
136
+ const rawValue = line.slice(separatorIndex + 1).trim();
137
+
138
+ while (stack.length > 1 && indent <= stack[stack.length - 1]?.indent) {
139
+ stack.pop();
140
+ }
141
+
142
+ const parent = stack[stack.length - 1]?.container;
143
+ if (!parent) {
144
+ throw new Error(`Could not resolve YAML parent for line: ${rawLine}`);
145
+ }
146
+
147
+ if (!rawValue) {
148
+ const child: YamlObject = {};
149
+ parent[key] = child;
150
+ stack.push({ container: child, indent });
151
+ continue;
152
+ }
153
+
154
+ parent[key] = parseYamlScalar(rawValue);
155
+ }
156
+
157
+ return root;
158
+ }
159
+
160
+ const PoolSizeRangeInputSchema = z
161
+ .string()
162
+ .regex(/^\d+\.\.\d+$/, "pool-size must use min..max format")
163
+ .transform((value, ctx) => {
164
+ const [minRaw, maxRaw] = value.split("..");
165
+ const min = Number.parseInt(minRaw, 10);
166
+ const max = Number.parseInt(maxRaw, 10);
167
+
168
+ if (min > max) {
169
+ ctx.addIssue({
170
+ code: z.ZodIssueCode.custom,
171
+ message: "pool-size min must be less than or equal to max",
172
+ });
173
+ return z.NEVER;
174
+ }
175
+
176
+ return { max, min };
177
+ });
178
+
179
+ const PoolSizeRangeSchema = z.object({
180
+ max: z.number().int(),
181
+ min: z.number().int(),
182
+ });
183
+
184
+ const SecurityOverrideSchema = z
185
+ .object({
186
+ "read-only-rootfs": z.boolean().optional(),
187
+ "no-new-privileges": z.boolean().optional(),
188
+ egress: z.array(z.string()).optional(),
189
+ env: z.array(z.string()).optional(),
190
+ })
191
+ .passthrough();
192
+
193
+ const ContainerOverrideSchema = z
194
+ .object({
195
+ image: z.string().optional(),
196
+ memory: z.string().optional(),
197
+ cpu: z.string().optional(),
198
+ timeout: z.string().optional(),
199
+ "restart-policy": z.enum(["on-failure", "always", "never"]).optional(),
200
+ "max-restarts": z.number().int().optional(),
201
+ })
202
+ .passthrough();
203
+
204
+ const CdpOverrideSchema = z
205
+ .object({
206
+ "pool-size": PoolSizeRangeInputSchema,
207
+ "page-timeout": z.string().optional(),
208
+ "pages-per-instance": z.number().int().optional(),
209
+ "idle-timeout": z.string().optional(),
210
+ "chrome-flags": z.array(z.string()).optional(),
211
+ })
212
+ .passthrough();
213
+
214
+ const DefaultsSchema = z
215
+ .object({
216
+ container: ContainerOverrideSchema.optional(),
217
+ security: SecurityOverrideSchema.optional(),
218
+ })
219
+ .passthrough();
220
+
221
+ const ProviderConfigOverrideSchema = z
222
+ .object({
223
+ container: ContainerOverrideSchema.optional(),
224
+ runtime: z.enum(["standard", "browser"]).optional(),
225
+ replicas: z.number().int().optional(),
226
+ security: SecurityOverrideSchema.optional(),
227
+ cdp: CdpOverrideSchema.optional(),
228
+ })
229
+ .passthrough();
230
+
231
+ export const SecuritySchema = z
232
+ .object({
233
+ "read-only-rootfs": z.boolean().default(true),
234
+ "no-new-privileges": z.boolean().default(true),
235
+ egress: z.array(z.string()).optional(),
236
+ env: z.array(z.string()).optional(),
237
+ })
238
+ .passthrough();
239
+
240
+ export const ContainerSchema = z
241
+ .object({
242
+ image: z.string().default("auto"),
243
+ memory: z.string().default("256Mi"),
244
+ cpu: z.string().default("250m"),
245
+ timeout: z.string().default("30s"),
246
+ "restart-policy": z
247
+ .enum(["on-failure", "always", "never"])
248
+ .default("on-failure"),
249
+ "max-restarts": z.number().int().default(3),
250
+ })
251
+ .passthrough();
252
+
253
+ export const CdpSchema = z
254
+ .object({
255
+ "pool-size": PoolSizeRangeSchema,
256
+ "page-timeout": z.string().default("120s"),
257
+ "pages-per-instance": z.number().int().default(4),
258
+ "idle-timeout": z.string().default("5m"),
259
+ "chrome-flags": z.array(z.string()).optional(),
260
+ })
261
+ .passthrough();
262
+
263
+ export const ProviderConfigSchema = z
264
+ .object({
265
+ container: ContainerSchema,
266
+ runtime: z.enum(["standard", "browser"]).default("standard"),
267
+ replicas: z.number().int().default(1),
268
+ security: SecuritySchema,
269
+ cdp: CdpSchema.optional(),
270
+ })
271
+ .passthrough();
272
+
273
+ export const ProvidersYamlSchema = z
274
+ .object({
275
+ defaults: DefaultsSchema.optional(),
276
+ providers: z.record(z.string(), ProviderConfigOverrideSchema),
277
+ })
278
+ .passthrough();
279
+
280
+ export type PoolSizeRange = z.infer<typeof PoolSizeRangeSchema>;
281
+ export type ProvidersYaml = z.infer<typeof ProvidersYamlSchema>;
282
+ export type ProviderConfig = z.infer<typeof ProviderConfigSchema>;
283
+
284
+ function toValidationError(error: unknown): ValidationError {
285
+ if (error instanceof z.ZodError) {
286
+ return new ValidationError("Invalid providers.yaml configuration", {
287
+ code: "INVALID_CONNECTORS_YAML",
288
+ fix: "Match the providers.yaml schema from openspec/provider-sdk/08-infrastructure.md §8.2.",
289
+ zodError: error,
290
+ });
291
+ }
292
+
293
+ return new ValidationError("Invalid providers.yaml configuration", {
294
+ code: "INVALID_CONNECTORS_YAML",
295
+ cause: error instanceof Error ? error : undefined,
296
+ fix: "Check providers.yaml syntax and field values.",
297
+ });
298
+ }
299
+
300
+ export function parseProvidersYaml(yamlContent: string): ProvidersYaml {
301
+ try {
302
+ const parsed = parseYamlObject(yamlContent);
303
+ return ProvidersYamlSchema.parse(parsed);
304
+ } catch (error) {
305
+ if (error instanceof z.ZodError) {
306
+ throw toValidationError(error);
307
+ }
308
+
309
+ throw new SDKError("Failed to parse providers.yaml", {
310
+ code: "CONNECTORS_YAML_PARSE_FAILED",
311
+ cause: error instanceof Error ? error : undefined,
312
+ fix: "Ensure providers.yaml contains valid YAML.",
313
+ });
314
+ }
315
+ }
316
+
317
+ export async function loadProvidersYaml(
318
+ filePath: string,
319
+ ): Promise<ProvidersYaml> {
320
+ try {
321
+ const yamlContent = await readFile(filePath, "utf8");
322
+ return parseProvidersYaml(yamlContent);
323
+ } catch (error) {
324
+ if (error instanceof SDKError || error instanceof ValidationError) {
325
+ throw error;
326
+ }
327
+
328
+ throw new SDKError(`Failed to load providers.yaml from ${filePath}`, {
329
+ code: "CONNECTORS_YAML_LOAD_FAILED",
330
+ cause: error instanceof Error ? error : undefined,
331
+ fix: "Verify the file exists and is readable.",
332
+ });
333
+ }
334
+ }
335
+
336
+ export function resolveProviderConfig(
337
+ yaml: ProvidersYaml,
338
+ providerId: string,
339
+ ): ProviderConfig {
340
+ const providerOverride = yaml.providers[providerId];
341
+
342
+ if (!providerOverride) {
343
+ throw new SDKError(`Provider "${providerId}" not found in providers.yaml`, {
344
+ code: "CONNECTOR_NOT_FOUND",
345
+ fix: `Add ${providerId} under providers: in providers.yaml.`,
346
+ });
347
+ }
348
+
349
+ const container = ContainerSchema.parse({
350
+ ...yaml.defaults?.container,
351
+ ...providerOverride.container,
352
+ });
353
+
354
+ const security = SecuritySchema.parse({
355
+ ...yaml.defaults?.security,
356
+ ...providerOverride.security,
357
+ });
358
+
359
+ const resolved = {
360
+ container,
361
+ security,
362
+ runtime: providerOverride.runtime ?? "standard",
363
+ replicas: providerOverride.replicas ?? 1,
364
+ cdp: providerOverride.cdp
365
+ ? CdpSchema.parse(providerOverride.cdp)
366
+ : undefined,
367
+ };
368
+
369
+ return ProviderConfigSchema.parse(resolved);
370
+ }
package/src/define.ts ADDED
@@ -0,0 +1,137 @@
1
+ import type { ZodType } from "zod";
2
+ import { ProviderError, ValidationError } from "./errors";
3
+ import type {
4
+ AuthConfig,
5
+ BrowserEngine,
6
+ OperationDefinition,
7
+ ProviderDefinition,
8
+ StealthPlatform,
9
+ } from "./types";
10
+
11
+ const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)*$/;
12
+
13
+ type ProviderOperation = OperationDefinition<ZodType, ZodType>;
14
+
15
+ export interface ProviderConfig<
16
+ TOperations extends Record<string, ProviderOperation>,
17
+ > {
18
+ id: string;
19
+ version: string;
20
+ runtime: "standard" | "browser";
21
+ stealth?: {
22
+ profile: string;
23
+ platform: StealthPlatform;
24
+ };
25
+ proxy?: boolean;
26
+ browser?: {
27
+ engine: BrowserEngine;
28
+ };
29
+ auth?: AuthConfig;
30
+ meta: {
31
+ displayName: string;
32
+ description?: string;
33
+ category: string;
34
+ tags?: string[];
35
+ icon?: string;
36
+ };
37
+ operations: TOperations;
38
+ }
39
+
40
+ function validateOperationFixtures(
41
+ providerId: string,
42
+ operations: Record<string, ProviderOperation>,
43
+ ): void {
44
+ for (const [operationName, operation] of Object.entries(operations)) {
45
+ if (typeof operation.handler !== "function") {
46
+ throw new ValidationError(
47
+ `Operation handler must be defined for provider "${providerId}" operation "${operationName}"`,
48
+ {
49
+ fix: `Add operations.${operationName}.handler as an async function with signature (ctx, input) => Promise<output>`,
50
+ },
51
+ );
52
+ }
53
+
54
+ if (operation.fixtures?.request !== undefined) {
55
+ const result = operation.input.safeParse(operation.fixtures.request);
56
+
57
+ if (!result.success) {
58
+ throw new ValidationError(
59
+ `Fixture request does not match input schema for provider "${providerId}" operation "${operationName}"`,
60
+ {
61
+ fix: `Update operations.${operationName}.fixtures.request to match operations.${operationName}.input`,
62
+ zodError: result.error,
63
+ },
64
+ );
65
+ }
66
+ }
67
+
68
+ if (operation.fixtures?.response !== undefined) {
69
+ const result = operation.output.safeParse(operation.fixtures.response);
70
+
71
+ if (!result.success) {
72
+ throw new ValidationError(
73
+ `Fixture response does not match output schema for provider "${providerId}" operation "${operationName}"`,
74
+ {
75
+ fix: `Update operations.${operationName}.fixtures.response to match operations.${operationName}.output`,
76
+ zodError: result.error,
77
+ },
78
+ );
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ export function defineProvider<
85
+ TOperations extends Record<string, ProviderOperation>,
86
+ >(
87
+ config: ProviderConfig<TOperations>,
88
+ ): ProviderDefinition & { operations: TOperations } {
89
+ if (!CONNECTOR_ID_REGEX.test(config.id)) {
90
+ throw new ProviderError(`Invalid provider id: "${config.id}"`, {
91
+ fix: 'Use lowercase alphanumeric with dashes, e.g., "coingecko-prices"',
92
+ });
93
+ }
94
+
95
+ if (Object.keys(config.operations).length === 0) {
96
+ throw new ProviderError(
97
+ `Provider "${config.id}" must define at least one operation`,
98
+ { fix: "Add at least one operation to the operations object" },
99
+ );
100
+ }
101
+
102
+ validateOperationFixtures(config.id, config.operations);
103
+
104
+ if (config.runtime === "browser" && !config.browser) {
105
+ throw new ProviderError(
106
+ `Provider "${config.id}" must define browser.engine when runtime is "browser"`,
107
+ {
108
+ fix: 'Add browser: { engine: "nodriver" } or another supported engine',
109
+ },
110
+ );
111
+ }
112
+
113
+ if (config.browser && config.runtime !== "browser") {
114
+ throw new ProviderError(
115
+ `Provider "${config.id}" cannot define browser config unless runtime is "browser"`,
116
+ { fix: 'Set runtime: "browser" or remove the browser config' },
117
+ );
118
+ }
119
+
120
+ if (config.proxy && !config.stealth) {
121
+ console.warn(
122
+ `[provider-sdk] Provider "${config.id}" enables proxy without a stealth profile.`,
123
+ );
124
+ }
125
+
126
+ return {
127
+ id: config.id,
128
+ version: config.version,
129
+ runtime: config.runtime,
130
+ stealth: config.stealth,
131
+ proxy: config.proxy,
132
+ browser: config.browser,
133
+ auth: config.auth,
134
+ meta: config.meta,
135
+ operations: config.operations,
136
+ };
137
+ }
package/src/dev.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { createProviderServer } from "./serve";
2
+ import type { ProviderDefinition } from "./types";
3
+
4
+ export interface DevServerOptions {
5
+ port?: number;
6
+ sessionDbPath?: string;
7
+ }
8
+
9
+ export function createDevServer(
10
+ provider: ProviderDefinition,
11
+ options?: DevServerOptions,
12
+ ): { start: () => void } {
13
+ const port = options?.port ?? 3900;
14
+ const server = createProviderServer(provider, {
15
+ port,
16
+ sessionDbPath: options?.sessionDbPath,
17
+ });
18
+
19
+ return {
20
+ start: () => {
21
+ server.start();
22
+ console.log(
23
+ `[apifuse dev] ${provider.id}@${provider.version} running at http://localhost:${port}`,
24
+ );
25
+ console.log(
26
+ `[apifuse dev] Operations: ${Object.keys(provider.operations).join(", ")}`,
27
+ );
28
+ console.log(`[apifuse dev] Health: http://localhost:${port}/health`);
29
+ },
30
+ };
31
+ }
32
+
33
+ export function startDevServer(
34
+ provider: ProviderDefinition,
35
+ options?: DevServerOptions,
36
+ ): void {
37
+ createDevServer(provider, options).start();
38
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,68 @@
1
+ export type ProviderErrorOptions = {
2
+ fix?: string;
3
+ code?: string;
4
+ cause?: Error;
5
+ };
6
+
7
+ export class ProviderError extends Error {
8
+ constructor(
9
+ message: string,
10
+ public readonly options?: ProviderErrorOptions,
11
+ ) {
12
+ super(message);
13
+ this.name = "ProviderError";
14
+ if (options?.cause) {
15
+ this.cause = options.cause;
16
+ }
17
+ }
18
+
19
+ get fix(): string | undefined {
20
+ return this.options?.fix;
21
+ }
22
+
23
+ get code(): string | undefined {
24
+ return this.options?.code;
25
+ }
26
+ }
27
+
28
+ export class SDKError extends ProviderError {
29
+ constructor(message: string, options?: ProviderErrorOptions) {
30
+ super(message, options);
31
+ this.name = "SDKError";
32
+ }
33
+ }
34
+
35
+ export class AuthError extends ProviderError {
36
+ constructor(message: string, options?: ProviderErrorOptions) {
37
+ super(message, options);
38
+ this.name = "AuthError";
39
+ }
40
+ }
41
+
42
+ export type ValidationErrorOptions = ProviderErrorOptions & {
43
+ zodError?: unknown;
44
+ };
45
+
46
+ export class ValidationError extends ProviderError {
47
+ readonly zodError?: unknown;
48
+
49
+ constructor(message: string, options?: ValidationErrorOptions) {
50
+ super(message, options);
51
+ this.name = "ValidationError";
52
+ this.zodError = options?.zodError;
53
+ }
54
+ }
55
+
56
+ export type TransportErrorOptions = ProviderErrorOptions & {
57
+ status?: number;
58
+ };
59
+
60
+ export class TransportError extends ProviderError {
61
+ readonly status?: number;
62
+
63
+ constructor(message: string, options?: TransportErrorOptions) {
64
+ super(message, options);
65
+ this.name = "TransportError";
66
+ this.status = options?.status;
67
+ }
68
+ }
@@ -0,0 +1 @@
1
+ // placeholder to keep bun test from erroring on zero test files
package/src/index.ts ADDED
@@ -0,0 +1,100 @@
1
+ // @apifuse/provider-sdk
2
+
3
+ export { z } from "zod";
4
+ export type {
5
+ ApiFuseConfig,
6
+ BrowserConfig,
7
+ ProxyConfig,
8
+ SessionConfig,
9
+ } from "./config/loader";
10
+ export { defineConfig, loadApiFuseConfig } from "./config/loader";
11
+ export type {
12
+ PoolSizeRange,
13
+ ProviderConfig,
14
+ ProvidersYaml,
15
+ } from "./config/providers-yaml";
16
+ export {
17
+ CdpSchema,
18
+ ContainerSchema,
19
+ loadProvidersYaml,
20
+ ProviderConfigSchema,
21
+ ProvidersYamlSchema,
22
+ parseProvidersYaml,
23
+ resolveProviderConfig,
24
+ SecuritySchema,
25
+ } from "./config/providers-yaml";
26
+ export { defineProvider } from "./define";
27
+ export type { DevServerOptions } from "./dev";
28
+ export { createDevServer, startDevServer } from "./dev";
29
+ export * from "./errors";
30
+ export * from "./protocol";
31
+ export * from "./recipes/gov-api";
32
+ export * from "./recipes/rest-api";
33
+ export type { AuthManager } from "./runtime/auth";
34
+ export { createAuthManager } from "./runtime/auth";
35
+ export type { BrowserClientOptions } from "./runtime/browser";
36
+ export { BrowserClient, createBrowserClient } from "./runtime/browser";
37
+ export { executeOperation } from "./runtime/executor";
38
+ export { createHttpClient } from "./runtime/http";
39
+ export type { Insight, InsightSeverity } from "./runtime/insights";
40
+ export { generateInsights } from "./runtime/insights";
41
+ export {
42
+ type InstrumentationOptions,
43
+ type InstrumentedProviderContext,
44
+ wrapWithInstrumentation,
45
+ } from "./runtime/instrumentation";
46
+ export { getProviderBaseUrl } from "./runtime/provider";
47
+ export type {
48
+ SessionFetch,
49
+ SupabaseSessionStoreConfig,
50
+ } from "./runtime/session";
51
+ export {
52
+ createSessionStore,
53
+ createSqliteSessionStore,
54
+ SupabaseSessionStore,
55
+ } from "./runtime/session";
56
+ export { createStateContext } from "./runtime/state";
57
+ export { createTlsClient } from "./runtime/tls";
58
+ export {
59
+ type CreateTraceContextOptions,
60
+ createTraceContext,
61
+ type Span,
62
+ type TraceContext,
63
+ } from "./runtime/trace";
64
+ export { createProviderServer } from "./serve";
65
+ export { getStealthProfile, listStealthProfiles } from "./stealth/profiles";
66
+ export {
67
+ runStandardTests,
68
+ snapshotTransform,
69
+ toMatchShape,
70
+ } from "./testing";
71
+ export type {
72
+ ApiFuseResponse,
73
+ AuthConfig,
74
+ AuthContext,
75
+ AuthField,
76
+ AuthMode,
77
+ BrowserEngine,
78
+ BrowserOptions,
79
+ HttpClient,
80
+ HttpResponse,
81
+ OperationDefinition,
82
+ ProviderContext,
83
+ ProviderDefinition,
84
+ ProviderMeta,
85
+ RequestOptions,
86
+ SessionStore,
87
+ StateContext,
88
+ StealthPlatform,
89
+ StealthProfile,
90
+ TlsClient,
91
+ TlsFetchOptions,
92
+ TlsResponse,
93
+ TlsSession,
94
+ TraceConfig,
95
+ TraceSpan,
96
+ } from "./types";
97
+ export * from "./utils/date";
98
+ export * from "./utils/parse";
99
+ export * from "./utils/text";
100
+ export * from "./utils/transform";