@apifuse/provider-sdk 2.1.0-beta.5 → 2.1.0-beta.8
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 +16 -0
- package/README.md +2 -2
- package/SUBMISSION.md +2 -1
- package/bin/apifuse-check.ts +60 -6
- package/bin/apifuse-dev.ts +48 -5
- package/bin/apifuse-perf.ts +50 -11
- package/bin/apifuse-record.ts +35 -11
- package/bin/apifuse-submit-check.ts +1425 -3
- 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 +827 -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 +1324 -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 +42 -25
- package/src/ceremonies/index.ts +8 -2
- package/src/choice-token.ts +1 -0
- package/src/cli/commands.ts +8 -5
- package/src/cli/create.ts +28 -0
- package/src/cli/templates/provider/operations/ping.ts.tpl +3 -2
- package/src/cli/templates/provider/schemas/ping.ts.tpl +8 -0
- package/src/config/loader.ts +19 -1
- package/src/contract-json.ts +75 -0
- package/src/contract-serialization.ts +89 -0
- package/src/contract-types.ts +52 -0
- package/src/contract.ts +215 -0
- package/src/define.ts +37 -2
- package/src/errors.ts +15 -0
- package/src/i18n/catalog.ts +156 -0
- package/src/index.ts +22 -1
- package/src/lint.ts +256 -37
- package/src/provider.ts +45 -2
- package/src/runtime/browser.ts +685 -30
- package/src/runtime/cache.ts +35 -89
- package/src/runtime/choice.ts +760 -0
- package/src/runtime/executor.ts +19 -2
- package/src/runtime/redis.ts +116 -0
- package/src/runtime/state.ts +487 -0
- package/src/runtime/stealth.ts +8 -1
- package/src/server/serve.ts +361 -46
- package/src/server/types.ts +2 -0
- package/src/testing/run.ts +16 -3
- package/src/types.ts +209 -6
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
export type JsonValue = JsonPrimitive | readonly JsonValue[] | {
|
|
3
|
+
readonly [key: string]: JsonValue;
|
|
4
|
+
};
|
|
5
|
+
export declare function canonicalJson(value: unknown): string;
|
|
6
|
+
export declare function toJsonValue(value: unknown): JsonValue | undefined;
|
|
7
|
+
export declare function compactObject(value: Record<string, JsonValue | undefined>): JsonValue;
|
|
8
|
+
export declare function copyRecordWithout(value: unknown, ignoredKeys: ReadonlySet<string>): Record<string, unknown>;
|
|
9
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export function canonicalJson(value) {
|
|
2
|
+
return JSON.stringify(canonicalize(toJsonValue(value) ?? null));
|
|
3
|
+
}
|
|
4
|
+
export function toJsonValue(value) {
|
|
5
|
+
if (value === null ||
|
|
6
|
+
typeof value === "string" ||
|
|
7
|
+
typeof value === "boolean") {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === "number") {
|
|
11
|
+
return Number.isFinite(value) ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(value)) {
|
|
14
|
+
return value.flatMap((item) => {
|
|
15
|
+
const json = toJsonValue(item);
|
|
16
|
+
return json === undefined ? [] : [json];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (!isRecord(value))
|
|
20
|
+
return undefined;
|
|
21
|
+
return compactObject(Object.fromEntries(Object.entries(value).flatMap(([key, item]) => {
|
|
22
|
+
const json = toJsonValue(item);
|
|
23
|
+
return json === undefined ? [] : [[key, json]];
|
|
24
|
+
})));
|
|
25
|
+
}
|
|
26
|
+
export function compactObject(value) {
|
|
27
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => {
|
|
28
|
+
const [, item] = entry;
|
|
29
|
+
return item !== undefined;
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
export function copyRecordWithout(value, ignoredKeys) {
|
|
33
|
+
if (!isRecord(value))
|
|
34
|
+
return {};
|
|
35
|
+
return Object.fromEntries(Object.entries(value).filter(([key]) => !ignoredKeys.has(key)));
|
|
36
|
+
}
|
|
37
|
+
export function isRecord(value) {
|
|
38
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
39
|
+
}
|
|
40
|
+
function canonicalize(value) {
|
|
41
|
+
if (Array.isArray(value))
|
|
42
|
+
return value.map(canonicalize);
|
|
43
|
+
if (!isRecord(value))
|
|
44
|
+
return value;
|
|
45
|
+
return Object.fromEntries(Object.entries(value)
|
|
46
|
+
.sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
|
|
47
|
+
.flatMap(([key, item]) => {
|
|
48
|
+
const json = toJsonValue(item);
|
|
49
|
+
return json === undefined ? [] : [[key, canonicalize(json)]];
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { canonicalJson, compactObject, isRecord, toJsonValue, } from "./contract-json";
|
|
4
|
+
export function describeSchema(schema) {
|
|
5
|
+
if (isZodSchema(schema)) {
|
|
6
|
+
const jsonSchema = zodJsonSchema(schema);
|
|
7
|
+
return compactObject({
|
|
8
|
+
kind: "schema",
|
|
9
|
+
vendor: "zod",
|
|
10
|
+
typeName: getSchemaTypeName(schema),
|
|
11
|
+
jsonSchema,
|
|
12
|
+
jsonSchemaHash: jsonSchema === undefined
|
|
13
|
+
? undefined
|
|
14
|
+
: digest(canonicalJson(jsonSchema)),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const standard = isRecord(schema) ? schema["~standard"] : undefined;
|
|
18
|
+
if (isRecord(standard)) {
|
|
19
|
+
return compactObject({
|
|
20
|
+
kind: "schema",
|
|
21
|
+
standard: "standard-schema-v1",
|
|
22
|
+
vendor: typeof standard.vendor === "string" ? standard.vendor : "unknown",
|
|
23
|
+
version: typeof standard.version === "number" ||
|
|
24
|
+
typeof standard.version === "string"
|
|
25
|
+
? standard.version
|
|
26
|
+
: undefined,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return compactObject({
|
|
30
|
+
kind: "schema",
|
|
31
|
+
vendor: "zod",
|
|
32
|
+
typeName: getSchemaTypeName(schema),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function serializeSmsMatcher(value) {
|
|
36
|
+
const code = value.code;
|
|
37
|
+
if (!isRecord(code))
|
|
38
|
+
return value;
|
|
39
|
+
const pattern = code.pattern;
|
|
40
|
+
if (!(pattern instanceof RegExp))
|
|
41
|
+
return value;
|
|
42
|
+
return {
|
|
43
|
+
...value,
|
|
44
|
+
code: {
|
|
45
|
+
...code,
|
|
46
|
+
pattern: {
|
|
47
|
+
source: pattern.source,
|
|
48
|
+
flags: pattern.flags,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function digest(value) {
|
|
54
|
+
return createHash("sha256").update(value).digest("hex");
|
|
55
|
+
}
|
|
56
|
+
function isZodSchema(schema) {
|
|
57
|
+
return schema instanceof z.ZodType;
|
|
58
|
+
}
|
|
59
|
+
function zodJsonSchema(schema) {
|
|
60
|
+
try {
|
|
61
|
+
const jsonSchema = z.toJSONSchema(schema);
|
|
62
|
+
return toJsonValue(jsonSchema);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof Error)
|
|
66
|
+
return undefined;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function getSchemaTypeName(schema) {
|
|
71
|
+
if (!isRecord(schema))
|
|
72
|
+
return undefined;
|
|
73
|
+
const def = schema._def;
|
|
74
|
+
if (!isRecord(def))
|
|
75
|
+
return undefined;
|
|
76
|
+
const typeName = def.typeName ?? def.type;
|
|
77
|
+
return typeof typeName === "string" ? typeName : undefined;
|
|
78
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { JsonValue } from "./contract-json";
|
|
2
|
+
import type { ProviderDefinition } from "./types";
|
|
3
|
+
export declare const PROVIDER_CONTRACT_SCHEMA_VERSION = "2026-06-23";
|
|
4
|
+
export interface ProviderContractSnapshot {
|
|
5
|
+
readonly schemaVersion: typeof PROVIDER_CONTRACT_SCHEMA_VERSION;
|
|
6
|
+
readonly provider: {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly version: string;
|
|
9
|
+
readonly runtime: ProviderDefinition["runtime"];
|
|
10
|
+
};
|
|
11
|
+
readonly allowedHosts?: readonly string[];
|
|
12
|
+
readonly stealth?: JsonValue;
|
|
13
|
+
readonly proxy?: JsonValue;
|
|
14
|
+
readonly stt?: JsonValue;
|
|
15
|
+
readonly browser?: JsonValue;
|
|
16
|
+
readonly auth?: JsonValue;
|
|
17
|
+
readonly reviewed?: JsonValue;
|
|
18
|
+
readonly access?: JsonValue;
|
|
19
|
+
readonly secrets?: JsonValue;
|
|
20
|
+
readonly credential?: JsonValue;
|
|
21
|
+
readonly context?: JsonValue;
|
|
22
|
+
readonly meta: JsonValue;
|
|
23
|
+
readonly healthMonitor?: JsonValue;
|
|
24
|
+
readonly healthJourneys?: readonly JsonValue[];
|
|
25
|
+
readonly operations: readonly ProviderContractOperation[];
|
|
26
|
+
}
|
|
27
|
+
export interface ProviderContractOperation {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly descriptionKey?: JsonValue;
|
|
30
|
+
readonly docs?: JsonValue;
|
|
31
|
+
readonly whenToUseKeys?: JsonValue;
|
|
32
|
+
readonly whenNotToUseKeys?: JsonValue;
|
|
33
|
+
readonly derivations?: JsonValue;
|
|
34
|
+
readonly inputExamples?: JsonValue;
|
|
35
|
+
readonly annotations?: JsonValue;
|
|
36
|
+
readonly contract?: JsonValue;
|
|
37
|
+
readonly tags?: JsonValue;
|
|
38
|
+
readonly relatedOperations?: JsonValue;
|
|
39
|
+
readonly toolRouter?: JsonValue;
|
|
40
|
+
readonly observability?: JsonValue;
|
|
41
|
+
readonly transport?: JsonValue;
|
|
42
|
+
readonly inputSchema: JsonValue;
|
|
43
|
+
readonly outputSchema: JsonValue;
|
|
44
|
+
readonly fixtures?: JsonValue;
|
|
45
|
+
readonly upstream?: JsonValue;
|
|
46
|
+
readonly hints?: JsonValue;
|
|
47
|
+
readonly healthCheck?: JsonValue;
|
|
48
|
+
readonly healthCheckUnsupported?: JsonValue;
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PROVIDER_CONTRACT_SCHEMA_VERSION = "2026-06-23";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { canonicalJson, type JsonPrimitive, type JsonValue } from "./contract-json";
|
|
2
|
+
import { PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot } from "./contract-types";
|
|
3
|
+
import type { ProviderDefinition } from "./types";
|
|
4
|
+
export { canonicalJson, type JsonPrimitive, type JsonValue, PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot, };
|
|
5
|
+
export declare function extractProviderContract(provider: ProviderDefinition): ProviderContractSnapshot;
|
|
6
|
+
export declare function digestProviderContract(snapshot: ProviderContractSnapshot): string;
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { canonicalJson, compactObject, copyRecordWithout, toJsonValue, } from "./contract-json";
|
|
3
|
+
import { describeSchema, serializeSmsMatcher } from "./contract-serialization";
|
|
4
|
+
import { PROVIDER_CONTRACT_SCHEMA_VERSION, } from "./contract-types";
|
|
5
|
+
export { canonicalJson, PROVIDER_CONTRACT_SCHEMA_VERSION, };
|
|
6
|
+
export function extractProviderContract(provider) {
|
|
7
|
+
const auth = extractAuth(provider.auth);
|
|
8
|
+
const stealth = toJsonValue(provider.stealth);
|
|
9
|
+
const proxy = toJsonValue(provider.proxy);
|
|
10
|
+
const stt = toJsonValue(provider.stt);
|
|
11
|
+
const browser = toJsonValue(provider.browser);
|
|
12
|
+
const reviewed = toJsonValue(provider.reviewed);
|
|
13
|
+
const access = toJsonValue(provider.access);
|
|
14
|
+
const secrets = toJsonValue(provider.secrets);
|
|
15
|
+
const credential = toJsonValue(provider.credential);
|
|
16
|
+
const context = toJsonValue(provider.context);
|
|
17
|
+
const healthMonitor = toJsonValue(provider.healthMonitor);
|
|
18
|
+
const healthJourneys = provider.healthJourneys?.map(extractHealthJourney);
|
|
19
|
+
return {
|
|
20
|
+
schemaVersion: PROVIDER_CONTRACT_SCHEMA_VERSION,
|
|
21
|
+
provider: {
|
|
22
|
+
id: provider.id,
|
|
23
|
+
version: provider.version,
|
|
24
|
+
runtime: provider.runtime,
|
|
25
|
+
},
|
|
26
|
+
meta: toJsonValue(provider.meta) ?? null,
|
|
27
|
+
operations: Object.entries(provider.operations)
|
|
28
|
+
.sort(([leftId], [rightId]) => leftId.localeCompare(rightId))
|
|
29
|
+
.map(([operationId, operation]) => extractOperation(operationId, operation)),
|
|
30
|
+
...(provider.allowedHosts
|
|
31
|
+
? { allowedHosts: [...provider.allowedHosts].sort() }
|
|
32
|
+
: {}),
|
|
33
|
+
...(stealth === undefined ? {} : { stealth }),
|
|
34
|
+
...(proxy === undefined ? {} : { proxy }),
|
|
35
|
+
...(stt === undefined ? {} : { stt }),
|
|
36
|
+
...(browser === undefined ? {} : { browser }),
|
|
37
|
+
...(auth === undefined ? {} : { auth }),
|
|
38
|
+
...(reviewed === undefined ? {} : { reviewed }),
|
|
39
|
+
...(access === undefined ? {} : { access }),
|
|
40
|
+
...(secrets === undefined ? {} : { secrets }),
|
|
41
|
+
...(credential === undefined ? {} : { credential }),
|
|
42
|
+
...(context === undefined ? {} : { context }),
|
|
43
|
+
...(healthMonitor === undefined ? {} : { healthMonitor }),
|
|
44
|
+
...(healthJourneys === undefined ? {} : { healthJourneys }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function digestProviderContract(snapshot) {
|
|
48
|
+
return createHash("sha256").update(canonicalJson(snapshot)).digest("hex");
|
|
49
|
+
}
|
|
50
|
+
function extractOperation(operationId, operation) {
|
|
51
|
+
const descriptionKey = toJsonValue(operation.descriptionKey);
|
|
52
|
+
const docs = toJsonValue(operation.docs);
|
|
53
|
+
const whenToUseKeys = toJsonValue(operation.whenToUseKeys);
|
|
54
|
+
const whenNotToUseKeys = toJsonValue(operation.whenNotToUseKeys);
|
|
55
|
+
const derivations = toJsonValue(operation.derivations);
|
|
56
|
+
const inputExamples = toJsonValue(operation.inputExamples);
|
|
57
|
+
const annotations = toJsonValue(operation.annotations);
|
|
58
|
+
const contract = toJsonValue(operation.contract);
|
|
59
|
+
const tags = toJsonValue(operation.tags);
|
|
60
|
+
const relatedOperations = toJsonValue(operation.relatedOperations);
|
|
61
|
+
const toolRouter = toJsonValue(operation.toolRouter);
|
|
62
|
+
const observability = toJsonValue(operation.observability);
|
|
63
|
+
const transport = extractTransport(operation.transport);
|
|
64
|
+
const fixtures = toJsonValue(operation.fixtures);
|
|
65
|
+
const upstream = toJsonValue(operation.upstream);
|
|
66
|
+
const hints = toJsonValue(operation.hints);
|
|
67
|
+
const healthCheck = extractHealthCheck(operation.healthCheck);
|
|
68
|
+
const healthCheckUnsupported = extractHealthCheckUnsupported(operation.healthCheckUnsupported);
|
|
69
|
+
return {
|
|
70
|
+
id: operationId,
|
|
71
|
+
inputSchema: describeSchema(operation.input),
|
|
72
|
+
outputSchema: describeSchema(operation.output),
|
|
73
|
+
...(descriptionKey === undefined ? {} : { descriptionKey }),
|
|
74
|
+
...(docs === undefined ? {} : { docs }),
|
|
75
|
+
...(whenToUseKeys === undefined ? {} : { whenToUseKeys }),
|
|
76
|
+
...(whenNotToUseKeys === undefined ? {} : { whenNotToUseKeys }),
|
|
77
|
+
...(derivations === undefined ? {} : { derivations }),
|
|
78
|
+
...(inputExamples === undefined ? {} : { inputExamples }),
|
|
79
|
+
...(annotations === undefined ? {} : { annotations }),
|
|
80
|
+
...(contract === undefined ? {} : { contract }),
|
|
81
|
+
...(tags === undefined ? {} : { tags }),
|
|
82
|
+
...(relatedOperations === undefined ? {} : { relatedOperations }),
|
|
83
|
+
...(toolRouter === undefined ? {} : { toolRouter }),
|
|
84
|
+
...(observability === undefined ? {} : { observability }),
|
|
85
|
+
...(transport === undefined ? {} : { transport }),
|
|
86
|
+
...(fixtures === undefined ? {} : { fixtures }),
|
|
87
|
+
...(upstream === undefined ? {} : { upstream }),
|
|
88
|
+
...(hints === undefined ? {} : { hints }),
|
|
89
|
+
...(healthCheck === undefined ? {} : { healthCheck }),
|
|
90
|
+
...(healthCheckUnsupported === undefined ? {} : { healthCheckUnsupported }),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function extractAuth(value) {
|
|
94
|
+
if (!value)
|
|
95
|
+
return undefined;
|
|
96
|
+
return compactObject({
|
|
97
|
+
mode: value.mode,
|
|
98
|
+
flow: value.flow
|
|
99
|
+
? compactObject({
|
|
100
|
+
start: true,
|
|
101
|
+
continue: true,
|
|
102
|
+
poll: value.flow.poll === undefined ? undefined : true,
|
|
103
|
+
abort: value.flow.abort === undefined ? undefined : true,
|
|
104
|
+
})
|
|
105
|
+
: undefined,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function extractTransport(value) {
|
|
109
|
+
if (!value)
|
|
110
|
+
return undefined;
|
|
111
|
+
if (value.kind !== "sse")
|
|
112
|
+
return toJsonValue(value);
|
|
113
|
+
return compactObject({
|
|
114
|
+
...copyRecordWithout(value, new Set(["events"])),
|
|
115
|
+
events: Object.fromEntries(Object.entries(value.events)
|
|
116
|
+
.sort(([leftId], [rightId]) => leftId.localeCompare(rightId))
|
|
117
|
+
.map(([eventName, schema]) => [eventName, describeSchema(schema)])),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function extractHealthCheck(value) {
|
|
121
|
+
if (!value)
|
|
122
|
+
return undefined;
|
|
123
|
+
return compactObject({
|
|
124
|
+
interval: value.interval,
|
|
125
|
+
timeoutMs: value.timeoutMs,
|
|
126
|
+
degradedThresholdMs: value.degradedThresholdMs,
|
|
127
|
+
requiresConnection: value.requiresConnection,
|
|
128
|
+
cases: value.cases.map((item) => compactObject({
|
|
129
|
+
name: item.name,
|
|
130
|
+
description: item.description,
|
|
131
|
+
input: toJsonValue(item.input),
|
|
132
|
+
degradedThresholdMs: item.degradedThresholdMs,
|
|
133
|
+
timeoutMs: item.timeoutMs,
|
|
134
|
+
expectedStatus: item.expectedStatus,
|
|
135
|
+
})),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function extractHealthCheckUnsupported(value) {
|
|
139
|
+
return toJsonValue(value);
|
|
140
|
+
}
|
|
141
|
+
function extractHealthJourney(value) {
|
|
142
|
+
return compactObject({
|
|
143
|
+
id: value.id,
|
|
144
|
+
title: value.title,
|
|
145
|
+
description: value.description,
|
|
146
|
+
schedule: toJsonValue(value.schedule),
|
|
147
|
+
coversOperations: toJsonValue(value.coversOperations),
|
|
148
|
+
timeout: value.timeout,
|
|
149
|
+
cooldown: value.cooldown,
|
|
150
|
+
smsMatchers: toJsonValue(value.smsMatchers?.map((matcher) => serializeSmsMatcher(copyRecordWithout(matcher, new Set(["extractOtp"]))))),
|
|
151
|
+
requiredSecrets: toJsonValue(value.requiredSecrets),
|
|
152
|
+
manualTrigger: toJsonValue(value.manualTrigger),
|
|
153
|
+
steps: toJsonValue(value.steps),
|
|
154
|
+
});
|
|
155
|
+
}
|
package/dist/define.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { AuthConfig, BrowserEngine, ContextDeclaration, CredentialDeclaration, HealthJourneyDefinition, HealthJourneySchedule, InferSchemaOutput, OperationDefinition, OperationHandlerResult, OperationHttpStreamTransport, OperationSseTransport, OperationWebSocketTransport, ProviderAccessConfig, ProviderDefinition, ProviderHealthMonitorConfig, ProviderProxyConfig, ProviderPublicProfile, ProviderReviewed, ProviderSecretDeclaration, ProviderStreamEvent, ProviderSttConfig, SchemaLike, SmsOtpMatcherDefinition, StealthPlatform } from "./types";
|
|
2
|
+
type ProviderImplementationSourceAccess = "official_api" | "private_api" | "browser_flow" | "hybrid";
|
|
3
|
+
type ProviderImplementationCredentialStrategy = "apifuse_managed" | "workspace_secret" | "user_oauth" | "user_session" | "none";
|
|
4
|
+
interface ProviderImplementationProfile {
|
|
5
|
+
sourceAccess: ProviderImplementationSourceAccess;
|
|
6
|
+
credentialStrategy: ProviderImplementationCredentialStrategy;
|
|
7
|
+
officialDocsUrl?: string;
|
|
8
|
+
operatorNotes?: string;
|
|
9
|
+
visibility: "internal" | "operator";
|
|
10
|
+
}
|
|
11
|
+
type ProviderOperation = OperationDefinition<SchemaLike, SchemaLike>;
|
|
12
|
+
type OperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike> = Omit<OperationDefinition<TInput, TOutput>, "handler"> & {
|
|
13
|
+
handler(ctx: Parameters<OperationDefinition<TInput, TOutput>["handler"]>[0], input: InferSchemaOutput<TInput>): OperationHandlerResult<InferSchemaOutput<TOutput>> | Promise<OperationHandlerResult<InferSchemaOutput<TOutput>>>;
|
|
14
|
+
};
|
|
15
|
+
type OperationMapConfig<TOperations extends Record<string, ProviderOperation>> = {
|
|
16
|
+
[K in keyof TOperations]: TOperations[K] extends OperationDefinition<infer TInput, infer TOutput> ? OperationConfig<TInput, TOutput> | OperationDefinition<TInput, TOutput> : never;
|
|
17
|
+
};
|
|
18
|
+
type StreamOperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike> = SseOperationConfig<TInput, TOutput> | HttpStreamOperationConfig<TInput, TOutput> | WebSocketOperationConfig<TInput, TOutput>;
|
|
19
|
+
type SseOperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike> = Omit<OperationConfig<TInput, TOutput>, "handler" | "transport"> & {
|
|
20
|
+
transport: OperationSseTransport;
|
|
21
|
+
handler(ctx: Parameters<OperationDefinition<TInput, TOutput>["handler"]>[0], input: InferSchemaOutput<TInput>): AsyncIterable<ProviderStreamEvent> | Promise<AsyncIterable<ProviderStreamEvent>>;
|
|
22
|
+
};
|
|
23
|
+
type HttpStreamOperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike> = Omit<OperationConfig<TInput, TOutput>, "handler" | "transport"> & {
|
|
24
|
+
transport: OperationHttpStreamTransport;
|
|
25
|
+
handler(ctx: Parameters<OperationDefinition<TInput, TOutput>["handler"]>[0], input: InferSchemaOutput<TInput>): Response | ReadableStream<Uint8Array> | Promise<Response | ReadableStream<Uint8Array>>;
|
|
26
|
+
};
|
|
27
|
+
type WebSocketOperationConfig<TInput extends SchemaLike, TOutput extends SchemaLike> = Omit<OperationConfig<TInput, TOutput>, "handler" | "transport"> & {
|
|
28
|
+
transport: OperationWebSocketTransport;
|
|
29
|
+
handler(ctx: Parameters<OperationDefinition<TInput, TOutput>["handler"]>[0], input: InferSchemaOutput<TInput>): Response | ReadableStream<Uint8Array> | Promise<Response | ReadableStream<Uint8Array>>;
|
|
30
|
+
};
|
|
31
|
+
type AuthStartNoInputGuard<TConfig> = TConfig extends {
|
|
32
|
+
auth?: {
|
|
33
|
+
flow?: {
|
|
34
|
+
start: infer TStart;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
} ? TStart extends (...args: infer TArgs) => unknown ? TArgs extends [unknown] ? unknown : {
|
|
38
|
+
"auth start handlers must not declare input parameters; return a form turn from start and receive user input in continue": never;
|
|
39
|
+
} : unknown : unknown;
|
|
40
|
+
export interface ProviderConfig<TOperations extends Record<string, ProviderOperation>> {
|
|
41
|
+
id: string;
|
|
42
|
+
version: string;
|
|
43
|
+
runtime: "standard" | "shared" | "browser";
|
|
44
|
+
allowedHosts?: string[];
|
|
45
|
+
stealth?: {
|
|
46
|
+
profile: string;
|
|
47
|
+
platform: StealthPlatform;
|
|
48
|
+
};
|
|
49
|
+
proxy?: ProviderProxyConfig;
|
|
50
|
+
stt?: ProviderSttConfig;
|
|
51
|
+
browser?: {
|
|
52
|
+
engine: BrowserEngine;
|
|
53
|
+
};
|
|
54
|
+
auth?: AuthConfig;
|
|
55
|
+
reviewed?: ProviderReviewed;
|
|
56
|
+
access?: ProviderAccessConfig;
|
|
57
|
+
secrets?: ProviderSecretDeclaration[];
|
|
58
|
+
credential?: CredentialDeclaration;
|
|
59
|
+
context?: ContextDeclaration;
|
|
60
|
+
meta: {
|
|
61
|
+
displayName: string;
|
|
62
|
+
displayNameKey?: string;
|
|
63
|
+
descriptionKey: string;
|
|
64
|
+
category: string;
|
|
65
|
+
tags?: readonly string[];
|
|
66
|
+
icon?: string;
|
|
67
|
+
docTitleKey?: string;
|
|
68
|
+
docDescriptionKey?: string;
|
|
69
|
+
docSummaryKey?: string;
|
|
70
|
+
docMarkdownKey?: string;
|
|
71
|
+
normalizationNotesKeys?: readonly string[];
|
|
72
|
+
environment?: "staging";
|
|
73
|
+
purpose?: string;
|
|
74
|
+
purposeKey?: string;
|
|
75
|
+
publicProfile?: ProviderPublicProfile;
|
|
76
|
+
implementationProfile?: ProviderImplementationProfile;
|
|
77
|
+
contract?: {
|
|
78
|
+
publicSchemaFieldNames?: "normalized";
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
operations: OperationMapConfig<TOperations>;
|
|
82
|
+
healthMonitor?: ProviderHealthMonitorConfig;
|
|
83
|
+
healthJourneys?: readonly HealthJourneyDefinition[];
|
|
84
|
+
}
|
|
85
|
+
/** Define one provider operation with schema-driven handler inference. */
|
|
86
|
+
export declare function defineOperation<TInput extends SchemaLike, TOutput extends SchemaLike>(operation: OperationConfig<TInput, TOutput>): OperationDefinition<TInput, TOutput>;
|
|
87
|
+
/** Define a non-JSON provider operation with explicit transport metadata. */
|
|
88
|
+
export declare function defineStreamOperation<TInput extends SchemaLike, TOutput extends SchemaLike>(operation: StreamOperationConfig<TInput, TOutput>): OperationDefinition<TInput, TOutput>;
|
|
89
|
+
export declare function every(interval: string, options?: {
|
|
90
|
+
jitter?: string;
|
|
91
|
+
}): HealthJourneySchedule;
|
|
92
|
+
export declare function defineSmsOtpMatcher(config: Omit<SmsOtpMatcherDefinition, "extractOtp">): SmsOtpMatcherDefinition;
|
|
93
|
+
export declare function defineHealthJourney(config: HealthJourneyDefinition): HealthJourneyDefinition;
|
|
94
|
+
export declare function defineProvider<TOperations extends Record<string, ProviderOperation>, TConfig extends ProviderConfig<TOperations>>(config: TConfig & AuthStartNoInputGuard<TConfig>): ProviderDefinition & {
|
|
95
|
+
operations: OperationMapConfig<TOperations>;
|
|
96
|
+
};
|
|
97
|
+
export {};
|