@apifuse/provider-sdk 2.2.0-beta.42 → 2.2.0-beta.44
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 +8 -0
- package/bin/apifuse-check.ts +1 -1
- package/bin/apifuse-dev.ts +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +2 -2
- package/dist/define.d.ts +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/server/serve-implementation.d.ts +11 -11
- package/dist/server/serve-implementation.js +11 -46
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/cli/create.ts +2 -2
- package/src/define.ts +10 -0
- package/src/index.ts +2 -0
- package/src/provider.ts +2 -0
- package/src/server/serve-implementation.ts +48 -78
- package/src/types.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @apifuse/provider-sdk Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.0-beta.44
|
|
4
|
+
|
|
5
|
+
- Release candidate for main commit a3091c0b4931c5ae48fe01b9776e4dc213db2716.
|
|
6
|
+
|
|
7
|
+
## 2.2.0-beta.43
|
|
8
|
+
|
|
9
|
+
- Release candidate for main commit 5b8b6048514fb500ead400495bd5e1ed8695ed6d.
|
|
10
|
+
|
|
3
11
|
## 2.2.0-beta.42
|
|
4
12
|
|
|
5
13
|
- Release candidate for main commit efbdbb409c9400e6211b061705b634e659f298bd.
|
package/bin/apifuse-check.ts
CHANGED
|
@@ -551,7 +551,7 @@ function isProviderDefinition(value: unknown): value is ProviderDefinition {
|
|
|
551
551
|
return (
|
|
552
552
|
typeof value.id === "string" &&
|
|
553
553
|
typeof value.version === "string" &&
|
|
554
|
-
(value.runtime === "standard" || value.runtime === "browser") &&
|
|
554
|
+
(value.runtime === "standard" || value.runtime === "shared" || value.runtime === "browser") &&
|
|
555
555
|
typeof value.meta.displayName === "string" &&
|
|
556
556
|
typeof value.meta.category === "string"
|
|
557
557
|
);
|
package/bin/apifuse-dev.ts
CHANGED
|
@@ -249,7 +249,7 @@ function isProviderDefinition(value: unknown): value is ProviderDefinition {
|
|
|
249
249
|
return (
|
|
250
250
|
typeof value.id === "string" &&
|
|
251
251
|
typeof value.version === "string" &&
|
|
252
|
-
(value.runtime === "standard" || value.runtime === "browser") &&
|
|
252
|
+
(value.runtime === "standard" || value.runtime === "shared" || value.runtime === "browser") &&
|
|
253
253
|
typeof value.meta.displayName === "string" &&
|
|
254
254
|
typeof value.meta.category === "string"
|
|
255
255
|
);
|
package/dist/cli/create.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const PROVIDER_NAME_REGEX: RegExp;
|
|
2
2
|
export declare const CATEGORY_OPTIONS: readonly ["developer-tools", "finance", "commerce", "productivity", "marketing", "data", "communication", "other"];
|
|
3
3
|
export declare const AUTH_MODE_OPTIONS: readonly ["none", "platform-managed", "credentials", "oauth2"];
|
|
4
|
-
export declare const RUNTIME_OPTIONS: readonly ["standard", "browser"];
|
|
4
|
+
export declare const RUNTIME_OPTIONS: readonly ["standard", "shared", "browser"];
|
|
5
5
|
export declare const PRESET_OPTIONS: readonly ["standalone", "monorepo"];
|
|
6
6
|
export type CreateCategory = (typeof CATEGORY_OPTIONS)[number];
|
|
7
7
|
export type CreateAuthMode = (typeof AUTH_MODE_OPTIONS)[number];
|
package/dist/cli/create.js
CHANGED
|
@@ -19,7 +19,7 @@ export const CATEGORY_OPTIONS = [
|
|
|
19
19
|
"other",
|
|
20
20
|
];
|
|
21
21
|
export const AUTH_MODE_OPTIONS = ["none", "platform-managed", "credentials", "oauth2"];
|
|
22
|
-
export const RUNTIME_OPTIONS = ["standard", "browser"];
|
|
22
|
+
export const RUNTIME_OPTIONS = ["standard", "shared", "browser"];
|
|
23
23
|
export const PRESET_OPTIONS = ["standalone", "monorepo"];
|
|
24
24
|
const CREATE_CONFIG_SCHEMA = z.object({
|
|
25
25
|
authMode: z.enum(AUTH_MODE_OPTIONS).optional(),
|
|
@@ -46,7 +46,7 @@ Options:
|
|
|
46
46
|
--display-name <name>
|
|
47
47
|
--category <category>
|
|
48
48
|
--auth-mode <mode>
|
|
49
|
-
--runtime <standard|browser>
|
|
49
|
+
--runtime <standard|shared|browser>
|
|
50
50
|
--yes
|
|
51
51
|
--dry-run
|
|
52
52
|
--json
|
package/dist/define.d.ts
CHANGED
|
@@ -130,6 +130,10 @@ export type ProviderBuilder<TDeclaration extends ProviderDeclaration> = <TOperat
|
|
|
130
130
|
};
|
|
131
131
|
/** Extract the declaration-derived operation context from a provider builder. */
|
|
132
132
|
export type ProviderContextOf<TBuilder> = TBuilder extends ProviderBuilder<infer TDeclaration> ? ProviderContextFor<TDeclaration> : never;
|
|
133
|
+
/** Annotate an operation while preserving the declaration-derived context. */
|
|
134
|
+
export type OperationDefinitionFor<TBuilder, TInput extends SchemaLike = SchemaLike, TOutput extends SchemaLike = SchemaLike> = OperationDefinition<TInput, TOutput, ProviderContextOf<TBuilder>>;
|
|
135
|
+
/** Annotate a built provider while preserving the declaration-derived context. */
|
|
136
|
+
export type ProviderDefinitionFor<TBuilder> = ProviderDefinition<ProviderContextOf<TBuilder>>;
|
|
133
137
|
/** Establish a provider declaration before its operations are contextually typed. */
|
|
134
138
|
export declare function defineProvider<const TDeclaration extends ProviderDeclaration>(declaration: TDeclaration & Record<Exclude<keyof TDeclaration, keyof ProviderDeclaration>, never> & AuthStartNoInputGuard<TDeclaration>): ProviderBuilder<TDeclaration>;
|
|
135
139
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export * from "./choice-token.js";
|
|
|
4
4
|
export type { ApiFuseConfig, BrowserConfig, ProxyCacheStatus, ProxyProtocol, ProxyResolutionOptions, ProxyResolutionSource, ProxyUserAgentSource, ProxyVendorName, ResolvedProxyConfig, SessionConfig, SmartproxyAllocatorBodyClass, } from "./config/loader.js";
|
|
5
5
|
export { defineConfig, loadApiFuseConfig, resolveProxy } from "./config/loader.js";
|
|
6
6
|
export { canonicalJson, digestProviderContract, extractProviderContract, type JsonPrimitive, type JsonValue, PROVIDER_CONTRACT_SCHEMA_VERSION, type ProviderContractOperation, type ProviderContractSnapshot, } from "./contract.js";
|
|
7
|
-
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, type AuthStartNoInputGuard, type ProviderBuilder, type ProviderContextOf, type ProviderDeclaration, } from "./define.js";
|
|
7
|
+
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, defineStreamOperation, every, type AuthStartNoInputGuard, type OperationDefinitionFor, type ProviderBuilder, type ProviderContextOf, type ProviderDeclaration, type ProviderDefinitionFor, } from "./define.js";
|
|
8
8
|
export { AssertionExpressionSchema, AssertionPredicateSchema, AssertStepSchema, BoundedJsonPathSchema, CandidateBlockSchema, CandidatePolicySchema, CredentialRefDeclarationSchema, defineHealthScenario, HealthScenarioSchema, HealthStepSchema, ExtractStepSchema, FindFirstSchema, GuardStepSchema, JournalPolicySchema, JsonTemplateSchema, ManualTriggerPolicySchema, OperandSchema, OperationStepSchema, QuantifierSchema, ReferenceSchema, RetryPolicySchema, SafeRegexSchema, ScopedAssertionExpressionSchema, ScopedAssertionPredicateSchema, ScopedItemReferenceSchema, ScopedOperandSchema, StepReferenceSchema, RelativeDateNodeSchema, ValueTypeSchema, } from "./health-scenario.js";
|
|
9
9
|
export type { AssertionExpression, AssertionPredicate, AttemptReference, AssertResult, AssertStep, BoundedJsonPath, CandidateBlock, CandidatePolicy, CandidateReference, CredentialReference, CredentialRefDeclaration, EstablishedConnectionReference, ExtractStep, FindFirst, GuardAttribution, GuardReasonCode, GuardResult, GuardStep, HealthScenario, HealthStep, JsonTemplate, JournalPolicy, ManualTriggerPolicy, NonEmpty, OperationResult, OperationStep, Operand, Quantifier, ReferenceNode, Reference, RelativeDateNode, RetryPolicy, SafeRegex, ScopedAssertionExpression, ScopedAssertionPredicate, ScopedItemReference, ScopedOperand, StepBase, StepReference, ExtractResult, ValueType, } from "./health-scenario.js";
|
|
10
10
|
export type { DevServerOptions } from "./dev.js";
|
package/dist/provider.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type { CredentialsAuthChallengeDefinition, CredentialsAuthChallengeReques
|
|
|
3
3
|
export { createFormCeremony } from "./ceremonies/index.js";
|
|
4
4
|
export { assertFreshProviderChoiceIssuedAt, createProviderChoiceToken, ProviderChoiceTokenError, type ProviderChoiceTokenErrorReason, type ProviderChoiceTokenPayload, parseProviderChoiceToken, } from "./choice-token.js";
|
|
5
5
|
export { centered, delayed, defineHealthJourney, defineOperation, defineProvider, defineSmsOtpMatcher, every, } from "./define.js";
|
|
6
|
-
export type { ProviderBuilder, ProviderContextOf, ProviderDeclaration, } from "./define.js";
|
|
6
|
+
export type { OperationDefinitionFor, ProviderBuilder, ProviderContextOf, ProviderDeclaration, ProviderDefinitionFor, } from "./define.js";
|
|
7
7
|
export type { JsonPrimitive, JsonValue } from "./contract-json.js";
|
|
8
8
|
export { AssertionExpressionSchema, AssertionPredicateSchema, AssertStepSchema, BoundedJsonPathSchema, CandidateBlockSchema, CandidatePolicySchema, CredentialRefDeclarationSchema, defineHealthScenario, HealthScenarioSchema, HealthStepSchema, ExtractStepSchema, FindFirstSchema, GuardStepSchema, JournalPolicySchema, JsonTemplateSchema, ManualTriggerPolicySchema, OperandSchema, OperationStepSchema, QuantifierSchema, ReferenceSchema, RetryPolicySchema, SafeRegexSchema, ScopedAssertionExpressionSchema, ScopedAssertionPredicateSchema, ScopedItemReferenceSchema, ScopedOperandSchema, StepReferenceSchema, RelativeDateNodeSchema, ValueTypeSchema, } from "./health-scenario.js";
|
|
9
9
|
export type { AssertionExpression, AssertionPredicate, AttemptReference, AssertResult, AssertStep, BoundedJsonPath, CandidateBlock, CandidatePolicy, CandidateReference, CredentialReference, CredentialRefDeclaration, EstablishedConnectionReference, ExtractStep, FindFirst, GuardAttribution, GuardReasonCode, GuardResult, GuardStep, HealthScenario, HealthStep, JsonTemplate, JournalPolicy, ManualTriggerPolicy, NonEmpty, OperationResult, OperationStep, Operand, Quantifier, ReferenceNode, Reference, RelativeDateNode, RetryPolicy, SafeRegex, ScopedAssertionExpression, ScopedAssertionPredicate, ScopedItemReference, ScopedOperand, StepBase, StepReference, ExtractResult, ValueType, } from "./health-scenario.js";
|
|
@@ -53,17 +53,17 @@ export declare const ProviderServerStatefulForwardEnvelopeSchema: z.ZodObject<{
|
|
|
53
53
|
export type ProviderServerStatefulForwardEnvelope = Readonly<z.infer<typeof ProviderServerStatefulForwardEnvelopeSchema>>;
|
|
54
54
|
export type ProviderServerStatefulOwnerFence = Readonly<Pick<ProviderServerStatefulForwardEnvelope, "providerId" | "sessionKey" | "ownerPodId" | "generation" | "sourcePodId" | "forwardedAt" | "requestId" | "idempotencyKey">>;
|
|
55
55
|
export type ProviderServerStatefulOwnerFenceValidator = (fence: ProviderServerStatefulOwnerFence, signal: AbortSignal) => boolean | Promise<boolean>;
|
|
56
|
-
export type ProviderServerOperationExecutorInput = {
|
|
57
|
-
readonly provider: ProviderDefinition
|
|
56
|
+
export type ProviderServerOperationExecutorInput<TContext extends Partial<ProviderContext> = ProviderContext> = {
|
|
57
|
+
readonly provider: ProviderDefinition<TContext>;
|
|
58
58
|
readonly operationId: string;
|
|
59
|
-
readonly ctx:
|
|
59
|
+
readonly ctx: TContext;
|
|
60
60
|
readonly request: OperationRequest & {
|
|
61
61
|
readonly deadlineAt?: string;
|
|
62
62
|
};
|
|
63
63
|
readonly signal?: AbortSignal;
|
|
64
64
|
readonly internalStatefulForward?: ProviderServerStatefulForwardEnvelope;
|
|
65
65
|
};
|
|
66
|
-
export type ProviderServerOperationExecutor = (input: ProviderServerOperationExecutorInput) => Promise<unknown>;
|
|
66
|
+
export type ProviderServerOperationExecutor<TContext extends Partial<ProviderContext> = ProviderContext> = (input: ProviderServerOperationExecutorInput<TContext>) => Promise<unknown>;
|
|
67
67
|
export declare function resolveProviderProxyAffinityKey(provider: ProviderDefinition, request: OperationRequest, operationId: string): string;
|
|
68
68
|
export declare function resolveProviderResolverIdentityScope(provider: ProviderDefinition, affinityKey: string, contextId: string): string;
|
|
69
69
|
export declare function resolveAuthFlowProxyAffinityKey(provider: ProviderDefinition, request: Pick<AuthFlowRequest, "connection" | "connectionId" | "externalRef" | "tenantId" | "providerId">): string;
|
|
@@ -138,12 +138,12 @@ export type ProviderServerLogEvent = (ProviderServerLogEventBase & {
|
|
|
138
138
|
message: string;
|
|
139
139
|
} | SelfTestCancellationLogEvent;
|
|
140
140
|
export type ProviderServerLogger = (event: ProviderServerLogEvent) => void;
|
|
141
|
-
export type ProviderServerOptions = {
|
|
141
|
+
export type ProviderServerOptions<TContext extends Partial<ProviderContext> = ProviderContext> = {
|
|
142
142
|
logger?: ProviderServerLogger;
|
|
143
143
|
/** Optional provider-specific operation executor. Stateful providers use this to preserve provider-local runtime semantics. */
|
|
144
|
-
operationExecutor?: ProviderServerOperationExecutor
|
|
144
|
+
operationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
145
145
|
/** Optional signed internal executor for stateful owner forwarding. */
|
|
146
|
-
internalOperationExecutor?: ProviderServerOperationExecutor
|
|
146
|
+
internalOperationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
147
147
|
statefulForwarding?: {
|
|
148
148
|
readonly secret: string;
|
|
149
149
|
readonly maxSkewMs?: number;
|
|
@@ -196,14 +196,14 @@ export type ProviderErrorCauseFrame = {
|
|
|
196
196
|
* Primary, cross-runtime app factory. Declared capability ESM is preloaded
|
|
197
197
|
* asynchronously, so this path works on Bun and every supported Node release.
|
|
198
198
|
*/
|
|
199
|
-
export declare function createServerAppAsync(provider: ProviderDefinition
|
|
199
|
+
export declare function createServerAppAsync<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ProviderServerOptions<TContext>): Promise<Hono>;
|
|
200
200
|
/**
|
|
201
201
|
* Synchronous compatibility factory. Standard providers remain synchronous on
|
|
202
202
|
* every runtime because they load no capability modules. Providers declaring a
|
|
203
203
|
* capability require Bun or Node >=22.12; older Node releases receive an
|
|
204
204
|
* actionable error directing them to createServerAppAsync().
|
|
205
205
|
*/
|
|
206
|
-
export declare function createServerApp(provider: ProviderDefinition
|
|
206
|
+
export declare function createServerApp<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ProviderServerOptions<TContext>): Hono;
|
|
207
207
|
export type ProviderServerCloseOptions = {
|
|
208
208
|
readonly timeoutMs?: number;
|
|
209
209
|
};
|
|
@@ -211,7 +211,7 @@ export type ProviderServerHandle = {
|
|
|
211
211
|
readonly port: number;
|
|
212
212
|
close(options?: ProviderServerCloseOptions): Promise<void>;
|
|
213
213
|
};
|
|
214
|
-
export interface ServeOptions extends ProviderServerOptions {
|
|
214
|
+
export interface ServeOptions<TContext extends Partial<ProviderContext> = ProviderContext> extends ProviderServerOptions<TContext> {
|
|
215
215
|
host?: string;
|
|
216
216
|
port?: number;
|
|
217
217
|
/**
|
|
@@ -221,5 +221,5 @@ export interface ServeOptions extends ProviderServerOptions {
|
|
|
221
221
|
*/
|
|
222
222
|
selfTestPort?: number;
|
|
223
223
|
}
|
|
224
|
-
export declare function serve(provider: ProviderDefinition
|
|
224
|
+
export declare function serve<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ServeOptions<TContext>): Promise<ProviderServerHandle>;
|
|
225
225
|
export {};
|
|
@@ -9,7 +9,7 @@ import { validateFailClosedDeclaration } from "../declaration-validation.js";
|
|
|
9
9
|
import { safeProviderErrorObservability } from "../error-observability.js";
|
|
10
10
|
import { SDK_OWNED_PROVIDER_ERROR_CODES, SDK_RUNTIME_OWNED_ERROR_CODES, SDK_STATUS_MAPPED_PROVIDER_ERROR_CODES, } from "../error-resolution.js";
|
|
11
11
|
import { AuthError, isProviderError, isSessionExpiredError, isTransportError, isValidationError, ProviderError, } from "../errors.js";
|
|
12
|
-
import {
|
|
12
|
+
import { sanitizeDiagnosticText } from "../fixture-sanitization.js";
|
|
13
13
|
import { loadProviderLocaleCatalogs, localizeAuthTurn, } from "../i18n/catalog.js";
|
|
14
14
|
import { categoryForStatus, sourceForCategory, isRetryableCategory, PROVIDER_OBSERVABILITY_TAXONOMY_VERSION, } from "../observability.js";
|
|
15
15
|
import { createScratchpad } from "../runtime/auth-flow.js";
|
|
@@ -979,47 +979,8 @@ function extractRequestId(raw) {
|
|
|
979
979
|
}
|
|
980
980
|
const MAX_PROVIDER_ERROR_CAUSE_FRAMES = 5;
|
|
981
981
|
const MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH = 300;
|
|
982
|
-
const UNSTRUCTURED_PROVIDER_ERROR_CAUSE_MESSAGE = "[UNSTRUCTURED_UPSTREAM_TEXT]";
|
|
983
|
-
const PROVIDER_ERROR_CAUSE_RETAINED_URL_RUN = /https?:\/\/[^\s"'<>]+/giu;
|
|
984
|
-
const PROVIDER_ERROR_CAUSE_TOKEN_RUN = /\S+/gu;
|
|
985
|
-
const PROVIDER_ERROR_CAUSE_TOKEN_EDGE_PUNCTUATION = /^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu;
|
|
986
|
-
const STRUCTURALLY_SAFE_PROVIDER_ERROR_CAUSE_WORDS = new Set([
|
|
987
|
-
"completion",
|
|
988
|
-
"diagnostic",
|
|
989
|
-
"provider",
|
|
990
|
-
"rejected",
|
|
991
|
-
"returned",
|
|
992
|
-
"upstream",
|
|
993
|
-
]);
|
|
994
|
-
/**
|
|
995
|
-
* Cause frames fail closed when sanitization leaves a plausible credential-shaped free-text run.
|
|
996
|
-
* Redaction sentinels and retained URLs are ignored. Every other whitespace token (or each side
|
|
997
|
-
* of a structured key=value token) with at least eight Unicode characters must reduce to this
|
|
998
|
-
* small vocabulary drawn from SDK diagnostics; counting punctuation keeps bare passwords opaque.
|
|
999
|
-
*/
|
|
1000
|
-
function isStructurallySafeProviderErrorCauseMessage(message) {
|
|
1001
|
-
const classifiableMessage = message
|
|
1002
|
-
.replaceAll(REDACTED_FIXTURE_VALUE, " ")
|
|
1003
|
-
.replace(PROVIDER_ERROR_CAUSE_RETAINED_URL_RUN, " ");
|
|
1004
|
-
for (const match of classifiableMessage.matchAll(PROVIDER_ERROR_CAUSE_TOKEN_RUN)) {
|
|
1005
|
-
const token = match[0];
|
|
1006
|
-
for (const run of token.split("=")) {
|
|
1007
|
-
const diagnosticWord = run
|
|
1008
|
-
.replace(PROVIDER_ERROR_CAUSE_TOKEN_EDGE_PUNCTUATION, "")
|
|
1009
|
-
.toLowerCase();
|
|
1010
|
-
if (STRUCTURALLY_SAFE_PROVIDER_ERROR_CAUSE_WORDS.has(diagnosticWord))
|
|
1011
|
-
continue;
|
|
1012
|
-
if ([...run].length >= 8)
|
|
1013
|
-
return false;
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
return true;
|
|
1017
|
-
}
|
|
1018
982
|
function providerErrorCauseMessage(message) {
|
|
1019
983
|
const sanitized = sanitizeDiagnosticText(message);
|
|
1020
|
-
if (!isStructurallySafeProviderErrorCauseMessage(sanitized)) {
|
|
1021
|
-
return UNSTRUCTURED_PROVIDER_ERROR_CAUSE_MESSAGE;
|
|
1022
|
-
}
|
|
1023
984
|
return sanitized.length > MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH
|
|
1024
985
|
? `${sanitized.slice(0, MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH)}… [truncated]`
|
|
1025
986
|
: sanitized;
|
|
@@ -1685,9 +1646,11 @@ function parseStatefulForwardingEnvelope(rawBody) {
|
|
|
1685
1646
|
* asynchronously, so this path works on Bun and every supported Node release.
|
|
1686
1647
|
*/
|
|
1687
1648
|
export async function createServerAppAsync(provider, options = {}) {
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1649
|
+
const runtimeProvider = provider;
|
|
1650
|
+
const runtimeOptions = options;
|
|
1651
|
+
validateFailClosedDeclaration(runtimeProvider);
|
|
1652
|
+
validateStatefulServerConfig(runtimeOptions);
|
|
1653
|
+
return createServerAppWithCapabilityModules(runtimeProvider, runtimeOptions, await loadProviderCapabilityModules(runtimeProvider));
|
|
1691
1654
|
}
|
|
1692
1655
|
/**
|
|
1693
1656
|
* Synchronous compatibility factory. Standard providers remain synchronous on
|
|
@@ -1696,9 +1659,11 @@ export async function createServerAppAsync(provider, options = {}) {
|
|
|
1696
1659
|
* actionable error directing them to createServerAppAsync().
|
|
1697
1660
|
*/
|
|
1698
1661
|
export function createServerApp(provider, options = {}) {
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1662
|
+
const runtimeProvider = provider;
|
|
1663
|
+
const runtimeOptions = options;
|
|
1664
|
+
validateFailClosedDeclaration(runtimeProvider);
|
|
1665
|
+
validateStatefulServerConfig(runtimeOptions);
|
|
1666
|
+
return createServerAppWithCapabilityModules(runtimeProvider, runtimeOptions, loadProviderCapabilityModulesSync(runtimeProvider));
|
|
1702
1667
|
}
|
|
1703
1668
|
function createServerAppWithCapabilityModules(provider, serverOptions, capabilityModules) {
|
|
1704
1669
|
const options = { ...serverOptions, capabilityModules };
|
package/dist/types.d.ts
CHANGED
|
@@ -2024,7 +2024,7 @@ export interface ProviderDeploymentOverrides {
|
|
|
2024
2024
|
};
|
|
2025
2025
|
buildContext?: string;
|
|
2026
2026
|
}
|
|
2027
|
-
export interface ProviderDefinition {
|
|
2027
|
+
export interface ProviderDefinition<TContext = ProviderContext> {
|
|
2028
2028
|
id: string;
|
|
2029
2029
|
version: string;
|
|
2030
2030
|
runtime: "standard" | "shared" | "browser";
|
|
@@ -2054,7 +2054,7 @@ export interface ProviderDefinition {
|
|
|
2054
2054
|
credential?: CredentialDeclaration;
|
|
2055
2055
|
context?: ContextDeclaration;
|
|
2056
2056
|
meta: ProviderMeta;
|
|
2057
|
-
operations: Record<string, OperationDefinition<SchemaLike, SchemaLike>>;
|
|
2057
|
+
operations: Record<string, OperationDefinition<SchemaLike, SchemaLike, TContext>>;
|
|
2058
2058
|
healthMonitor?: ProviderHealthMonitorConfig;
|
|
2059
2059
|
/** Transitional alias for `healthMonitor`; `defineProvider` mirrors both. */
|
|
2060
2060
|
healthProbe?: ProviderHealthProbeConfig;
|
package/package.json
CHANGED
package/src/cli/create.ts
CHANGED
|
@@ -26,7 +26,7 @@ export const CATEGORY_OPTIONS = [
|
|
|
26
26
|
"other",
|
|
27
27
|
] as const;
|
|
28
28
|
export const AUTH_MODE_OPTIONS = ["none", "platform-managed", "credentials", "oauth2"] as const;
|
|
29
|
-
export const RUNTIME_OPTIONS = ["standard", "browser"] as const;
|
|
29
|
+
export const RUNTIME_OPTIONS = ["standard", "shared", "browser"] as const;
|
|
30
30
|
export const PRESET_OPTIONS = ["standalone", "monorepo"] as const;
|
|
31
31
|
|
|
32
32
|
export type CreateCategory = (typeof CATEGORY_OPTIONS)[number];
|
|
@@ -102,7 +102,7 @@ Options:
|
|
|
102
102
|
--display-name <name>
|
|
103
103
|
--category <category>
|
|
104
104
|
--auth-mode <mode>
|
|
105
|
-
--runtime <standard|browser>
|
|
105
|
+
--runtime <standard|shared|browser>
|
|
106
106
|
--yes
|
|
107
107
|
--dry-run
|
|
108
108
|
--json
|
package/src/define.ts
CHANGED
|
@@ -2892,6 +2892,16 @@ export type ProviderContextOf<TBuilder> = TBuilder extends ProviderBuilder<infer
|
|
|
2892
2892
|
? ProviderContextFor<TDeclaration>
|
|
2893
2893
|
: never;
|
|
2894
2894
|
|
|
2895
|
+
/** Annotate an operation while preserving the declaration-derived context. */
|
|
2896
|
+
export type OperationDefinitionFor<
|
|
2897
|
+
TBuilder,
|
|
2898
|
+
TInput extends SchemaLike = SchemaLike,
|
|
2899
|
+
TOutput extends SchemaLike = SchemaLike,
|
|
2900
|
+
> = OperationDefinition<TInput, TOutput, ProviderContextOf<TBuilder>>;
|
|
2901
|
+
|
|
2902
|
+
/** Annotate a built provider while preserving the declaration-derived context. */
|
|
2903
|
+
export type ProviderDefinitionFor<TBuilder> = ProviderDefinition<ProviderContextOf<TBuilder>>;
|
|
2904
|
+
|
|
2895
2905
|
/** Establish a provider declaration before its operations are contextually typed. */
|
|
2896
2906
|
export function defineProvider<const TDeclaration extends ProviderDeclaration>(
|
|
2897
2907
|
declaration: TDeclaration &
|
package/src/index.ts
CHANGED
|
@@ -37,9 +37,11 @@ export {
|
|
|
37
37
|
defineStreamOperation,
|
|
38
38
|
every,
|
|
39
39
|
type AuthStartNoInputGuard,
|
|
40
|
+
type OperationDefinitionFor,
|
|
40
41
|
type ProviderBuilder,
|
|
41
42
|
type ProviderContextOf,
|
|
42
43
|
type ProviderDeclaration,
|
|
44
|
+
type ProviderDefinitionFor,
|
|
43
45
|
} from "./define.js";
|
|
44
46
|
export {
|
|
45
47
|
AssertionExpressionSchema,
|
package/src/provider.ts
CHANGED
|
@@ -36,9 +36,11 @@ export {
|
|
|
36
36
|
every,
|
|
37
37
|
} from "./define.js";
|
|
38
38
|
export type {
|
|
39
|
+
OperationDefinitionFor,
|
|
39
40
|
ProviderBuilder,
|
|
40
41
|
ProviderContextOf,
|
|
41
42
|
ProviderDeclaration,
|
|
43
|
+
ProviderDefinitionFor,
|
|
42
44
|
} from "./define.js";
|
|
43
45
|
export type { JsonPrimitive, JsonValue } from "./contract-json.js";
|
|
44
46
|
export {
|
|
@@ -23,10 +23,7 @@ import {
|
|
|
23
23
|
type ProviderErrorObservability,
|
|
24
24
|
type ProviderErrorOptions,
|
|
25
25
|
} from "../errors.js";
|
|
26
|
-
import {
|
|
27
|
-
REDACTED_FIXTURE_VALUE,
|
|
28
|
-
sanitizeDiagnosticText,
|
|
29
|
-
} from "../fixture-sanitization.js";
|
|
26
|
+
import { sanitizeDiagnosticText } from "../fixture-sanitization.js";
|
|
30
27
|
import {
|
|
31
28
|
loadProviderLocaleCatalogs,
|
|
32
29
|
localizeAuthTurn,
|
|
@@ -234,17 +231,21 @@ export type ProviderServerStatefulOwnerFenceValidator = (
|
|
|
234
231
|
signal: AbortSignal,
|
|
235
232
|
) => boolean | Promise<boolean>;
|
|
236
233
|
|
|
237
|
-
export type ProviderServerOperationExecutorInput
|
|
238
|
-
|
|
234
|
+
export type ProviderServerOperationExecutorInput<
|
|
235
|
+
TContext extends Partial<ProviderContext> = ProviderContext,
|
|
236
|
+
> = {
|
|
237
|
+
readonly provider: ProviderDefinition<TContext>;
|
|
239
238
|
readonly operationId: string;
|
|
240
|
-
readonly ctx:
|
|
239
|
+
readonly ctx: TContext;
|
|
241
240
|
readonly request: OperationRequest & { readonly deadlineAt?: string };
|
|
242
241
|
readonly signal?: AbortSignal;
|
|
243
242
|
readonly internalStatefulForward?: ProviderServerStatefulForwardEnvelope;
|
|
244
243
|
};
|
|
245
244
|
|
|
246
|
-
export type ProviderServerOperationExecutor
|
|
247
|
-
|
|
245
|
+
export type ProviderServerOperationExecutor<
|
|
246
|
+
TContext extends Partial<ProviderContext> = ProviderContext,
|
|
247
|
+
> = (
|
|
248
|
+
input: ProviderServerOperationExecutorInput<TContext>,
|
|
248
249
|
) => Promise<unknown>;
|
|
249
250
|
|
|
250
251
|
type RequestCleanup = () => void | Promise<void>;
|
|
@@ -1072,12 +1073,12 @@ export type ProviderServerLogEvent =
|
|
|
1072
1073
|
|
|
1073
1074
|
export type ProviderServerLogger = (event: ProviderServerLogEvent) => void;
|
|
1074
1075
|
|
|
1075
|
-
export type ProviderServerOptions = {
|
|
1076
|
+
export type ProviderServerOptions<TContext extends Partial<ProviderContext> = ProviderContext> = {
|
|
1076
1077
|
logger?: ProviderServerLogger;
|
|
1077
1078
|
/** Optional provider-specific operation executor. Stateful providers use this to preserve provider-local runtime semantics. */
|
|
1078
|
-
operationExecutor?: ProviderServerOperationExecutor
|
|
1079
|
+
operationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
1079
1080
|
/** Optional signed internal executor for stateful owner forwarding. */
|
|
1080
|
-
internalOperationExecutor?: ProviderServerOperationExecutor
|
|
1081
|
+
internalOperationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
1081
1082
|
statefulForwarding?: {
|
|
1082
1083
|
readonly secret: string;
|
|
1083
1084
|
readonly maxSkewMs?: number;
|
|
@@ -1522,48 +1523,9 @@ export type ProviderErrorCauseFrame = {
|
|
|
1522
1523
|
|
|
1523
1524
|
const MAX_PROVIDER_ERROR_CAUSE_FRAMES = 5;
|
|
1524
1525
|
const MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH = 300;
|
|
1525
|
-
const UNSTRUCTURED_PROVIDER_ERROR_CAUSE_MESSAGE = "[UNSTRUCTURED_UPSTREAM_TEXT]";
|
|
1526
|
-
const PROVIDER_ERROR_CAUSE_RETAINED_URL_RUN = /https?:\/\/[^\s"'<>]+/giu;
|
|
1527
|
-
const PROVIDER_ERROR_CAUSE_TOKEN_RUN = /\S+/gu;
|
|
1528
|
-
const PROVIDER_ERROR_CAUSE_TOKEN_EDGE_PUNCTUATION =
|
|
1529
|
-
/^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu;
|
|
1530
|
-
const STRUCTURALLY_SAFE_PROVIDER_ERROR_CAUSE_WORDS = new Set([
|
|
1531
|
-
"completion",
|
|
1532
|
-
"diagnostic",
|
|
1533
|
-
"provider",
|
|
1534
|
-
"rejected",
|
|
1535
|
-
"returned",
|
|
1536
|
-
"upstream",
|
|
1537
|
-
]);
|
|
1538
|
-
|
|
1539
|
-
/**
|
|
1540
|
-
* Cause frames fail closed when sanitization leaves a plausible credential-shaped free-text run.
|
|
1541
|
-
* Redaction sentinels and retained URLs are ignored. Every other whitespace token (or each side
|
|
1542
|
-
* of a structured key=value token) with at least eight Unicode characters must reduce to this
|
|
1543
|
-
* small vocabulary drawn from SDK diagnostics; counting punctuation keeps bare passwords opaque.
|
|
1544
|
-
*/
|
|
1545
|
-
function isStructurallySafeProviderErrorCauseMessage(message: string): boolean {
|
|
1546
|
-
const classifiableMessage = message
|
|
1547
|
-
.replaceAll(REDACTED_FIXTURE_VALUE, " ")
|
|
1548
|
-
.replace(PROVIDER_ERROR_CAUSE_RETAINED_URL_RUN, " ");
|
|
1549
|
-
for (const match of classifiableMessage.matchAll(PROVIDER_ERROR_CAUSE_TOKEN_RUN)) {
|
|
1550
|
-
const token = match[0];
|
|
1551
|
-
for (const run of token.split("=")) {
|
|
1552
|
-
const diagnosticWord = run
|
|
1553
|
-
.replace(PROVIDER_ERROR_CAUSE_TOKEN_EDGE_PUNCTUATION, "")
|
|
1554
|
-
.toLowerCase();
|
|
1555
|
-
if (STRUCTURALLY_SAFE_PROVIDER_ERROR_CAUSE_WORDS.has(diagnosticWord)) continue;
|
|
1556
|
-
if ([...run].length >= 8) return false;
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
return true;
|
|
1560
|
-
}
|
|
1561
1526
|
|
|
1562
1527
|
function providerErrorCauseMessage(message: string): string {
|
|
1563
1528
|
const sanitized = sanitizeDiagnosticText(message);
|
|
1564
|
-
if (!isStructurallySafeProviderErrorCauseMessage(sanitized)) {
|
|
1565
|
-
return UNSTRUCTURED_PROVIDER_ERROR_CAUSE_MESSAGE;
|
|
1566
|
-
}
|
|
1567
1529
|
return sanitized.length > MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH
|
|
1568
1530
|
? `${sanitized.slice(0, MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH)}… [truncated]`
|
|
1569
1531
|
: sanitized;
|
|
@@ -2413,16 +2375,18 @@ function parseStatefulForwardingEnvelope(rawBody: unknown): ProviderServerStatef
|
|
|
2413
2375
|
* Primary, cross-runtime app factory. Declared capability ESM is preloaded
|
|
2414
2376
|
* asynchronously, so this path works on Bun and every supported Node release.
|
|
2415
2377
|
*/
|
|
2416
|
-
export async function createServerAppAsync(
|
|
2417
|
-
provider: ProviderDefinition
|
|
2418
|
-
options: ProviderServerOptions = {},
|
|
2378
|
+
export async function createServerAppAsync<TContext extends Partial<ProviderContext> = ProviderContext>(
|
|
2379
|
+
provider: ProviderDefinition<TContext>,
|
|
2380
|
+
options: ProviderServerOptions<TContext> = {},
|
|
2419
2381
|
): Promise<Hono> {
|
|
2420
|
-
|
|
2421
|
-
|
|
2382
|
+
const runtimeProvider = provider as unknown as ProviderDefinition;
|
|
2383
|
+
const runtimeOptions = options as unknown as ProviderServerOptions;
|
|
2384
|
+
validateFailClosedDeclaration(runtimeProvider);
|
|
2385
|
+
validateStatefulServerConfig(runtimeOptions);
|
|
2422
2386
|
return createServerAppWithCapabilityModules(
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
await loadProviderCapabilityModules(
|
|
2387
|
+
runtimeProvider,
|
|
2388
|
+
runtimeOptions,
|
|
2389
|
+
await loadProviderCapabilityModules(runtimeProvider),
|
|
2426
2390
|
);
|
|
2427
2391
|
}
|
|
2428
2392
|
|
|
@@ -2432,16 +2396,18 @@ export async function createServerAppAsync(
|
|
|
2432
2396
|
* capability require Bun or Node >=22.12; older Node releases receive an
|
|
2433
2397
|
* actionable error directing them to createServerAppAsync().
|
|
2434
2398
|
*/
|
|
2435
|
-
export function createServerApp(
|
|
2436
|
-
provider: ProviderDefinition
|
|
2437
|
-
options: ProviderServerOptions = {},
|
|
2399
|
+
export function createServerApp<TContext extends Partial<ProviderContext> = ProviderContext>(
|
|
2400
|
+
provider: ProviderDefinition<TContext>,
|
|
2401
|
+
options: ProviderServerOptions<TContext> = {},
|
|
2438
2402
|
): Hono {
|
|
2439
|
-
|
|
2440
|
-
|
|
2403
|
+
const runtimeProvider = provider as unknown as ProviderDefinition;
|
|
2404
|
+
const runtimeOptions = options as unknown as ProviderServerOptions;
|
|
2405
|
+
validateFailClosedDeclaration(runtimeProvider);
|
|
2406
|
+
validateStatefulServerConfig(runtimeOptions);
|
|
2441
2407
|
return createServerAppWithCapabilityModules(
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
loadProviderCapabilityModulesSync(
|
|
2408
|
+
runtimeProvider,
|
|
2409
|
+
runtimeOptions,
|
|
2410
|
+
loadProviderCapabilityModulesSync(runtimeProvider),
|
|
2445
2411
|
);
|
|
2446
2412
|
}
|
|
2447
2413
|
|
|
@@ -3131,7 +3097,8 @@ export type ProviderServerHandle = {
|
|
|
3131
3097
|
close(options?: ProviderServerCloseOptions): Promise<void>;
|
|
3132
3098
|
};
|
|
3133
3099
|
|
|
3134
|
-
export interface ServeOptions extends
|
|
3100
|
+
export interface ServeOptions<TContext extends Partial<ProviderContext> = ProviderContext>
|
|
3101
|
+
extends ProviderServerOptions<TContext> {
|
|
3135
3102
|
host?: string;
|
|
3136
3103
|
port?: number;
|
|
3137
3104
|
/**
|
|
@@ -3158,9 +3125,9 @@ type ProcessSignalCoordinator = {
|
|
|
3158
3125
|
|
|
3159
3126
|
const processSignalCoordinators = new Map<NodeJS.Signals, ProcessSignalCoordinator>();
|
|
3160
3127
|
|
|
3161
|
-
export async function serve(
|
|
3162
|
-
provider: ProviderDefinition
|
|
3163
|
-
options: ServeOptions = {},
|
|
3128
|
+
export async function serve<TContext extends Partial<ProviderContext> = ProviderContext>(
|
|
3129
|
+
provider: ProviderDefinition<TContext>,
|
|
3130
|
+
options: ServeOptions<TContext> = {},
|
|
3164
3131
|
): Promise<ProviderServerHandle> {
|
|
3165
3132
|
const bunRuntime = getBunServeRuntime();
|
|
3166
3133
|
|
|
@@ -3175,7 +3142,7 @@ export async function serve(
|
|
|
3175
3142
|
);
|
|
3176
3143
|
const configuredSignals = resolveShutdownSignals(options.shutdown?.signals ?? true);
|
|
3177
3144
|
const selfTestSecrets = resolveSelfTestMasterSecrets();
|
|
3178
|
-
const serverAppOptions: ProviderServerOptions = {
|
|
3145
|
+
const serverAppOptions: ProviderServerOptions<TContext> = {
|
|
3179
3146
|
logger: options.logger,
|
|
3180
3147
|
ocr: options.ocr,
|
|
3181
3148
|
stt: options.stt,
|
|
@@ -3205,12 +3172,15 @@ export async function serve(
|
|
|
3205
3172
|
// socket the tenant-facing gateway never dials. Off by default — it only
|
|
3206
3173
|
// starts when the shared self-test master secret env is present.
|
|
3207
3174
|
if (selfTestSecrets && selfTestModule) {
|
|
3208
|
-
const selfTestApp = selfTestModule.createSelfTestApp(
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3175
|
+
const selfTestApp = selfTestModule.createSelfTestApp(
|
|
3176
|
+
provider as unknown as ProviderDefinition,
|
|
3177
|
+
{
|
|
3178
|
+
secrets: selfTestSecrets,
|
|
3179
|
+
invoke: selfTestModule.createSelfTestInvoke(app),
|
|
3180
|
+
authFlow: selfTestModule.createSelfTestAuthFlowInvoke(app),
|
|
3181
|
+
logger,
|
|
3182
|
+
},
|
|
3183
|
+
);
|
|
3214
3184
|
servers.push(
|
|
3215
3185
|
bunRuntime.serve({
|
|
3216
3186
|
port: options.selfTestPort ?? selfTestModule.resolveSelfTestPort(),
|
package/src/types.ts
CHANGED
|
@@ -2479,7 +2479,7 @@ export interface ProviderDeploymentOverrides {
|
|
|
2479
2479
|
buildContext?: string;
|
|
2480
2480
|
}
|
|
2481
2481
|
|
|
2482
|
-
export interface ProviderDefinition {
|
|
2482
|
+
export interface ProviderDefinition<TContext = ProviderContext> {
|
|
2483
2483
|
id: string;
|
|
2484
2484
|
version: string;
|
|
2485
2485
|
runtime: "standard" | "shared" | "browser";
|
|
@@ -2509,7 +2509,7 @@ export interface ProviderDefinition {
|
|
|
2509
2509
|
credential?: CredentialDeclaration;
|
|
2510
2510
|
context?: ContextDeclaration;
|
|
2511
2511
|
meta: ProviderMeta;
|
|
2512
|
-
operations: Record<string, OperationDefinition<SchemaLike, SchemaLike>>;
|
|
2512
|
+
operations: Record<string, OperationDefinition<SchemaLike, SchemaLike, TContext>>;
|
|
2513
2513
|
healthMonitor?: ProviderHealthMonitorConfig;
|
|
2514
2514
|
/** Transitional alias for `healthMonitor`; `defineProvider` mirrors both. */
|
|
2515
2515
|
healthProbe?: ProviderHealthProbeConfig;
|