@zuplo/runtime 7.9.9 → 7.9.12

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.
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{E as p,J as c,M as u}from"../chunk-WFAFGL5Y.js";import"../chunk-54HRCPVQ.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import"../chunk-6O4OZCO6.js";import{aa as i}from"../chunk-MWIJG5KC.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
25
+ import{E as p,J as c,M as u}from"../chunk-2XSPVUOE.js";import"../chunk-VTO3F6DK.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import"../chunk-YJ2BHVUH.js";import{aa as i}from"../chunk-PBDT4FDO.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
26
26
  //# sourceMappingURL=index.js.map
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{H as a,I as l,J as c,K as o,N as p,O as y,P as m}from"../../chunk-6O4OZCO6.js";import"../../chunk-MWIJG5KC.js";import{a as i}from"../../chunk-TYV53J3B.js";async function g(r,e){let t=typeof e.credentials=="function"?await e.credentials():e.credentials,n=r.method,d=n!=="GET"&&n!=="HEAD"&&r.body!=null?await r.arrayBuffer():null,s=await new o({method:n,url:r.url,headers:r.headers,body:d,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey,sessionToken:t.sessionToken,service:e.service,region:e.region,signQuery:e.signQuery}).sign();return new Request(s.url.toString(),{method:s.method,headers:s.headers,body:s.body})}i(g,"signRequest");export{c as AwsClient,o as AwsV4Signer,p as fromTemporaryCredentials,y as fromWebToken,m as fromZuploIdentity,l as getAwsCredentialProvider,a as setAwsCredentialProvider,g as signRequest};
25
+ import{H as a,I as l,J as c,K as o,N as p,O as y,P as m}from"../../chunk-YJ2BHVUH.js";import"../../chunk-PBDT4FDO.js";import{a as i}from"../../chunk-TYV53J3B.js";async function g(r,e){let t=typeof e.credentials=="function"?await e.credentials():e.credentials,n=r.method,d=n!=="GET"&&n!=="HEAD"&&r.body!=null?await r.arrayBuffer():null,s=await new o({method:n,url:r.url,headers:r.headers,body:d,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey,sessionToken:t.sessionToken,service:e.service,region:e.region,signQuery:e.signQuery}).sign();return new Request(s.url.toString(),{method:s.method,headers:s.headers,body:s.body})}i(g,"signRequest");export{c as AwsClient,o as AwsV4Signer,p as fromTemporaryCredentials,y as fromWebToken,m as fromZuploIdentity,l as getAwsCredentialProvider,a as setAwsCredentialProvider,g as signRequest};
26
26
  //# sourceMappingURL=index.js.map
@@ -526,59 +526,19 @@ export declare function aiGatewayHandlerV2(
526
526
  ): Promise<Response>;
527
527
 
528
528
  /**
529
- * Accepts only requests that this gateway made itself with
530
- * `context.invokeRoute`, and rejects every request that arrived over the
531
- * network with `403 Forbidden`.
532
- *
533
- * Use it in place of AI Gateway Authentication on an application that is only
534
- * ever called by other routes and policies on the same gateway, such as the
535
- * classifier application behind the Smart Router or Prompt Injection
536
- * Protection policies. Those calls never leave the gateway, so an API key on
537
- * them protects nothing. This policy asserts the one thing that matters: the
538
- * request originated inside the deployment.
539
- *
540
- * The check reads `context.parentContext`, which the runtime sets only on the
541
- * child context that `context.invokeRoute` creates. A client cannot supply it
542
- * through a header, the URL, or the body. The policy has no options, makes no
543
- * network calls, reads no body, and leaves `request.user` unset.
544
- *
545
- * @title Ensure Gateway Internal Invocation Only
546
- * @product ai-gateway
547
- * @requiresAI
529
+ * @deprecated Use InternalOnlyInboundPolicy instead. This name is from before
530
+ * the policy moved out of the AI Gateway.
548
531
  * @public
549
- *
550
- * @param request - The incoming ZuploRequest
551
- * @param context - The ZuploContext
552
- * @param _options - The policy options set in policies.json (this policy has none)
553
- * @param policyName - The name of the policy as set in policies.json
554
- * @returns The request when the gateway made it with `context.invokeRoute`, otherwise a 403 response
555
- *
556
- * @example
557
- * ```json
558
- * // policies.json - Declare the policy so an application chain can select it
559
- * {
560
- * "name": "ai-gateway-internal-only-inbound",
561
- * "policyType": "ai-gateway-internal-only",
562
- * "handler": {
563
- * "export": "AIGatewayInternalOnlyInboundPolicy",
564
- * "module": "$import(@zuplo/runtime)",
565
- * "options": {}
566
- * }
567
- * }
568
- * ```
569
532
  */
570
- export declare function AIGatewayInternalOnlyInboundPolicy(
571
- request: ZuploRequest,
572
- context: ZuploContext,
573
- _options: AIGatewayInternalOnlyInboundPolicyOptions,
574
- policyName: string
575
- ): Promise<ZuploRequest | Response>;
533
+ export declare const AIGatewayInternalOnlyInboundPolicy: typeof InternalOnlyInboundPolicy;
576
534
 
577
535
  /**
578
- * The options for this policy. It has none.
536
+ * @deprecated Use InternalOnlyInboundPolicyOptions instead. This name is from
537
+ * before the policy moved out of the AI Gateway.
579
538
  * @public
580
539
  */
581
- export declare interface AIGatewayInternalOnlyInboundPolicyOptions {}
540
+ export declare type AIGatewayInternalOnlyInboundPolicyOptions =
541
+ InternalOnlyInboundPolicyOptions;
582
542
 
583
543
  /* Excluded from this release type: AIGatewayMeterIncrements */
584
544
 
