@apifuse/provider-sdk 2.1.0-beta.0 → 2.1.0-beta.10
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 +218 -21
- package/CHANGELOG.md +54 -0
- package/README.md +147 -10
- package/SUBMISSION.md +87 -0
- package/bin/apifuse-check.ts +86 -4
- package/bin/apifuse-dev.ts +87 -13
- package/bin/apifuse-pack-check.ts +120 -0
- package/bin/apifuse-pack-smoke.ts +423 -0
- package/bin/apifuse-perf.ts +142 -49
- package/bin/apifuse-record.ts +182 -104
- package/bin/apifuse-submit-check.ts +2538 -0
- package/bin/apifuse.ts +1 -1
- 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/cli/templates/provider/.dockerignore.tpl +22 -0
- package/dist/cli/templates/provider/.gitignore.tpl +22 -0
- package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
- package/dist/cli/templates/provider/README.md.tpl +160 -0
- package/dist/cli/templates/provider/dev.ts.tpl +5 -0
- package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
- package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
- package/dist/cli/templates/provider/index.ts.tpl +15 -0
- package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
- package/dist/cli/templates/provider/meta.ts.tpl +7 -0
- package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
- package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/start.ts.tpl +5 -0
- package/dist/cli/templates/provider/upstream/README.md.tpl +3 -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 +57 -29
- package/src/ceremonies/index.ts +30 -3
- package/src/choice-token.ts +165 -0
- package/src/cli/commands.ts +34 -11
- package/src/cli/create.ts +214 -52
- package/src/cli/templates/provider/.dockerignore.tpl +22 -0
- package/src/cli/templates/provider/.gitignore.tpl +22 -0
- package/src/cli/templates/provider/README.md.tpl +134 -2
- package/src/cli/templates/provider/dev.ts.tpl +1 -1
- package/src/cli/templates/provider/domain/README.md.tpl +3 -0
- package/src/cli/templates/provider/index.ts.tpl +5 -44
- package/src/cli/templates/provider/mappers/README.md.tpl +3 -0
- package/src/cli/templates/provider/meta.ts.tpl +7 -0
- package/src/cli/templates/provider/operations/index.ts.tpl +5 -0
- package/src/cli/templates/provider/operations/ping.ts.tpl +24 -0
- package/src/cli/templates/provider/schemas/ping.ts.tpl +24 -0
- package/src/cli/templates/provider/start.ts.tpl +1 -1
- package/src/cli/templates/provider/upstream/README.md.tpl +3 -0
- package/src/config/loader.ts +1282 -7
- 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 +1726 -48
- package/src/errors.ts +27 -0
- package/src/i18n/catalog.ts +277 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/keys.ts +64 -0
- package/src/index.ts +174 -15
- package/src/lint.ts +547 -73
- package/src/observability.ts +41 -0
- package/src/provider.ts +104 -5
- package/src/public-schema-field-lint.ts +237 -0
- package/src/runtime/auth-flow.ts +7 -0
- package/src/runtime/browser.ts +762 -51
- package/src/runtime/cache.ts +528 -0
- package/src/runtime/choice.ts +760 -0
- package/src/runtime/executor.ts +32 -3
- package/src/runtime/http.ts +945 -185
- package/src/runtime/insights.ts +11 -11
- package/src/runtime/instrumentation.ts +12 -4
- package/src/runtime/key-derivation.ts +1 -1
- package/src/runtime/keyring.ts +4 -3
- package/src/runtime/proxy-errors.ts +132 -0
- package/src/runtime/proxy-telemetry.ts +253 -0
- package/src/runtime/redis.ts +116 -0
- package/src/runtime/request-options.ts +66 -0
- package/src/runtime/state.ts +563 -0
- package/src/runtime/stealth.ts +1159 -0
- package/src/runtime/stt.ts +629 -0
- package/src/runtime/trace.ts +1 -1
- package/src/schema.ts +363 -1
- package/src/server/serve.ts +1172 -76
- package/src/server/types.ts +37 -0
- package/src/stream.ts +210 -0
- package/src/testing/run.ts +31 -5
- package/src/types.ts +1118 -44
- package/src/composite.ts +0 -43
- package/src/runtime/tls.ts +0 -425
- package/src/types/playwright-stealth.d.ts +0 -9
package/src/errors.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import type { ProviderErrorCategory } from "./observability";
|
|
2
|
+
|
|
1
3
|
export type ProviderErrorOptions = {
|
|
2
4
|
fix?: string;
|
|
3
5
|
code?: string;
|
|
6
|
+
details?: unknown;
|
|
4
7
|
cause?: Error;
|
|
8
|
+
category?: ProviderErrorCategory;
|
|
9
|
+
retryable?: boolean;
|
|
5
10
|
};
|
|
6
11
|
|
|
7
12
|
export class ProviderError extends Error {
|
|
@@ -23,6 +28,10 @@ export class ProviderError extends Error {
|
|
|
23
28
|
get code(): string | undefined {
|
|
24
29
|
return this.options?.code;
|
|
25
30
|
}
|
|
31
|
+
|
|
32
|
+
get details(): unknown {
|
|
33
|
+
return this.options?.details;
|
|
34
|
+
}
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
export class SDKError extends ProviderError {
|
|
@@ -39,6 +48,21 @@ export class AuthError extends ProviderError {
|
|
|
39
48
|
}
|
|
40
49
|
}
|
|
41
50
|
|
|
51
|
+
export class SessionExpiredError extends AuthError {
|
|
52
|
+
constructor(
|
|
53
|
+
message = "Provider session expired",
|
|
54
|
+
options?: ProviderErrorOptions,
|
|
55
|
+
) {
|
|
56
|
+
super(message, {
|
|
57
|
+
code: "reauth_required",
|
|
58
|
+
category: "credential_expired",
|
|
59
|
+
retryable: false,
|
|
60
|
+
...options,
|
|
61
|
+
});
|
|
62
|
+
this.name = "SessionExpiredError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
42
66
|
export type ValidationErrorOptions = ProviderErrorOptions & {
|
|
43
67
|
zodError?: unknown;
|
|
44
68
|
};
|
|
@@ -55,15 +79,18 @@ export class ValidationError extends ProviderError {
|
|
|
55
79
|
|
|
56
80
|
export type TransportErrorOptions = ProviderErrorOptions & {
|
|
57
81
|
status?: number;
|
|
82
|
+
upstreamStatus?: number;
|
|
58
83
|
};
|
|
59
84
|
|
|
60
85
|
export class TransportError extends ProviderError {
|
|
61
86
|
readonly status?: number;
|
|
87
|
+
readonly upstreamStatus?: number;
|
|
62
88
|
|
|
63
89
|
constructor(message: string, options?: TransportErrorOptions) {
|
|
64
90
|
super(message, options);
|
|
65
91
|
this.name = "TransportError";
|
|
66
92
|
this.status = options?.status;
|
|
93
|
+
this.upstreamStatus = options?.upstreamStatus ?? options?.status;
|
|
67
94
|
}
|
|
68
95
|
}
|
|
69
96
|
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { AuthTurn } from "../types";
|
|
5
|
+
import {
|
|
6
|
+
getProviderLocalePath,
|
|
7
|
+
isProviderLocaleValue,
|
|
8
|
+
type ProviderLocale,
|
|
9
|
+
type ProviderLocaleCatalog,
|
|
10
|
+
type ProviderLocaleKey,
|
|
11
|
+
type ProviderLocaleValue,
|
|
12
|
+
providerLocaleKey,
|
|
13
|
+
} from "./keys";
|
|
14
|
+
|
|
15
|
+
export type ProviderLocaleCatalogMap = Record<
|
|
16
|
+
ProviderLocale,
|
|
17
|
+
ProviderLocaleCatalog
|
|
18
|
+
>;
|
|
19
|
+
|
|
20
|
+
export interface LoadProviderLocaleCatalogsOptions {
|
|
21
|
+
providerDir: string;
|
|
22
|
+
locales: readonly ProviderLocale[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ProviderLocaleValidationIssue {
|
|
26
|
+
locale: ProviderLocale;
|
|
27
|
+
key: string;
|
|
28
|
+
message: string;
|
|
29
|
+
severity: "error" | "warning";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ProviderLocaleValidationResult {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
issues: ProviderLocaleValidationIssue[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function loadProviderLocaleCatalogs(
|
|
38
|
+
options: LoadProviderLocaleCatalogsOptions,
|
|
39
|
+
): ProviderLocaleCatalogMap {
|
|
40
|
+
const catalogs: ProviderLocaleCatalogMap = {};
|
|
41
|
+
for (const locale of options.locales) {
|
|
42
|
+
const filePath = join(options.providerDir, "locales", `${locale}.json`);
|
|
43
|
+
catalogs[locale] = JSON.parse(readFileSync(filePath, "utf8"));
|
|
44
|
+
}
|
|
45
|
+
return catalogs;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function resolveProviderLocaleValue(
|
|
49
|
+
catalogs: ProviderLocaleCatalogMap,
|
|
50
|
+
key: ProviderLocaleKey | string,
|
|
51
|
+
locale: ProviderLocale,
|
|
52
|
+
fallbackLocale: ProviderLocale = "en",
|
|
53
|
+
): ProviderLocaleValue | undefined {
|
|
54
|
+
providerLocaleKey(key);
|
|
55
|
+
return (
|
|
56
|
+
getProviderLocalePath(catalogs[locale] ?? {}, key) ??
|
|
57
|
+
getProviderLocalePath(catalogs[fallbackLocale] ?? {}, key)
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function asStringValue(
|
|
62
|
+
value: ProviderLocaleValue | undefined,
|
|
63
|
+
): string | undefined {
|
|
64
|
+
return typeof value === "string" ? value : undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isStringRecord(value: unknown): value is Record<string, string> {
|
|
68
|
+
return (
|
|
69
|
+
!!value &&
|
|
70
|
+
typeof value === "object" &&
|
|
71
|
+
!Array.isArray(value) &&
|
|
72
|
+
Object.values(value).every((entry) => typeof entry === "string")
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function localizeAuthInputSchema(
|
|
77
|
+
expectedInput: Record<string, unknown> | undefined,
|
|
78
|
+
options: {
|
|
79
|
+
catalogs: ProviderLocaleCatalogMap;
|
|
80
|
+
locale: ProviderLocale;
|
|
81
|
+
fallbackLocale: ProviderLocale;
|
|
82
|
+
},
|
|
83
|
+
): Record<string, unknown> | undefined {
|
|
84
|
+
if (!expectedInput) return undefined;
|
|
85
|
+
const schema = isRecord(expectedInput.schema)
|
|
86
|
+
? expectedInput.schema
|
|
87
|
+
: expectedInput;
|
|
88
|
+
const localizedSchema = localizeAuthSchemaObject(schema, options);
|
|
89
|
+
if (localizedSchema === schema) return undefined;
|
|
90
|
+
return isRecord(expectedInput.schema)
|
|
91
|
+
? { ...expectedInput, schema: localizedSchema }
|
|
92
|
+
: localizedSchema;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
96
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function localizeAuthSchemaObject(
|
|
100
|
+
schema: Record<string, unknown>,
|
|
101
|
+
options: {
|
|
102
|
+
catalogs: ProviderLocaleCatalogMap;
|
|
103
|
+
locale: ProviderLocale;
|
|
104
|
+
fallbackLocale: ProviderLocale;
|
|
105
|
+
},
|
|
106
|
+
): Record<string, unknown> {
|
|
107
|
+
const properties = isRecord(schema.properties)
|
|
108
|
+
? schema.properties
|
|
109
|
+
: undefined;
|
|
110
|
+
if (!properties) return schema;
|
|
111
|
+
|
|
112
|
+
let changed = false;
|
|
113
|
+
const localizedProperties = Object.fromEntries(
|
|
114
|
+
Object.entries(properties).map(([fieldName, property]) => {
|
|
115
|
+
if (!isRecord(property)) return [fieldName, property];
|
|
116
|
+
const nameKey =
|
|
117
|
+
typeof property.nameKey === "string" ? property.nameKey : undefined;
|
|
118
|
+
const descriptionKey =
|
|
119
|
+
typeof property.descriptionKey === "string"
|
|
120
|
+
? property.descriptionKey
|
|
121
|
+
: undefined;
|
|
122
|
+
const title = nameKey
|
|
123
|
+
? asStringValue(
|
|
124
|
+
resolveProviderLocaleValue(
|
|
125
|
+
options.catalogs,
|
|
126
|
+
nameKey,
|
|
127
|
+
options.locale,
|
|
128
|
+
options.fallbackLocale,
|
|
129
|
+
),
|
|
130
|
+
)
|
|
131
|
+
: undefined;
|
|
132
|
+
const description = descriptionKey
|
|
133
|
+
? asStringValue(
|
|
134
|
+
resolveProviderLocaleValue(
|
|
135
|
+
options.catalogs,
|
|
136
|
+
descriptionKey,
|
|
137
|
+
options.locale,
|
|
138
|
+
options.fallbackLocale,
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
: undefined;
|
|
142
|
+
if (!title && !description) return [fieldName, property];
|
|
143
|
+
changed = true;
|
|
144
|
+
return [
|
|
145
|
+
fieldName,
|
|
146
|
+
{
|
|
147
|
+
...property,
|
|
148
|
+
...(title ? { title } : {}),
|
|
149
|
+
...(description ? { description } : {}),
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
}),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return changed ? { ...schema, properties: localizedProperties } : schema;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function localizeAuthTurn(
|
|
159
|
+
turn: AuthTurn,
|
|
160
|
+
options: {
|
|
161
|
+
catalogs: ProviderLocaleCatalogMap;
|
|
162
|
+
locale: ProviderLocale;
|
|
163
|
+
fallbackLocale?: ProviderLocale;
|
|
164
|
+
},
|
|
165
|
+
): AuthTurn {
|
|
166
|
+
const fallbackLocale = options.fallbackLocale ?? "en";
|
|
167
|
+
const hint = turn.hintKey
|
|
168
|
+
? asStringValue(
|
|
169
|
+
resolveProviderLocaleValue(
|
|
170
|
+
options.catalogs,
|
|
171
|
+
turn.hintKey,
|
|
172
|
+
options.locale,
|
|
173
|
+
fallbackLocale,
|
|
174
|
+
),
|
|
175
|
+
)
|
|
176
|
+
: undefined;
|
|
177
|
+
const expectedInput = localizeAuthInputSchema(turn.expectedInput, {
|
|
178
|
+
catalogs: options.catalogs,
|
|
179
|
+
locale: options.locale,
|
|
180
|
+
fallbackLocale,
|
|
181
|
+
});
|
|
182
|
+
const fieldErrorKeys = turn.data?.fieldErrorKeys;
|
|
183
|
+
const fieldErrors = isStringRecord(fieldErrorKeys)
|
|
184
|
+
? Object.fromEntries(
|
|
185
|
+
Object.entries(fieldErrorKeys).flatMap(([fieldName, key]) => {
|
|
186
|
+
const message = asStringValue(
|
|
187
|
+
resolveProviderLocaleValue(
|
|
188
|
+
options.catalogs,
|
|
189
|
+
key,
|
|
190
|
+
options.locale,
|
|
191
|
+
fallbackLocale,
|
|
192
|
+
),
|
|
193
|
+
);
|
|
194
|
+
return message ? [[fieldName, message]] : [];
|
|
195
|
+
}),
|
|
196
|
+
)
|
|
197
|
+
: undefined;
|
|
198
|
+
|
|
199
|
+
if (!hint && !fieldErrors && !expectedInput) return turn;
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
...turn,
|
|
203
|
+
...(hint ? { hint } : {}),
|
|
204
|
+
...(expectedInput ? { expectedInput } : {}),
|
|
205
|
+
...(fieldErrors
|
|
206
|
+
? {
|
|
207
|
+
data: {
|
|
208
|
+
...(turn.data ?? {}),
|
|
209
|
+
fieldErrors,
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
: {}),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function validateProviderLocaleCatalogs(options: {
|
|
217
|
+
catalogs: ProviderLocaleCatalogMap;
|
|
218
|
+
requiredLocales: readonly ProviderLocale[];
|
|
219
|
+
requiredKeys: readonly (ProviderLocaleKey | string)[];
|
|
220
|
+
}): ProviderLocaleValidationResult {
|
|
221
|
+
const issues: ProviderLocaleValidationIssue[] = [];
|
|
222
|
+
const uniqueKeys = Array.from(
|
|
223
|
+
new Set(
|
|
224
|
+
options.requiredKeys.map((key) => {
|
|
225
|
+
providerLocaleKey(key);
|
|
226
|
+
return key;
|
|
227
|
+
}),
|
|
228
|
+
),
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
for (const locale of options.requiredLocales) {
|
|
232
|
+
const catalog = options.catalogs[locale];
|
|
233
|
+
if (!catalog) {
|
|
234
|
+
issues.push({
|
|
235
|
+
locale,
|
|
236
|
+
key: "*",
|
|
237
|
+
message: `Missing provider locale catalog for ${locale}`,
|
|
238
|
+
severity: "error",
|
|
239
|
+
});
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
for (const key of uniqueKeys) {
|
|
244
|
+
const value = getProviderLocalePath(catalog, key);
|
|
245
|
+
if (value === undefined) {
|
|
246
|
+
issues.push({
|
|
247
|
+
locale,
|
|
248
|
+
key,
|
|
249
|
+
message: `Missing provider locale key ${key} in ${locale}`,
|
|
250
|
+
severity: "error",
|
|
251
|
+
});
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (!isProviderLocaleValue(value)) {
|
|
255
|
+
issues.push({
|
|
256
|
+
locale,
|
|
257
|
+
key,
|
|
258
|
+
message: `Provider locale key ${key} must resolve to a string or string array`,
|
|
259
|
+
severity: "error",
|
|
260
|
+
});
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
for (const text of Array.isArray(value) ? value : [value]) {
|
|
264
|
+
if (text.trim().length === 0 || /\bTODO\b/i.test(text)) {
|
|
265
|
+
issues.push({
|
|
266
|
+
locale,
|
|
267
|
+
key,
|
|
268
|
+
message: `Provider locale key ${key} in ${locale} is empty or placeholder text`,
|
|
269
|
+
severity: "error",
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return { ok: issues.every((issue) => issue.severity !== "error"), issues };
|
|
277
|
+
}
|
package/src/i18n/keys.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ProviderLocaleKey } from "../types";
|
|
2
|
+
|
|
3
|
+
export type { ProviderLocale, ProviderLocaleKey } from "../types";
|
|
4
|
+
|
|
5
|
+
const PROVIDER_LOCALE_KEY_RE =
|
|
6
|
+
/^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]+)*(?:\.[a-z][a-z0-9]*(?:[A-Z][a-z0-9]+)*|\.[0-9]+)*$/;
|
|
7
|
+
|
|
8
|
+
export function providerLocaleKey(key: string): ProviderLocaleKey {
|
|
9
|
+
assertProviderLocaleKey(key);
|
|
10
|
+
return key;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function isProviderLocaleKey(
|
|
14
|
+
value: unknown,
|
|
15
|
+
): value is ProviderLocaleKey {
|
|
16
|
+
return typeof value === "string" && PROVIDER_LOCALE_KEY_RE.test(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function assertProviderLocaleKey(
|
|
20
|
+
value: unknown,
|
|
21
|
+
): asserts value is ProviderLocaleKey {
|
|
22
|
+
if (!isProviderLocaleKey(value)) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Provider locale key must be a dot path such as "meta.description" or "operations.search.description"; received ${JSON.stringify(value)}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function qualifyProviderLocaleKey(
|
|
30
|
+
providerId: string,
|
|
31
|
+
key: ProviderLocaleKey | string,
|
|
32
|
+
): string {
|
|
33
|
+
assertProviderLocaleKey(key);
|
|
34
|
+
return `providers.${providerId}.${key}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function getProviderLocalePath(
|
|
38
|
+
catalog: ProviderLocaleCatalog,
|
|
39
|
+
key: ProviderLocaleKey | string,
|
|
40
|
+
): ProviderLocaleValue | undefined {
|
|
41
|
+
assertProviderLocaleKey(key);
|
|
42
|
+
let cursor: unknown = catalog;
|
|
43
|
+
for (const segment of key.split(".")) {
|
|
44
|
+
if (!isRecord(cursor)) return undefined;
|
|
45
|
+
cursor = cursor[segment];
|
|
46
|
+
}
|
|
47
|
+
return isProviderLocaleValue(cursor) ? cursor : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type ProviderLocaleValue = string | readonly string[];
|
|
51
|
+
export type ProviderLocaleCatalog = Record<string, unknown>;
|
|
52
|
+
|
|
53
|
+
export function isProviderLocaleValue(
|
|
54
|
+
value: unknown,
|
|
55
|
+
): value is ProviderLocaleValue {
|
|
56
|
+
return (
|
|
57
|
+
typeof value === "string" ||
|
|
58
|
+
(Array.isArray(value) && value.every((entry) => typeof entry === "string"))
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
63
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
64
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
// @apifuse/provider-sdk
|
|
2
2
|
|
|
3
|
-
export { z } from "zod";
|
|
4
3
|
export * from "./ceremonies";
|
|
5
|
-
export
|
|
6
|
-
type ClarifyResponse,
|
|
7
|
-
type CompositeContext,
|
|
8
|
-
type CompositeOperationDefinition,
|
|
9
|
-
defineCompositeOperation,
|
|
10
|
-
} from "./composite";
|
|
4
|
+
export * from "./choice-token";
|
|
11
5
|
export type {
|
|
12
6
|
ApiFuseConfig,
|
|
13
7
|
BrowserConfig,
|
|
@@ -15,10 +9,29 @@ export type {
|
|
|
15
9
|
SessionConfig,
|
|
16
10
|
} from "./config/loader";
|
|
17
11
|
export { defineConfig, loadApiFuseConfig } from "./config/loader";
|
|
18
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
canonicalJson,
|
|
14
|
+
digestProviderContract,
|
|
15
|
+
extractProviderContract,
|
|
16
|
+
type JsonPrimitive,
|
|
17
|
+
type JsonValue,
|
|
18
|
+
PROVIDER_CONTRACT_SCHEMA_VERSION,
|
|
19
|
+
type ProviderContractOperation,
|
|
20
|
+
type ProviderContractSnapshot,
|
|
21
|
+
} from "./contract";
|
|
22
|
+
export {
|
|
23
|
+
defineHealthJourney,
|
|
24
|
+
defineOperation,
|
|
25
|
+
defineProvider,
|
|
26
|
+
defineSmsOtpMatcher,
|
|
27
|
+
defineStreamOperation,
|
|
28
|
+
every,
|
|
29
|
+
type ProviderConfig,
|
|
30
|
+
} from "./define";
|
|
19
31
|
export type { DevServerOptions } from "./dev";
|
|
20
32
|
export { createDevServer, startDevServer } from "./dev";
|
|
21
33
|
export * from "./errors";
|
|
34
|
+
export * from "./i18n";
|
|
22
35
|
export {
|
|
23
36
|
type LintDiagnostic,
|
|
24
37
|
lintOperation,
|
|
@@ -29,6 +42,18 @@ export * from "./recipes/rest-api";
|
|
|
29
42
|
export { createFlowContext, createScratchpad } from "./runtime/auth-flow";
|
|
30
43
|
export type { BrowserClientOptions } from "./runtime/browser";
|
|
31
44
|
export { BrowserClient, createBrowserClient } from "./runtime/browser";
|
|
45
|
+
export {
|
|
46
|
+
createBypassProviderCache,
|
|
47
|
+
createProviderCache,
|
|
48
|
+
type ProviderCacheOptions,
|
|
49
|
+
resetProviderCacheForTests,
|
|
50
|
+
} from "./runtime/cache";
|
|
51
|
+
export {
|
|
52
|
+
type CreateProviderChoiceContextOptions,
|
|
53
|
+
createProviderChoiceContext,
|
|
54
|
+
createTestProviderChoiceContext,
|
|
55
|
+
PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
|
|
56
|
+
} from "./runtime/choice";
|
|
32
57
|
export {
|
|
33
58
|
type CreateCredentialContextOptions,
|
|
34
59
|
createCredentialContext,
|
|
@@ -45,23 +70,56 @@ export {
|
|
|
45
70
|
} from "./runtime/instrumentation";
|
|
46
71
|
export { type PrevalidateResult, prevalidate } from "./runtime/prevalidate";
|
|
47
72
|
export { getProviderBaseUrl } from "./runtime/provider";
|
|
48
|
-
export {
|
|
73
|
+
export {
|
|
74
|
+
createUnsupportedProviderRuntimeState,
|
|
75
|
+
UnsupportedProviderStateError,
|
|
76
|
+
} from "./runtime/state";
|
|
77
|
+
export { createStealthClient } from "./runtime/stealth";
|
|
78
|
+
export {
|
|
79
|
+
APIFUSE__STT__BACKEND_ENV,
|
|
80
|
+
APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV,
|
|
81
|
+
APIFUSE__STT__MODEL_ENV,
|
|
82
|
+
createSttClientFromEnv,
|
|
83
|
+
createUnsupportedSttClient,
|
|
84
|
+
extractVerificationCode,
|
|
85
|
+
resolveSttPrompt,
|
|
86
|
+
} from "./runtime/stt";
|
|
49
87
|
export {
|
|
50
88
|
type CreateTraceContextOptions,
|
|
51
89
|
createTraceContext,
|
|
52
90
|
type Span,
|
|
53
91
|
type TraceContext,
|
|
54
92
|
} from "./runtime/trace";
|
|
93
|
+
export {
|
|
94
|
+
APIFUSE_DESCRIPTION_KEY_META_KEY,
|
|
95
|
+
APIFUSE_REDACTION_MARKER,
|
|
96
|
+
APIFUSE_SENSITIVE_KIND_META_KEY,
|
|
97
|
+
APIFUSE_SENSITIVE_META_KEY,
|
|
98
|
+
collectSensitivePaths,
|
|
99
|
+
describeKey,
|
|
100
|
+
field,
|
|
101
|
+
fields,
|
|
102
|
+
isSensitiveSchema,
|
|
103
|
+
redactPayload,
|
|
104
|
+
type SensitiveFieldKind,
|
|
105
|
+
type SensitiveFieldOptions,
|
|
106
|
+
type SensitivePath,
|
|
107
|
+
sensitive,
|
|
108
|
+
z,
|
|
109
|
+
} from "./schema";
|
|
55
110
|
export { createServerApp, type ServeOptions, serve } from "./server";
|
|
56
111
|
export { getStealthProfile, listStealthProfiles } from "./stealth/profiles";
|
|
112
|
+
export * from "./stream";
|
|
57
113
|
export type {
|
|
58
114
|
ApiFuseResponse,
|
|
59
115
|
AuthConfig,
|
|
60
116
|
AuthContext,
|
|
61
117
|
AuthFlowDefinition,
|
|
62
|
-
|
|
118
|
+
AuthFlowInputHandler,
|
|
119
|
+
AuthFlowStartHandler,
|
|
63
120
|
AuthMode,
|
|
64
121
|
AuthTurn,
|
|
122
|
+
Bcp47Locale,
|
|
65
123
|
BrowserEngine,
|
|
66
124
|
BrowserOptions,
|
|
67
125
|
ConnectionMode,
|
|
@@ -69,6 +127,7 @@ export type {
|
|
|
69
127
|
ContextScratchpad,
|
|
70
128
|
CredentialContext,
|
|
71
129
|
CredentialDeclaration,
|
|
130
|
+
E164PhoneNumber,
|
|
72
131
|
EnvContext,
|
|
73
132
|
FlowContext,
|
|
74
133
|
FlowContextStore,
|
|
@@ -77,35 +136,135 @@ export type {
|
|
|
77
136
|
HealthCheckCaseResult,
|
|
78
137
|
HealthCheckSuite,
|
|
79
138
|
HealthCheckUnsupported,
|
|
139
|
+
HealthJourneyDefinition,
|
|
140
|
+
HealthJourneyEventContext,
|
|
141
|
+
HealthJourneyGatewayContext,
|
|
142
|
+
HealthJourneyJournalContext,
|
|
143
|
+
HealthJourneyManualTriggerPolicy,
|
|
144
|
+
HealthJourneyRunContext,
|
|
145
|
+
HealthJourneyRunResult,
|
|
146
|
+
HealthJourneySchedule,
|
|
147
|
+
HealthJourneySmsContext,
|
|
148
|
+
HealthJourneyStep,
|
|
80
149
|
HttpClient,
|
|
150
|
+
HttpMethod,
|
|
81
151
|
HttpResponse,
|
|
152
|
+
HttpRetryOptions,
|
|
153
|
+
HttpRetrySummary,
|
|
154
|
+
HttpStreamResponse,
|
|
155
|
+
IanaTimeZone,
|
|
82
156
|
InferSchemaOutput,
|
|
157
|
+
Iso3166Alpha2CountryCode,
|
|
158
|
+
Iso4217CurrencyCode,
|
|
159
|
+
Iso8601Duration,
|
|
83
160
|
OperationAnnotations,
|
|
161
|
+
OperationApprovalPolicy,
|
|
162
|
+
OperationContractMetadata,
|
|
84
163
|
OperationDefinition,
|
|
164
|
+
OperationDeprecationMetadata,
|
|
85
165
|
OperationDocMeta,
|
|
86
166
|
OperationErrorCode,
|
|
167
|
+
OperationHandlerResult,
|
|
87
168
|
OperationInputExample,
|
|
169
|
+
OperationLifecycle,
|
|
170
|
+
OperationObservabilityConfig,
|
|
171
|
+
OperationObservabilitySensitiveConfig,
|
|
88
172
|
OperationRelationships,
|
|
173
|
+
OperationRiskClass,
|
|
174
|
+
OperationSensitivePath,
|
|
175
|
+
OperationToolRouterMetadata,
|
|
176
|
+
OperationTransport,
|
|
177
|
+
OperationTransportKind,
|
|
89
178
|
ProbeInterval,
|
|
179
|
+
ProviderAccessConfig,
|
|
180
|
+
ProviderAccessVisibility,
|
|
181
|
+
ProviderCache,
|
|
182
|
+
ProviderCacheGetOrSetOptions,
|
|
183
|
+
ProviderCacheKeyOptions,
|
|
184
|
+
ProviderCacheLookupMeta,
|
|
185
|
+
ProviderCacheResponseMeta,
|
|
186
|
+
ProviderCacheResult,
|
|
187
|
+
ProviderChoiceBindingOptions,
|
|
188
|
+
ProviderChoiceContext,
|
|
189
|
+
ProviderChoiceIssueOptions,
|
|
190
|
+
ProviderChoiceParseOptions,
|
|
90
191
|
ProviderContext,
|
|
91
192
|
ProviderDefinition,
|
|
92
193
|
ProviderHealthMonitorConfig,
|
|
194
|
+
ProviderLocale,
|
|
195
|
+
ProviderLocaleKey,
|
|
196
|
+
ProviderLocaleKeyInput,
|
|
197
|
+
ProviderLogoProfile,
|
|
198
|
+
ProviderLogoSource,
|
|
93
199
|
ProviderMeta,
|
|
200
|
+
ProviderProxyConfig,
|
|
201
|
+
ProviderProxyMode,
|
|
202
|
+
ProviderProxyPolicy,
|
|
203
|
+
ProviderProxyProvider,
|
|
204
|
+
ProviderProxySessionAffinity,
|
|
205
|
+
ProviderPublicConnectionMode,
|
|
206
|
+
ProviderPublicProfile,
|
|
94
207
|
ProviderReviewed,
|
|
208
|
+
ProviderRuntimeState,
|
|
95
209
|
ProviderSecretDeclaration,
|
|
210
|
+
ProviderStateDurationString,
|
|
211
|
+
ProviderStateNamespace,
|
|
212
|
+
ProviderStreamEvent,
|
|
213
|
+
ProviderSttConfig,
|
|
214
|
+
ProviderSttMode,
|
|
215
|
+
ProviderSupportLevel,
|
|
96
216
|
RequestOptions,
|
|
217
|
+
Rfc3339Instant,
|
|
97
218
|
SchemaLike,
|
|
219
|
+
SmsOrigin,
|
|
220
|
+
SmsOtpExtractionPattern,
|
|
221
|
+
SmsOtpMatcherDefinition,
|
|
222
|
+
SseMessage,
|
|
98
223
|
StandardSchemaV1,
|
|
224
|
+
StateCasResult,
|
|
225
|
+
StateNamespaceOptions,
|
|
226
|
+
StateValue,
|
|
227
|
+
StateWriteOptions,
|
|
228
|
+
StealthClient,
|
|
229
|
+
StealthFetchOptions,
|
|
99
230
|
StealthPlatform,
|
|
100
231
|
StealthProfile,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
232
|
+
StealthResponse,
|
|
233
|
+
StealthSession,
|
|
234
|
+
SttAudioInput,
|
|
235
|
+
SttContext,
|
|
236
|
+
SttPromptPolicy,
|
|
237
|
+
SttSegment,
|
|
238
|
+
SttTranscribeMode,
|
|
239
|
+
SttTranscribeRequest,
|
|
240
|
+
SttTranscript,
|
|
241
|
+
SttUnsupportedOptionPolicy,
|
|
242
|
+
SttUsage,
|
|
243
|
+
SttVerificationCodeOptions,
|
|
244
|
+
SttWarning,
|
|
105
245
|
TraceConfig,
|
|
106
246
|
TraceSpan,
|
|
247
|
+
VerificationCodeCandidate,
|
|
248
|
+
VerificationCodeCandidateSource,
|
|
249
|
+
VerificationCodeExtractionResult,
|
|
250
|
+
} from "./types";
|
|
251
|
+
export {
|
|
252
|
+
DEFAULT_OPERATION_TRANSPORT,
|
|
253
|
+
HttpRetryAfterPolicy,
|
|
254
|
+
HttpRetryDelayStrategy,
|
|
255
|
+
HttpRetryJitter,
|
|
256
|
+
HttpRetryPreset,
|
|
257
|
+
HttpRetryUnsafeMethodPolicy,
|
|
258
|
+
PROBE_INTERVALS,
|
|
259
|
+
STREAM_CHUNK_BYTES_MAX,
|
|
260
|
+
STREAM_CHUNK_BYTES_MIN,
|
|
261
|
+
STREAM_HEARTBEAT_MS_MAX,
|
|
262
|
+
STREAM_HEARTBEAT_MS_MIN,
|
|
263
|
+
STREAM_IDLE_TIMEOUT_MS_MAX,
|
|
264
|
+
STREAM_IDLE_TIMEOUT_MS_MIN,
|
|
265
|
+
STREAM_MAX_DURATION_MS_MAX,
|
|
266
|
+
STREAM_MAX_DURATION_MS_MIN,
|
|
107
267
|
} from "./types";
|
|
108
|
-
export { PROBE_INTERVALS } from "./types";
|
|
109
268
|
export * from "./utils/date";
|
|
110
269
|
export * from "./utils/parse";
|
|
111
270
|
export * from "./utils/text";
|