@@ -1813,7 +1773,7 @@ export declare interface ApiAuthKeyInboundPolicyOptions {
1813
1773
  declare type APIKey = string;
1814
1774
 
1815
1775
  /**
1816
- * Credential used to run the classifier. Without `appId` this is the API key for the OpenAI-compatible service at `baseUrl`, and it is required. With `appId` it is optional: omit it when the classifier app runs the Ensure Gateway Internal Invocation Only policy, which authorizes the in-process invocation itself, and set it only when that app authenticates callers with API keys, in which case it is sent as `Authorization: Bearer`.
1776
+ * Credential used to run the classifier. Without `appId` this is the API key for the OpenAI-compatible service at `baseUrl`, and it is required. With `appId` it is optional: omit it when the classifier app runs the Internal Only policy, which authorizes the in-process invocation itself, and set it only when that app authenticates callers with API keys, in which case it is sent as `Authorization: Bearer`.
1817
1777
  * @public
1818
1778
  */
1819
1779
  declare type APIKey_2 = string;
@@ -3750,7 +3710,8 @@ declare interface ChatCompletionResponse {
3750
3710
  }
3751
3711
 
3752
3712
  /**
3753
- * Classify by calling an OpenAI-compatible Chat Completions API directly, outside the gateway. The model must support structured outputs (`response_format` with a JSON schema).
3713
+ * @deprecated
3714
+ * Deprecated: use classifier.adapter with flat apiKey, model, and baseUrl fields. Classify by calling an OpenAI-compatible Chat Completions API directly, outside the gateway. The model must support structured outputs (`response_format` with a JSON schema).
3754
3715
  * @public
3755
3716
  */
3756
3717
  declare interface ChatCompletionsAPI {
@@ -3796,15 +3757,31 @@ declare type Claim = string;
3796
3757
  declare type ClaimCheck = EqualsRule | InRule | StartsWithRule;
3797
3758
 
3798
3759
  /**
3799
- * Where the user's prompt is classified. Required unless the deprecated `classifierAppID` and `classifierModel` are set. Set exactly one of `app`, `chatCompletions`, or `jev`; setting more than one is a configuration error.
3760
+ * Where the prompt is classified. For a direct API, set adapter, apiKey, model, and optional baseUrl. Alternatively set app. Legacy chatCompletions and jev sections remain supported; do not mix forms.
3800
3761
  * @public
3801
3762
  */
3802
3763
  declare interface Classifier {
3803
3764
  app?: ClassifierApp;
3804
3765
  chatCompletions?: ChatCompletionsAPI;
3805
3766
  jev?: JevTypeSafe;
3767
+ adapter?: ClassifierAdapter;
3768
+ apiKey?: ClassifierAPIKey;
3769
+ model?: ClassifierModel1;
3770
+ baseUrl?: ClassifierBaseURL;
3806
3771
  }
3807
3772
 
3773
+ /**
3774
+ * API contract for direct classification. chatCompletions requires a model supporting JSON-schema structured outputs. systemOne uses the existing Jev typed-question implementation; it does not accept classifierPrompt.
3775
+ * @public
3776
+ */
3777
+ declare type ClassifierAdapter = "chatCompletions" | "systemOne";
3778
+
3779
+ /**
3780
+ * API key for the direct classifier, sent as Authorization: Bearer.
3781
+ * @public
3782
+ */
3783
+ declare type ClassifierAPIKey = string;
3784
+
3808
3785
  /**
3809
3786
  * Classify with another AI Gateway app in this project. The call runs in-process and never leaves the gateway, so the classifier uses that app's providers, routing, and quotas.
3810
3787
  * @public
@@ -3816,7 +3793,7 @@ declare interface ClassifierApp {
3816
3793
  }
3817
3794
 
3818
3795
  /**
3819
- * API key sent as `Authorization: Bearer` when invoking the classifier app. Omit it when the classifier app runs the Ensure Gateway Internal Invocation Only policy: the classifier call never leaves the gateway, so that policy accepts it and rejects everything arriving over the network, and no credential is sent. Set it only when the classifier app authenticates callers with API keys.
3796
+ * API key sent as `Authorization: Bearer` when invoking the classifier app. Omit it when the classifier app runs the Internal Only policy: the classifier call never leaves the gateway, so that policy accepts it and rejects everything arriving over the network, and no credential is sent. Set it only when the classifier app authenticates callers with API keys.
3820
3797
  * @public
3821
3798
  */
3822
3799
  declare type ClassifierAppAPIKey = string;
@@ -3828,7 +3805,7 @@ declare type ClassifierAppAPIKey = string;
3828
3805
  declare type ClassifierAppAPIKeyDeprecated = string;
3829
3806
 
3830
3807
  /**
3831
- * Run the classifier on another AI Gateway app instead of calling an external API directly. The gateway invokes that app in-process — no outbound HTTP hop — so the classifier inherits its provider credentials, model routing, fallbacks and quotas, and provider keys stay on one app. Give that app the Ensure Gateway Internal Invocation Only policy and `apiKey` is not needed at all. When set, `model` must name a routed model as `provider/model` and `baseUrl` must not be set. The target app must not itself run this policy: it would be asked to classify its own classification request, which is rejected as a configuration error rather than silently skipped. Omit to call `baseUrl` directly.
3808
+ * Run the classifier on another AI Gateway app instead of calling an external API directly. The gateway invokes that app in-process — no outbound HTTP hop — so the classifier inherits its provider credentials, model routing, fallbacks and quotas, and provider keys stay on one app. Give that app the Internal Only policy and `apiKey` is not needed at all. When set, `model` must name a routed model as `provider/model` and `baseUrl` must not be set. The target app must not itself run this policy: it would be asked to classify its own classification request, which is rejected as a configuration error rather than silently skipped. Omit to call `baseUrl` directly.
3832
3809
  * @public
3833
3810
  */
3834
3811
  declare type ClassifierAppID = string;
@@ -3845,12 +3822,24 @@ declare type ClassifierAppID_2 = string;
3845
3822
  */
3846
3823
  declare type ClassifierAppIDDeprecated = string;
3847
3824
 
3825
+ /**
3826
+ * HTTP(S) API root. chatCompletions defaults to https://api.openai.com/v1 and appends /chat/completions. systemOne defaults to https://api.typesafe.ai and appends /v1/systemone.
3827
+ * @public
3828
+ */
3829
+ declare type ClassifierBaseURL = string;
3830
+
3848
3831
  /**
3849
3832
  * Tool-calling capable model used to classify prompts. Prefer a small, fast model; the classification runs before every inspected request reaches the upstream model. With `appId` set this must name a model the classifier app routes, written as `provider/model` (for example `openai/gpt-4o-mini`), and has no default.
3850
3833
  * @public
3851
3834
  */
3852
3835
  declare type ClassifierModel = string;
3853
3836
 
3837
+ /**
3838
+ * Model id sent to the direct API. Required for chatCompletions; defaults to jev-latest for systemOne.
3839
+ * @public
3840
+ */
3841
+ declare type ClassifierModel1 = string;
3842
+
3854
3843
  /**
3855
3844
  * The model (`providerName/model`) the classifier app uses to evaluate the user's request. E.g. `openai/gpt-4o-mini`.
3856
3845
  * @public
@@ -3870,7 +3859,7 @@ declare type ClassifierModelDeprecated = string;
3870
3859
  declare type ClassifierPrompt = string | [string, ...string[]];
3871
3860
 
3872
3861
  /**
3873
- * Prompt used to analyze and classify the user message with `classifier.app` or `classifier.chatCompletions`. Omit to use the built-in classifier prompt. Jev takes no prompt, so setting this with `classifier.jev` is a configuration error.
3862
+ * Prompt for classifier.app or the chatCompletions adapter (including its legacy section). Omit to use the built-in prompt. The systemOne adapter and legacy jev section take no prompt; combining them with classifierPrompt is a configuration error.
3874
3863
  * @public
3875
3864
  */
3876
3865
  declare type ClassifierPrompt_2 = string | [string, ...string[]];
@@ -4135,6 +4124,50 @@ declare interface CompatibilityFlags {
4135
4124
  * @compatibilityDate 2026-03-01
4136
4125
  */
4137
4126
  return501ForUnsupportedHttpMethods: boolean;
4127
+ /**
4128
+ * Whether the MCP server handler leaves the non-standard
4129
+ * `capabilities.tools.supported` and `capabilities.tools.available` fields
4130
+ * out of its `initialize` response.
4131
+ *
4132
+ * Before this flag: `initialize` returns `supported: true` and lists every
4133
+ * registered tool name in `available`, to every caller.
4134
+ *
4135
+ * After this flag: `initialize` returns `capabilities.tools: {}`. Clients
4136
+ * discover tools with `tools/list`, as the MCP spec defines.
4137
+ */
4138
+ removeMcpToolsCapabilityExtension: boolean;
4139
+ /**
4140
+ * Whether OpenAPI schema combinators (`allOf`, `oneOf`, `anyOf`, `not`) are
4141
+ * applied with JSON Schema semantics when an operation's schemas are turned
4142
+ * into runtime validators. Today that is the MCP server handler: a tool's
4143
+ * advertised `inputSchema`/`outputSchema` and its argument validation.
4144
+ * `request-validation-inbound` already uses Ajv and is unaffected.
4145
+ *
4146
+ * Before this flag:
4147
+ * - A top-level combinator is used on its own, and every keyword beside it
4148
+ * (`type`, `properties`, `required`, `additionalProperties`, `nullable`,
4149
+ * `description`, ...) is ignored. A body of
4150
+ * `{ type: object, properties, required, oneOf: [...] }` can be advertised
4151
+ * as `{ anyOf: [{}, {}] }` and accept any value.
4152
+ * - `oneOf` behaves like `anyOf`: a value matching several branches is
4153
+ * accepted, and `oneOf` is advertised as `anyOf`.
4154
+ *
4155
+ * After this flag:
4156
+ * - The schema's own keywords and every combinator beside them all apply,
4157
+ * intersected.
4158
+ * - `oneOf` accepts a value only when exactly one branch matches, and is
4159
+ * advertised as `oneOf`.
4160
+ * - Within a combinator schema and its branches: `required`,
4161
+ * `additionalProperties`, `minProperties` or `maxProperties` without a
4162
+ * `type` mark an object schema, an object schema rejects non-objects, a
4163
+ * `required` name that `properties` omits is enforced, a numeric or
4164
+ * boolean `enum` is enforced, and `unevaluatedProperties: false` is
4165
+ * enforced. A schema with no combinator is unchanged.
4166
+ *
4167
+ * The advertised schema changes for every affected tool, and calls the
4168
+ * gateway's request validation would reject are rejected with -32602.
4169
+ */
4170
+ enforceOpenApiCombinatorSemantics: boolean;
4138
4171
  }
4139
4172
 
4140
4173
  declare interface CompletionsFallbacks {
@@ -7819,6 +7852,82 @@ declare type Intents = [
7819
7852
  }[],
7820
7853
  ];
7821
7854
 
7855
+ /**
7856
+ * Accepts only requests that this gateway made itself with
7857
+ * `context.invokeRoute`, and rejects every request that arrived over the
7858
+ * network.
7859
+ *
7860
+ * Use it on a route that only other routes, handlers, and policies on the same
7861
+ * gateway call: a REST endpoint that an MCP server exposes as a tool, or the
7862
+ * classifier application behind the Smart Router or Prompt Injection
7863
+ * Protection policies. Those calls never leave the gateway, so an API key on
7864
+ * them protects nothing. This policy asserts the one thing that matters: the
7865
+ * request originated inside the deployment.
7866
+ *
7867
+ * The check reads `context.parentContext`, which the runtime sets only on the
7868
+ * child context that `context.invokeRoute` creates. A client cannot supply it
7869
+ * through a header, the URL, or the body. The policy makes no network calls,
7870
+ * reads no body, and leaves `request.user` unset.
7871
+ *
7872
+ * A rejected request gets a `403 Forbidden` problem response with no `detail`
7873
+ * by default, so the caller learns nothing about how the gateway works; the
7874
+ * reason goes to the request log. Set `status` to answer with another client
7875
+ * error, such as `404` to hide the route or `401`, `statusText` to change the
7876
+ * status text, and `detail` to add a message.
7877
+ *
7878
+ * @title Internal Only
7879
+ * @product api-gateway
7880
+ * @product ai-gateway
7881
+ * @public
7882
+ *
7883
+ * @param request - The incoming ZuploRequest
7884
+ * @param context - The ZuploContext
7885
+ * @param options - The policy options set in policies.json
7886
+ * @param policyName - The name of the policy as set in policies.json
7887
+ * @returns The request when the gateway made it with `context.invokeRoute`, otherwise the rejection response
7888
+ *
7889
+ * @example
7890
+ * ```json
7891
+ * // policies.json - Hide a REST route that an MCP server calls as a tool
7892
+ * {
7893
+ * "name": "internal-only-inbound",
7894
+ * "policyType": "internal-only-inbound",
7895
+ * "handler": {
7896
+ * "export": "InternalOnlyInboundPolicy",
7897
+ * "module": "$import(@zuplo/runtime)",
7898
+ * "options": {
7899
+ * "status": 404
7900
+ * }
7901
+ * }
7902
+ * }
7903
+ * ```
7904
+ */
7905
+ export declare function InternalOnlyInboundPolicy(
7906
+ request: ZuploRequest,
7907
+ context: ZuploContext,
7908
+ options: InternalOnlyInboundPolicyOptions,
7909
+ policyName: string
7910
+ ): Promise<ZuploRequest | Response>;
7911
+
7912
+ /**
7913
+ * The options for this policy.
7914
+ * @public
7915
+ */
7916
+ export declare interface InternalOnlyInboundPolicyOptions {
7917
+ /**
7918
+ * The HTTP status code returned to a request that did not come from inside the gateway. Any client error status from 400 to 499 is allowed. Use `404` to answer as if the route did not exist, or `401` to answer as an authentication policy does.
7919
+ */
7920
+ status?: number;
7921
+ /**
7922
+ * The status text returned with `status`, such as `Not Found`. When it is omitted, the response uses the standard text for the status. Clients don't always receive it: HTTP/2 and HTTP/3 have no status text, and Managed Dedicated and self-hosted gateways always send the standard text.
7923
+ */
7924
+ statusText?: string;
7925
+ /**
7926
+ * The `detail` of the problem response returned to a rejected request. Every caller outside the gateway receives it, so don't describe how the route is called. When it is omitted, the response has no `detail`, and a `404` matches the response for a route that does not exist.
7927
+ */
7928
+ detail?: string;
7929
+ }
7930
+
7822
7931
  /**
7823
7932
  * Restricts which client IP addresses can call a route using an allow list, a
7824
7933
  * deny list, or both. Entries are individual IP addresses or CIDR ranges, in
@@ -8147,7 +8256,8 @@ declare type JevBaseURL = string;
8147
8256
  declare type JevModel = string;
8148
8257
 
8149
8258
  /**
8150
- * Classify with Jev, TypeSafe's classification model, by calling a System One API directly: TypeSafe's by default, or another host such as OpenRouter through `baseUrl`. Jev answers typed questions instead of generating text, so it takes no `classifierPrompt`.
8259
+ * @deprecated
8260
+ * Deprecated: use classifier.adapter with flat apiKey, model, and baseUrl fields. Classify with Jev, TypeSafe's classification model, by calling a System One API directly: TypeSafe's by default, or another host such as OpenRouter through `baseUrl`. Jev answers typed questions instead of generating text, so it takes no `classifierPrompt`.
8151
8261
  * @public
8152
8262
  */
8153
8263
  declare interface JevTypeSafe {
@@ -142,6 +142,50 @@ declare interface CompatibilityFlags {
142
142
  * @compatibilityDate 2026-03-01
143
143
  */
144
144
  return501ForUnsupportedHttpMethods: boolean;
145
+ /**
146
+ * Whether the MCP server handler leaves the non-standard
147
+ * `capabilities.tools.supported` and `capabilities.tools.available` fields
148
+ * out of its `initialize` response.
149
+ *
150
+ * Before this flag: `initialize` returns `supported: true` and lists every
151
+ * registered tool name in `available`, to every caller.
152
+ *
153
+ * After this flag: `initialize` returns `capabilities.tools: {}`. Clients
154
+ * discover tools with `tools/list`, as the MCP spec defines.
155
+ */
156
+ removeMcpToolsCapabilityExtension: boolean;
157
+ /**
158
+ * Whether OpenAPI schema combinators (`allOf`, `oneOf`, `anyOf`, `not`) are
159
+ * applied with JSON Schema semantics when an operation's schemas are turned
160
+ * into runtime validators. Today that is the MCP server handler: a tool's
161
+ * advertised `inputSchema`/`outputSchema` and its argument validation.
162
+ * `request-validation-inbound` already uses Ajv and is unaffected.
163
+ *
164
+ * Before this flag:
165
+ * - A top-level combinator is used on its own, and every keyword beside it
166
+ * (`type`, `properties`, `required`, `additionalProperties`, `nullable`,
167
+ * `description`, ...) is ignored. A body of
168
+ * `{ type: object, properties, required, oneOf: [...] }` can be advertised
169
+ * as `{ anyOf: [{}, {}] }` and accept any value.
170
+ * - `oneOf` behaves like `anyOf`: a value matching several branches is
171
+ * accepted, and `oneOf` is advertised as `anyOf`.
172
+ *
173
+ * After this flag:
174
+ * - The schema's own keywords and every combinator beside them all apply,
175
+ * intersected.
176
+ * - `oneOf` accepts a value only when exactly one branch matches, and is
177
+ * advertised as `oneOf`.
178
+ * - Within a combinator schema and its branches: `required`,
179
+ * `additionalProperties`, `minProperties` or `maxProperties` without a
180
+ * `type` mark an object schema, an object schema rejects non-objects, a
181
+ * `required` name that `properties` omits is enforced, a numeric or
182
+ * boolean `enum` is enforced, and `unevaluatedProperties: false` is
183
+ * enforced. A schema with no combinator is unchanged.
184
+ *
185
+ * The advertised schema changes for every affected tool, and calls the
186
+ * gateway's request validation would reject are rejected with -32602.
187
+ */
188
+ enforceOpenApiCombinatorSemantics: boolean;
145
189
  }
146
190
 
147
191
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zuplo/runtime",
3
3
  "type": "module",
4
- "version": "7.9.9",
4
+ "version": "7.9.12",
5
5
  "repository": "https://github.com/zuplo/zuplo",
6
6
  "author": "Zuplo, Inc.",
7
7
  "exports": {
@@ -1,37 +0,0 @@
1
-
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Zuplo, Inc. All rights reserved.
4
- *
5
- * This software and associated documentation files (the "Software") is intended to be used
6
- * only by Zuplo customers solely to develop and test applications that will be deployed
7
- * to Zuplo hosted services. You and others in your organization may use these files on your
8
- * Development Devices solely for the above stated purpose.
9
- *
10
- * Outside of uses stated above, no license is granted for any other purpose including
11
- * without limitation the rights to use, copy, modify, merge, publish, distribute,
12
- * sublicense, host, and/or sell copies of the Software.
13
- *
14
- * The software may include third party components with separate legal notices or governed by
15
- * other agreements, as described in licenses either embedded in or accompanying the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
20
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
- * DEALINGS IN THE SOFTWARE.
23
- *--------------------------------------------------------------------------------------------*/
24
-
25
- import{a as r}from"./chunk-TYV53J3B.js";var U=class extends Error{static{r(this,"SystemError")}constructor(t,n){super(t,n),this.name="InternalError"}},N=class extends TypeError{static{r(this,"NetworkError")}cause;constructor(t){super("The upstream request failed due to a network error.",{cause:t}),this.name="TypeError",this.cause=t}},T=class extends Error{static{r(this,"RuntimeError")}extensionMembers;constructor(t,n){typeof t=="string"?super(t,n):(super(t.message,n),this.extensionMembers=t.extensionMembers),this.name="RuntimeError"}},K=class extends T{static{r(this,"ConfigurationError")}constructor(t,n){super(t,n),this.name="ConfigurationError"}};var Rt="zuplo-request-id",he="zp-rid",Re="zp-body-removed",Oe="cf-ray",Ot="x-forwarded-scheme",yt="x-forwarded-proto",Tt="x-scheme",ye="cf-ipcity",Te="cf-ipcontinent",be="cf-ipcountry",Ae="cf-iplongitude",xe="cf-iplatitude",bt="cf-region",At="cf-region-code",xt="cf-metro-code",Lt="cf-postal-code",Pt="cf-timezone",It="zp-ipcity",St="zp-ipcontinent",Ct="zp-ipcountry",wt="zp-iplongitude",Ut="zp-iplatitude",X="x-real-ip",M="true-client-ip";var Le="zp-client-cert",Pe="zp-mtls-status",Ie="zp-mtls-failure-reason",Se="zp-mtls-cert-fingerprint-sha256",Ce="zp-mtls-cert-not-before",we="zp-mtls-cert-not-after",Ue="zp-mtls-cert-issuer-dn",Ne="zp-mtls-cert-subject-dn",De="zp-asn",He="zp-asorg",Me="zp-colo",ve="zp-postalcode",ze="zp-metrocode",Ze="zp-region",Fe="zp-regioncode",ke="zp-timezone",Nt="zp-http-protocol",v="zp-local-service",$e="zp-gateway-api-key",Ge="x-akamai-edgescape",Dt=[Le,Pe,Ie,Se,Ce,we,Ue,Ne,Ge,v],Ht=[ye,Te,be,Ae,xe,De,He,Me,ve,ze,Ze,Fe,ke],Mt=["zp-","cf-"],vt=[he,Oe,Re,$e];var zt="system-logger";var Q=class e{static{r(this,"ContextData")}static#e;#t;constructor(t){this.#t=t}get(t){return e.get(t,this.#t)}static get(t,n){return e.#e||(e.#e=new WeakMap),e.#e.get(t)?.get(n)}set(t,n){e.set(t,this.#t,n)}static set(t,n,i){e.#e||(e.#e=new WeakMap);let o=e.#e.get(t);o||(o=new Map),o.set(n,i),e.#e.set(t,o)}};var Be=!1;function L(e,t){return{open:`\x1B[${e.join(";")}m`,close:`\x1B[${t}m`,regexp:new RegExp(`\\x1b\\[${t}m`,"g")}}r(L,"code");function P(e,t){return Be?`${t.open}${e.replace(t.regexp,t.open)}${t.close}`:e}r(P,"run");function Ve(e){return P(e,L([31],39))}r(Ve,"red");function Ye(e){return P(e,L([32],39))}r(Ye,"green");function je(e){return P(e,L([33],39))}r(je,"yellow");function qe(e){return P(e,L([34],39))}r(qe,"blue");function We(e){return P(e,L([35],39))}r(We,"magenta");function Je(e){return P(e,L([36],39))}r(Je,"cyan");var $t=new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|"),"g");var ee=[Ve,Ye,je,qe,We,Je];function Ke(e){let t=0,n=e.length,i=0;if(n>0)for(;i<n;)t=(t<<5)-t+e.charCodeAt(i++)|0;return t}r(Ke,"hashCode");function te(e){let t=Math.abs(Ke(e));return ee[t%ee.length]}r(te,"generateColor");function ne(e,t,...n){let i=0,o=n.length,u=String(t).replace(/%[sdjoO%]/g,s=>{if(s==="%%")return"%";if(i>=o)return s;switch(s){case"%s":return String(n[i++]);case"%d":return Number(n[i++]).toString();case"%o":return e(n[i++]).split(`
26
- `).map(l=>l.trim()).join(" ");case"%O":return e(n[i++]);case"%j":try{return JSON.stringify(n[i++])}catch{return"[Circular]"}default:return s}});for(let s of n.splice(i))s===null||!(typeof s=="object"&&s!==null)?u+=" "+s:u+=" "+e(s);return u}r(ne,"format");function A(e,t,n,i){let o={seen:[],stylize:Xe,showHidden:t??!1,depth:n??2,colors:i??!1,customInspect:!0};return o.colors&&(o.stylize=et),D(o,e,o.depth)}r(A,"inspect");A.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};A.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};function Xe(e,t){return e}r(Xe,"stylizeNoColor");function Qe(e){return typeof e=="boolean"}r(Qe,"isBoolean");function oe(e){return e===void 0}r(oe,"isUndefined");function et(e,t){let n=A.styles[t];return n?"\x1B["+A.colors[n][0]+"m"+e+"\x1B["+A.colors[n][1]+"m":e}r(et,"stylizeWithColor");function z(e){return typeof e=="function"}r(z,"isFunction");function ie(e){return typeof e=="string"}r(ie,"isString");function tt(e){return typeof e=="number"}r(tt,"isNumber");function se(e){return e===null}r(se,"isNull");function ce(e,t){return Object.hasOwn(e,t)}r(ce,"hasOwn");function Z(e){return G(e)&&B(e)==="[object RegExp]"}r(Z,"isRegExp");function G(e){return typeof e=="object"&&e!==null}r(G,"isObject");function F(e){return G(e)&&(B(e)==="[object Error]"||e instanceof Error)}r(F,"isError");function re(e){return G(e)&&B(e)==="[object Date]"}r(re,"isDate");function B(e){return Object.prototype.toString.call(e)}r(B,"objectToString");function nt(e){let t={};return e.forEach(function(n,i){t[n]=!0}),t}r(nt,"arrayToHash");function rt(e,t,n,i,o){let u=[];for(let s=0,l=t.length;s<l;++s)ce(t,String(s))?u.push($(e,t,n,i,String(s),!0)):u.push("");return o.forEach(function(s){s.match(/^\d+$/)||u.push($(e,t,n,i,s,!0))}),u}r(rt,"formatArray");function k(e){return"["+Error.prototype.toString.call(e)+"]"}r(k,"formatError");function D(e,t,n){if(e.customInspect&&t&&z(t.inspect)&&t.inspect!==A&&!(t.constructor&&t.constructor.prototype===t)){let a=t.inspect(n,e);return ie(a)||(a=D(e,a,n)),a}let i=ot(e,t);if(i)return i;let o=Object.keys(t),u=nt(o);try{e.showHidden&&Object.getOwnPropertyNames&&(o=Object.getOwnPropertyNames(t))}catch{}if(F(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return k(t);if(o.length===0){if(z(t)){let a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(Z(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(re(t))return e.stylize(Date.prototype.toString.call(t),"date");if(F(t))return k(t)}let s="",l=!1,p=["{","}"];if(Array.isArray(t)&&(l=!0,p=["[","]"]),z(t)&&(s=" [Function"+(t.name?": "+t.name:"")+"]"),Z(t)&&(s=" "+RegExp.prototype.toString.call(t)),re(t)&&(s=" "+Date.prototype.toUTCString.call(t)),F(t)&&(s=" "+k(t)),o.length===0&&(!l||t.length==0))return p[0]+s+p[1];if(n<0)return Z(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);let c;return l?c=rt(e,t,n,u,o):c=o.map(function(a){return $(e,t,n,u,a,l)}),e.seen.pop(),it(c,s,p)}r(D,"formatValue");function $(e,t,n,i,o,u){let s,l,p;p={value:void 0};try{p.value=t[o]}catch{}try{Object.getOwnPropertyDescriptor&&(p=Object.getOwnPropertyDescriptor(t,o)||p)}catch{}if(p.get?p.set?l=e.stylize("[Getter/Setter]","special"):l=e.stylize("[Getter]","special"):p.set&&(l=e.stylize("[Setter]","special")),ce(i,o)||(s="["+o+"]"),l||(e.seen.indexOf(p.value)<0?(se(n)?l=D(e,p.value,null):l=D(e,p.value,n-1),l.indexOf(`
27
- `)>-1&&(u?l=l.split(`
28
- `).map(function(c){return" "+c}).join(`
29
- `).substr(2):l=`
30
- `+l.split(`
31
- `).map(function(c){return" "+c}).join(`
32
- `))):l=e.stylize("[Circular]","special")),oe(s)){if(u&&o.match(/^\d+$/))return l;s=JSON.stringify(""+o),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+l}r($,"formatProperty");function ot(e,t){if(oe(t))return e.stylize("undefined","undefined");if(ie(t)){let n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(tt(t))return e.stylize(""+t,"number");if(Qe(t))return e.stylize(""+t,"boolean");if(se(t))return e.stylize("null","null")}r(ot,"formatPrimitive");function it(e,t,n){let i=0;return e.reduce(function(u,s){return i++,s.indexOf(`
33
- `)>=0&&i++,u+s.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60?n[0]+(t===""?"":t+`
34
- `)+" "+e.join(`,
35
- `)+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}r(it,"reduceToSingleString");var ue=r((e,...t)=>ne(A,e,t),"format");var V=class{static{r(this,"Debugger")}manager;ns;color;last;enabled;constructor(t,n){this.manager=t,this.ns=n,this.color=te(n),this.last=0,this.enabled=t.enabled.some(i=>i.test(n))}log(...t){if(!this.enabled)return;let n,i=t[0];typeof i=="function"?n=i():n=String(i);let o=Date.now()-(this.last||Date.now());n=ue(n,...t);let u=`${this.color(this.ns)} ${n} ${this.color(`+${o}ms`)}`;console.log(u),this.last=Date.now()}},Y=class{static{r(this,"DebugManager")}debuggers;enabled;constructor(t){this.debuggers=new Map,this.enabled=t??[]}};function st(e){return!e||e.length===0?[]:(e=e.replace(/\s/g,"").replace(/\*/g,".+"),e.split(",").map(t=>new RegExp(`^${t}$`)))}r(st,"extract");var H;function le(e){let t=globalThis.DEBUG;H||(H=new Y(st(t)));let n=new V(H,e);return H.debuggers.set(e,n),Object.assign(n.log.bind(n),{self:n})}r(le,"debug");function ct(e){if(e.length>=255)throw new TypeError("Alphabet too long");let t=new Uint8Array(256);for(let c=0;c<t.length;c++)t[c]=255;for(let c=0;c<e.length;c++){let a=e.charAt(c),m=a.charCodeAt(0);if(t[m]!==255)throw new TypeError(a+" is ambiguous");t[m]=c}let n=e.length,i=e.charAt(0),o=Math.log(n)/Math.log(256),u=Math.log(256)/Math.log(n);function s(c){if(c instanceof Uint8Array||(ArrayBuffer.isView(c)?c=new Uint8Array(c.buffer,c.byteOffset,c.byteLength):Array.isArray(c)&&(c=Uint8Array.from(c))),!(c instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(c.length===0)return"";let a=0,m=0,g=0,d=c.length;for(;g!==d&&c[g]===0;)g++,a++;let R=(d-g)*u+1>>>0,_=new Uint8Array(R);for(;g!==d;){let O=c[g],h=0;for(let b=R-1;(O!==0||h<m)&&b!==-1;b--,h++)O+=256*_[b]>>>0,_[b]=O%n>>>0,O=O/n>>>0;if(O!==0)throw new Error("Non-zero carry");m=h,g++}let f=R-m;for(;f!==R&&_[f]===0;)f++;let y=i.repeat(a);for(;f<R;++f)y+=e.charAt(_[f]);return y}r(s,"encode");function l(c){if(typeof c!="string")throw new TypeError("Expected String");if(c.length===0)return new Uint8Array;let a=0,m=0,g=0;for(;c[a]===i;)m++,a++;let d=(c.length-a)*o+1>>>0,R=new Uint8Array(d);for(;a<c.length;){let O=c.charCodeAt(a);if(O>255)return;let h=t[O];if(h===255)return;let b=0;for(let w=d-1;(h!==0||b<g)&&w!==-1;w--,b++)h+=n*R[w]>>>0,R[w]=h%256>>>0,h=h/256>>>0;if(h!==0)throw new Error("Non-zero carry");g=b,a++}let _=d-g;for(;_!==d&&R[_]===0;)_++;let f=new Uint8Array(m+(d-_)),y=m;for(;_!==d;)f[y++]=R[_++];return f}r(l,"decodeUnsafe");function p(c){let a=l(c);if(a)return a;throw new Error("Non-base"+n+" character")}return r(p,"decode"),{encode:s,decodeUnsafe:l,decode:p}}r(ct,"base");var ae=ct;var ut="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",pe=ae(ut);var lt=/: client error \((?:Connect|SendRequest)\):/;function at(e){return e instanceof TypeError&&e.message.startsWith("error sending request ")&&lt.test(e.message)}r(at,"isDenoClientError");function I(e,t){return t?e.catch(n=>{throw at(n)?new N(n):n}):e}r(I,"wrapDenoNetworkErrors");var x=le("zuplo:runtime:external-service");function pt(){let e,{__ZUPLO_EXTERNAL_SERVICE_TOKEN:t}=E.instance.runtime;if(t&&t!=="undefined")try{let n=atob(t);e=JSON.parse(n)}catch{}return e}r(pt,"getServiceAuth");async function fe(e,t){let n=".proxy",i=".tunnel";if(typeof e=="string"){let o=new URL(e),u=o.hostname;if(u.endsWith(n)){let f=u.slice(0,-n.length),y=new URL(`http://${f}${o.pathname}${o.search}`);x(`Routing to proxy: ${y.toString()}`);let O=t??{};return S(y.toString(),O)}let s=u.endsWith(i),l=u.indexOf(".")===-1;if(!(s||l))throw new T(`Invalid service hostname suffix: ${u}. Use .proxy for proxy routing, .tunnel for explicit tunnel routing, or no suffix for default tunnel routing.`);let c=s?u.slice(0,-i.length):u,a=pt();if(!a)throw x("There is no external service auth configured for this zup."),new T("There are no external services configured for this zup.");x(`Using external service auth. ClientId: ${a.clientId})`);let m=t??{},g=new Headers(m.headers||{});g.set("CF-Access-Client-Id",a.clientId),g.set("CF-Access-Client-Secret",a.clientSecret),m.headers=g;let d;if(a.customServiceMapping?.[c])d=`https://${a.customServiceMapping[c]}`;else if(E.instance.useLegacyServiceRouting)d=`https://${c}.zuptunnel.com`;else{x("Using sha256 service routing");let f=E.instance.build;if(f.ACCOUNT_NAME&&f.PROJECT_NAME&&f.ENVIRONMENT_TYPE){let y=await ft(c,f.ACCOUNT_NAME,f.PROJECT_NAME,f.ENVIRONMENT_TYPE),O=ge(f.ENVIRONMENT_TYPE),h=await j(`${f.ACCOUNT_NAME}-${f.PROJECT_NAME}-${O}`);h==="40d7ad502f5d743997999594c177184a00161a77865423511f3a1ea21eb5a5e"||h==="d05bffe8fa91a300187d2cf43e8aa4a56bd809c442ae10d1ee49af7d29a5a11"?d=`https://${y}.zuptunnel.com`:d=`https://${y}.t.zuplo.app`}else throw x("Cannot use sha256 service routing, missing build variables"),new T("Failed to generate fully qualified tunnel url.")}let R=new URL(`${d}${o.pathname}${o.search}`);x(`Calling external service: ${R.toString()}`);let _=await S(R.toString(),m);if(_.status===403&&_.headers.get("cf-access-domain")!==null)throw C.console.error("403 Forbidden when calling external service.",{clientId:a.clientId,tunnelHost:d}),new T("Could not connect to secure tunnel.");return _}else throw x("Cannot call external service with Request object"),new T("Currently, we only support fetch(<some_string>, ...).")}r(fe,"externalServiceHandler");async function de(e,t){if(typeof e=="string"){let n=new URL(e),i=n.hostname,o=t??{},u=`http://${i}.zuplo.svc.cluster.local:9000`,s=new URL(`${u}${n.pathname}${n.search}`),l=new Headers(o.headers||{});return l.set(v,i),o.headers=l,await S(s.toString(),o)}else throw new T("Currently, we only support fetch(<some_string>, ...).")}r(de,"clusterServiceHandler");async function ft(e,t,n,i){let o=e.toLowerCase(),u=t.toLowerCase(),s=n.toLowerCase(),l=ge(i);x(`Hashing service name: ${u}-${o}.${u}-${s}-${l}`);let p=await j(`${u}-${o}`),c=await j(`${u}-${s}-${l}`);return`${p}.${c}`}r(ft,"hashServiceName");async function j(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(u=>u.toString(16).padStart(2,"0")).join("").slice(0,-1)}r(j,"hashSegment");function ge(e){let t=e.toLowerCase();switch(t){case"production":case"preview":return t;default:return"working-copy"}}r(ge,"sanitizeEnvironmentType");var q=new Map;q.set("service:",fe);q.set("local:",de);var S=globalThis.fetch;function W(e,t){let{transformedInit:n,mtlsCertificate:i}=dt(t);if(typeof e=="string"){let o=new URL(e),u=q.get(o.protocol);return u?I(u(e,n),E.instance.isDeno):_e(e,n,i)}else return _e(e,n,i)}r(W,"internalFetch");globalThis.fetch=W;function _e(e,t,n){if(!n)return I(S(e,t),E.instance.isDeno);if(E.instance.isCloudflare){let o=E.instance.runtime[n];if(!o)throw new Error(`mTLS certificate binding '${n}' not found. Ensure the certificate is uploaded and properly configured.`);if(typeof o!="object"||typeof o.fetch!="function")throw new Error(`mTLS certificate binding '${n}' is not a valid mTLS certificate binding. Make sure it's configured as an mTLS certificate, not an environment variable.`);return I(o.fetch(e,t),E.instance.isDeno)}else if(E.instance.isDeno){let i=globalThis.managedDedicatedMtlsBindings?.[n];if(!i)throw new Error(`mTLS certificate binding '${n}' not found. Ensure the certificate is uploaded and properly configured.`);if(typeof i.fetch!="function")throw new Error(`mTLS certificate binding '${n}' is not a valid mTLS certificate binding.`);return I(i.fetch(e,t),!0)}else throw new Error("mTLS client certificates are not supported in this runtime environment")}r(_e,"performFetch");var dt=r(e=>{if(!e||e instanceof Request)return{transformedInit:e,mtlsCertificate:void 0};let t=e;if(!t.zuplo)return{transformedInit:e,mtlsCertificate:void 0};let n=t.zuplo.mtlsCertificate,i=e;return i.cf={cacheEverything:t.zuplo?.cacheEverything,cacheTtl:t.zuplo?.cacheTtlSeconds},delete e.zuplo,{transformedInit:e,mtlsCertificate:n}},"transformInit");var gt={console:{log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console),assert:console.assert.bind(console),clear:console.clear.bind(console),count:console.count.bind(console),countReset:console.countReset.bind(console),dir:console.dir.bind(console),dirxml:console.dirxml.bind(console),group:console.group.bind(console),groupCollapsed:console.groupCollapsed.bind(console),groupEnd:console.groupEnd.bind(console),table:console.table.bind(console),time:console.time.bind(console),timeEnd:console.timeEnd.bind(console),timeLog:console.timeLog.bind(console),timeStamp:console.timeStamp.bind(console),trace:console.trace.bind(console),profile:console.profile.bind(console),profileEnd:console.profileEnd.bind(console)},fetch:W},C=gt;var J="2025-02-06",Ee=Object.freeze({none:{runOutboundPoliciesOnHandlerOnAllStatuses:!1,doNotRunHooksOnSystemRoutes:!1,removeAllVendorHeadersExceptListed:!1,allowCustomPorts:!1,removeLegacyLogInitialization:!1,useForwardRedirectsPropOnUrlForwardHandler:!1,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2023-03-14":{runOutboundPoliciesOnHandlerOnAllStatuses:!1,doNotRunHooksOnSystemRoutes:!1,removeAllVendorHeadersExceptListed:!1,allowCustomPorts:!1,removeLegacyLogInitialization:!1,useForwardRedirectsPropOnUrlForwardHandler:!1,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2024-01-15":{runOutboundPoliciesOnHandlerOnAllStatuses:!0,doNotRunHooksOnSystemRoutes:!0,removeAllVendorHeadersExceptListed:!0,allowCustomPorts:!1,removeLegacyLogInitialization:!1,useForwardRedirectsPropOnUrlForwardHandler:!1,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2024-03-14":{runOutboundPoliciesOnHandlerOnAllStatuses:!0,doNotRunHooksOnSystemRoutes:!0,removeAllVendorHeadersExceptListed:!0,allowCustomPorts:!1,removeLegacyLogInitialization:!1,useForwardRedirectsPropOnUrlForwardHandler:!1,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2024-09-02":{runOutboundPoliciesOnHandlerOnAllStatuses:!0,doNotRunHooksOnSystemRoutes:!0,removeAllVendorHeadersExceptListed:!0,allowCustomPorts:!0,removeLegacyLogInitialization:!1,useForwardRedirectsPropOnUrlForwardHandler:!1,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2025-02-06":{runOutboundPoliciesOnHandlerOnAllStatuses:!0,doNotRunHooksOnSystemRoutes:!0,removeAllVendorHeadersExceptListed:!0,allowCustomPorts:!0,removeLegacyLogInitialization:!0,useForwardRedirectsPropOnUrlForwardHandler:!0,chainResponseSendingHooks:!1,return501ForUnsupportedHttpMethods:!1},"2026-03-01":{runOutboundPoliciesOnHandlerOnAllStatuses:!0,doNotRunHooksOnSystemRoutes:!0,removeAllVendorHeadersExceptListed:!0,allowCustomPorts:!0,removeLegacyLogInitialization:!0,useForwardRedirectsPropOnUrlForwardHandler:!0,chainResponseSendingHooks:!0,return501ForUnsupportedHttpMethods:!0}});function me(e={}){let{runtime:t="cloudflare"}=e;return new E({build:{ACCOUNT_NAME:"mock-account-name",PROJECT_NAME:"mock-project-name",API_VERSION:"0.0.0",BUILD_ID:crypto.randomUUID(),TIMESTAMP:new Date().toISOString(),BUILD_ENV:"test",ZUPLO_VERSION:"0.0.0",COMPATIBILITY_DATE:J,ENVIRONMENT_TYPE:"mock-environment-type",GIT_SHA:void 0,IS_LOCAL_DEVELOPMENT:!1,COMPATIBILITY_FLAGS:Ee[J]},runtime:{RUNTIME_ENV:"test",RUNTIME_STAGE:"test",__ZUPLO_DEPLOYMENT_NAME:"mock-deployment-name",__ZUPLO_LOG_LEVEL:"debug",__ZUPLO_LOG_FORMAT:"pretty",__ZUPLO_MANAGEMENT_API_URL:"",__ZUPLO_RUNTIME_TYPE:t,__ZUPLO_AUTH_API_JWT:"",ZUPLO_SERVICE_BUCKET_ID:"bckt_mock"}})}r(me,"getMockEnvironment");var _t=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;function Et(e,t){let n=e.__ZUPLO_TRUSTED_IP_HEADER?.trim();if(!n)return t?M:X;if(!_t.test(n))throw new U(`__ZUPLO_TRUSTED_IP_HEADER is set to '${n}', which is not a valid HTTP header name. Header names may only contain the RFC 9110 token characters (letters, digits, and !#$%&'*+-.^_\`|~) - spaces, colons and tabs are not allowed. Set it to a valid header name such as '${M}' or 'cf-connecting-ip'.`);return n.toLowerCase()}r(Et,"resolveTrustedIpHeader");var E=class e{static{r(this,"Environment")}config;#e;static#t;static#n=!1;static initialize(t){e.#t||(e.#t=new e(t),e.#n=!0)}static get instance(){return e.#n||(C.console.debug("Environment has not been initialized. This is okay when running tests, a mock environment will be used."),e.#t??=me(),e.#n=!0),e.#t}constructor({build:t,runtime:n}){let i;try{if(n.ZUPLO_SYSTEM_CONFIGURATIONS){let o=new TextDecoder().decode(pe.decode(n.ZUPLO_SYSTEM_CONFIGURATIONS)),u=JSON.parse(o);for(let s of Object.keys(u))n[s]||(n[s]=u[s])}if(n.__ZUPLO_CONFIG){let o=atob(n.__ZUPLO_CONFIG);i=JSON.parse(o)}}catch(o){C.console.error("Failed to parse runtime configuration",o)}this.config=i??{},this.build=t,this.runtime=n,this.instanceId=crypto.randomUUID(),this.#e=Et(n,this.isCloudflare)}build;runtime;instanceId;get deploymentName(){return this.runtime.__ZUPLO_DEPLOYMENT_NAME??this.config.deployment_name??void 0}get accountName(){return this.build.ACCOUNT_NAME??this.runtime.ZUPLO_ACCOUNT_NAME??void 0}get projectName(){return this.build.PROJECT_NAME??this.runtime.ZUPLO_PROJECT_NAME??void 0}get useLegacyServiceRouting(){return this.config.use_legacy_service_routing??void 0}get useProxyForFetchFromZups(){return this.config.use_proxy_for_fetch_from_zups??void 0}get devPortalBaseUrl(){return this.runtime.__ZUPLO_DEV_PORTAL_URL??this.config.dev_portal_url??"https://dev-portal-v4-1.zuplo.com"}get buildAssetsUrl(){return this.runtime.__ZUPLO_BUILD_ASSETS_URL??this.config.build_assets_url??"https://build-assets.zuplo.com"}get zuploEdgeApiUrl(){return this.runtime.__ZUPLO_EDGE_API_URL??this.config.zuplo_edge_api_url??"https://api.zuploedge.com"}get remoteLogToken(){return this.runtime.__ZUPLO_REMOTE_LOG_TOKEN??this.config.remote_log_token??void 0}get zuploClientAuthBucketId(){return this.config.zuplo_auth_client_bucket_id??"auth_o8PUdhKxSTOiB794GWPwLQCD"}get managementApiURL(){return this.runtime.__ZUPLO_MANAGEMENT_API_URL??this.config.management_api_url??"https://api.zuplo.com"}get developerApiUrl(){return this.config.developer_api_url??"https://dev.zuplo.com"}get cdnURL(){return this.runtime.__ZUPLO_CDN_URL??this.config.cdn_url??"https://cdn.zuplo.com"}get remoteLogURL(){return this.runtime.__ZUPLO_REMOTE_LOG_URL??this.config.log_event_api??"https://ellie.zuploedge.com"}get loggingId(){return this.runtime.__ZUPLO_LOGGING_ID??this.config.logging_id??void 0}get redisURL(){return this.runtime.__ZUPLO_REDIS_URL??this.config.redis_proxy_url??"https://redis-proxy.zuploedge.com"}get apiKeyServiceUrl(){return this.runtime.__ZUPLO_API_KEY_SERVICE_URL??this.config.api_key_service_url??"https://apikey.zuploedge.com"}get meteringServiceUrl(){return this.config.metering_service_url??"https://meters.zuploedge.com"}get authApiJWT(){return this.runtime.__ZUPLO_AUTH_API_JWT??void 0}get authClientId(){return this.config.auth_client_id??this.runtime.__ZUPLO_AUTH_CLIENT_ID}get authClientSecret(){return this.config.auth_client_secret??this.runtime.__ZUPLO_AUTH_CLIENT_SECRET}get authPublicKey(){return this.config.auth_public_key??this.runtime.__ZUPLO_AUTH_PUBLIC_KEY}get authPrivateKey(){return this.config.auth_private_key??this.runtime.__ZUPLO_AUTH_PRIVATE_KEY}get userLogLevel(){return this.runtime.ZUPLO_LOG_LEVEL??this.runtime.__ZUPLO_LOG_LEVEL??this.config.user_log_level??"debug"}get systemLogLevel(){return this.runtime.__ZUPLO_LOG_LEVEL??this.config.system_log_level??"debug"}get logFormat(){return this.runtime.__ZUPLO_LOG_FORMAT??this.config.log_format??"cloudflare"}get isCloudflare(){return this.runtime.__ZUPLO_RUNTIME_TYPE?this.runtime.__ZUPLO_RUNTIME_TYPE==="cloudflare":this.config.runtime_type?this.config.runtime_type==="cloudflare":typeof WebSocketPair=="function"}get isManagedDedicated(){return this.runtime.__ZUPLO_IS_MANAGED_DEDICATED==="true"}get trustedIpHeader(){return this.#e}get isDeno(){if(this.runtime.__ZUPLO_RUNTIME_TYPE)return this.runtime.__ZUPLO_RUNTIME_TYPE==="deno";if(this.config.runtime_type)return this.config.runtime_type==="deno";{let t=globalThis.Deno?.version?.deno;return typeof WebSocketPair!="function"&&t}}get isLocalDevelopment(){return this.build.IS_LOCAL_DEVELOPMENT}get isTestMode(){return!!this.runtime.__ZUPLO_TEST_MODE}get budgetRulesCaptureDisabled(){return this.runtime.__ZUPLO_BUDGET_RULES_CAPTURE==="off"}get budgetDimensionLogValuesEnabled(){return this.runtime.__ZUPLO_BUDGET_DIMENSION_LOG_VALUES==="on"}get systemUserAgent(){return`Zuplo/${this.build.ZUPLO_VERSION}`}get loggingEnvironmentType(){return this.isCloudflare?"edge":this.isLocalDevelopment?"local":this.isDeno?"working-copy":"unknown"}get loggingEnvironmentStage(){return this.build.ENVIRONMENT_TYPE==="PRODUCTION"?"production":this.build.ENVIRONMENT_TYPE==="PREVIEW"?"preview":this.isLocalDevelopment?"local":this.isWorkingCopy?"working-copy":"unknown"}get isWorkingCopy(){return this.build.ENVIRONMENT_TYPE==="WORKING_COPY"}get rateLimitServiceTimeoutMs(){let t=this.runtime.__ZUPLO_RATE_LIMIT_TIMEOUT_MS,n=this.config.rate_limit_service_timeout_ms,i=t??n;if(!i)return 500;let o=Number(i);return Number.isFinite(o)&&o>0?o:500}};export{U as a,N as b,T as c,K as d,le as e,Rt as f,he as g,Re as h,Oe as i,Ot as j,yt as k,Tt as l,ye as m,Te as n,be as o,Ae as p,xe as q,bt as r,At as s,xt as t,Lt as u,Pt as v,It as w,St as x,Ct as y,wt as z,Ut as A,X as B,Le as C,Pe as D,Ie as E,Se as F,Ce as G,we as H,Ue as I,Ne as J,De as K,He as L,Me as M,ve as N,ze as O,Ze as P,Fe as Q,ke as R,Nt as S,v as T,$e as U,Ge as V,Dt as W,Ht as X,Mt as Y,vt as Z,zt as _,E as $,C as aa,Q as ba};
36
- /*! For license information please see chunk-MWIJG5KC.js.LEGAL.txt */
37
- //# sourceMappingURL=chunk-MWIJG5KC.js.map