@wildo-ai/external-connectors-models 1.1.11 → 1.1.13
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/dist/esm/companion-exports.d.ts.map +1 -1
- package/dist/esm/companion-exports.js.map +1 -1
- package/dist/esm/core/commons.external-connectors-models.schemas.d.ts +10 -0
- package/dist/esm/core/commons.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/commons.external-connectors-models.schemas.js +10 -0
- package/dist/esm/core/commons.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/oauth2.enums.d.ts.map +1 -1
- package/dist/esm/core/oauth2.enums.js.map +1 -1
- package/dist/esm/core/operation-classification.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/operation-classification.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/operations.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/operations.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/core/security.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/core/security.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts +20 -46
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js +34 -5
- package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/billing.standard-interface.schemas.d.ts +56 -3
- package/dist/esm/protocols/billing.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/billing.standard-interface.schemas.js +15 -2
- package/dist/esm/protocols/billing.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/content-safety.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/content-safety.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts +157 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js +134 -0
- package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts +85 -0
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.js +46 -2
- package/dist/esm/protocols/email-inbound.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/email.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/email.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/email.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts +49 -6
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js +89 -6
- package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/file-storage.standard-interface.d.ts +9 -2
- package/dist/esm/protocols/file-storage.standard-interface.d.ts.map +1 -1
- package/dist/esm/protocols/file-storage.standard-interface.js +6 -0
- package/dist/esm/protocols/file-storage.standard-interface.js.map +1 -1
- package/dist/esm/protocols/frontend.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/frontend.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts +254 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js +480 -0
- package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts +95 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.js +110 -0
- package/dist/esm/protocols/hooks.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/image.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/image.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts +95 -3
- package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/llm.external-connectors-models.schemas.js +147 -15
- package/dist/esm/protocols/llm.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.definitions.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.definitions.js.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2-provider-assurance.schemas.js.map +1 -1
- package/dist/esm/protocols/oauth2.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/oauth2.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts +52 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js +132 -0
- package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts +111 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts.map +1 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js +203 -0
- package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js.map +1 -0
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts +6 -0
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts.map +1 -1
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js +13 -7
- package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js.map +1 -1
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts +50 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts.map +1 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js +30 -0
- package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js.map +1 -0
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts +730 -17
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js +822 -20
- package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts +73 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts.map +1 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js +82 -0
- package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js.map +1 -0
- package/dist/esm/protocols/sms.external-connectors-models.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/sms.external-connectors-models.schemas.js.map +1 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.d.ts +79 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.d.ts.map +1 -1
- package/dist/esm/protocols/sms.standard-interface.schemas.js +93 -0
- package/dist/esm/protocols/sms.standard-interface.schemas.js.map +1 -1
- package/dist/esm/protocols/subject-erasure-effect.standard-interface.d.ts.map +1 -1
- package/dist/esm/protocols/subject-erasure-effect.standard-interface.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/dist/esm/.native.tsbuildinfo +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-operations.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../../src/protocols/rest-operations.external-connectors-models.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The REST OPERATION vocabulary — what an operation IS, independent of who executes one.\n *\n * Moved here from `@wildo-ai/external-connectors-private/backend` on 2026-09-06 (#378), and the\n * reason is a measurement rather than tidiness. A generated provider's operation catalogue is loaded\n * LAZILY on purpose: the loader contract forbids evaluating it at boot, because a provider whose\n * operations are eager puts every vendor's operations into every process's boot graph. But the\n * catalogue module needs `ProviderRestParameterLocation` and `ProviderRestRequestBodyEncoding` as\n * VALUES, and their only public door was the backend barrel — so reading two string enums pulled the\n * entire backend provider surface in behind them:\n *\n * | import | heap | time |\n * |---|---|---|\n * | `@wildo-ai/external-connectors-models` | 20.8 MB | 39 ms |\n * | `@wildo-ai/external-connectors-private/backend` | 160.7 MB | 251 ms |\n *\n * 161 MB to answer \"is this parameter in the path or the query\". The vocabulary belongs here for a\n * reason that survives the measurement, too: it describes what an operation IS — its method, its\n * path template, where its parameters ride — and none of that is backend runtime. The arrow already\n * pointed this way, since this package has no dependency on the private backend and the private\n * backend depends on it.\n *\n * ## This is the ONLY description of a REST provider — two earlier ones were deleted\n *\n * `rest-api.external-connectors-models.schemas.ts` described REST providers twice over, and both\n * descriptions are gone. Neither should come back beside this module.\n *\n * - **An OpenAPI-shaped operation layer** (`REST_API_OperationSpecSchema`,\n * `REST_API_OperationContextSchema`, `REST_API_OperationDefinition`, `API_Parameter*`,\n * `API_ContentType`) — deleted 2026-09-06 by #331. Ten exported symbols and zero code readers: a\n * provider that authored one compiled, shipped, and was invisible to every runtime.\n * - **A profile / configuration / status triple** (`REST_API_Provider_Profile`,\n * `REST_API_Provider_Configuration`, `REST_APIProvider_StatusSchema`) — deleted 2026-09-12 (#18).\n * Its only reader was the `ExternalProvider_ExchangeProtocol` union, itself read by nothing but a\n * drift test pinning it to the enum, and deleted in the same change. Its `pagination.style` was an\n * anonymous `\"offset\" | \"cursor\" | \"page\" | \"link\"` restating {@link ProviderRestPaginationStyle}.\n *\n * WHERE a REST API lives and how it authenticates is the `rest` arm of the backend runtime contract\n * (`@wildo-ai/external-connectors-private/backend`); WHAT can be called against it is\n * {@link ProviderRestOperation}, executed by `ProviderOperationExecutorBackendService`. A second\n * description of either is not a missing feature — it is the drift that makes an authoring surface\n * untrustworthy, because an author cannot tell which of two shapes is the one that runs. If an\n * OpenAPI document is ever read (a second mapper input), it feeds `ProviderRestOperation` like\n * every other source.\n */\n\nimport { z } from 'zod';\n\nimport { API_HttpMethod } from '../core/commons.external-connectors-models.schemas';\nimport { ExternalOperation_Classification } from '../core/operation-classification.external-connectors-models.schemas';\nimport type { ExternalProvider_ConnectionTarget } from '../core/security.external-connectors-models.schemas';\n\n/** @wildo_source:part:start external-connectors.models.rest-operation-contract facet:layer:shared facet:family:provider facet:audience:app-developer */\n/** Where a declared parameter rides on the wire. */\nexport enum ProviderRestParameterLocation {\n /** Substituted into a `{token}` of the path template. Always required — a path cannot have a hole. */\n PATH = 'path',\n QUERY = 'query',\n HEADER = 'header',\n}\n\n/**\n * How the request body is encoded. The ETL read surface only ever needed JSON; a hand-authored\n * write reaches vendors that take form bodies (OAuth-adjacent endpoints, older CRMs) and file\n * uploads, so the encoding is DECLARED per operation rather than inferred from the method.\n */\nexport enum ProviderRestRequestBodyEncoding {\n JSON = 'json',\n FORM_URLENCODED = 'form-urlencoded',\n MULTIPART = 'multipart',\n /** A raw text body; `contentType` on the declaration says which media type is sent. */\n TEXT = 'text',\n /**\n * Raw bytes (#367, folding #364) — an image, a PDF, a file upload a vendor takes as the whole body.\n * `contentType` is REQUIRED, by the TEXT arm's rule: a body without its media type is not addressable.\n * The input must supply a `Uint8Array` (a Node `Buffer` is one); nothing is converted into bytes here,\n * because a string encoded under a guessed charset is exactly how an upload arrives corrupted.\n */\n BINARY = 'binary',\n}\n\n/**\n * How the vendor's ANSWER is read (#367, folding #364).\n *\n * The request side could already send TEXT and the transport could already read TEXT and NONE, while\n * the operation declaration could only say JSON — so an operation against a `text/csv` export could be\n * authored and then failed at runtime as `INVALID_JSON`, a contract-breach message for a declaration\n * the contract had no way to state. This is the missing half of that asymmetry.\n */\nexport enum ProviderRestResponseDecoding {\n /** Parse the body as JSON. The default, and what an absent `responseDecoding` means. */\n JSON = 'json',\n /** Keep the body as text — a CSV export, an XML document. The operation's output is that string. */\n TEXT = 'text',\n /** Read nothing — a write whose answer carries no information (a 204). The output is `undefined`. */\n NONE = 'none',\n /**\n * Keep the raw bytes — a signed PDF, an evidence container (#2910). Requires `binaryResponse` (a byte ceiling and the\n * accepted media types); the output is `{ bytes, contentType }`. The bytes are the vendor's, unscanned: do not relay\n * them to a person or write them as a file yourself. Keep one through `ProviderDocumentFileWriterBackendService`\n * (`@wildo-ai/saas-backend-lib`, #2963), which stores it as a scanned file (`scan: REQUIRED`) whatever the caller asks.\n */\n BINARY = 'binary',\n}\n\n/** The bounds a {@link ProviderRestResponseDecoding.BINARY} answer is read under (#2910). Both mandatory. */\nexport interface ProviderRestBinaryResponse {\n /** The most bytes the vendor's answer may hold. Enforced while streaming; a larger answer is refused, never truncated. */\n readonly maxBytes: number;\n /** Media types accepted (`application/pdf`), compared on the type alone, case-insensitively. */\n readonly acceptedContentTypes: readonly string[];\n}\n\n/**\n * How a listing operation continues. A HINT the caller reads, never something the executor acts\n * on: an executor that paged on its own would decide a caller's memory budget for it, and the\n * ETL lane already owns paging as a discipline (drift-safe continuation only).\n */\nexport enum ProviderRestPaginationStyle {\n OFFSET = 'offset',\n PAGE = 'page',\n CURSOR = 'cursor',\n /** The vendor returns its own continuation URL (`@odata.nextLink`, `links.next`). */\n LINK = 'link',\n}\n\n/** One declared parameter: a wire name, where it rides, and which input field feeds it. */\nexport interface ProviderRestOperationParameter {\n /** The name ON THE WIRE (`page_size`, `X-Vendor-Version`, or the `{token}` in the path). */\n readonly name: string;\n readonly in: ProviderRestParameterLocation;\n /**\n * The INPUT field that feeds it, when the two differ (`pageSize` → `page_size`). Absent means\n * the input field is spelled exactly like the wire name. Declared, never camel/snake-guessed:\n * a guess that is wrong drops a parameter silently and the vendor answers a valid-looking\n * default page.\n */\n readonly from?: string;\n /** PATH parameters are required whatever this says; for QUERY/HEADER, absent means optional. */\n readonly required?: boolean;\n /** A literal value sent on every call — for a version pin or a fixed format selector. */\n readonly constantValue?: string;\n /**\n * PATH only (#2663): the value may hold several `/`-separated segments, each percent-encoded on its own, instead of\n * one segment whose `/` is encoded. For a vendor that routes per region or tenant inside ONE origin: the Bot\n * Connector's `serviceUrl` is `https://smba.trafficmanager.net/<region>/…`, and an operation's path begins with that\n * region path. Empty segments, `.` and `..` are refused, so the value moves the path within the base origin and never\n * above it; the origin itself cannot move, as for every path value.\n */\n readonly multiSegment?: true;\n readonly description?: string;\n}\n\n/** How the request body is built from the operation's input. */\nexport interface ProviderRestOperationRequestBody {\n readonly encoding: ProviderRestRequestBodyEncoding;\n /**\n * The input field carrying the whole body. Absent = the body is every input field NOT consumed\n * by a declared parameter — the ordinary shape, and the reason parameters declare `from`.\n */\n readonly from?: string;\n /** For `TEXT` and `BINARY`: the media type actually sent (`text/csv`, `application/pdf`). Required for both. */\n readonly contentType?: string;\n /**\n * A JSON body sent INSIDE one named property: `envelope: 'data'` sends `{ \"data\": { …the body… } }` (#333).\n *\n * Asana answers `data: Missing input` to a task whose fields arrive at the top level — its API reads\n * every write from a `data` wrapper, which the source catalogue builds in its request helper and the\n * transposer never saw. Declared here rather than modelled as a nested input, so the INPUT stays flat:\n * the fields a person fills in, and the fields an `inputOptions` key names, are the fields they see.\n *\n * JSON only. Any other encoding with an envelope is refused by name when the request is compiled — a\n * form, text or binary body has no property to wrap it in.\n */\n readonly envelope?: string;\n}\n\n/** Where the payload sits inside a response, and how a listing continues. */\nexport interface ProviderRestOperationPagination {\n readonly style: ProviderRestPaginationStyle;\n /** OFFSET/PAGE/CURSOR: the request parameter names the caller advances. */\n readonly limitParam?: string;\n readonly offsetParam?: string;\n readonly pageParam?: string;\n readonly cursorParam?: string;\n /** CURSOR/LINK: dot-path in the RESPONSE carrying the next cursor or the next URL. */\n readonly nextPath?: string;\n}\n\n/**\n * Where an input's CHOICES come from: another operation of the same provider, run through the SAME\n * connection, whose answer lists the values a person may pick (#333).\n *\n * The shape every workflow product converged on, and deliberately not a value stored on the connection.\n * A workspace, a project, a channel are choices WITHIN an account, made per call: Zapier fills a\n * dynamic dropdown with \"a live API call\", Make fills a module field through an RPC that \"must have the\n * same connection\", n8n's resource locator lists through the node's credentials, and the Activepieces\n * source this catalogue is scraped from declares Asana's workspace as a required dropdown whose options\n * are fetched with the connected account. A connection records only what the vendor REPORTED when it\n * was authorized ({@link ProviderRestOAuth2.accountRefResponsePath}).\n *\n * Declaring an options source does not make the options operation reachable from a browser: it is its\n * own operation, and `providers.browserOperations` must list it like any other.\n *\n * @example\n * // Asana: a task's project is chosen from the projects of the chosen workspace.\n * inputOptions: {\n * workspace: { operationId: 'list_workspaces', valuePath: 'gid', labelPath: 'name' },\n * project: { operationId: 'list_projects', valuePath: 'gid', labelPath: 'name', dependsOn: { workspace: 'workspace' } },\n * }\n */\nexport interface ProviderRestOperationInputOptions {\n /** The operation that lists the choices. Same provider; its output (after its own `resultPath`) must be an array. */\n readonly operationId: string;\n /** That operation's catalogue domain, when it differs from the one being called. */\n readonly domain?: string;\n /** Dot-path, inside each listed item, to the value the input receives (`gid`). */\n readonly valuePath: string;\n /** Dot-path, inside each listed item, to the text a person reads (`name`). Vendor content, never derived from the value. */\n readonly labelPath: string;\n /**\n * Inputs the options depend on: `{ <options-operation input field>: <this operation's input field> }`.\n * A choice that is not yet made is REFUSED by name rather than listed as empty — \"no projects\" and\n * \"choose a workspace first\" are different answers, and only one of them is true.\n */\n readonly dependsOn?: Readonly<Record<string, string>>;\n}\n\n/**\n * A provider operation, hand-authored. The unit an application addresses:\n * `executeProviderOperation({ providerRef: 'slack', operationId: 'conversations.list', input })`.\n */\nexport interface ProviderRestOperation {\n /** Unique within the provider, and the address an ETL binding reference uses. */\n readonly operationId: string;\n /**\n * The lazy-load unit. `operations('conversations')` answers only this domain's operations, so a\n * vendor with hundreds need not evaluate them all to run one.\n */\n readonly domain: string;\n readonly method: API_HttpMethod;\n /** Relative to the provider's base URL. `{token}` interpolates a PATH parameter of that name. */\n readonly pathTemplate: string;\n /**\n * The API host this operation is served on, when it is not the base URL's host (#2546): an exact lower-case DNS name,\n * always https. The request is then `https://<host><pathTemplate>`; the base URL's path is not prepended, since it\n * belongs to the base's host. Absent, which is the norm, the request is `<baseUrl><pathTemplate>`.\n *\n * Admitted only where the token the call already carries is valid: the connection's OAuth2 client declares\n * `audiences`, and the audience that admits the base URL's host admits this host too. So no second token is minted\n * and no token reaches a host outside its own resource ({@link describeProviderRestOperationHostDefect}). This is\n * Google's shape: one grant serves every `*.googleapis.com` API, and a Gmail operation names `gmail.googleapis.com`\n * on the one Google connection. Microsoft's Dataverse is not this shape: its token is a different audience's, so it\n * stays a provider of its own sharing the connection.\n */\n readonly host?: string;\n readonly summary?: string;\n /**\n * Whether the operation MUTATES the vendor.\n *\n * ONE vocabulary for every operation catalogue, whatever produced it: a hand-authored operation\n * and a generated one are the same concept, and two enums over the same two values is precisely\n * the drift D1 exists to remove. Read by an ETL binding reference (which refuses to serve a read\n * surface from a WRITE), by the audit trail as the axis a reviewer filters on first, and by a UI\n * deciding whether to confirm.\n *\n * The name carried a source catalogue's spelling until 2026-09-06 and no longer does — an\n * operation's EFFECT is not a property of where its definition came from.\n */\n readonly classification: ExternalOperation_Classification;\n readonly parameters?: readonly ProviderRestOperationParameter[];\n readonly requestBody?: ProviderRestOperationRequestBody;\n /**\n * Zod schema the caller's input is parsed through BEFORE anything is compiled. A typed client\n * (S3b) derives its argument type from it. Absent = the input is passed through unvalidated,\n * which is legal for a thin wrapper and honest about carrying no contract.\n */\n readonly inputSchema?: z.ZodType;\n /**\n * Zod schema the RESPONSE is parsed through. Absent = the parsed body is returned as `unknown`.\n * A vendor adding a field must never break a call, so authors should keep these permissive; the\n * value is in naming the fields a caller may rely on, not in policing the vendor.\n */\n readonly outputSchema?: z.ZodType;\n /**\n * How the answer is read. Absent = `JSON`, so every operation authored before this field existed\n * reads exactly as it did.\n *\n * It also sets the default `Accept` header — `application/json` for JSON, `*\\/*` otherwise — which a\n * declared `Accept` HEADER parameter overrides when a vendor needs a specific media type.\n *\n * Two combinations are refused by name when the request is compiled, because each describes a payload\n * that cannot exist: `resultPath` beside `TEXT` or `NONE` (there is no structure to walk), and\n * `outputSchema` beside `NONE` (there is nothing to parse). `outputSchema` beside `TEXT` is legal and\n * validates the string.\n */\n readonly responseDecoding?: ProviderRestResponseDecoding;\n /** Required with `responseDecoding: BINARY`, refused with any other decoding (#2910). */\n readonly binaryResponse?: ProviderRestBinaryResponse;\n /** Dot-path to the payload inside the response body. Absent = the body IS the payload. JSON answers only. */\n readonly resultPath?: string;\n readonly pagination?: ProviderRestOperationPagination;\n /**\n * OAuth scopes (or vendor permission names) the credential must carry, as the exact strings the vendor\n * grants. CHECKED before the request leaves (#979): `ProviderOperationExecutorBackendService` compares them\n * with the scopes recorded on the spent grant and refuses with the missing ones named when any is absent.\n * A grant that records no scopes (a pasted key, a vendor that does not echo `scope`) proceeds, and the\n * call's audit row says the check could not be made — refusing there would break every such vendor.\n *\n * Until 2026-09-14 this said \"declared and not checked\"; checking needed the granted set on the grant,\n * which the connected-accounts lane now stores. Two things not to confuse it\n * with: `ProviderRestOAuth2.scopes` is the vendor's ADVISORY default set, and the wildo-cli\n * `getProviderApiKey({ requiredScopes })` parameter is a list of secret-contract SLUGS — a\n * different concept sharing the name, which no production caller feeds from this field. As of\n * 2026-09-12 no generated provider declares it either.\n */\n readonly requiredScopes?: readonly string[];\n /**\n * Whether re-sending this request is safe. Absent = derived from the method: GET, HEAD, OPTIONS,\n * PUT and DELETE are idempotent, POST and PATCH are not.\n * spec-cite: RFC 9110 §9.2.2 (PUT, DELETE and the safe methods are idempotent) and §9.2.1\n * (GET, HEAD, OPTIONS, TRACE are safe).\n * Declare it TRUE on a POST the vendor documents as idempotent (an idempotency-key endpoint);\n * declaring it wrongly is how a retried timeout charges a customer twice.\n */\n readonly idempotent?: boolean;\n /** Narrows the provider's semantics for this one operation (a slow export, a tight endpoint). */\n readonly remoteCallSemantics?: Partial<ProviderRestCallSemantics>;\n /**\n * Where each input's choices come from, keyed by INPUT field name. Absent for an input a caller types.\n * See {@link ProviderRestOperationInputOptions}.\n */\n readonly inputOptions?: Readonly<Record<string, ProviderRestOperationInputOptions>>;\n /** Set when the vendor has deprecated it; the executor logs once per operation, never refuses. */\n readonly deprecated?: {\n readonly reason: string;\n readonly since?: string;\n readonly replacedByOperationId?: string;\n };\n}\n\n/** What one `operations(domain?)` call answers. */\nexport interface ProviderRestOperationCatalogue {\n /** The domains this load carries — the whole set when called with no argument. */\n readonly domains: readonly string[];\n /** Keyed by `operationId`. */\n readonly operations: Readonly<Record<string, ProviderRestOperation>>;\n /**\n * Which package contributed an operation that the provider's OWN module does not declare, keyed by\n * `operationId` (#1672). Absent on every catalogue a provider module loads itself; set only by the\n * framework when it merges an opted-in AUGMENTATION into a provider it does not own.\n *\n * A catalogue value and not a property of the operation, on purpose: an operation declaration is the\n * augmentation author's data, and a field the author could write would let a package claim to be\n * somebody else. The merge refuses a loaded catalogue that already carries this field.\n *\n * Read by the operation executor, which writes the contributor into the `PROVIDER_OPERATION_CALL` audit\n * row: a call spending a shared grant must say whose code declared the request it sent.\n */\n readonly augmentedBy?: Readonly<Record<string, ProviderRestOperationContributor>>;\n}\n\n/** The package that contributed an operation to a provider it does not own (#1672). */\nexport interface ProviderRestOperationContributor {\n /** The augmentation package's npm name, as its own manifest states it. */\n readonly packageName: string;\n /** The installed version of that package, as `wildo config sync` read it from the manifest. */\n readonly packageVersion: string;\n}\n\n/**\n * How a vendor states, INSIDE a successful HTTP answer, whether the call it answered succeeded (#2661).\n *\n * Most vendors say it with the status: a 4xx or 5xx is a failure, and the transport already treats it as one. Some\n * answer HTTP 200 for every call they could parse and put the verdict in the body. Slack's Web API is the case:\n * \"All Web API responses contain a JSON object, which will always contain a top-level boolean property `ok` that\n * indicates success or failure\", and \"For failure results, the `error` property will contain a short machine-readable\n * error code\".\n * spec-cite: https://docs.slack.dev/apis/web-api/ — \"Evaluating responses\", fetched 2026-10-06.\n *\n * Without this declaration such an answer reads as a success: `channel_not_found` is returned to the caller as if it\n * were a posted message, the call's audit row says it succeeded, and a revoked token stays \"accepted\" on the\n * credential. Declared on the provider's REST contract (`rest.applicationOutcome`), because the envelope is a fact\n * about the vendor's API, not about one operation.\n *\n * Read for JSON answers only: an operation declaring `TEXT` or `NONE` decoding (a file download) has no envelope.\n */\nexport interface ProviderRestApplicationOutcome {\n /** Dot-path to the boolean the vendor sets `true` exactly when the call succeeded (Slack: `ok`). */\n readonly successFlagPath: string;\n /** Dot-path to the vendor's machine-readable error code on a failed call (Slack: `error`). */\n readonly errorCodePath: string;\n /**\n * The error codes that mean the vendor refused the CREDENTIAL itself, rather than the request: the stored\n * credential is then recorded as rejected, the way the vendor's answer said (Slack: `invalid_auth`,\n * `account_inactive`, `token_revoked`, `token_expired`). A code that means the caller sent no credential at all\n * (Slack's `not_authed`) does not belong here: that is our request's fault, not a dead credential.\n */\n readonly credentialRefusedErrorCodes?: readonly string[];\n}\n\n/** What a successful HTTP answer said about the call, read through a {@link ProviderRestApplicationOutcome}. */\nexport enum ProviderRestApplicationOutcomeKind {\n /** The success flag is `true`. */\n SUCCEEDED = 'succeeded',\n /** The success flag is `false`: the vendor refused the call, naming why at the error path when it could. */\n REFUSED = 'refused',\n /** The flag is absent or not a boolean: the answer does not carry the envelope its provider declares. */\n UNSTATED = 'unstated',\n}\n\n/** The verdict a body carries. `errorCode` is kept only when it is a code-shaped string, never prose. */\nexport type ProviderRestApplicationOutcomeVerdict =\n | { readonly kind: ProviderRestApplicationOutcomeKind.SUCCEEDED }\n | { readonly kind: ProviderRestApplicationOutcomeKind.REFUSED; readonly errorCode?: string }\n | { readonly kind: ProviderRestApplicationOutcomeKind.UNSTATED };\n\n/**\n * A vendor error code as the engine may carry it: identifier characters only, at most 128. A value of any other shape\n * is dropped rather than carried, because it travels to audit rows, logs and API answers, and a vendor that puts a\n * sentence (or request data) where a code belongs must not have it repeated there.\n */\nexport const PROVIDER_VENDOR_ERROR_CODE_SHAPE = /^[A-Za-z0-9_.:-]{1,128}$/;\n\n/**\n * The defects of a declared outcome envelope, refused at boot: an empty path, and a credential-refusal code that is not\n * code-shaped, which the transport would never carry and so would never match (#2661 review L7).\n */\nexport function describeProviderRestApplicationOutcomeDefects(outcome: ProviderRestApplicationOutcome): string[] {\n const defects: string[] = [];\n const path = /^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$/;\n if (!path.test(outcome.successFlagPath)) defects.push(`applicationOutcome.successFlagPath '${outcome.successFlagPath}' is not a dot-path`);\n if (!path.test(outcome.errorCodePath)) defects.push(`applicationOutcome.errorCodePath '${outcome.errorCodePath}' is not a dot-path`);\n for (const code of outcome.credentialRefusedErrorCodes ?? []) {\n if (!PROVIDER_VENDOR_ERROR_CODE_SHAPE.test(code)) {\n defects.push(`applicationOutcome.credentialRefusedErrorCodes names '${code}', which is not code-shaped and would never match a code the transport keeps`);\n }\n }\n return defects;\n}\n\n/**\n * The placeholder a client-credentials token URL may carry for the tenant the credential belongs to:\n * `https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token`. Filled from the connection's\n * {@link ProviderRestClientCredentials.tenantSecretRef} slot, never from a request.\n */\nexport const PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER = '{tenant}';\n\n/** A tenant value the token URL admits: a GUID or a DNS name. Nothing that can leave the URL's path segment. */\nexport const PROVIDER_CLIENT_CREDENTIALS_TENANT_SHAPE = /^[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?$/;\n\n/** What a {@link ProviderClientCredentialsVerifiedFact} records: a value the person typed and the vendor accepted. */\nexport enum ProviderClientCredentialsFactSource {\n /** The client id the token endpoint issued a token for: Microsoft's bot App ID. */\n CLIENT_ID = 'client_id',\n /** The tenant whose token endpoint issued it. */\n TENANT = 'tenant',\n}\n\n/**\n * One fact a client-credentials connection records once the vendor has accepted its credential. See\n * {@link ProviderRestClientCredentials.verifiedAccountFacts}.\n */\nexport interface ProviderClientCredentialsVerifiedFact {\n readonly source: ProviderClientCredentialsFactSource;\n /**\n * `true` when the inbound receiver routes deliveries to an organization by this fact: an organization's own Teams\n * bot, by its App ID (#2663). Such a fact may name ONE organization only, so a connect whose value another\n * organization's enabled connection holds is refused, as for a vendor-reported fact.\n */\n readonly routesInboundDeliveries?: true;\n /**\n * `true` when the vendor treats the value without case, as Microsoft does an App ID or a tenant id (both GUIDs): the\n * value is recorded LOWER-CASED, so a lookup by the vendor's own spelling (a token's `aud`) finds an id the\n * administrator typed in capitals (#2663). Never for a value the vendor compares exactly, which most client ids are.\n */\n readonly caseInsensitive?: true;\n}\n\n/**\n * A REST provider whose access token is minted with the OAuth 2.0 client-credentials grant, from a client id and\n * secret the connection holds (#2663). The Bot Framework is the first: a Teams bot's App ID and secret, and for a\n * single-tenant bot the tenant it is registered in, mint a token for `https://api.botframework.com/.default`.\n *\n * The token is minted per call when no unexpired one is cached, never stored, and attached where\n * {@link ProviderProtocolRuntimeContract}'s `apiKey` says, so `apiKey.secretRef` names the client SECRET (the slot\n * whose absence means \"not configured\"). The client id, secret and tenant are read from the connection: the\n * application's own environment for an APPLICATION connection, the organization's typed credential for an\n * ORGANIZATION one.\n *\n * The client id and tenant of an ORGANIZATION connection are typed by its administrator, so on their own they prove\n * nothing. They become evidence when the vendor accepts them: at connect the engine mints a token with the typed\n * values, refuses the connection when the vendor refuses, and records each {@link verifiedAccountFacts} entry as\n * `VERIFIED_BY_VENDOR`. A bot App ID then routes deliveries only to the organization that holds its secret.\n *\n * spec-cite: RFC 6749 §4.4 — the client credentials grant (`grant_type=client_credentials`, client authentication,\n * `scope`); Microsoft, \"Authenticate requests with the Bot Connector API\" — the single-tenant token request\n * `POST https://login.microsoftonline.com/MICROSOFT-TENANT-ID/oauth2/v2.0/token` with the scope\n * `https://api.botframework.com/.default`, fetched 2026-10-06.\n */\nexport interface ProviderRestClientCredentials {\n /** The https token endpoint. May carry {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}. */\n readonly tokenUrl: string;\n /** The hosts the token endpoint may be on once filled. The client secret is sent nowhere else. */\n readonly tokenHosts: readonly string[];\n /** The `scope` parameter, sent as written. */\n readonly scope: string;\n /** The slot holding the client id. */\n readonly clientIdSecretRef: string;\n /** The slot holding the client secret. Equal to the contract's `apiKey.secretRef`. */\n readonly clientSecretSecretRef: string;\n /** The slot filling {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}. Required exactly when the token URL carries it. */\n readonly tenantSecretRef?: string;\n /** Facts an ORGANIZATION connection records once the vendor accepted its credential, keyed by fact name. */\n readonly verifiedAccountFacts?: Readonly<Record<string, ProviderClientCredentialsVerifiedFact>>;\n /** Seconds a token is kept when the answer states no `expires_in`. Omitted, it is not cached. */\n readonly tokenLifetimeFallbackSeconds?: number;\n}\n\n/**\n * Why a client-credentials declaration cannot be honoured, or an empty list. Checked where a provider is composed:\n * a token URL that is not https, a token host that is not a DNS name or that the URL is not on, a tenant placeholder\n * with no tenant slot (or the reverse), or any other placeholder in the URL.\n */\nexport function describeProviderRestClientCredentialsDefects(credentials: ProviderRestClientCredentials): string[] {\n const defects: string[] = [];\n const hasTenant = credentials.tokenUrl.includes(PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER);\n const filled = credentials.tokenUrl.split(PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER).join('tenant.example');\n if (/[{}]/.test(filled)) defects.push(`clientCredentials.tokenUrl '${credentials.tokenUrl}' carries a placeholder other than ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}`);\n if (hasTenant && credentials.tenantSecretRef === undefined) defects.push(`clientCredentials.tokenUrl carries ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER} and no tenantSecretRef fills it`);\n if (!hasTenant && credentials.tenantSecretRef !== undefined) defects.push(`clientCredentials.tenantSecretRef '${credentials.tenantSecretRef}' fills nothing: the token URL carries no ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}`);\n const host = /^https:\\/\\/([^/:?#]+)(?::\\d+)?\\//.exec(filled)?.[1]?.toLowerCase();\n if (host === undefined) defects.push(`clientCredentials.tokenUrl '${credentials.tokenUrl}' is not an https URL with a path`);\n if (credentials.tokenHosts.length === 0) defects.push('clientCredentials.tokenHosts admits no host');\n for (const tokenHost of credentials.tokenHosts) {\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(tokenHost.toLowerCase())) defects.push(`clientCredentials.tokenHosts names '${tokenHost}', which is not a DNS name`);\n }\n if (host !== undefined && !credentials.tokenHosts.some((tokenHost) => tokenHost.toLowerCase() === host)) {\n defects.push(`clientCredentials.tokenUrl is on '${host}', which tokenHosts does not admit`);\n }\n if (credentials.scope.trim() === '') defects.push('clientCredentials.scope is empty');\n for (const [name, fact] of Object.entries(credentials.verifiedAccountFacts ?? {})) {\n if (!/^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(name)) defects.push(`clientCredentials.verifiedAccountFacts names '${name}', which is not a fact name`);\n if (fact.source === ProviderClientCredentialsFactSource.TENANT && credentials.tenantSecretRef === undefined) {\n defects.push(`clientCredentials.verifiedAccountFacts '${name}' records the tenant, and no tenantSecretRef holds one`);\n }\n }\n if (credentials.tokenLifetimeFallbackSeconds !== undefined && !(credentials.tokenLifetimeFallbackSeconds > 0)) {\n defects.push('clientCredentials.tokenLifetimeFallbackSeconds is not a positive number');\n }\n return defects;\n}\n\nfunction readDotPath(body: unknown, path: string): unknown {\n let current: unknown = body;\n for (const segment of path.split('.')) {\n if (current === null || typeof current !== 'object' || !Object.hasOwn(current, segment)) return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * The vendor's error code at `errorCodePath` in a parsed answer, when it is code-shaped. Used for a refused 2xx and for\n * a non-2xx answer alike: a vendor that states its code in the body states it in the same place whatever the status.\n */\nexport function readProviderVendorErrorCode(body: unknown, errorCodePath: string): string | undefined {\n const code = readDotPath(body, errorCodePath);\n return typeof code === 'string' && PROVIDER_VENDOR_ERROR_CODE_SHAPE.test(code) ? code : undefined;\n}\n\n/** Reads the verdict a parsed JSON answer carries. The ONE reader: the transport and every test go through it. */\nexport function readProviderRestApplicationOutcome(\n body: unknown,\n outcome: Pick<ProviderRestApplicationOutcome, 'successFlagPath' | 'errorCodePath'>,\n): ProviderRestApplicationOutcomeVerdict {\n const flag = readDotPath(body, outcome.successFlagPath);\n if (flag === true) return { kind: ProviderRestApplicationOutcomeKind.SUCCEEDED };\n if (flag !== false) return { kind: ProviderRestApplicationOutcomeKind.UNSTATED };\n const errorCode = readProviderVendorErrorCode(body, outcome.errorCodePath);\n return errorCode === undefined\n ? { kind: ProviderRestApplicationOutcomeKind.REFUSED }\n : { kind: ProviderRestApplicationOutcomeKind.REFUSED, errorCode };\n}\n/** @wildo_source:part:end external-connectors.models.rest-operation-contract */\n\n/**\n * The lazy catalogue loader — the seam #330's host loader consumes (interface note on #331).\n *\n * MUST NOT be called during composition, discovery or boot: it exists so a provider package can\n * `import()` its own operation module only when a run needs it, and calling it at boot puts every\n * provider's operations back into every process's boot graph, which is the thing on-demand\n * loading exists to remove. Async, idempotent, and memoized by the executor per\n * `(providerRef, domain)` — a loader may assume one call per pair and must stay correct on two.\n *\n * The values it returns carry live Zod schemas, so a catalogue is an IN-PROCESS value and is\n * never serializable into a runtime artifact or any JSON the CLI emits.\n */\nexport type ProviderRestOperationCatalogueLoader = (domain?: string) => Promise<ProviderRestOperationCatalogue>;\n\n/**\n * The QUERY parameters an operation declares under a name its provider places a credential in, compared IGNORING CASE\n * (#2123, #2707). Empty when there is none.\n *\n * Such a parameter asks the caller for the credential the contract already places, so the operation would send the key\n * twice, or send the caller's value instead of the configured one. A name differing only in case travels BESIDE the\n * credential, and a vendor that reads names without regard to case may read the caller's value. Both are a declaration\n * defect.\n *\n * ONE comparison for every place that refuses it, so they cannot drift apart:\n * - the operation executor, once per catalogue load, against the contract's `apiKey.queryParameterName`;\n * - the operation request builder, on every call, against the resolved access's query-placed names (the backstop for a\n * placement that does not come from the contract);\n * - `wildo` registry module checks, at publish, against the module's own contract.\n *\n * A PATH or HEADER parameter is not compared: a path token is a resource id that may merely be spelled like a\n * credential, and a header credential is refused by its own placement rules.\n */\nexport function providerRestOperationCredentialQueryParameters(\n operation: Pick<ProviderRestOperation, 'parameters'>,\n credentialQueryParameterNames: Iterable<string>,\n): string[] {\n const credentialNames = new Set([...credentialQueryParameterNames].map((name) => name.toLowerCase()));\n if (credentialNames.size === 0) return [];\n return (operation.parameters ?? [])\n .filter((parameter) => parameter.in === ProviderRestParameterLocation.QUERY && credentialNames.has(parameter.name.toLowerCase()))\n .map((parameter) => parameter.name);\n}\n\n/**\n * Provider-level call semantics: the defaults every operation of this provider runs under.\n *\n * Structurally the executable subset of the ETL's `HttpApiRemoteCallSemantics`, and deliberately\n * NOT that type: the ETL's lives in `@wildo-ai/saas-models/external-data` and carries\n * `maxIdSetSize`, an ETL query-translation bound that means nothing to a provider operation.\n * Importing it here would point the PROVIDER contract at the ETL read surface — backwards, since\n * the ETL references provider operations and not the reverse. Three fields is the price of\n * keeping that arrow pointing the right way.\n */\nexport interface ProviderRestCallSemantics {\n /** Per-attempt timeout. */\n readonly timeoutMs: number;\n readonly retry: {\n /** Total attempts including the first; 1 disables retry. */\n readonly maxAttempts: number;\n /** Linear backoff base — attempt N waits `backoffMs * (N - 1)`. */\n readonly backoffMs: number;\n };\n /**\n * This REF's share of its connection's allowance: a sliding-window ceiling counted for every call made\n * through this ref, whichever account it spends (#1729).\n *\n * It is a CEILING UNDER the connection's own budgets ({@link ProviderRateBudgetDeclaration}, declared by\n * the connection's base), never a statement of the vendor's limit: several refs of one shared connection\n * each keep their own ceiling and all draw on the one vendor allowance together.\n */\n readonly maxRequestsPerMinute?: number;\n}\n\n/** @wildo_source:part:start external-connectors.models.connection-rate-budgets facet:layer:shared facet:family:provider facet:audience:app-developer */\n/**\n * WHOSE allowance a vendor counts a request against, under one connection (#1729).\n *\n * A connection is one application registration at the vendor (one OAuth client, one API project) — the\n * base provider's, however many refs spend it. Vendors meter on two axes of it, and a provider declares the\n * one each of its limits uses:\n *\n * | vendor wording | member |\n * |---|---|\n * | Microsoft Graph \"per app across all tenants\"; Google \"per minute per project\" | {@link CONNECTION} |\n * | Google \"per minute per user per project\"; Dataverse \"for each user\"; Graph \"per app per tenant\" / \"per app and mailbox\" when the grant owner IS that tenant or mailbox | {@link OWNER} |\n *\n * spec-cite: https://learn.microsoft.com/en-us/graph/throttling-limits — the global-limits table (\"Per app across all\n * tenants\") and the scope list \"per app across all tenants, per tenant for all apps, per app per tenant\"; and\n * https://developers.google.com/workspace/drive/api/guides/limits — \"per minute per project\" / \"per minute per user per\n * project\". Fetched 2026-09-28.\n *\n * Deliberately NOT a member: \"per tenant for all apps\" (Graph). It counts OTHER applications' calls, which this\n * deployment cannot see, so no local counter can hold it; the vendor's `429` is the only honest signal there.\n */\nexport enum ProviderRateBudgetPartition {\n /** One allowance for the whole connection — every ref, every account it acts for, every process. */\n CONNECTION = 'connection',\n /** One allowance per account the connection acts for — the grant's owner (a person, an organization, the deployment). */\n OWNER = 'owner',\n}\n\n/**\n * One limit a vendor publishes, as the connection's BASE provider declares it (#1729).\n *\n * Read only from the connection's base: a member ref's declaration is inert, exactly like a member's OAuth client,\n * because the limit belongs to the registration and the base owns the registration. Declared on the REST contract\n * (`rest.rateBudgets`) for a connection whose tokens serve one resource, and on each OAuth2 AUDIENCE\n * (`oauth2.audiences.<id>.rateBudgets`) for a connection spanning several — Microsoft Graph and a Dataverse\n * environment are metered by different services with different numbers, so one list for both would be wrong for one.\n *\n * Counted by the engine BEFORE a request leaves: a call waits for room (bounded, see the executor's\n * `rateBudgetWaitMs`) instead of spending a request the vendor would answer with `429`. The window is SLIDING, which\n * is at least as strict as a vendor's fixed window of the same length.\n */\nexport interface ProviderRateBudgetDeclaration {\n /** How many requests the window admits. */\n readonly maxRequests: number;\n /** The window's length, in seconds, as the vendor states it (Graph's global limit is per 10 s, Dataverse's per 300 s). */\n readonly windowSeconds: number;\n /** Whose allowance it is — see {@link ProviderRateBudgetPartition}. */\n readonly partition: ProviderRateBudgetPartition;\n}\n\n/**\n * Where a budget was COUNTED, as the call that spent it observed (#1729): `shared` when the deployment's shared store\n * (Redis) counted it for every process of the application — backend replicas, minions, workers — and `process` when\n * only this process did, because no shared store is configured here or it did not answer. Recorded on the call's audit\n * row, so a per-process count is visible rather than implied.\n */\nexport enum RateBudgetCounting {\n SHARED = 'shared',\n PROCESS = 'process',\n}\n\n/**\n * The defects of a connection's rate-budget declarations: a non-positive number, and a contract-level list beside\n * `oauth2.audiences` — which would apply to nothing, since every call of such a connection is on one audience. A pure\n * function so the registry refuses it at boot and a test pins it without a host.\n */\nexport function describeProviderRateBudgetDefects(input: {\n readonly contractRateBudgets?: readonly ProviderRateBudgetDeclaration[];\n readonly audiences?: Readonly<Record<string, { readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[] }>>;\n}): string[] {\n const defects: string[] = [];\n const check = (where: string, declarations: readonly ProviderRateBudgetDeclaration[] | undefined): void => {\n for (const [index, declaration] of (declarations ?? []).entries()) {\n if (!Number.isInteger(declaration.maxRequests) || declaration.maxRequests < 1) {\n defects.push(`${where}[${index}].maxRequests must be a positive integer (got ${String(declaration.maxRequests)})`);\n }\n if (!Number.isFinite(declaration.windowSeconds) || declaration.windowSeconds <= 0) {\n defects.push(`${where}[${index}].windowSeconds must be positive (got ${String(declaration.windowSeconds)})`);\n }\n if (!Object.values(ProviderRateBudgetPartition).includes(declaration.partition)) {\n defects.push(`${where}[${index}].partition '${String(declaration.partition)}' is not a ProviderRateBudgetPartition`);\n }\n }\n };\n check('rest.rateBudgets', input.contractRateBudgets);\n for (const [id, audience] of Object.entries(input.audiences ?? {})) check(`oauth2.audiences.${id}.rateBudgets`, audience.rateBudgets);\n if ((input.contractRateBudgets?.length ?? 0) > 0 && Object.keys(input.audiences ?? {}).length > 0) {\n defects.push('rest.rateBudgets is declared beside oauth2.audiences and would apply to no call — declare each limit on the audience it meters');\n }\n return defects;\n}\n\n/**\n * The declarations that apply to one call: the audience's own when the call's token is for an audience, else the\n * contract's. Nothing is inherited between the two — see {@link describeProviderRateBudgetDefects}.\n */\nexport function selectProviderRateBudgetDeclarations(input: {\n readonly contractRateBudgets?: readonly ProviderRateBudgetDeclaration[];\n readonly audience?: { readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[] };\n}): readonly ProviderRateBudgetDeclaration[] {\n return input.audience !== undefined ? input.audience.rateBudgets ?? [] : input.contractRateBudgets ?? [];\n}\n/** @wildo_source:part:end external-connectors.models.connection-rate-budgets */\n\n\n/**\n * A provider whose credential is MINTED by an authorization-code exchange rather than pasted.\n *\n * Recorded because the source catalogues state it and nothing else does. 131 of the 699 transposed\n * vendors declare OAuth2, and their authorize URL, token URL and scopes exist nowhere in this\n * repository except the catalogue that was read — so extracting them and keeping them only in a\n * comment (which is what the transposer did until 2026-09-07) means the delegated-authorization lane\n * re-derives 131 vendors' endpoints by hand.\n *\n * ## What it does NOT change\n *\n * The wire placement. An OAuth2 access token rides in the same header as an API key —\n * `Authorization: Bearer …` — so `apiKey.headerName` and `apiKey.prefix` still describe the request,\n * and `apiKey.secretRef` still names the slot the credential is read from. What this block adds is\n * where that value COMES FROM: an exchange, per organization or per user, refreshable — rather than\n * an operator pasting a long-lived token into an environment variable.\n *\n * That distinction is the whole point. Without it a provider declares a static bearer key and, if an\n * operator happens to paste a long-lived token, WORKS — while advertising a credential model the\n * vendor does not offer, with no authorize step, no refresh and no per-tenant token. A wrong\n * configuration that works is worse than one that fails, because nothing surfaces it.\n *\n * The FLOW is not here and is not implied: connected accounts, the authorization round trip, refresh\n * and revocation are their own lane. This is the declaration that lane consumes.\n */\nexport interface ProviderRestOAuth2 {\n /** Where the user is sent to grant access. Carries the vendor's own default scopes when it states them. */\n readonly authorizeUrl: string;\n /** Where an authorization code (or a refresh token) is exchanged for an access token. */\n readonly tokenUrl: string;\n /**\n * Where a token is handed back to the vendor so the GRANT ends there too (#545).\n *\n * Deleting our copy of a token stops US using it. It does not stop the token working, and a\n * refresh token frequently never expires on its own — so without this, \"Disconnect\" leaves the\n * application listed in the person's own connected-apps screen at the vendor, and their belief\n * that they have withdrawn access is not quite true.\n *\n * ## Why the field names RFC 7009 rather than \"revocation\"\n *\n * The name is the CONTRACT, not decoration. A URL here is POSTed\n * `application/x-www-form-urlencoded` with a `token` parameter and an optional\n * `token_type_hint`, and a 200 means the grant is gone — including for a token the server does\n * not recognise.\n * spec-cite: RFC 7009 §2.1 (revocation request) and §2.2 (revocation response), fetched\n * 2026-09-18 — §2.2: *\"The authorization server responds with HTTP status code 200 if the token\n * has been revoked successfully or if the client submitted an invalid token\"*, and *\"invalid\n * tokens do not cause an error response since the client cannot handle such an error in a\n * reasonable way.\"*\n *\n * That last sentence is why the caller is best-effort and never branches on the body: there is\n * nothing to branch on.\n *\n * **A vendor whose revocation is NOT RFC 7009 declares nothing here, deliberately.** Slack's\n * `auth.revoke` is a Web API method and GitHub's is `DELETE /applications/{client_id}/token` with\n * basic auth and a JSON body; neither is expressible as this URL, and bending the field to fit\n * them would make a declaration that names RFC 7009 and means something else entirely. Those vendors\n * need a per-vendor revocation ACTION, which is a bigger surface and is not built on speculation —\n * until then the honest answer is an absent field, and the disconnect surface says so.\n *\n * Absent — not empty — when no revocation is declared, so \"this vendor cannot be told\" stays\n * distinguishable from \"nobody has looked\".\n */\n readonly rfc7009RevocationUrl?: string;\n /**\n * Scopes the vendor's own catalogue entry asked for. An application may request FEWER (a subset of\n * these, once resolved), and an operation's `requiredScopes` is the finer statement. Kept because\n * it is the only record of what the vendor expects for the operations transposed beside it.\n *\n * ## A scope may carry a placeholder, and it is resolved like an endpoint's (#991)\n *\n * Two shapes exist, classified by {@link classifyProviderOAuth2ScopePlaceholder}:\n *\n * - `{hostUrl}/.default` — the placeholder BEGINS the scope and is followed by `/`, so its value is\n * an ORIGIN (Microsoft Dataverse names the resource a token is minted FOR by the environment URL).\n * It is filled only within {@link endpointHostAllowances}, exactly like an origin in an endpoint:\n * a caller-chosen resource would have the vendor mint a token for a host nobody declared.\n * - `{permissions}` — the placeholder IS the whole scope entry, and its value is one or more scope\n * tokens chosen from {@link scopeValueAllowances}. Such a value can itself name a resource\n * (`https://graph.microsoft.com/.default`), so it is a closed choice, never free text.\n *\n * Any other placement (`api://{x}`, `{a}{b}`, `{x}.default`) is refused as malformed.\n */\n readonly scopes?: readonly string[];\n /**\n * How this vendor lets an EXISTING grant grow by one permission (#1671) — declared by the provider module that\n * owns the OAuth client, never guessed by the engine. See {@link ProviderOAuth2IncrementalConsent}.\n *\n * Absent means the vendor's behaviour is not recorded, so a re-authorization for a missing scope RESTATES what the\n * grant already holds beside the addition: an ordinary authorization that replaces the previous one, which every\n * RFC 6749 server honours. Declared, the re-authorization asks for the missing scope only and the stored granted\n * set ACCUMULATES the previous consent with the new answer.\n */\n readonly incrementalConsent?: ProviderOAuth2IncrementalConsent;\n /**\n * How this vendor is asked for a refresh token, when it is an authorize-request PARAMETER rather than a scope (#2546).\n * See {@link ProviderOAuth2OfflineAccess}. Absent means the vendor needs no parameter: it issues a refresh token to\n * every authorization code, or asks for it through a scope the provider lists in `scopes` (Microsoft's\n * `offline_access`).\n */\n readonly offlineAccess?: ProviderOAuth2OfflineAccess;\n /**\n * How the token answer's `scope` lists what was granted, when it is not the specification's space-delimited list\n * (#2546). Absent means RFC 6749's encoding. Read only from the answer; the request is {@link authorizeScopesDelimiter}.\n */\n readonly grantedScopesDelimiter?: ProviderOAuth2ScopeListDelimiter;\n /**\n * How the AUTHORIZE request's `scope` must list the scopes asked for, when the vendor does not take the specification's\n * space-delimited list (#2661). Absent means RFC 6749's encoding, which most vendors accept even when their token\n * answer uses another (GitHub). Slack documents commas for the request: \"a comma-separated list of scopes, such as:\n * `scope=incoming-webhook,commands`\".\n * spec-cite: https://docs.slack.dev/authentication/installing-with-oauth — the authorize step, fetched 2026-10-06.\n */\n readonly authorizeScopesDelimiter?: ProviderOAuth2ScopeListDelimiter;\n /**\n * Whether the vendor accepts PKCE from this application's (confidential) client (#2661). Absent means\n * {@link ProviderOAuth2PkceSupport.S256}: the authorize request carries an S256 `code_challenge` and the code exchange its\n * `code_verifier`, which RFC 9700 recommends for every client and every vendor that ignores unknown parameters accepts.\n *\n * {@link ProviderOAuth2PkceSupport.NOT_ACCEPTED} is a vendor that REFUSES PKCE unless the application registered as a public\n * client: Slack answers `pkce_not_allowed` (\"The app is not allowed to use the PKCE flow\"), and turning PKCE on there\n * is irreversible (\"Enabling PKCE marks your app as a public client, which is is a one-way operation\"), drops the\n * client secret, and makes every refresh token expire in 30 days. The install then relies on `state`, the exact\n * `redirect_uri` and the client secret at the exchange, which is what a confidential client has without PKCE.\n * spec-cite: https://docs.slack.dev/reference/methods/oauth.v2.access — the `pkce_not_allowed` row, and\n * https://docs.slack.dev/authentication/using-pkce — the quoted sentence, both fetched 2026-10-06.\n */\n readonly pkce?: ProviderOAuth2PkceSupport;\n /**\n * Scopes a person cannot grant for themselves: only an administrator of the account can (#1671). Microsoft's\n * application permissions and its admin-restricted delegated permissions are the case — \"Application permissions\n * always require admin consent\", and a delegated permission that requires admin consent answers a user with \"an\n * 'unauthorized to consent' error\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — \"Admin Consent for\n * Application permissions\" and \"Admin Consent for Delegated Permissions\", fetched 2026-09-27.\n *\n * Never put in a re-authorization request a person is sent to: an operation needing one is refused with the\n * statement that an administrator must grant it, which is the only thing the person can act on.\n */\n readonly administratorConsentScopes?: readonly string[];\n /**\n * Env-var names resolving the APPLICATION's registration with the vendor. These are the two values\n * an operator genuinely does paste — they identify the integration, not the end user — and they\n * are separate from `apiKey.secretRef`, which names the minted access token.\n */\n readonly clientIdSecretRef?: string;\n readonly clientSecretSecretRef?: string;\n /**\n * Placeholders the endpoints above carry, which a CONNECTION must answer before either URL is a\n * URL at all — `{cloud}`, `{tenantId}`, `{region}`, `{domain}`. A PATH placeholder is answered freely;\n * a HOST or ORIGIN one only from {@link ProviderRestOAuth2.endpointHostAllowances}.\n *\n * Re-measured over the generated catalogue on 2026-09-12: of the 99 vendors that recovered both\n * endpoints, **20 carry at least one placeholder**, led by `{cloud}` (18 occurrences), `{location}`\n * (10) and `{tenantId}` (6). Microsoft's authorize URL is\n * `https://{cloud}/{tenantId}/oauth2/v2.0/authorize`, and no amount of application configuration\n * supplies those: which Azure cloud and which directory are facts about the ACCOUNT BEING\n * CONNECTED, known only to the person connecting it.\n *\n * So this is not decoration on the endpoint strings — it is the difference between a vendor that\n * can be connected and one that cannot. Without it the flow would build\n * `https://{cloud}/…/authorize`, send somebody to a hostname containing a brace, and fail in the\n * browser rather than at the point where the missing input could have been asked for.\n *\n * DERIVED from the endpoint strings rather than authored, so a vendor whose URL gains a\n * placeholder declares one the next time the batch runs. Absent — not empty — when the endpoints\n * are plain, which is the common case and must stay distinguishable from \"nobody has looked\".\n *\n * Deliberately NOT a judgement about which connections a provider admits. That is a recorded\n * decision in the catalogue record and is never read from a vendor's API surface; this is a\n * mechanical fact about a string.\n *\n * A placeholder filled from {@link ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL} or\n * {@link ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED} is NOT listed: nobody\n * connecting an account is asked for it, and a value they supply is refused.\n *\n * Derived from the {@link scopes} as well as the endpoints (#991): Dataverse's `{hostUrl}/.default`\n * names a fact about the account (its environment URL) that no endpoint carries, and a placeholder\n * only a scope mentions was otherwise never asked for — so the authorize request carried the literal\n * brace to the vendor.\n */\n readonly connectionParameters?: readonly string[];\n /**\n * How each placeholder that forms an endpoint's HOST or ORIGIN may be filled, keyed by\n * placeholder name. A host/origin placeholder with NO entry here cannot be filled at all, and the\n * connect flow refuses it.\n *\n * ## Why this exists: the token endpoint receives the application's client secret\n *\n * The exchange POSTs `client_id` and the APPLICATION's `client_secret` to the resolved `tokenUrl`.\n * Until 2026-09-12 every placeholder was answered from the connect-start request body, so where a\n * placeholder formed the HOST — Microsoft's `https://{cloud}/…/token`, Salesforce's\n * `https://{environment}/…`, Zoho's `https://accounts.{location}/…` — any user allowed to start a\n * connection chose where that secret was sent (`cloud=attacker.tld`). Measured over the generated\n * catalogue that day: 34 host-position occurrences across 17 vendors (9 Microsoft, 6 Zoho,\n * Salesforce, Workday), plus two whole-origin\n * placeholders (`gitea`, `bigin-by-zoho`) that were safe only because percent-encoding made them\n * undialable (#623).\n *\n * So a host/origin value is chosen from what the PROVIDER declares, never from what a caller\n * types. Path and query placeholders (`{tenantId}`, Workday's `{tenant}`) stay free and are\n * percent-encoded, because an encoded path segment cannot move the request to another host.\n *\n * Derived by the transposer where the source catalogue states a closed choice (a dropdown), and\n * otherwise taken from a recorded human decision in the catalogue record — never guessed.\n *\n * Also governs a placeholder that forms the ORIGIN of a SCOPE (`{hostUrl}/.default`, #991). One\n * allow-list per placeholder name, wherever the name forms a host: a scope's resource URI decides\n * which host the vendor mints the token for, which is the same question an endpoint's host answers.\n */\n readonly endpointHostAllowances?: Readonly<Record<string, ProviderOAuth2EndpointHostAllowance>>;\n /**\n * The closed set of values a WHOLE-SCOPE placeholder (`scopes: ['{permissions}']`) may be answered\n * with, keyed by placeholder name (#991).\n *\n * Each value is substituted verbatim as that scope entry and may hold several space-delimited scope\n * tokens — Microsoft Entra ID's permission presets are one such string each. Matched exactly, because\n * scope values are case-sensitive.\n * spec-cite: RFC 6749 §3.3 (the scope parameter is a list of space-delimited, case-sensitive strings).\n *\n * Closed rather than free because a scope value can itself name a resource\n * (`https://graph.microsoft.com/.default`), and a whole-scope placeholder with NO entry here cannot be\n * answered at all. Derived by the transposer from the source's own dropdown; never guessed.\n */\n readonly scopeValueAllowances?: Readonly<Record<string, ProviderOAuth2ScopeValueAllowance>>;\n /**\n * Dot-path, inside the TOKEN ENDPOINT'S JSON answer, to the vendor's own identifier for the account\n * that was just authorized — Slack's `team.id` (#333).\n *\n * Read once, at the exchange, into the stored grant's `accountRef`, so a person holding two\n * connections to one vendor can tell which is which and the grant audit names the account. Absent\n * means the vendor reports no account identity in its token answer (Asana's names only the user).\n *\n * Identity only: nothing looks a credential up by it, and an answer that lacks the path stores the\n * grant without it — a missing label is not a reason to discard an authorization the person just gave.\n */\n readonly accountRefResponsePath?: string;\n /**\n * Facts about the connected ACCOUNT that the vendor reports in its token answer and OPERATIONS consume,\n * keyed by the fact's name (#333, #1047) — Salesforce's `instance_url`, Pipedrive's `api_domain`.\n *\n * Captured at the authorization-code exchange and again at every refresh, into the credential row's\n * `connectionFacts` with provenance `REPORTED_BY_VENDOR`. Distinct from {@link accountRefResponsePath}:\n * that is a LABEL a person reads, sealed in the grant; these are values requests are built from, kept\n * client-readable beside the answers a person typed at connect.\n *\n * A fact that carries an `origin` allowance is an https ORIGIN operations may dial, so it decides where a\n * request carrying the credential goes. It is therefore admitted exactly as an ORIGIN placeholder is\n * ({@link endpointHostAllowances}): refused at connect when absent or outside the allowance, and\n * re-checked on every call that uses it.\n */\n readonly reportedAccountFacts?: Readonly<Record<string, ProviderOAuth2ReportedAccountFact>>;\n /**\n * Conditions the ID token of the sign-in that makes a connection must meet (#2663), every one of them, or the\n * connect is refused before anything is stored. See {@link ProviderOAuth2IdTokenRequirement}. Needs `openid` among\n * {@link scopes}.\n */\n readonly idTokenRequirements?: readonly ProviderOAuth2IdTokenRequirement[];\n /**\n * The issuer (`iss`) an ID token this client reads claims from must name (#2663 re-review I1). Required when it reads\n * any: an {@link idTokenRequirements} entry, or a {@link reportedAccountFacts} fact sourced from ID token claims.\n *\n * A claim is used only from a token that names this issuer, names this client as its only audience (`aud`), and has\n * not expired (`exp`): the checks OpenID Connect requires of a client. A token listing any other audience is refused\n * too, since a client trusts no audience but itself unless it says so, and nothing here says so. Only the signature\n * check may be replaced by TLS, which is the one this exchange relies on. A `{claim}` placeholder is filled from the token's own claims, for\n * an issuer that varies per tenant: Microsoft's multi-tenant `https://login.microsoftonline.com/{tid}/v2.0`.\n * spec-cite: OpenID Connect Core 1.0 §3.1.3.7, items 2 (\"MUST exactly match the value of the iss (issuer) Claim\"),\n * 3 (\"MUST validate that the aud (audience) Claim contains its client_id\"; \"The ID Token MUST be rejected if the ID\n * Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the\n * Client\"), 6 (TLS in place of the signature) and 9\n * (\"The current time MUST be before the time represented by the exp Claim\").\n */\n readonly idTokenIssuer?: string;\n /**\n * The RESOURCE AUDIENCES one grant of this client can mint tokens for, keyed by audience id (#1725), and the\n * HOSTS a token of each may be sent to.\n *\n * ## Why a grant needs more than one access token\n *\n * Microsoft issues an access token for ONE resource per request: the token redemption's scopes \"must all be from a\n * single resource\", and a refresh request spanning several resources returns \"a token for the resource specified\n * in the first scope\". A refresh token, though, is not tied to a resource: \"A client can use a refresh token to\n * acquire access tokens across any combination of resource and tenant where it has permission to do so.\" So a\n * connection spanning Graph and Dataverse keeps ONE refresh token and mints a token per audience from it.\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow — the `scope` rows\n * of \"Redeem a code for an access token\" and \"Refresh the access token\"; and\n * https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens — the opening section. Fetched 2026-09-27.\n *\n * ## Why the HOSTS are part of the declaration\n *\n * An access token is a bearer credential for its resource. Declaring which hosts receive a token of each audience is\n * what lets the engine attach a token only to a request bound for its own resource (the token-host binding), so an\n * operation — the base's own, a member's, or an augmentation's (#1672) — can never carry a Graph token to another\n * host.\n *\n * Absent means the provider mints one token for one resource, which is every provider except a connection base that\n * spans several. When present, {@link primaryAudience} names the audience the AUTHORIZATION grants — the resource of\n * the connect request's scopes — whose token is the one stored with the grant; every other audience's token is minted\n * from the refresh token on demand and cached, never stored.\n */\n readonly audiences?: Readonly<Record<string, ProviderRestOAuth2Audience>>;\n /** The audience the authorization itself grants — see {@link audiences}. Required when `audiences` is declared. */\n readonly primaryAudience?: string;\n /**\n * What this vendor's URI scopes NAME (#2546) — see {@link ProviderOAuth2ScopeMeaning}. Read only with `audiences`:\n * it decides which audience a scope belongs to. Absent means {@link ProviderOAuth2ScopeMeaning.RESOURCE}, Microsoft's\n * model, where `https://graph.microsoft.com/Mail.Send` is a permission ON the Graph resource.\n */\n readonly scopeMeaning?: ProviderOAuth2ScopeMeaning;\n}\n\n/** @wildo_source:part:start external-connectors.models.oauth2-audiences facet:layer:shared facet:family:provider facet:audience:app-developer */\n/** The placeholder a {@link ProviderRestOAuth2Audience.mintScopes} entry uses for the https origin of the request's host. */\nexport const PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER = '{audienceOrigin}';\n\n/** What a vendor's URI scopes name, which decides the audience a scope belongs to — see {@link ProviderRestOAuth2.scopeMeaning}. */\nexport enum ProviderOAuth2ScopeMeaning {\n /**\n * A URI scope names the RESOURCE a token is minted for: the scope without its last path segment\n * (`https://graph.microsoft.com/Mail.Send` is Graph's). Microsoft's model, and the default.\n */\n RESOURCE = 'RESOURCE',\n /**\n * A URI scope names a PERMISSION of the vendor's one grant, not a resource: Google's scopes are URIs on several hosts\n * (`https://www.googleapis.com/auth/gmail.readonly`, `https://mail.google.com/`, `https://spreadsheets.google.com/feeds`)\n * and every one is consented on the same grant, whose one token serves every Google API. So every scope belongs to the\n * PRIMARY audience, whatever host its URI names. Declared with a single audience only.\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/scopes — the scope tables, which list both forms\n * (fetched 2026-10-05).\n */\n PERMISSION = 'PERMISSION',\n}\n\n/** One resource audience of a connection's grant. See {@link ProviderRestOAuth2.audiences}. */\nexport interface ProviderRestOAuth2Audience {\n /**\n * The hosts a token of this audience may be sent to: exact lower-case hosts, and dotted suffixes admitting\n * `<dns-labels><suffix>` (never the bare suffix). Every host is https.\n */\n readonly hosts: {\n readonly values: readonly string[];\n readonly hostSuffixes?: readonly string[];\n };\n /**\n * The scopes that mint a token for this audience, all of ONE resource. An entry may begin with\n * {@link PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER} — the https origin of the request's own host, admitted by\n * {@link hosts} first — for a resource named per customer (a Dataverse environment's `<environment-url>/.default`).\n */\n readonly mintScopes: readonly string[];\n /**\n * The vendor's published limits for THIS resource (#1729) — see {@link ProviderRateBudgetDeclaration}. Per audience\n * because each resource is metered by its own service: Graph's limits say nothing about a Dataverse environment.\n */\n readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[];\n}\n\n/** The audience a request host belongs to, with its id — see {@link selectProviderOAuth2AudienceForHost}. */\nexport interface ProviderOAuth2AudienceSelection {\n readonly id: string;\n readonly audience: ProviderRestOAuth2Audience;\n readonly primary: boolean;\n}\n\n/** Whether `host` is admitted by one audience's hosts: an exact value, or `<labels><suffix>` for a declared suffix. */\nexport function providerOAuth2AudienceAdmitsHost(audience: ProviderRestOAuth2Audience, host: string): boolean {\n const candidate = host.toLowerCase();\n if (audience.hosts.values.some((value) => value.toLowerCase() === candidate)) return true;\n return (audience.hosts.hostSuffixes ?? []).some((suffix) => {\n const lowered = suffix.toLowerCase();\n if (!candidate.endsWith(lowered) || candidate.length === lowered.length) return false;\n return PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(candidate.slice(0, candidate.length - lowered.length));\n });\n}\n\n/**\n * The ONE audience whose hosts admit `host`, or `undefined` when none does. The declaration guarantees at most one\n * ({@link describeProviderOAuth2AudienceDefects} refuses overlapping hosts), so the answer never depends on order.\n */\nexport function selectProviderOAuth2AudienceForHost(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience'>,\n host: string,\n): ProviderOAuth2AudienceSelection | undefined {\n for (const [id, audience] of Object.entries(oauth2.audiences ?? {})) {\n if (providerOAuth2AudienceAdmitsHost(audience, host)) return { id, audience, primary: id === oauth2.primaryAudience };\n }\n return undefined;\n}\n\n/** Whether `audience` mints its token per request ORIGIN (a mint scope beginning {@link PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER}). */\nexport function providerOAuth2AudienceIsOriginScoped(audience: Pick<ProviderRestOAuth2Audience, 'mintScopes'>): boolean {\n return audience.mintScopes.some((scope) => scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER));\n}\n\n/**\n * The scopes that mint `audience`'s token for a request to `origin` — `{audienceOrigin}` replaced by that origin.\n * The caller has already admitted the origin's host through {@link selectProviderOAuth2AudienceForHost}; nothing a\n * caller supplies reaches a scope any other way.\n */\nexport function resolveProviderOAuth2AudienceMintScopes(audience: ProviderRestOAuth2Audience, origin: string): readonly string[] {\n return audience.mintScopes.map((scope) => (scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)\n ? `${origin}${scope.slice(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER.length)}`\n : scope));\n}\n\n/**\n * The declared audience a scope a connection might REQUEST names (#1671): its id, or `undefined` when the scope names a\n * resource none of the connection's audiences covers. Only meaningful when `audiences` is declared.\n *\n * A scope that is an absolute URI names the resource a token is minted for (`https://graph.microsoft.com/Mail.Send`,\n * `https://contoso.crm.dynamics.com/user_impersonation`): the resource of one of an audience's fixed mint scopes (the\n * mint scope without its last path segment), or — for a mint scope beginning `{audienceOrigin}` — an https origin whose\n * host the audience admits. A scope that is not an absolute URI (`offline_access`, `Files.Read`) names no resource, and\n * the vendor reads it against its default one, the PRIMARY audience: \"omitting the resource identifier in the `scope`\n * parameter defaults to Microsoft Graph\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — the note under\n * \"Admin Consent for Delegated Permissions\", fetched 2026-09-27.\n */\nexport function findProviderOAuth2ScopeAudience(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopeMeaning'>,\n scope: string,\n): string | undefined {\n const audiences = oauth2.audiences ?? {};\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(scope)) return oauth2.primaryAudience;\n // A vendor whose scopes name permissions of one grant (Google): every scope is the primary audience's (#2546).\n if (oauth2.scopeMeaning === ProviderOAuth2ScopeMeaning.PERMISSION) return oauth2.primaryAudience;\n // The https origin's host, read by the same shape the audiences declare (a DNS name, no port, no credentials) rather\n // than by a URL parser: this package runs in a browser-neutral program with no URL global, and a scope that is not\n // that shape names no host an audience could admit.\n const origin = /^https:\\/\\/([^/?#:@]+)(?:\\/|$)/i.exec(scope);\n const host = origin?.[1]?.toLowerCase();\n for (const [id, audience] of Object.entries(audiences)) {\n for (const mintScope of audience.mintScopes) {\n if (mintScope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)) {\n if (host !== undefined && PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host) && providerOAuth2AudienceAdmitsHost(audience, host)) return id;\n continue;\n }\n const resource = mintScope.slice(0, mintScope.lastIndexOf('/'));\n if (resource.length > 0 && scope.startsWith(`${resource}/`)) return id;\n }\n }\n return undefined;\n}\n\n/**\n * Whether a scope a connection might REQUEST names a resource among the connection's declared audiences (#1671) — see\n * {@link findProviderOAuth2ScopeAudience}. Asking a person to consent to it is asking them to let this application reach\n * THAT resource, so a scope from a member ref or an opted-in augmentation (#1672) is requestable only when it names one\n * the connection declares. `true` without looking further when the connection declares no audiences: it mints one token\n * for one resource and its scopes are the vendor's own vocabulary (Google's scope URIs name permissions, not resources).\n */\nexport function providerOAuth2ScopeNamesDeclaredAudience(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopeMeaning'>,\n scope: string,\n): boolean {\n if (oauth2.audiences === undefined) return true;\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(scope)) return true;\n return findProviderOAuth2ScopeAudience(oauth2, scope) !== undefined;\n}\n/**\n * Why an operation's {@link ProviderRestOperation.host} cannot be used on a provider whose REST binding is `contract`, or\n * `undefined` when it can (#2546). The token a call carries is chosen by the base URL's host, so the operation's host\n * must belong to that same audience: then the same token is valid there and nothing is minted for it.\n */\nexport function describeProviderRestOperationHostDefect(\n host: string,\n contract: { readonly baseUrl?: string; readonly oauth2?: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience'> },\n): string | undefined {\n if (host !== host.toLowerCase() || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host)) {\n return `host '${host}' is not a lower-case DNS name (no scheme, port, path or placeholder)`;\n }\n if (contract.oauth2?.audiences === undefined) {\n return `host '${host}' is declared on a provider whose connection declares no OAuth2 audiences, so its credential is valid only on the base URL's own host`;\n }\n // The base URL's https host, read without a URL parser (this package carries no DOM or Node types): the authority up to\n // the first '/', '?' or '#'. Anything that is not a plain DNS name there (a placeholder, userinfo, a port) has no fixed\n // audience and is refused.\n const authority = contract.baseUrl === undefined ? undefined : /^https:\\/\\/([^/?#]*)/i.exec(contract.baseUrl)?.[1]?.toLowerCase();\n const baseHost = authority !== undefined && PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(authority) ? authority : undefined;\n if (baseHost === undefined) return `host '${host}' is declared on a provider whose base URL is not one fixed https URL, so the audience its token belongs to is not known`;\n const baseAudience = selectProviderOAuth2AudienceForHost(contract.oauth2, baseHost);\n const hostAudience = selectProviderOAuth2AudienceForHost(contract.oauth2, host);\n if (hostAudience === undefined) return `host '${host}' is admitted by none of the connection's audiences (${Object.keys(contract.oauth2.audiences).join(', ')})`;\n if (baseAudience?.id !== hostAudience.id) {\n return `host '${host}' belongs to the audience '${hostAudience.id}', not to '${baseAudience?.id ?? '(none)'}' that the base URL's token is for; an operation on another audience is a provider of its own sharing the connection`;\n }\n // An audience whose token is minted per ORIGIN (`{audienceOrigin}/.default`, a Dataverse environment) gives the base\n // URL's origin its own token, which is not valid on another origin the same audience admits.\n if (host !== baseHost && providerOAuth2AudienceIsOriginScoped(hostAudience.audience)) {\n return `host '${host}' is another origin of the audience '${hostAudience.id}', whose token is minted for one origin at a time (the base URL's)`;\n }\n return undefined;\n}\n\n/** @wildo_source:part:end external-connectors.models.oauth2-audiences */\n\n/** @wildo_source:part:start external-connectors.models.oauth2-incremental-consent facet:layer:shared facet:family:provider facet:audience:app-developer */\n/**\n * How a vendor extends an existing delegated grant with more scopes — see {@link ProviderRestOAuth2.incrementalConsent}.\n */\nexport enum ProviderOAuth2IncrementalConsentForm {\n /**\n * The vendor keeps what the person already consented to, and a new authorization request naming only the added\n * scopes ADDS them: Microsoft's delegated permissions \"will be granted in addition to any other permissions that\n * were already granted for that app (i.e. incremental)\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — \"Incremental and\n * dynamic user consent\", fetched 2026-09-27.\n */\n ADDITIVE = 'ADDITIVE',\n /**\n * The vendor adds the new scopes to the existing grant only when the request carries `include_granted_scopes=true`:\n * \"If you set this parameter's value to `true` and the authorization request is granted, then the new access token\n * will also cover any scopes to which the user previously granted the application access.\"\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/web-server#incrementalAuth — the\n * `include_granted_scopes` parameter row, fetched 2026-09-27.\n */\n INCLUDE_GRANTED_SCOPES = 'INCLUDE_GRANTED_SCOPES',\n}\n\n/**\n * How a vendor is asked for a refresh token, when a scope does not do it — see {@link ProviderRestOAuth2.offlineAccess}.\n */\nexport enum ProviderOAuth2OfflineAccessForm {\n /**\n * Google: the authorize request carries `access_type=offline`, without which no refresh token is issued. The parameter\n * \"Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid\n * parameter values are `online`, which is the default value, and `offline`.\"; and \"the refresh token is only returned\n * if your application set the `access_type` parameter to `offline`\".\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/web-server — Step 1 (`access_type` row) and\n * Step 5, fetched 2026-10-05.\n *\n * Google issues the refresh token at the FIRST exchange for a consent, so a request that does not grow an existing grant\n * (a first connect, or a reconnect replacing a grant) also carries `prompt=consent`: a reconnect of an account that had\n * already consented would otherwise store a grant with no refresh token, which expires within the hour. A request that\n * grows a grant (`include_granted_scopes`) does not need it, because the stored grant keeps its refresh token.\n * Decided by practice: the established Google integrations ask for `access_type=offline` with `prompt=consent` for\n * exactly this reason.\n */\n ACCESS_TYPE_OFFLINE = 'ACCESS_TYPE_OFFLINE',\n}\n\n/** Whether a vendor takes PKCE from a confidential client. See {@link ProviderRestOAuth2.pkce}. */\nexport enum ProviderOAuth2PkceSupport {\n /** An S256 challenge on the authorize request and its verifier on the exchange: the default. */\n S256 = 'S256',\n /** The vendor refuses PKCE from a confidential client (Slack): neither is sent. */\n NOT_ACCEPTED = 'NOT_ACCEPTED',\n}\n\n/**\n * A `scope` list encoding that deviates from RFC 6749's space-delimited list, in either direction: the token answer\n * ({@link ProviderRestOAuth2.grantedScopesDelimiter}) or the authorize request ({@link ProviderRestOAuth2.authorizeScopesDelimiter}).\n * One vocabulary for both, because it is one question (how a vendor writes a list of scopes) asked of two messages.\n */\nexport enum ProviderOAuth2ScopeListDelimiter {\n /**\n * GitHub's token answer is `{\"access_token\":\"gho_…\",\"scope\":\"repo,gist\",\"token_type\":\"bearer\"}`, while its authorize\n * request takes \"A space-delimited list of scopes\". Slack's authorize URL takes \"a comma-separated list of scopes, such\n * as: `scope=incoming-webhook,commands`\".\n * spec-cite: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps — step 2's JSON\n * response example and step 1's `scope` row, fetched 2026-10-05; https://docs.slack.dev/authentication/installing-with-oauth\n * — the authorize step's `scope` parameter, fetched 2026-10-06.\n */\n COMMA = 'COMMA',\n}\n\n/**\n * The granted scopes a token answer's `scope` string names, read with the vendor's declared delimiter: whitespace (RFC\n * 6749 §5.1) when none is declared, a comma for {@link ProviderOAuth2ScopeListDelimiter.COMMA}.\n */\nexport function splitProviderOAuth2GrantedScopes(scope: string, delimiter: ProviderOAuth2ScopeListDelimiter | undefined): string[] {\n const separator = delimiter === ProviderOAuth2ScopeListDelimiter.COMMA ? /\\s*,\\s*/ : /\\s+/;\n return scope.split(separator).map((token) => token.trim()).filter((token) => token.length > 0);\n}\n\n/**\n * The authorize request's `scope` value for the scopes asked for, written with the vendor's declared delimiter: a single\n * space (RFC 6749 §3.3) when none is declared, a comma for {@link ProviderOAuth2ScopeListDelimiter.COMMA}.\n * spec-cite: RFC 6749 §3.3 (scope is expressed as a list of space-delimited, case-sensitive strings).\n */\nexport function joinProviderOAuth2RequestedScopes(scopes: readonly string[], delimiter: ProviderOAuth2ScopeListDelimiter | undefined): string {\n return scopes.join(delimiter === ProviderOAuth2ScopeListDelimiter.COMMA ? ',' : ' ');\n}\n\n/** A vendor's refresh-token request form. See {@link ProviderRestOAuth2.offlineAccess}. */\nexport interface ProviderOAuth2OfflineAccess {\n readonly form: ProviderOAuth2OfflineAccessForm;\n}\n\n/** A vendor's incremental-consent behaviour. See {@link ProviderRestOAuth2.incrementalConsent}. */\nexport interface ProviderOAuth2IncrementalConsent {\n readonly form: ProviderOAuth2IncrementalConsentForm;\n /**\n * Scopes every re-authorization request repeats beside the added ones — protocol scopes the answer needs rather than\n * permissions (Microsoft's `offline_access`, without which a code redemption returns no refresh token). Each must be\n * among the provider's declared {@link ProviderRestOAuth2.scopes}.\n */\n readonly restatedScopes?: readonly string[];\n}\n/** @wildo_source:part:end external-connectors.models.oauth2-incremental-consent */\n\n/**\n * Why a declared audience set cannot be honoured, or an empty list. Checked where a provider is composed, so a\n * malformed declaration never reaches a request:\n * - `primaryAudience` names no declared audience, or is missing while audiences are declared;\n * - the primary audience's mint scopes are not among the authorization's own `scopes` (its token is the one the\n * code redemption returns, so the authorization must be FOR that resource) or use the origin placeholder;\n * - an audience with no host or no mint scope, a suffix without a leading dot, an origin placeholder anywhere but\n * the start of a scope, or any other `{placeholder}` in a mint scope;\n * - two audiences admitting one host — a request host must select exactly one token.\n */\nexport function describeProviderOAuth2AudienceDefects(oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopes' | 'scopeMeaning'>): string[] {\n const audiences = oauth2.audiences;\n if (audiences === undefined) {\n return oauth2.primaryAudience === undefined ? [] : [`primaryAudience '${oauth2.primaryAudience}' is declared with no audiences`];\n }\n // Under PERMISSION every scope is the primary audience's, so a second audience could never be asked for (#2546).\n if (oauth2.scopeMeaning === ProviderOAuth2ScopeMeaning.PERMISSION && Object.keys(audiences).length > 1) {\n return [`scopeMeaning PERMISSION reads every scope as the primary audience's, so it is declared with one audience; this declares ${Object.keys(audiences).length}`];\n }\n const defects: string[] = [];\n const primary = oauth2.primaryAudience === undefined ? undefined : audiences[oauth2.primaryAudience];\n if (primary === undefined) defects.push(`primaryAudience '${String(oauth2.primaryAudience)}' names no declared audience`);\n for (const [id, audience] of Object.entries(audiences)) {\n if (audience.hosts.values.length === 0 && (audience.hosts.hostSuffixes ?? []).length === 0) defects.push(`audience '${id}' admits no host`);\n for (const suffix of audience.hosts.hostSuffixes ?? []) {\n if (!suffix.startsWith('.') || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(suffix.slice(1).toLowerCase())) defects.push(`audience '${id}' declares the host suffix '${suffix}', which is not '.<dns-name>'`);\n }\n for (const value of audience.hosts.values) {\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(value.toLowerCase())) defects.push(`audience '${id}' declares the host '${value}', which is not a DNS name`);\n }\n if (audience.mintScopes.length === 0) defects.push(`audience '${id}' declares no mint scope`);\n for (const scope of audience.mintScopes) {\n const rest = scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER) ? scope.slice(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER.length) : scope;\n if (rest.includes('{') || rest.includes('}')) defects.push(`audience '${id}' mint scope '${scope}' carries a placeholder other than a leading ${PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER}`);\n }\n }\n if (primary !== undefined) {\n for (const scope of primary.mintScopes) {\n if (scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)) defects.push(`the primary audience '${oauth2.primaryAudience}' mint scope '${scope}' names a per-request origin; the authorization must be for one fixed resource`);\n else if (!(oauth2.scopes ?? []).includes(scope)) defects.push(`the primary audience '${oauth2.primaryAudience}' mint scope '${scope}' is not among the authorization's own scopes`);\n }\n }\n const entries = Object.entries(audiences);\n for (let left = 0; left < entries.length; left += 1) {\n for (let right = left + 1; right < entries.length; right += 1) {\n const [leftId, leftAudience] = entries[left]!;\n const [rightId, rightAudience] = entries[right]!;\n const overlap = leftAudience.hosts.values.some((host) => providerOAuth2AudienceAdmitsHost(rightAudience, host))\n || rightAudience.hosts.values.some((host) => providerOAuth2AudienceAdmitsHost(leftAudience, host))\n || (leftAudience.hosts.hostSuffixes ?? []).some((suffix) => (rightAudience.hosts.hostSuffixes ?? []).some((other) => suffix.toLowerCase().endsWith(other.toLowerCase()) || other.toLowerCase().endsWith(suffix.toLowerCase())));\n if (overlap) defects.push(`audiences '${leftId}' and '${rightId}' admit a common host; a request host must select one token`);\n }\n }\n return defects;\n}\n\n/** Where in the token endpoint's answer a {@link ProviderOAuth2ReportedAccountFact} is read. */\nexport enum ProviderOAuth2ReportedFactSource {\n /** The token endpoint's JSON answer itself: Slack's `team.id`, Salesforce's `instance_url`. The default. */\n TOKEN_RESPONSE = 'token_response',\n /**\n * The claims of the `id_token` that answer carries (OpenID Connect): Microsoft's `tid`, the tenant the person signed\n * in to. Read without checking the token's signature, which the specification permits for an ID token received\n * directly from the token endpoint, because TLS has already authenticated who sent it. An answer carrying no\n * `id_token` reports no such fact. This is how a vendor's account identity becomes VENDOR-REPORTED when its token\n * answer names the account only inside the ID token (#2660).\n * spec-cite: OpenID Connect Core 1.0 §3.1.3.7, item 6.\n */\n ID_TOKEN_CLAIMS = 'id_token_claims',\n}\n\n/** One vendor-reported account fact. See {@link ProviderRestOAuth2.reportedAccountFacts}. */\nexport interface ProviderOAuth2ReportedAccountFact {\n /**\n * Dot-path inside the fact's {@link source}: the token endpoint's JSON answer by default, or the claims of its\n * `id_token`. A string or finite number there is the value.\n */\n readonly responsePath: string;\n /** Where {@link responsePath} is read. Omitted, the token endpoint's JSON answer. */\n readonly source?: ProviderOAuth2ReportedFactSource;\n /**\n * Present when the value is an https ORIGIN operations dial. The same DECLARED_VALUES vocabulary an\n * ORIGIN placeholder uses: exact origins, or `https://<dns-labels><suffix>` for each dotted suffix.\n */\n readonly origin?: Extract<ProviderOAuth2EndpointHostAllowance, { readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES }>;\n /**\n * `true` when the inbound receiver routes the vendor's deliveries to an organization by this fact: Slack's\n * `team.id`, the workspace an event comes from (#2660). Such a fact may name ONE organization only, so an\n * organization's connection reporting a value another organization's enabled connection already reports is\n * refused at connect, naming why. Routing fails closed on a value two organizations hold either way; the refusal is\n * what makes that a clear answer at connect instead of deliveries that silently route nowhere.\n */\n readonly routesInboundDeliveries?: true;\n}\n\n/** What a {@link ProviderOAuth2IdTokenRequirement} asks of the sign-in's ID token claims. */\nexport enum ProviderOAuth2IdTokenRequirementKind {\n /**\n * The claim is an array holding at least one of `values`, compared exactly. Microsoft's `wids`, the directory roles\n * the person holds: a tenant claim requires a role that administers the tenant.\n */\n CLAIM_CONTAINS_ANY = 'claim_contains_any',\n /**\n * When the claim is present, it equals `equalsClaim`. Microsoft's `idp` against `iss`: they differ for a guest, an\n * account another tenant authenticated, who speaks for nothing in this one.\n */\n CLAIM_EQUALS_CLAIM_WHEN_PRESENT = 'claim_equals_claim_when_present',\n}\n\n/**\n * One condition the ID token of the sign-in that MAKES a connection must meet, or the connect is refused before\n * anything is stored (#2663). For a connection whose reported fact routes deliveries (a Microsoft tenant), proving\n * the account is not enough: the person must also have the authority to bind it to an organization, and the vendor's\n * signed claims are where that authority is stated.\n *\n * Checked at the authorization-code exchange only. A refresh does not re-make the connection, and a vendor need not\n * return an ID token with it; a person whose authority lapsed is caught the next time the connection is made.\n */\nexport type ProviderOAuth2IdTokenRequirement =\n | { readonly kind: ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY; readonly claim: string; readonly values: readonly string[] }\n | { readonly kind: ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT; readonly claim: string; readonly equalsClaim: string };\n\n/** Why an ID token's claims may not be used (#2663 re-review I1). See {@link providerOAuth2IdTokenRejection}. */\nexport enum ProviderOAuth2IdTokenRejection {\n /** The token endpoint's answer carries no ID token, or not one whose payload is a JSON object. */\n ABSENT = 'absent',\n /** `iss` is not the declared issuer, with its placeholders filled from the token's claims. */\n ISSUER_MISMATCH = 'issuer_mismatch',\n /** `aud` does not name this client, or names another audience beside it. */\n AUDIENCE_MISMATCH = 'audience_mismatch',\n /** `exp` is missing, or not after the current time. */\n EXPIRED = 'expired',\n}\n\n/**\n * Why these ID token claims may not be used, or `undefined` when they may: the token names the declared issuer, this\n * client as its only audience, and an expiry still ahead. See {@link ProviderRestOAuth2.idTokenIssuer}.\n *\n * A placeholder of the issuer naming a claim the token does not carry as a non-empty string fails the issuer check:\n * an issuer that cannot be written cannot be matched.\n */\nexport function providerOAuth2IdTokenRejection(\n claims: Readonly<Record<string, unknown>> | undefined,\n expected: { readonly issuer: string; readonly clientId: string; readonly nowEpochSeconds: number },\n): ProviderOAuth2IdTokenRejection | undefined {\n if (claims === undefined) return ProviderOAuth2IdTokenRejection.ABSENT;\n const claimOf = (name: string): unknown => (Object.hasOwn(claims, name) ? claims[name] : undefined);\n let unfillable = false;\n const issuer = expected.issuer.replace(/\\{([^{}]+)\\}/g, (_placeholder, name: string) => {\n const value = claimOf(name);\n if (typeof value !== 'string' || value.length === 0) {\n unfillable = true;\n return '';\n }\n return value;\n });\n if (unfillable || claimOf('iss') !== issuer) return ProviderOAuth2IdTokenRejection.ISSUER_MISMATCH;\n const audience = claimOf('aud');\n const audiences: readonly unknown[] = Array.isArray(audience) ? audience : [audience];\n // Every listed audience must be this client: OpenID Connect rejects a token that lists \"additional audiences not\n // trusted by the Client\", and this client trusts none but itself (no declaration names another).\n if (audiences.length === 0 || !audiences.every((entry) => entry === expected.clientId)) return ProviderOAuth2IdTokenRejection.AUDIENCE_MISMATCH;\n const expiry = claimOf('exp');\n if (typeof expiry !== 'number' || !Number.isFinite(expiry) || expiry <= expected.nowEpochSeconds) return ProviderOAuth2IdTokenRejection.EXPIRED;\n return undefined;\n}\n\n/** Whether ID token claims meet one requirement. An absent ID token meets none. */\nexport function providerOAuth2IdTokenRequirementHolds(requirement: ProviderOAuth2IdTokenRequirement, claims: Readonly<Record<string, unknown>> | undefined): boolean {\n if (claims === undefined) return false;\n const value = Object.hasOwn(claims, requirement.claim) ? claims[requirement.claim] : undefined;\n switch (requirement.kind) {\n case ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY:\n return Array.isArray(value) && value.some((entry) => typeof entry === 'string' && requirement.values.includes(entry));\n case ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT: {\n if (value === undefined) return true;\n const other = Object.hasOwn(claims, requirement.equalsClaim) ? claims[requirement.equalsClaim] : undefined;\n return typeof value === 'string' && value === other;\n }\n default: {\n const unhandled: never = requirement;\n return unhandled;\n }\n }\n}\n\n/**\n * What makes a declaration of ID token requirements unusable: a requirement with no claim or no value, and any\n * requirement on a contract that does not ask for `openid`, without which \"the behavior is entirely unspecified\" and\n * no ID token is returned to read.\n * spec-cite: OpenID Connect Core 1.0 §3.1.2.1 — the `scope` parameter row (\"If the openid scope value is not present,\n * the behavior is entirely unspecified\").\n */\nexport function describeProviderOAuth2IdTokenRequirementDefects(oauth2: Pick<ProviderRestOAuth2, 'idTokenRequirements' | 'scopes' | 'reportedAccountFacts' | 'idTokenIssuer'>): string[] {\n const requirements = oauth2.idTokenRequirements ?? [];\n const readsIdTokenFacts = Object.values(oauth2.reportedAccountFacts ?? {}).some((fact) => fact.source === ProviderOAuth2ReportedFactSource.ID_TOKEN_CLAIMS);\n if (requirements.length === 0 && !readsIdTokenFacts) return [];\n const defects: string[] = [];\n if (!(oauth2.scopes ?? []).includes('openid')) defects.push('reads ID token claims without asking for the `openid` scope, so no ID token is returned to read them from');\n // OpenID Connect Core §3.1.3.7 item 2: a claim is used only from a token naming the expected issuer.\n if (oauth2.idTokenIssuer === undefined || oauth2.idTokenIssuer.trim().length === 0) {\n defects.push('reads ID token claims without declaring `idTokenIssuer`, the issuer a token must name before any of its claims is used');\n } else if (!oauth2.idTokenIssuer.startsWith('https://')) {\n defects.push(`declares \\`idTokenIssuer\\` ${JSON.stringify(oauth2.idTokenIssuer)}, which is not an https URL as an OpenID issuer identifier is`);\n }\n for (const [index, requirement] of requirements.entries()) {\n if (requirement.claim.trim().length === 0) defects.push(`ID token requirement ${index} names no claim`);\n if (requirement.kind === ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY && requirement.values.length === 0) {\n defects.push(`ID token requirement ${index} (${requirement.claim}) admits no value, so no sign-in could meet it`);\n }\n if (requirement.kind === ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT && requirement.equalsClaim.trim().length === 0) {\n defects.push(`ID token requirement ${index} (${requirement.claim}) names no claim to equal`);\n }\n }\n return defects;\n}\n\n/** The values a whole-scope placeholder admits. See {@link ProviderRestOAuth2.scopeValueAllowances}. */\nexport interface ProviderOAuth2ScopeValueAllowance {\n readonly values: readonly string[];\n /** Values the vendor's source offers and the catalogue declines, matched exactly. See {@link ProviderOAuth2UnsupportedValues}. */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n}\n\n/**\n * Values the vendor's OWN source offers for a placeholder and this catalogue deliberately does NOT admit, each mapped\n * to the reason (#1937). Keyed by the value as the source writes it.\n *\n * Not a second allow-list: the admitted set (`values`, `hosts`) alone decides what is admitted, and a value found\n * here is refused exactly as any other unadmitted value is (`VALUE_NOT_ADMITTED`, which also retires a STORED\n * connection that carries it). What this adds is the WHY. A person who chose, or a connection that stored, a value\n * the catalogue declined is told that it is unsupported and for what reason, instead of being handed a list of other\n * values as though they had made a typing mistake.\n *\n * The first entry is the US Government Microsoft clouds (`login.microsoftonline.us`, GCC High and DoD), declared out\n * of scope by product decision on 2026-09-29. The transposer writes these from the vendor record's declared\n * exclusion (`_code_archive/providers/catalogue-record/vendors/<vendor>.json` since #2019 archived the catalogue; a\n * registry provider adopted from it states them in its own module under `providers-registry/<ref>/`), so reversing a\n * decision is record edits and a regeneration, never an engine change. How many edits depends on what the decline also removed: for the US\n * Government clouds, three (the catalogue README lists them).\n */\nexport type ProviderOAuth2UnsupportedValues = Readonly<Record<string, string>>;\n\n/** How a placeholder's value is compared with a declared one. */\nexport enum ProviderOAuth2ValueComparison {\n /** A host or an origin: DNS names compare case-insensitively. spec-cite: RFC 4343 §2. */\n CASE_INSENSITIVE = 'CASE_INSENSITIVE',\n /** A scope value: scope strings are case-sensitive. spec-cite: RFC 6749 §3.3. */\n EXACT = 'EXACT',\n}\n\n/**\n * The declared reason a value is unsupported, or `undefined` when it is not declared unsupported. Compared as the\n * placeholder's values are: case-insensitively for a host or origin, exactly for a scope value.\n */\nexport function findProviderOAuth2UnsupportedValueReason(\n unsupportedValues: ProviderOAuth2UnsupportedValues | undefined,\n value: string,\n comparison: ProviderOAuth2ValueComparison,\n): string | undefined {\n if (unsupportedValues === undefined) return undefined;\n const key = comparison === ProviderOAuth2ValueComparison.EXACT\n ? (Object.hasOwn(unsupportedValues, value) ? value : undefined)\n : Object.keys(unsupportedValues).find((candidate) => candidate.toLowerCase() === value.toLowerCase());\n return key === undefined ? undefined : unsupportedValues[key];\n}\n\n/**\n * Why a declared unsupported-value map contradicts the admitted set it sits beside, or an empty list: a value both\n * admitted and declined would make the refusal reason a lie, and a declined value with no reason says nothing.\n */\nfunction describeProviderOAuth2UnsupportedValueDefects(\n unsupportedValues: ProviderOAuth2UnsupportedValues | undefined,\n admitted: readonly string[],\n comparison: ProviderOAuth2ValueComparison,\n): readonly string[] {\n if (unsupportedValues === undefined) return [];\n const defects: string[] = [];\n const normalise = (value: string): string => (comparison === ProviderOAuth2ValueComparison.EXACT ? value : value.toLowerCase());\n const admittedSet = new Set(admitted.map(normalise));\n for (const [value, reason] of Object.entries(unsupportedValues)) {\n if (admittedSet.has(normalise(value))) defects.push(`'${value}' is both admitted and declared unsupported`);\n if (typeof reason !== 'string' || reason.trim() === '') defects.push(`unsupported value '${value}' states no reason`);\n }\n return defects;\n}\n\n/**\n * Where a `{placeholder}` sits inside one OAuth2 SCOPE entry. See {@link classifyProviderOAuth2ScopePlaceholder}.\n *\n * Deliberately not {@link ProviderOAuth2EndpointPlaceholderPosition}: a scope is not a URL, and the\n * endpoint scan would call `{permissions}` an ORIGIN (it begins the string and nothing follows it).\n */\nexport enum ProviderOAuth2ScopePlaceholderPosition {\n /**\n * The placeholder begins the scope and is followed by `/` — `{hostUrl}/.default`. Its value is an\n * https ORIGIN, admitted only within {@link ProviderRestOAuth2.endpointHostAllowances}.\n */\n ORIGIN = 'ORIGIN',\n /**\n * The placeholder is the entire scope entry — `{permissions}`. Its value is one of\n * {@link ProviderRestOAuth2.scopeValueAllowances}.\n */\n WHOLE_SCOPE = 'WHOLE_SCOPE',\n}\n\n/** Why a scope entry cannot be resolved safely, whatever is supplied. See {@link findProviderOAuth2ScopeTemplateDefects}. */\nexport enum ProviderOAuth2ScopeTemplateDefect {\n /**\n * A placeholder sits anywhere except at the start of the scope followed by `/` or the end —\n * `api://{x}/.default`, `{x}.default`, `openid {x}`. Such a value would be concatenated with text\n * around it into a resource or scope nobody declared.\n */\n UNSUPPORTED_PLACEHOLDER_POSITION = 'UNSUPPORTED_PLACEHOLDER_POSITION',\n /** More than one placeholder in one scope entry: each value validated alone can compose an undeclared one. */\n SEVERAL_PLACEHOLDERS = 'SEVERAL_PLACEHOLDERS',\n /** A `{` or `}` that is not part of a well-formed placeholder: a vendor can never grant a scope carrying one. */\n STRAY_BRACE = 'STRAY_BRACE',\n}\n\n/** One `{placeholder}` in a scope entry. */\nexport interface ProviderOAuth2ScopePlaceholderOccurrence {\n readonly name: string;\n readonly position: ProviderOAuth2ScopePlaceholderPosition;\n /** The whole `{name}` token, for substitution. */\n readonly token: string;\n}\n\n/**\n * The defects that make a scope entry unsafe to resolve, or an empty list. Shared by the runtime (which\n * refuses) and the transposer (which refuses to emit), so neither admits a shape the other rejects.\n */\nexport function findProviderOAuth2ScopeTemplateDefects(scope: string): readonly ProviderOAuth2ScopeTemplateDefect[] {\n const occurrences = [...scope.matchAll(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN)];\n const withoutPlaceholders = scope.replace(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN, '');\n const defects: ProviderOAuth2ScopeTemplateDefect[] = [];\n if (withoutPlaceholders.includes('{') || withoutPlaceholders.includes('}')) defects.push(ProviderOAuth2ScopeTemplateDefect.STRAY_BRACE);\n if (occurrences.length > 1) defects.push(ProviderOAuth2ScopeTemplateDefect.SEVERAL_PLACEHOLDERS);\n const first = occurrences[0];\n if (first !== undefined) {\n const next = scope.charAt((first.index ?? 0) + first[0].length);\n if ((first.index ?? 0) !== 0 || (next !== '' && next !== '/')) defects.push(ProviderOAuth2ScopeTemplateDefect.UNSUPPORTED_PLACEHOLDER_POSITION);\n }\n return defects;\n}\n\n/**\n * Classify the one placeholder a scope entry may carry, or `undefined` when it carries none.\n *\n * ONE function, shared by the transposer and the runtime, like its endpoint counterpart. Meaningful only\n * for a scope with no {@link findProviderOAuth2ScopeTemplateDefects}; every consumer refuses those first.\n */\nexport function classifyProviderOAuth2ScopePlaceholder(scope: string): ProviderOAuth2ScopePlaceholderOccurrence | undefined {\n const match = /^\\{([A-Za-z_][A-Za-z0-9_]*)\\}/.exec(scope);\n if (match === null) return undefined;\n return {\n name: match[1]!,\n position: match[0].length === scope.length ? ProviderOAuth2ScopePlaceholderPosition.WHOLE_SCOPE : ProviderOAuth2ScopePlaceholderPosition.ORIGIN,\n token: match[0],\n };\n}\n\n/**\n * One scope token: printable ASCII except space, `\"` and backslash.\n * spec-cite: RFC 6749 §3.3 (scope-token = 1*( %x21 / %x23-5B / %x5D-7E )).\n * Braces are additionally refused: a value carrying one would read as a placeholder nobody resolves.\n */\nconst PROVIDER_OAUTH2_SCOPE_TOKEN_PATTERN = /^[\\x21\\x23-\\x5B\\x5D-\\x7A\\x7C\\x7E]+$/;\n\n/**\n * Why a declared whole-scope allowance cannot be applied, or an empty list. Enforced at generation so a\n * broken set refuses the batch; the runtime matches exactly and never trusts a value it did not declare.\n */\nexport function describeProviderOAuth2ScopeValueAllowanceDefects(allowance: ProviderOAuth2ScopeValueAllowance): readonly string[] {\n const defects: string[] = [];\n if (!Array.isArray(allowance.values) || allowance.values.length === 0) return ['a scope value allowance admits nothing'];\n for (const value of allowance.values) {\n const tokens = typeof value === 'string' ? value.split(' ') : [];\n if (typeof value !== 'string' || value.length === 0 || !tokens.every((token) => PROVIDER_OAUTH2_SCOPE_TOKEN_PATTERN.test(token))) {\n defects.push(`'${String(value)}' is not a space-delimited list of scope tokens`);\n }\n }\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, allowance.values, ProviderOAuth2ValueComparison.EXACT));\n return defects;\n}\n\n/**\n * Where a `{placeholder}` sits inside an OAuth2 endpoint template — the classification the host\n * allow-list keys on. See {@link classifyProviderOAuth2EndpointPlaceholders}.\n */\nexport enum ProviderOAuth2EndpointPlaceholderPosition {\n /**\n * The placeholder BEGINS the template, so its value is the whole scheme + authority (+ any path\n * prefix): `{baseUrl}/login/oauth/authorize`. The most dangerous position — the value names the\n * scheme as well as the host.\n */\n ORIGIN = 'ORIGIN',\n /**\n * The placeholder sits between `://` and the first `/`, `?` or `#` after it:\n * `https://{cloud}/common/…`, `https://accounts.{location}/…`. Its value decides which host\n * receives the request.\n */\n HOST = 'HOST',\n /** Anywhere after the authority. Percent-encoded, so it cannot move the request to another host. */\n PATH_OR_QUERY = 'PATH_OR_QUERY',\n}\n\n/** How a host- or origin-forming placeholder may be filled. See {@link ProviderRestOAuth2.endpointHostAllowances}. */\nexport enum ProviderOAuth2EndpointHostAllowanceKind {\n /**\n * Chosen at connect time from values the provider DECLARES — Microsoft's commercial login cloud,\n * Zoho's data centres. A value outside the set is refused; a declared value is substituted\n * verbatim (it is a hostname or origin, not a path segment to encode).\n *\n * `hostSuffixes` additionally admits `<dns-label>(.<dns-label>)*` followed by one of the suffixes,\n * for a vendor whose per-customer host is a subdomain it controls (Salesforce My Domain,\n * `<name>.my.salesforce.com`). On a HOST placeholder a suffix applies only when the placeholder is\n * the WHOLE host. On an ORIGIN placeholder it admits exactly `https://<dns-labels><suffix>` — the\n * scheme fixed to https, no port, path, userinfo, query or fragment — which is what a per-customer\n * origin such as a Dataverse environment URL (`https://<org>.crm4.dynamics.com`, #991) needs.\n */\n DECLARED_VALUES = 'DECLARED_VALUES',\n /**\n * Filled from the DEPLOYMENT's configured base URL for this provider — the REST contract's\n * `baseUrl`, or the environment variable its `baseUrlEnvVarName` names. For a self-hosted vendor\n * (Gitea) the operator names the instance once; a person connecting an account is never asked, and\n * a value they supply is refused. Admitted in the ORIGIN position only.\n */\n DEPLOYMENT_BASE_URL = 'DEPLOYMENT_BASE_URL',\n /**\n * Filled from a deployment environment variable dedicated to THIS placeholder, named by the\n * allowance's `envVarName` (#992). For a vendor whose endpoints sit on more than one per-tenant host\n * — Workday's `https://{authHost}/…/authorize` and `https://{apiHost}/…/token` — one base URL cannot\n * name both, so each host is its own operator setting (`WORKDAY_AUTH_HOST`, `WORKDAY_API_HOST`).\n *\n * Like DEPLOYMENT_BASE_URL, never asked of a person connecting, and a value they supply is refused.\n * The trade is explicit: the application serves the one vendor tenant (data centre) the operator\n * names. Admitted on a HOST placeholder that is the whole host, with a DNS-name value.\n */\n DEPLOYMENT_CONFIGURED = 'DEPLOYMENT_CONFIGURED',\n /**\n * DERIVED from another connect-time answer through a declared table (#1937): Microsoft Graph's operation host follows\n * the login cloud the connection chose (`login.microsoftonline.com` → `graph.microsoft.com`), because a token minted by\n * one national cloud is not accepted by another. The Microsoft source also maps the US Government login cloud; that\n * row is declined (`unsupportedValues`), because US Government clouds are out of scope (decision of 2026-09-29).\n *\n * Never asked of a person and never taken from a request: the value is looked up from the ANSWER the connection\n * stored for `answer`, and an answer the table does not name is refused. `whenUnanswered` is the host for a connection\n * that answered nothing (the application's own pasted credential); absent, such a connection is refused. The table is\n * the allow-list, so no other host can result. Admitted on a HOST placeholder that is the whole host.\n *\n * spec-cite: https://learn.microsoft.com/en-us/graph/deployments — \"Access tokens acquired for a national cloud\n * deployment are not interchangeable with those acquired for the global service or any other national cloud.\"\n */\n DERIVED_FROM_CONNECTION_ANSWER = 'DERIVED_FROM_CONNECTION_ANSWER',\n}\n\nexport type ProviderOAuth2EndpointHostAllowance =\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES;\n /** Exact admitted values, compared case-insensitively. A hostname for HOST, an origin for ORIGIN. */\n readonly values: readonly string[];\n /**\n * A whole HOST, or an ORIGIN (admitting `https://<labels><suffix>` only). Each MUST begin with `.`,\n * so `evilmy.salesforce.com` never matches `.my.salesforce.com`.\n */\n readonly hostSuffixes?: readonly string[];\n /**\n * ORIGIN only: an admitted value must ALSO have the same origin as the deployment's configured base\n * URL (the REST contract's `baseUrl` / `baseUrlEnvVarName`) (#991 review F4).\n *\n * For a vendor whose token is minted for a per-customer environment and whose operations dial the\n * operator's configured instance — Dataverse mints for the scope's `{hostUrl}` while operations go to\n * `MICROSOFT_DYNAMICS_CRM_BASE_URL` — a connection naming another environment would hold a token that\n * fails every call. So the two are required to agree at connect, and an unset base URL refuses the\n * connect as a deployment gap rather than minting a token nothing can use.\n */\n readonly originMatchesDeploymentBaseUrl?: true;\n /** Values the vendor's source offers and the catalogue declines, with the reason. See {@link ProviderOAuth2UnsupportedValues}. */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED;\n /**\n * The deployment environment variable holding the host — derived by the transposer as\n * `<PROVIDER_ENV_PREFIX>_<PLACEHOLDER_IN_SCREAMING_SNAKE>` and declared as a REGISTRATION secret slot,\n * without which the runtime environment builder would strip it.\n */\n readonly envVarName: string;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DERIVED_FROM_CONNECTION_ANSWER;\n /** The connect-time answer the host is derived from (`cloud`) — itself a placeholder of the same provider. */\n readonly answer: string;\n /** Per answer value (compared case-insensitively), the host it selects. DNS names. */\n readonly hosts: Readonly<Record<string, string>>;\n /** The host when the connection answered nothing; absent, an unanswered connection is refused. */\n readonly whenUnanswered?: string;\n /**\n * ANSWER values the vendor's source maps to a host and the catalogue declines, with the reason — so a stored\n * connection carrying one is refused at use naming why. See {@link ProviderOAuth2UnsupportedValues}.\n */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL;\n /**\n * A path the configured base URL carries and the OAuth2 endpoints do NOT — stripped before\n * substitution, and REQUIRED to be present. Gitea's operation base is `<instance>/api/v1` while\n * its OAuth2 endpoints hang off `<instance>`; stripping keeps an instance served under a sub-path\n * correct, where taking only the origin would drop it.\n */\n readonly baseUrlPathSuffix?: string;\n };\n\n/** One `{placeholder}` occurrence in an OAuth2 endpoint template. */\nexport interface ProviderOAuth2EndpointPlaceholderOccurrence {\n readonly name: string;\n readonly position: ProviderOAuth2EndpointPlaceholderPosition;\n /** Offset of the opening brace in the template. */\n readonly index: number;\n /** The whole `{name}` token, for substitution. */\n readonly token: string;\n /**\n * HOST only: the token is the ENTIRE authority (`https://{cloud}/…`), as opposed to one part of it\n * (`https://accounts.{location}/…`). A declared host SUFFIX is only meaningful for a whole host — on a\n * partial one it would be concatenated with the text around it and admit a host nobody declared.\n */\n readonly occupiesWholeHost: boolean;\n /**\n * HOST only: when the token OPENS the authority and is followed by literal text up to the end of the authority —\n * `https://{subdomain}.zendesk.com/…` → `.zendesk.com` — that literal text (#1015). A declared host SUFFIX equal to it\n * bounds the composed host exactly as it bounds a whole host: the value is DNS labels, the template's own literal\n * supplies the suffix, and `<labels>.zendesk.com` is the only shape that can result. Absent for a whole host, for a\n * token that does not open the host (`accounts.{location}`), and for an ORIGIN or PATH token.\n */\n readonly literalHostSuffix?: string;\n}\n\n/**\n * Why an OAuth2 endpoint TEMPLATE cannot be resolved safely, whatever values are supplied.\n * See {@link findProviderOAuth2EndpointTemplateDefects}.\n */\nexport enum ProviderOAuth2EndpointTemplateDefect {\n /**\n * The template neither begins `http://` / `https://` nor begins with a placeholder. The WHATWG URL\n * parser reads `https:/{h}/t`, `https:{h}/t` and `https:` + two backslashes + `{h}/t` as `https://h/t`, so a string scan\n * for `://` would call `{h}` a PATH placeholder, encode it (a hostname survives encoding untouched),\n * and send the request — and the client secret — to whatever a caller typed.\n */\n NOT_AN_ABSOLUTE_TEMPLATE = 'NOT_AN_ABSOLUTE_TEMPLATE',\n /**\n * An ORIGIN placeholder is followed by something other than `/`, `?`, `#` or the end —\n * `{baseUrl}.evil.test/…`, `{baseUrl}:8443/…`, `{a}{b}/…`. The text after it would extend the host\n * the origin value names.\n */\n ORIGIN_NOT_TERMINATED = 'ORIGIN_NOT_TERMINATED',\n /**\n * One authority carries more than one placeholder (`https://{a}{b}/…`, `https://{sub}.{domain}/…`).\n * Each value validated alone can still compose a host no declaration admits.\n */\n SEVERAL_PLACEHOLDERS_IN_AUTHORITY = 'SEVERAL_PLACEHOLDERS_IN_AUTHORITY',\n /**\n * The authority after `://` is empty, begins with `/` or a backslash, or carries a backslash or `@`\n * before the first `/`, `?` or `#`. The parser skips extra slashes (`https:///{h}/t` dials `{h}` as the\n * HOST, while the `://` scan sees an empty authority and calls `{h}` a PATH), reads a backslash as a\n * path separator, and\n * reads text before `@` as userinfo — each makes the scan and the parser disagree about the host.\n */\n MALFORMED_AUTHORITY = 'MALFORMED_AUTHORITY',\n}\n\n/**\n * A DNS name: one or more LDH labels, lower-case (callers lower-case first).\n * spec-cite: RFC 1123 §2.1 (a label may begin with a digit) and RFC 1035 §2.3.1 (letters, digits,\n * hyphen; 63 octets per label).\n */\nexport const PROVIDER_OAUTH2_DNS_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/;\n\n/**\n * Why a DECLARED host allowance cannot be applied where its placeholder sits — the position rules the\n * transposer enforces at GENERATION time, so a broken declaration refuses the batch instead of being\n * emitted and refused at every connect. Empty when the allowance is sound.\n *\n * The runtime resolver refuses each of these too; this exists so they are caught where a human is\n * already looking at a diff rather than where a person is pressing Connect.\n */\nexport function describeProviderOAuth2EndpointHostAllowanceDefects(\n placeholder: { readonly position: ProviderOAuth2EndpointPlaceholderPosition; readonly occupiesWholeHost: boolean; readonly literalHostSuffix?: string },\n allowance: ProviderOAuth2EndpointHostAllowance,\n): readonly string[] {\n const defects: string[] = [];\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.PATH_OR_QUERY) {\n return ['a PATH or QUERY placeholder takes no host allowance'];\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n defects.push('DEPLOYMENT_BASE_URL fills an ORIGIN only, and this placeholder does not begin its endpoint');\n }\n if (allowance.baseUrlPathSuffix !== undefined && !/^\\/[^?#]*[^/?#]$/.test(allowance.baseUrlPathSuffix)) {\n defects.push(`baseUrlPathSuffix '${allowance.baseUrlPathSuffix}' must begin with '/' and name a path (no trailing '/', query or fragment)`);\n }\n return defects;\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DERIVED_FROM_CONNECTION_ANSWER) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.HOST || !placeholder.occupiesWholeHost) {\n defects.push('DERIVED_FROM_CONNECTION_ANSWER fills a WHOLE HOST only, and this placeholder is not one');\n }\n if (typeof allowance.answer !== 'string' || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(allowance.answer)) {\n defects.push(`answer '${String(allowance.answer)}' is not a placeholder name`);\n }\n const hosts = Object.values(allowance.hosts ?? {});\n if (hosts.length === 0) defects.push('DERIVED_FROM_CONNECTION_ANSWER maps no answer to a host, which admits nothing');\n for (const host of [...hosts, ...(allowance.whenUnanswered === undefined ? [] : [allowance.whenUnanswered])]) {\n if (typeof host !== 'string' || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host.toLowerCase())) defects.push(`'${String(host)}' is not a DNS name`);\n }\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, Object.keys(allowance.hosts ?? {}), ProviderOAuth2ValueComparison.CASE_INSENSITIVE));\n return defects;\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.HOST || !placeholder.occupiesWholeHost) {\n defects.push('DEPLOYMENT_CONFIGURED fills a WHOLE HOST only, and this placeholder is not one');\n }\n if (typeof allowance.envVarName !== 'string' || !/^[A-Z][A-Z0-9_]*$/.test(allowance.envVarName)) {\n defects.push(`envVarName '${String(allowance.envVarName)}' is not an upper-case environment variable name`);\n }\n return defects;\n }\n if (allowance.originMatchesDeploymentBaseUrl === true && placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n defects.push('originMatchesDeploymentBaseUrl applies to an ORIGIN only, and this placeholder is not one');\n }\n if (allowance.values.length === 0 && (allowance.hostSuffixes ?? []).length === 0) {\n defects.push('DECLARED_VALUES admits nothing');\n }\n for (const value of allowance.values) {\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n // Matched as text, not with `URL`: this package compiles without a DOM or Node lib. A lower-case\n // `https://` + DNS name, with nothing after the host but an optional port, is exactly an origin as\n // `URL#origin` would print it back.\n const match = /^https:\\/\\/([^:/?#@]+)(?::\\d{1,5})?$/.exec(value);\n if (match === null || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(match[1]!)) {\n defects.push(`'${value}' is not an https origin (scheme and lower-case host only)`);\n }\n } else if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(value.toLowerCase())) {\n defects.push(`'${value}' is not a DNS name`);\n }\n }\n for (const suffix of allowance.hostSuffixes ?? []) {\n // An ORIGIN is a whole authority by construction (the scheme is then fixed to https); a HOST\n // placeholder qualifies only when nothing surrounds it inside the authority.\n // A placeholder that OPENS the host qualifies too, but only for the ONE suffix the template itself writes after\n // it (#1015): any other suffix would be concatenated with that literal into a host nobody declared.\n const opensHostWithThisSuffix = placeholder.literalHostSuffix !== undefined && placeholder.literalHostSuffix.toLowerCase() === suffix.toLowerCase();\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.HOST && !placeholder.occupiesWholeHost && !opensHostWithThisSuffix) {\n defects.push(`host suffix '${suffix}' on a placeholder that is not the whole host`);\n continue;\n }\n const labels = suffix.startsWith('.') ? suffix.slice(1) : '';\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(labels.toLowerCase()) || !labels.includes('.')) {\n defects.push(`host suffix '${suffix}' must begin with '.' and name at least two DNS labels (a bare '.com' admits every host under a TLD)`);\n }\n }\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, allowance.values, ProviderOAuth2ValueComparison.CASE_INSENSITIVE));\n for (const declined of Object.keys(allowance.unsupportedValues ?? {})) {\n // A declined value a declared SUFFIX would still admit is admitted, whatever the reason says.\n const coveringSuffix = (allowance.hostSuffixes ?? []).find((suffix) => declined.toLowerCase().endsWith(suffix.toLowerCase()));\n if (coveringSuffix !== undefined) defects.push(`'${declined}' is declared unsupported but the host suffix '${coveringSuffix}' admits it`);\n }\n return defects;\n}\n\n/**\n * The defects that make a template unsafe to resolve, or an empty list. Shared by the runtime (which\n * refuses) and the transposer (which refuses to emit), so neither can admit a shape the other rejects.\n */\nexport function findProviderOAuth2EndpointTemplateDefects(template: string): readonly ProviderOAuth2EndpointTemplateDefect[] {\n const defects: ProviderOAuth2EndpointTemplateDefect[] = [];\n const leadingPlaceholder = /^\\{[A-Za-z_][A-Za-z0-9_]*\\}/.exec(template);\n if (!/^https?:\\/\\//i.test(template) && leadingPlaceholder === null) {\n return [ProviderOAuth2EndpointTemplateDefect.NOT_AN_ABSOLUTE_TEMPLATE];\n }\n if (leadingPlaceholder !== null) {\n const next = template.charAt(leadingPlaceholder[0].length);\n if (next !== '' && next !== '/' && next !== '?' && next !== '#') defects.push(ProviderOAuth2EndpointTemplateDefect.ORIGIN_NOT_TERMINATED);\n } else {\n const afterScheme = template.slice(template.indexOf('://') + 3);\n const authorityEnd = afterScheme.search(/[/?#]/);\n const authority = authorityEnd < 0 ? afterScheme : afterScheme.slice(0, authorityEnd);\n if (authority === '' || authority.includes('\\\\') || authority.includes('@')) {\n defects.push(ProviderOAuth2EndpointTemplateDefect.MALFORMED_AUTHORITY);\n return defects;\n }\n const hostPlaceholders = classifyProviderOAuth2EndpointPlaceholders(template)\n .filter((occurrence) => occurrence.position === ProviderOAuth2EndpointPlaceholderPosition.HOST);\n if (hostPlaceholders.length > 1) defects.push(ProviderOAuth2EndpointTemplateDefect.SEVERAL_PLACEHOLDERS_IN_AUTHORITY);\n }\n return defects;\n}\n\n/** The placeholder syntax an endpoint template uses — the same braces the operation path templates use. */\nexport const PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN = /\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g;\n\n/**\n * Classify every placeholder in an OAuth2 endpoint template by the URL component it forms.\n *\n * ONE function, shared by the transposer (which decides which placeholders need an allowance) and\n * the runtime (which refuses an unallowed one), so the two cannot disagree about what a host is.\n *\n * Deliberately a string scan, not a URL parse: a template whose host is still `{cloud}` is not a\n * parseable URL, which is exactly the population this classifies.\n *\n * - offset 0 → {@link ProviderOAuth2EndpointPlaceholderPosition.ORIGIN};\n * - between the first `://` and the next `/`, `?` or `#` → HOST;\n * - otherwise → PATH_OR_QUERY.\n *\n * This classification is only meaningful for a template with no\n * {@link findProviderOAuth2EndpointTemplateDefects}: a template that does not begin `http(s)://` or a\n * placeholder has no authority this scan can find, and every consumer must refuse it FIRST rather than\n * trust the PATH_OR_QUERY answer it would get here.\n */\nexport function classifyProviderOAuth2EndpointPlaceholders(template: string): readonly ProviderOAuth2EndpointPlaceholderOccurrence[] {\n const schemeSeparator = template.indexOf('://');\n let authorityEnd = -1;\n if (schemeSeparator >= 0) {\n const rest = template.slice(schemeSeparator + 3);\n const end = rest.search(/[/?#]/);\n authorityEnd = end < 0 ? template.length : schemeSeparator + 3 + end;\n }\n const occurrences: ProviderOAuth2EndpointPlaceholderOccurrence[] = [];\n for (const match of template.matchAll(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN)) {\n const index = match.index ?? 0;\n const position = index === 0\n ? ProviderOAuth2EndpointPlaceholderPosition.ORIGIN\n : schemeSeparator >= 0 && index > schemeSeparator && index < authorityEnd\n ? ProviderOAuth2EndpointPlaceholderPosition.HOST\n : ProviderOAuth2EndpointPlaceholderPosition.PATH_OR_QUERY;\n const occupiesWholeHost = position === ProviderOAuth2EndpointPlaceholderPosition.HOST\n && index === schemeSeparator + 3\n && index + match[0].length === authorityEnd;\n const followingLiteral = position === ProviderOAuth2EndpointPlaceholderPosition.HOST && !occupiesWholeHost && index === schemeSeparator + 3\n ? template.slice(index + match[0].length, authorityEnd)\n : undefined;\n // Only a PURELY literal remainder qualifies: a second placeholder in the authority is refused as malformed anyway.\n const literalHostSuffix = followingLiteral !== undefined && followingLiteral.startsWith('.') && !followingLiteral.includes('{') ? followingLiteral : undefined;\n occurrences.push({ name: match[1]!, position, index, token: match[0], occupiesWholeHost, ...(literalHostSuffix === undefined ? {} : { literalHostSuffix }) });\n }\n return occurrences;\n}\n\n\n/**\n * Vendors whose credential is COMPUTED per request rather than sent as a fixed header.\n *\n * A static header covers bearer tokens and API keys, which is most of the world. It cannot express a\n * signature: AWS Signature Version 4 signs the method, the canonical path, the sorted query, a\n * subset of headers, a SHA-256 of the payload and a timestamp, with a key derived from the secret,\n * the date, the region and the service — so the header's VALUE differs for every request and none of\n * its inputs exist when a provider module is authored.\n *\n * Until this existed, such a vendor could not be expressed at all — not badly, not partially. There\n * was no `if` to write, because the field where the answer goes did not exist. 45 transposed actions\n * across `amazon-s3`, `amazon-ses`, `amazon-textract`, `amazon-secrets-manager`, `amazon-sqs`,\n * `amazon-bedrock`, `azure-blob-storage`, `azure-communication-services` and `azure-openai` are\n * blocked on it (#373).\n */\nexport enum ProviderRestSigningScheme {\n /**\n * AWS Signature Version 4 — the `Authorization: AWS4-HMAC-SHA256 …` scheme used by every current\n * AWS service API.\n * spec-cite: AWS General Reference, \"Signature Version 4 signing process\"\n * (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv4-signing-process.html)\n */\n AWS_SIGV4 = 'AWS_SIGV4',\n /**\n * Azure Storage shared-key — `Authorization: SharedKey <account>:<signature>` over a canonicalized\n * request and resource.\n * spec-cite: Azure Storage REST, \"Authorize with Shared Key\"\n * (https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key)\n */\n AZURE_SHARED_KEY = 'AZURE_SHARED_KEY',\n}\n\n/**\n * How a provider signs each request.\n *\n * Declared by the provider module and executed by the engine, with NO vendor branch in the executor:\n * the scheme is data, and the signer dispatches on it exhaustively. That is the same discipline the\n * rest of the provider contract keeps — a consumer branches on a contract field, never on a\n * provider ref.\n *\n * The credential is TWO values for both schemes (an identity and a secret), and optionally a third\n * for temporary credentials, which is why it cannot ride in the single `apiKey.secretRef` slot.\n */\nexport interface ProviderRestRequestSigning {\n readonly scheme: ProviderRestSigningScheme;\n /** Env-var naming the identity half — an AWS access-key id, an Azure storage account name. */\n readonly keyIdSecretRef: string;\n /** Env-var naming the secret half. */\n readonly secretKeySecretRef: string;\n /**\n * Env-var naming a session token, for temporary credentials (STS, a role assumption). Absent means\n * long-lived credentials; present-but-unset is treated as long-lived rather than as an error,\n * because the same provider serves both.\n */\n readonly sessionTokenSecretRef?: string;\n /**\n * AWS_SIGV4: the region and service that scope the derived key. Both are part of the SIGNATURE,\n * not merely of the URL, so a wrong value fails authentication rather than routing — which is why\n * they are declared rather than parsed out of the host.\n */\n readonly region?: string;\n readonly service?: string;\n /**\n * Env-var overriding {@link region} per deployment, for an application that runs in more than one.\n * The declared value is the default.\n */\n readonly regionEnvVarName?: string;\n}\n\n/**\n * The one function a generated typed client needs, as a TYPE.\n *\n * A generated provider package must not import the engine's runtime to be callable: that would put\n * the whole backend into the module graph of anything that touches a vendor, which is precisely the\n * weight #378 removed (models 20.8 MB against the backend barrel's 160.7 MB). So a client is a\n * FACTORY that takes the executor as an argument — the application wires its own, the package\n * declares only this signature, and nothing crosses at runtime.\n *\n * R3's ergonomics bought with a type rather than a dependency.\n *\n * ## The connection is a parameter, and OPTIONAL for a reason that is not convenience\n *\n * Omitted means the application's own account, acting as itself — the floor, and the only connection\n * that needs no store and no authorization. That default is what keeps the ordinary single-account\n * call as short as it should be.\n *\n * It could not be anything BUT a parameter. One execution may legitimately spend several tenants'\n * accounts — a user action pushing a message to every organization that user belongs to — so a client\n * that read the owner from ambient state could not vary it per call, and the fan-out would be\n * inexpressible through the generated surface even though the engine beneath it supports one.\n */\nexport type ProviderOperationExecute = (\n providerRef: string,\n operationId: string,\n input: Readonly<Record<string, unknown>>,\n connection?: ExternalProvider_ConnectionTarget,\n) => Promise<unknown>;\n"]}
|
|
1
|
+
{"version":3,"file":"rest-operations.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../src/protocols/rest-operations.external-connectors-models.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The REST OPERATION vocabulary — what an operation IS, independent of who executes one.\n *\n * Moved here from `@wildo-ai/external-connectors-private/backend` on 2026-09-06 (#378), and the\n * reason is a measurement rather than tidiness. A generated provider's operation catalogue is loaded\n * LAZILY on purpose: the loader contract forbids evaluating it at boot, because a provider whose\n * operations are eager puts every vendor's operations into every process's boot graph. But the\n * catalogue module needs `ProviderRestParameterLocation` and `ProviderRestRequestBodyEncoding` as\n * VALUES, and their only public door was the backend barrel — so reading two string enums pulled the\n * entire backend provider surface in behind them:\n *\n * | import | heap | time |\n * |---|---|---|\n * | `@wildo-ai/external-connectors-models` | 20.8 MB | 39 ms |\n * | `@wildo-ai/external-connectors-private/backend` | 160.7 MB | 251 ms |\n *\n * 161 MB to answer \"is this parameter in the path or the query\". The vocabulary belongs here for a\n * reason that survives the measurement, too: it describes what an operation IS — its method, its\n * path template, where its parameters ride — and none of that is backend runtime. The arrow already\n * pointed this way, since this package has no dependency on the private backend and the private\n * backend depends on it.\n *\n * ## This is the ONLY description of a REST provider — two earlier ones were deleted\n *\n * `rest-api.external-connectors-models.schemas.ts` described REST providers twice over, and both\n * descriptions are gone. Neither should come back beside this module.\n *\n * - **An OpenAPI-shaped operation layer** (`REST_API_OperationSpecSchema`,\n * `REST_API_OperationContextSchema`, `REST_API_OperationDefinition`, `API_Parameter*`,\n * `API_ContentType`) — deleted 2026-09-06 by #331. Ten exported symbols and zero code readers: a\n * provider that authored one compiled, shipped, and was invisible to every runtime.\n * - **A profile / configuration / status triple** (`REST_API_Provider_Profile`,\n * `REST_API_Provider_Configuration`, `REST_APIProvider_StatusSchema`) — deleted 2026-09-12 (#18).\n * Its only reader was the `ExternalProvider_ExchangeProtocol` union, itself read by nothing but a\n * drift test pinning it to the enum, and deleted in the same change. Its `pagination.style` was an\n * anonymous `\"offset\" | \"cursor\" | \"page\" | \"link\"` restating {@link ProviderRestPaginationStyle}.\n *\n * WHERE a REST API lives and how it authenticates is the `rest` arm of the backend runtime contract\n * (`@wildo-ai/external-connectors-private/backend`); WHAT can be called against it is\n * {@link ProviderRestOperation}, executed by `ProviderOperationExecutorBackendService`. A second\n * description of either is not a missing feature — it is the drift that makes an authoring surface\n * untrustworthy, because an author cannot tell which of two shapes is the one that runs. If an\n * OpenAPI document is ever read (a second mapper input), it feeds `ProviderRestOperation` like\n * every other source.\n */\n\nimport { z } from 'zod';\n\nimport { API_HttpMethod } from '../core/commons.external-connectors-models.schemas';\nimport { ExternalOperation_Classification } from '../core/operation-classification.external-connectors-models.schemas';\nimport { ExternalProvider_Connection_OwnerScope, type ExternalProvider_ConnectionTarget } from '../core/security.external-connectors-models.schemas';\n\nimport type { ProviderRestOperationGraphql } from './graphql-operations.external-connectors-models.schemas';\n\n/** @wildo_source:part:start external-connectors.models.rest-operation-contract facet:layer:shared facet:family:provider facet:audience:app-developer */\n/** Where a declared parameter rides on the wire. */\nexport enum ProviderRestParameterLocation {\n /** Substituted into a `{token}` of the path template. Always required — a path cannot have a hole. */\n PATH = 'path',\n QUERY = 'query',\n HEADER = 'header',\n}\n\n/**\n * How the request body is encoded. The ETL read surface only ever needed JSON; a hand-authored\n * write reaches vendors that take form bodies (OAuth-adjacent endpoints, older CRMs) and file\n * uploads, so the encoding is DECLARED per operation rather than inferred from the method.\n */\nexport enum ProviderRestRequestBodyEncoding {\n JSON = 'json',\n FORM_URLENCODED = 'form-urlencoded',\n MULTIPART = 'multipart',\n /** A raw text body; `contentType` on the declaration says which media type is sent. */\n TEXT = 'text',\n /**\n * Raw bytes (#367, folding #364) — an image, a PDF, a file upload a vendor takes as the whole body.\n * `contentType` is REQUIRED, by the TEXT arm's rule: a body without its media type is not addressable.\n * The input must supply a `Uint8Array` (a Node `Buffer` is one); nothing is converted into bytes here,\n * because a string encoded under a guessed charset is exactly how an upload arrives corrupted.\n */\n BINARY = 'binary',\n}\n\n/**\n * How the vendor's ANSWER is read (#367, folding #364).\n *\n * The request side could already send TEXT and the transport could already read TEXT and NONE, while\n * the operation declaration could only say JSON — so an operation against a `text/csv` export could be\n * authored and then failed at runtime as `INVALID_JSON`, a contract-breach message for a declaration\n * the contract had no way to state. This is the missing half of that asymmetry.\n */\nexport enum ProviderRestResponseDecoding {\n /** Parse the body as JSON. The default, and what an absent `responseDecoding` means. */\n JSON = 'json',\n /** Keep the body as text — a CSV export, an XML document. The operation's output is that string. */\n TEXT = 'text',\n /** Read nothing — a write whose answer carries no information (a 204). The output is `undefined`. */\n NONE = 'none',\n /**\n * Keep the raw bytes — a signed PDF, an evidence container (#2910). Requires `binaryResponse` (a byte ceiling and the\n * accepted media types); the output is `{ bytes, contentType }`. The bytes are the vendor's, unscanned: do not relay\n * them to a person or write them as a file yourself. Keep one through `ProviderDocumentFileWriterBackendService`\n * (`@wildo-ai/saas-backend-lib`, #2963), which stores it as a scanned file (`scan: REQUIRED`) whatever the caller asks.\n */\n BINARY = 'binary',\n}\n\n/** The bounds a {@link ProviderRestResponseDecoding.BINARY} answer is read under (#2910). Both mandatory. */\nexport interface ProviderRestBinaryResponse {\n /** The most bytes the vendor's answer may hold. Enforced while streaming; a larger answer is refused, never truncated. */\n readonly maxBytes: number;\n /** Media types accepted (`application/pdf`), compared on the type alone, case-insensitively. */\n readonly acceptedContentTypes: readonly string[];\n}\n\n/**\n * How a listing operation continues. A HINT the caller reads, never something the executor acts\n * on: an executor that paged on its own would decide a caller's memory budget for it, and the\n * ETL lane already owns paging as a discipline (drift-safe continuation only).\n */\nexport enum ProviderRestPaginationStyle {\n OFFSET = 'offset',\n PAGE = 'page',\n CURSOR = 'cursor',\n /** The vendor returns its own continuation URL (`@odata.nextLink`, `links.next`). */\n LINK = 'link',\n}\n\n/** One declared parameter: a wire name, where it rides, and which input field feeds it. */\nexport interface ProviderRestOperationParameter {\n /** The name ON THE WIRE (`page_size`, `X-Vendor-Version`, or the `{token}` in the path). */\n readonly name: string;\n readonly in: ProviderRestParameterLocation;\n /**\n * The INPUT field that feeds it, when the two differ (`pageSize` → `page_size`). Absent means\n * the input field is spelled exactly like the wire name. Declared, never camel/snake-guessed:\n * a guess that is wrong drops a parameter silently and the vendor answers a valid-looking\n * default page.\n */\n readonly from?: string;\n /** PATH parameters are required whatever this says; for QUERY/HEADER, absent means optional. */\n readonly required?: boolean;\n /** A literal value sent on every call — for a version pin or a fixed format selector. */\n readonly constantValue?: string;\n /**\n * PATH only (#2663): the value may hold several `/`-separated segments, each percent-encoded on its own, instead of\n * one segment whose `/` is encoded. For a vendor that routes per region or tenant inside ONE origin: the Bot\n * Connector's `serviceUrl` is `https://smba.trafficmanager.net/<region>/…`, and an operation's path begins with that\n * region path. Empty segments, `.` and `..` are refused, so the value moves the path within the base origin and never\n * above it; the origin itself cannot move, as for every path value.\n */\n readonly multiSegment?: true;\n /**\n * PATH only (#3397): the value is the CONNECTION's vendor-reported fact of this name, never the caller's input. Every\n * QuickBooks path is `/v3/company/{realmId}/…`, and the company is the one the person connected, so asking each caller\n * for it would let a call name a company its connection was not made for and leave every application re-typing it.\n *\n * The fact must be declared on the connection's OAuth2 contract with a\n * {@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern}; the access resolver re-admits the stored value on every\n * call and hands it to the request compiler, which fills nothing else from it. A caller value under the same input\n * name is refused rather than ignored, and the operation's `inputSchema` must not declare one\n * ({@link describeProviderRestOperationConnectionFactDefects}). Exclusive with `from`, `constantValue` and\n * `multiSegment`.\n */\n readonly connectionFact?: string;\n readonly description?: string;\n}\n\n/** How the request body is built from the operation's input. */\nexport interface ProviderRestOperationRequestBody {\n readonly encoding: ProviderRestRequestBodyEncoding;\n /**\n * The input field carrying the whole body. Absent = the body is every input field NOT consumed\n * by a declared parameter — the ordinary shape, and the reason parameters declare `from`.\n */\n readonly from?: string;\n /** For `TEXT` and `BINARY`: the media type actually sent (`text/csv`, `application/pdf`). Required for both. */\n readonly contentType?: string;\n /**\n * A JSON body sent INSIDE one named property: `envelope: 'data'` sends `{ \"data\": { …the body… } }` (#333).\n *\n * Asana answers `data: Missing input` to a task whose fields arrive at the top level — its API reads\n * every write from a `data` wrapper, which the source catalogue builds in its request helper and the\n * transposer never saw. Declared here rather than modelled as a nested input, so the INPUT stays flat:\n * the fields a person fills in, and the fields an `inputOptions` key names, are the fields they see.\n *\n * JSON only. Any other encoding with an envelope is refused by name when the request is compiled — a\n * form, text or binary body has no property to wrap it in.\n */\n readonly envelope?: string;\n}\n\n/** Where the payload sits inside a response, and how a listing continues. */\nexport interface ProviderRestOperationPagination {\n readonly style: ProviderRestPaginationStyle;\n /** OFFSET/PAGE/CURSOR: the request parameter names the caller advances. */\n readonly limitParam?: string;\n readonly offsetParam?: string;\n readonly pageParam?: string;\n readonly cursorParam?: string;\n /** CURSOR/LINK: dot-path in the RESPONSE carrying the next cursor or the next URL. */\n readonly nextPath?: string;\n}\n\n/**\n * Where an input's CHOICES come from: another operation of the same provider, run through the SAME\n * connection, whose answer lists the values a person may pick (#333).\n *\n * The shape every workflow product converged on, and deliberately not a value stored on the connection.\n * A workspace, a project, a channel are choices WITHIN an account, made per call: Zapier fills a\n * dynamic dropdown with \"a live API call\", Make fills a module field through an RPC that \"must have the\n * same connection\", n8n's resource locator lists through the node's credentials, and the Activepieces\n * source this catalogue is scraped from declares Asana's workspace as a required dropdown whose options\n * are fetched with the connected account. A connection records only what the vendor REPORTED when it\n * was authorized ({@link ProviderRestOAuth2.accountRefResponsePath}).\n *\n * Declaring an options source does not make the options operation reachable from a browser: it is its\n * own operation, and `providers.browserOperations` must list it like any other.\n *\n * @example\n * // Asana: a task's project is chosen from the projects of the chosen workspace.\n * inputOptions: {\n * workspace: { operationId: 'list_workspaces', valuePath: 'gid', labelPath: 'name' },\n * project: { operationId: 'list_projects', valuePath: 'gid', labelPath: 'name', dependsOn: { workspace: 'workspace' } },\n * }\n */\nexport interface ProviderRestOperationInputOptions {\n /** The operation that lists the choices. Same provider; its output (after its own `resultPath`) must be an array. */\n readonly operationId: string;\n /** That operation's catalogue domain, when it differs from the one being called. */\n readonly domain?: string;\n /** Dot-path, inside each listed item, to the value the input receives (`gid`). */\n readonly valuePath: string;\n /** Dot-path, inside each listed item, to the text a person reads (`name`). Vendor content, never derived from the value. */\n readonly labelPath: string;\n /**\n * Inputs the options depend on: `{ <options-operation input field>: <this operation's input field PATH> }`.\n * The value side is a dot path into this operation's input, like the `inputOptions` key (#3399): Jira's issue\n * types depend on `project.key`. The key side is a top-level field of the options operation's own input.\n * A choice that is not yet made is REFUSED by name rather than listed as empty — \"no projects\" and\n * \"choose a workspace first\" are different answers, and only one of them is true.\n */\n readonly dependsOn?: Readonly<Record<string, string>>;\n /**\n * Fixed values the options operation is called with, beside what `dependsOn` forwards (#3399): Jira lists only the\n * projects a person may create in (`action: 'create'`), Box lists the root folder (`folder_id: '0'`). A field may\n * not be both fixed and forwarded.\n */\n readonly input?: Readonly<Record<string, string | number | boolean>>;\n /**\n * Dot path, inside the options operation's output, to the listed items, when that output is an object rather than the\n * list itself (#3399): QuickBooks answers a query as `{ Customer: [...] }`, Box a folder as `{ entries: [...] }`. An\n * object without that path lists nothing, which is how QuickBooks answers a query with no rows; anything else at the\n * path that is not a list is an unreadable answer. Absent, the output itself must be the list.\n */\n readonly itemsPath?: string;\n /**\n * Keeps only the listed items whose value at each dot path equals the given text (#3399): a folder's items are files,\n * folders and web links, and only a folder can be a parent (`{ type: 'folder' }`). Absent, every item is a choice.\n */\n readonly itemWhere?: Readonly<Record<string, string>>;\n}\n\n/**\n * The schema a dot path into an operation's input names, or `undefined` when a segment names no declared field (#3399).\n *\n * Walked through Zod's own definition (`_zod.def`), not `instanceof`: a provider module may be built against another\n * copy of Zod than the host's. Wrappers that leave the value's shape alone (optional, nullable, default, prefault,\n * readonly, catch, nonoptional, a pipe's input, a lazy getter) are seen through. A union names the field when any of its\n * options declares it, as a discriminated body does. Only an object's DECLARED fields count: a loose object admits other\n * keys at runtime, and a picker for a key nobody declared is the typo this check exists to refuse.\n */\nfunction providerRestInputSchemaAtPath(schema: unknown, segments: readonly string[]): unknown {\n let current: unknown = schema;\n for (let depth = 0; depth < 64; depth += 1) {\n const def = (current as { _zod?: { def?: Record<string, unknown> } } | undefined)?._zod?.def;\n if (def === undefined) return undefined;\n switch (def.type) {\n case 'optional': case 'nullable': case 'default': case 'prefault': case 'readonly': case 'catch': case 'nonoptional':\n current = def.innerType;\n continue;\n case 'pipe':\n current = def.in;\n continue;\n case 'lazy':\n current = typeof def.getter === 'function' ? (def.getter as () => unknown)() : undefined;\n continue;\n case 'union': {\n if (segments.length === 0) return current;\n const options = Array.isArray(def.options) ? def.options : [];\n return options.map((option) => providerRestInputSchemaAtPath(option, segments)).find((found) => found !== undefined);\n }\n case 'object': {\n if (segments.length === 0) return current;\n const shape = def.shape as Record<string, unknown> | undefined;\n const [head, ...rest] = segments;\n if (shape === undefined || head === undefined || !Object.hasOwn(shape, head)) return undefined;\n return providerRestInputSchemaAtPath(shape[head], rest);\n }\n default:\n return segments.length === 0 ? current : undefined;\n }\n }\n return undefined;\n}\n\n/**\n * Why an operation's `inputOptions` cannot be honoured, or an empty list (#3399). Each key, and each `dependsOn` value,\n * is a dot path into the operation's input (`project.key`, `CustomerRef.value`; a top-level field is a one-segment\n * path), and must name a field the operation's `inputSchema` declares. Checked where a catalogue loads (the operation\n * executor, an augmentation or supplement merge) and at publish, so a mistyped path is refused once, by name, instead of\n * offering a picker that fills nothing. An operation without an `inputSchema` passes its input through unvalidated and\n * declares no fields, so there is nothing to check its paths against; only their shape is.\n */\nexport function describeProviderRestOperationInputOptionsDefects(operation: Pick<ProviderRestOperation, 'operationId' | 'inputSchema' | 'inputOptions'>): string[] {\n const defects: string[] = [];\n const check = (path: string, role: string) => {\n const segments = path.split('.');\n if (segments.some((segment) => segment.length === 0)) {\n defects.push(`operation '${operation.operationId}': ${role} '${path}' is not a dot path of field names`);\n return;\n }\n if (operation.inputSchema !== undefined && providerRestInputSchemaAtPath(operation.inputSchema, segments) === undefined) {\n defects.push(`operation '${operation.operationId}': ${role} '${path}' names no field of its inputSchema`);\n }\n };\n for (const [inputPath, declaration] of Object.entries(operation.inputOptions ?? {})) {\n check(inputPath, 'the inputOptions key');\n for (const sourcePath of Object.values(declaration.dependsOn ?? {})) check(sourcePath, `the dependsOn of '${inputPath}'`);\n for (const fixed of Object.keys(declaration.input ?? {})) {\n if (Object.hasOwn(declaration.dependsOn ?? {}, fixed)) {\n defects.push(`operation '${operation.operationId}': the options of '${inputPath}' both fix and forward '${fixed}'`);\n }\n }\n for (const listPath of [declaration.itemsPath, ...Object.keys(declaration.itemWhere ?? {})]) {\n if (listPath !== undefined && listPath.split('.').some((segment) => segment.length === 0)) {\n defects.push(`operation '${operation.operationId}': the options of '${inputPath}' name '${listPath}', which is not a dot path`);\n }\n }\n }\n return defects;\n}\n\n/**\n * Why an operation's {@link ProviderRestOperationParameter.connectionFact} parameters cannot be honoured, or an empty\n * list (#3397). Each must be a PATH parameter the path template uses, fed by nothing else (no `from`, `constantValue` or\n * `multiSegment`), and the operation's `inputSchema` must not declare a field of its name: a caller is never asked for a\n * value the connection supplies, and one it sends anyway is refused at the call. With `reportedAccountFacts` (the\n * connection's OAuth2 declaration), each named fact must also be declared there with a `pathSegmentPattern`; without\n * it the request compiler refuses the call, so a module walk passes them to catch it before any call.\n */\nexport function describeProviderRestOperationConnectionFactDefects(\n operation: Pick<ProviderRestOperation, 'operationId' | 'pathTemplate' | 'parameters' | 'inputSchema'>,\n reportedAccountFacts?: Readonly<Record<string, ProviderOAuth2ReportedAccountFact>>,\n): string[] {\n const defects: string[] = [];\n for (const parameter of operation.parameters ?? []) {\n const factName = parameter.connectionFact;\n if (factName === undefined) continue;\n const at = `operation '${operation.operationId}': the parameter '${parameter.name}' filled from the connection fact '${factName}'`;\n if (parameter.in !== ProviderRestParameterLocation.PATH) defects.push(`${at} is a ${parameter.in} parameter; only a PATH value may come from a connection fact`);\n if (parameter.from !== undefined || parameter.constantValue !== undefined || parameter.multiSegment !== undefined) {\n defects.push(`${at} also declares from, constantValue or multiSegment; its value comes from the connection alone`);\n }\n if (!operation.pathTemplate.includes(`{${parameter.name}}`)) defects.push(`${at} fills no '{${parameter.name}}' token of the path template`);\n if (operation.inputSchema !== undefined && providerRestInputSchemaAtPath(operation.inputSchema, [parameter.name]) !== undefined) {\n defects.push(`${at} is also declared by the inputSchema, which would ask callers for a value the connection supplies`);\n }\n if (reportedAccountFacts !== undefined) {\n const fact = Object.hasOwn(reportedAccountFacts, factName) ? reportedAccountFacts[factName] : undefined;\n if (fact?.pathSegmentPattern === undefined) {\n defects.push(`${at}: the connection's OAuth2 contract declares no reported fact '${factName}' with a pathSegmentPattern`);\n }\n }\n }\n return defects;\n}\n\n/**\n * A provider operation, hand-authored. The unit an application addresses:\n * `executeProviderOperation({ providerRef: 'slack', operationId: 'conversations.list', input })`.\n */\nexport interface ProviderRestOperation {\n /** Unique within the provider, and the address an ETL binding reference uses. */\n readonly operationId: string;\n /**\n * The lazy-load unit. `operations('conversations')` answers only this domain's operations, so a\n * vendor with hundreds need not evaluate them all to run one.\n */\n readonly domain: string;\n readonly method: API_HttpMethod;\n /** Relative to the provider's base URL. `{token}` interpolates a PATH parameter of that name. */\n readonly pathTemplate: string;\n /**\n * The API host this operation is served on, when it is not the base URL's host (#2546): an exact lower-case DNS name,\n * always https. The request is then `https://<host><pathTemplate>`; the base URL's path is not prepended, since it\n * belongs to the base's host. Absent, which is the norm, the request is `<baseUrl><pathTemplate>`.\n *\n * Admitted only where the token the call already carries is valid: the connection's OAuth2 client declares\n * `audiences`, and the audience that admits the base URL's host admits this host too. So no second token is minted\n * and no token reaches a host outside its own resource ({@link describeProviderRestOperationHostDefect}). This is\n * Google's shape: one grant serves every `*.googleapis.com` API, and a Gmail operation names `gmail.googleapis.com`\n * on the one Google connection. Microsoft's Dataverse is not this shape: its token is a different audience's, so it\n * stays a provider of its own sharing the connection.\n */\n readonly host?: string;\n readonly summary?: string;\n /**\n * Whether the operation MUTATES the vendor.\n *\n * ONE vocabulary for every operation catalogue, whatever produced it: a hand-authored operation\n * and a generated one are the same concept, and two enums over the same two values is precisely\n * the drift D1 exists to remove. Read by an ETL binding reference (which refuses to serve a read\n * surface from a WRITE), by the audit trail as the axis a reviewer filters on first, and by a UI\n * deciding whether to confirm.\n *\n * The name carried a source catalogue's spelling until 2026-09-06 and no longer does — an\n * operation's EFFECT is not a property of where its definition came from.\n */\n readonly classification: ExternalOperation_Classification;\n readonly parameters?: readonly ProviderRestOperationParameter[];\n readonly requestBody?: ProviderRestOperationRequestBody;\n /**\n * Zod schema the caller's input is parsed through BEFORE anything is compiled. A typed client\n * (S3b) derives its argument type from it. Absent = the input is passed through unvalidated,\n * which is legal for a thin wrapper and honest about carrying no contract.\n */\n readonly inputSchema?: z.ZodType;\n /**\n * Zod schema the RESPONSE is parsed through. Absent = the parsed body is returned as `unknown`.\n * A vendor adding a field must never break a call, so authors should keep these permissive; the\n * value is in naming the fields a caller may rely on, not in policing the vendor.\n */\n readonly outputSchema?: z.ZodType;\n /**\n * How the answer is read. Absent = `JSON`, so every operation authored before this field existed\n * reads exactly as it did.\n *\n * It also sets the default `Accept` header — `application/json` for JSON, `*\\/*` otherwise — which a\n * declared `Accept` HEADER parameter overrides when a vendor needs a specific media type.\n *\n * Two combinations are refused by name when the request is compiled, because each describes a payload\n * that cannot exist: `resultPath` beside `TEXT` or `NONE` (there is no structure to walk), and\n * `outputSchema` beside `NONE` (there is nothing to parse). `outputSchema` beside `TEXT` is legal and\n * validates the string.\n */\n readonly responseDecoding?: ProviderRestResponseDecoding;\n /** Required with `responseDecoding: BINARY`, refused with any other decoding (#2910). */\n readonly binaryResponse?: ProviderRestBinaryResponse;\n /** Dot-path to the payload inside the response body. Absent = the body IS the payload. JSON answers only. */\n readonly resultPath?: string;\n readonly pagination?: ProviderRestOperationPagination;\n /**\n * OAuth scopes (or vendor permission names) the credential must carry, as the exact strings the vendor\n * grants. CHECKED before the request leaves (#979): `ProviderOperationExecutorBackendService` compares them\n * with the scopes recorded on the spent grant and refuses with the missing ones named when any is absent.\n * A grant that records no scopes (a pasted key, a vendor that does not echo `scope`) proceeds, and the\n * call's audit row says the check could not be made — refusing there would break every such vendor.\n *\n * Until 2026-09-14 this said \"declared and not checked\"; checking needed the granted set on the grant,\n * which the connected-accounts lane now stores. Two things not to confuse it\n * with: `ProviderRestOAuth2.scopes` is the vendor's ADVISORY default set, and the wildo-cli\n * `getProviderApiKey({ requiredScopes })` parameter is a list of secret-contract SLUGS — a\n * different concept sharing the name, which no production caller feeds from this field. As of\n * 2026-09-12 no generated provider declares it either.\n */\n readonly requiredScopes?: readonly string[];\n /**\n * Whether re-sending this request is safe. Absent = derived from the method: GET, HEAD, OPTIONS,\n * PUT and DELETE are idempotent, POST and PATCH are not.\n * spec-cite: RFC 9110 §9.2.2 (PUT, DELETE and the safe methods are idempotent) and §9.2.1\n * (GET, HEAD, OPTIONS, TRACE are safe).\n * Declare it TRUE on a POST the vendor documents as idempotent (an idempotency-key endpoint);\n * declaring it wrongly is how a retried timeout charges a customer twice.\n */\n readonly idempotent?: boolean;\n /** Narrows the provider's semantics for this one operation (a slow export, a tight endpoint). */\n readonly remoteCallSemantics?: Partial<ProviderRestCallSemantics>;\n /**\n * Where each input's choices come from, keyed by a dot PATH into the input (#3399): `workspace` for a top-level\n * field, `project.key` or `CustomerRef.value` for the value a vendor nests inside a reference object. Absent for an\n * input a caller types. Every path must name a field of `inputSchema`\n * ({@link describeProviderRestOperationInputOptionsDefects}). See {@link ProviderRestOperationInputOptions}.\n */\n readonly inputOptions?: Readonly<Record<string, ProviderRestOperationInputOptions>>;\n /**\n * Present for a GraphQL operation (#3392): the provider-owned document the call sends to `pathTemplate` (the vendor's\n * GraphQL endpoint), with the operation's input as its variables. A 2xx answer carrying `errors` fails the call; the\n * output is read from the answer's `data`. See {@link ProviderRestOperationGraphql} for what such an operation may and\n * may not declare beside it.\n */\n readonly graphql?: ProviderRestOperationGraphql;\n /** Set when the vendor has deprecated it; the executor logs once per operation, never refuses. */\n readonly deprecated?: {\n readonly reason: string;\n readonly since?: string;\n readonly replacedByOperationId?: string;\n };\n}\n\n/** What one `operations(domain?)` call answers. */\nexport interface ProviderRestOperationCatalogue {\n /** The domains this load carries — the whole set when called with no argument. */\n readonly domains: readonly string[];\n /** Keyed by `operationId`. */\n readonly operations: Readonly<Record<string, ProviderRestOperation>>;\n /**\n * Which package contributed an operation that the provider's OWN module does not declare, keyed by\n * `operationId` (#1672). Absent on every catalogue a provider module loads itself; set only by the\n * framework when it merges an opted-in AUGMENTATION into a provider it does not own.\n *\n * A catalogue value and not a property of the operation, on purpose: an operation declaration is the\n * augmentation author's data, and a field the author could write would let a package claim to be\n * somebody else. The merge refuses a loaded catalogue that already carries this field.\n *\n * Read by the operation executor, which writes the contributor into the `PROVIDER_OPERATION_CALL` audit\n * row: a call spending a shared grant must say whose code declared the request it sent.\n */\n readonly augmentedBy?: Readonly<Record<string, ProviderRestOperationContributor>>;\n}\n\n/** The package that contributed an operation to a provider it does not own (#1672). */\nexport interface ProviderRestOperationContributor {\n /** The augmentation package's npm name, as its own manifest states it. */\n readonly packageName: string;\n /** The installed version of that package, as `wildo config sync` read it from the manifest. */\n readonly packageVersion: string;\n}\n\n/**\n * How a vendor states, INSIDE a successful HTTP answer, whether the call it answered succeeded (#2661).\n *\n * Most vendors say it with the status: a 4xx or 5xx is a failure, and the transport already treats it as one. Some\n * answer HTTP 200 for every call they could parse and put the verdict in the body. Slack's Web API is the case:\n * \"All Web API responses contain a JSON object, which will always contain a top-level boolean property `ok` that\n * indicates success or failure\", and \"For failure results, the `error` property will contain a short machine-readable\n * error code\".\n * spec-cite: https://docs.slack.dev/apis/web-api/ — \"Evaluating responses\", fetched 2026-10-06.\n *\n * Without this declaration such an answer reads as a success: `channel_not_found` is returned to the caller as if it\n * were a posted message, the call's audit row says it succeeded, and a revoked token stays \"accepted\" on the\n * credential. Declared on the provider's REST contract (`rest.applicationOutcome`), because the envelope is a fact\n * about the vendor's API, not about one operation.\n *\n * Read for JSON answers only: an operation declaring `TEXT` or `NONE` decoding (a file download) has no envelope.\n */\nexport interface ProviderRestApplicationOutcome {\n /** Dot-path to the boolean the vendor sets `true` exactly when the call succeeded (Slack: `ok`). */\n readonly successFlagPath: string;\n /** Dot-path to the vendor's machine-readable error code on a failed call (Slack: `error`). */\n readonly errorCodePath: string;\n /**\n * The error codes that mean the vendor refused the CREDENTIAL itself, rather than the request: the stored\n * credential is then recorded as rejected, the way the vendor's answer said (Slack: `invalid_auth`,\n * `account_inactive`, `token_revoked`, `token_expired`). A code that means the caller sent no credential at all\n * (Slack's `not_authed`) does not belong here: that is our request's fault, not a dead credential.\n */\n readonly credentialRefusedErrorCodes?: readonly string[];\n}\n\n/** What a successful HTTP answer said about the call, read through a {@link ProviderRestApplicationOutcome}. */\nexport enum ProviderRestApplicationOutcomeKind {\n /** The success flag is `true`. */\n SUCCEEDED = 'succeeded',\n /** The success flag is `false`: the vendor refused the call, naming why at the error path when it could. */\n REFUSED = 'refused',\n /** The flag is absent or not a boolean: the answer does not carry the envelope its provider declares. */\n UNSTATED = 'unstated',\n}\n\n/** The verdict a body carries. `errorCode` is kept only when it is a code-shaped string, never prose. */\nexport type ProviderRestApplicationOutcomeVerdict =\n | { readonly kind: ProviderRestApplicationOutcomeKind.SUCCEEDED }\n | { readonly kind: ProviderRestApplicationOutcomeKind.REFUSED; readonly errorCode?: string }\n | { readonly kind: ProviderRestApplicationOutcomeKind.UNSTATED };\n\n/**\n * A vendor error code as the engine may carry it: identifier characters only, at most 128. A value of any other shape\n * is dropped rather than carried, because it travels to audit rows, logs and API answers, and a vendor that puts a\n * sentence (or request data) where a code belongs must not have it repeated there.\n */\nexport const PROVIDER_VENDOR_ERROR_CODE_SHAPE = /^[A-Za-z0-9_.:-]{1,128}$/;\n\n/**\n * The defects of a declared outcome envelope, refused at boot: an empty path, and a credential-refusal code that is not\n * code-shaped, which the transport would never carry and so would never match (#2661 review L7).\n */\nexport function describeProviderRestApplicationOutcomeDefects(outcome: ProviderRestApplicationOutcome): string[] {\n const defects: string[] = [];\n const path = /^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$/;\n if (!path.test(outcome.successFlagPath)) defects.push(`applicationOutcome.successFlagPath '${outcome.successFlagPath}' is not a dot-path`);\n if (!path.test(outcome.errorCodePath)) defects.push(`applicationOutcome.errorCodePath '${outcome.errorCodePath}' is not a dot-path`);\n for (const code of outcome.credentialRefusedErrorCodes ?? []) {\n if (!PROVIDER_VENDOR_ERROR_CODE_SHAPE.test(code)) {\n defects.push(`applicationOutcome.credentialRefusedErrorCodes names '${code}', which is not code-shaped and would never match a code the transport keeps`);\n }\n }\n return defects;\n}\n\n/**\n * The placeholder a client-credentials token URL may carry for the tenant the credential belongs to:\n * `https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token`. Filled from the connection's\n * {@link ProviderRestClientCredentials.tenantSecretRef} slot, never from a request.\n */\nexport const PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER = '{tenant}';\n\n/** A tenant value the token URL admits: a GUID or a DNS name. Nothing that can leave the URL's path segment. */\nexport const PROVIDER_CLIENT_CREDENTIALS_TENANT_SHAPE = /^[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?$/;\n\n/**\n * The placeholder that BEGINS a client-credentials token URL whose token endpoint is on the deployment's own vendor\n * instance (#3402): `{deploymentOrigin}/oauth2/v1/token`. Filled with the ORIGIN of the base URL the engine resolved for\n * the REST contract (from `baseUrlHostEnvVarName` or `baseUrlEnvVarName`), never from a connection or a request.\n *\n * Okta is the case: every org has its own host (`<org>.okta.com`, or a custom domain), and its org authorization server's\n * token endpoint is on that host. A fixed {@link ProviderRestClientCredentials.tokenHosts} list cannot admit a host only\n * the operator knows, and a `{tenant}` value would be a second, separately typed copy of the host the operations already\n * go to, which could disagree with it. Filling the token endpoint from the SAME resolved origin keeps them one value: the\n * client's assertion is sent to the host the operator named, and to nothing a person connecting could choose.\n *\n * spec-cite: Okta Developer, \"Implement OAuth for Okta with a service app\"\n * (https://developer.okta.com/docs/guides/implement-oauth-for-okta-serviceapp/main/, fetched 2026-11-10) — the token\n * request is `POST https://{yourOktaDomain}/oauth2/v1/token`, and the assertion's `aud` is that URL.\n */\nexport const PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER = '{deploymentOrigin}';\n\n/** What a {@link ProviderClientCredentialsVerifiedFact} records: a value the person typed and the vendor accepted. */\nexport enum ProviderClientCredentialsFactSource {\n /** The client id the token endpoint issued a token for: Microsoft's bot App ID. */\n CLIENT_ID = 'client_id',\n /** The tenant whose token endpoint issued it. */\n TENANT = 'tenant',\n}\n\n/**\n * One fact a client-credentials connection records once the vendor has accepted its credential. See\n * {@link ProviderRestClientCredentials.verifiedAccountFacts}.\n */\nexport interface ProviderClientCredentialsVerifiedFact {\n readonly source: ProviderClientCredentialsFactSource;\n /**\n * `true` when the inbound receiver routes deliveries to an organization by this fact: an organization's own Teams\n * bot, by its App ID (#2663). Such a fact may name ONE organization only, so a connect whose value another\n * organization's enabled connection holds is refused, as for a vendor-reported fact.\n */\n readonly routesInboundDeliveries?: true;\n /**\n * `true` when the vendor treats the value without case, as Microsoft does an App ID or a tenant id (both GUIDs): the\n * value is recorded LOWER-CASED, so a lookup by the vendor's own spelling (a token's `aud`) finds an id the\n * administrator typed in capitals (#2663). Never for a value the vendor compares exactly, which most client ids are.\n */\n readonly caseInsensitive?: true;\n}\n\n/**\n * A REST provider whose access token is minted with the OAuth 2.0 client-credentials grant, from a client id and\n * secret the connection holds (#2663). The Bot Framework is the first: a Teams bot's App ID and secret, and for a\n * single-tenant bot the tenant it is registered in, mint a token for `https://api.botframework.com/.default`.\n *\n * Declared beside `oauth2` (#3398), it is the APPLICATION's own connection: Box's client-credentials grant and Zoom's\n * server-to-server OAuth renew the application's token while people and organizations connect through the exchange.\n * {@link providerClientCredentialsServesOwnerScope} says which door a connection takes.\n *\n * The token is minted per call when no unexpired one is cached, never stored, and attached where\n * {@link ProviderProtocolRuntimeContract}'s `apiKey` says, so (with no `oauth2` beside it) `apiKey.secretRef` names the\n * client's credential, its SECRET or its private key (#3402), the slot whose absence means \"not configured\". The\n * client id, credential and tenant are read from the connection: the\n * application's own environment for an APPLICATION connection, the organization's typed credential for an\n * ORGANIZATION one.\n *\n * The client id and tenant of an ORGANIZATION connection are typed by its administrator, so on their own they prove\n * nothing. They become evidence when the vendor accepts them: at connect the engine mints a token with the typed\n * values, refuses the connection when the vendor refuses, and records each {@link verifiedAccountFacts} entry as\n * `VERIFIED_BY_VENDOR`. A bot App ID then routes deliveries only to the organization that holds its secret.\n *\n * spec-cite: RFC 6749 §4.4 — the client credentials grant (`grant_type=client_credentials`, client authentication,\n * `scope`); Microsoft, \"Authenticate requests with the Bot Connector API\" — the single-tenant token request\n * `POST https://login.microsoftonline.com/MICROSOFT-TENANT-ID/oauth2/v2.0/token` with the scope\n * `https://api.botframework.com/.default`, fetched 2026-10-06.\n */\nexport interface ProviderRestClientCredentials {\n /**\n * The https token endpoint. May carry {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}, or BEGIN with\n * {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} when the token endpoint is on the deployment's own\n * vendor instance (Okta's org, #3402).\n */\n readonly tokenUrl: string;\n /**\n * The hosts the token endpoint may be on once filled. The client secret is sent nowhere else. EMPTY exactly when the\n * token URL begins with {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}: its host is the one the\n * operator named for the operations, and no fixed list can name it.\n */\n readonly tokenHosts: readonly string[];\n /**\n * The `scope` parameter, sent as written. Omitted, no `scope` is sent: RFC 6749 makes it optional, and Box, Zoom and\n * Salesforce grant the scopes configured on the app instead (#3398).\n * spec-cite: RFC 6749 §4.4.2 — `scope`: \"OPTIONAL. The scope of the access request as described by Section 3.3.\"\n * Fetched 2026-10-06.\n */\n readonly scope?: string;\n /**\n * The `grant_type` sent. Omitted, `client_credentials` (RFC 6749 §4.4). See {@link ProviderClientCredentialsGrantType}.\n */\n readonly grantType?: ProviderClientCredentialsGrantType;\n /**\n * Further parameters of the token request a vendor requires, by name: a fixed value, or one read from a slot of the\n * connection (#3398). Box's client-credentials grant names the subject it authenticates as (`box_subject_type`,\n * `box_subject_id`); Zoom's server-to-server grant names the account (`account_id`). A parameter the grant itself\n * defines (`grant_type`, `client_id`, `client_secret`, `scope`, the client assertion) is refused here: each has its own\n * field. See {@link ProviderClientCredentialsTokenRequestParameter}.\n */\n readonly tokenRequestParameters?: Readonly<Record<string, ProviderClientCredentialsTokenRequestParameter>>;\n /**\n * How the client authenticates to the token endpoint. Omitted,\n * {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST} with a client secret: the id and secret in the\n * body, as Microsoft's identity platform documents. {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC}\n * sends them in the Basic header only (Zoom's server-to-server OAuth documents nothing else). With\n * {@link privateKeyJwt} the method is {@link ProviderOAuth2ClientAuthenticationMethod.PRIVATE_KEY_JWT}, implied when\n * omitted (#3402).\n */\n readonly tokenEndpointAuthMethod?: ProviderOAuth2ClientAuthenticationMethod;\n /** The slot holding the client id. */\n readonly clientIdSecretRef: string;\n /**\n * The slot holding the client secret. Exactly one of this and {@link privateKeyJwt} (#3402): a client authenticates\n * with a shared secret or with a key it alone holds, never both. The client's CREDENTIAL slot (this one, or the\n * private key's) equals the contract's `apiKey.secretRef` when the contract declares no `oauth2` (the slot whose\n * absence means \"not configured\"); beside `oauth2`, `apiKey.secretRef` is the slot of the people's and organizations'\n * minted tokens and this one serves the application alone.\n */\n readonly clientSecretSecretRef?: string;\n /**\n * The client authenticates with a JWT it signs with its own private key (`private_key_jwt`, #3402) instead of a\n * secret: Okta's OAuth service apps accept nothing else for the Management API. See\n * {@link ProviderClientCredentialsPrivateKeyJwt}.\n */\n readonly privateKeyJwt?: ProviderClientCredentialsPrivateKeyJwt;\n /** The slot filling {@link PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}. Required exactly when the token URL carries it. */\n readonly tenantSecretRef?: string;\n /** Facts an ORGANIZATION connection records once the vendor accepted its credential, keyed by fact name. */\n readonly verifiedAccountFacts?: Readonly<Record<string, ProviderClientCredentialsVerifiedFact>>;\n /** Seconds a token is kept when the answer states no `expires_in`. Omitted, it is not cached. */\n readonly tokenLifetimeFallbackSeconds?: number;\n}\n\n/**\n * The `grant_type` a client-credentials token request sends. Narrower than `OAuth2_GrantType` on purpose: these are the\n * grants the client-credentials minter performs, each with nothing but the client's own credential and the declared\n * parameters, and a member joins in the change that implements it.\n */\nexport enum ProviderClientCredentialsGrantType {\n /**\n * The OAuth 2.0 client-credentials grant: the default.\n * spec-cite: RFC 6749 §4.4.2 — `grant_type`: \"REQUIRED. Value MUST be set to \"client_credentials\".\" Fetched 2026-10-06.\n */\n CLIENT_CREDENTIALS = 'client_credentials',\n /**\n * Zoom's server-to-server OAuth: the same exchange (a client authenticated with Basic, one token back, no refresh\n * token) under Zoom's own grant name, with the account named in `account_id`.\n * spec-cite: https://developers.zoom.us/docs/internal-apps/s2s-oauth/ — \"Use the `account_credentials` grant type to\n * generate an access token.\"; \"Set up the body of the access token request using the `account_credentials`\n * `grant_type` and your `account_id`.\" Fetched 2026-11-09.\n */\n ACCOUNT_CREDENTIALS = 'account_credentials',\n}\n\n/**\n * One further parameter of a client-credentials token request ({@link ProviderRestClientCredentials.tokenRequestParameters}):\n * a fixed `value` the module states (`box_subject_type: enterprise`), or a `secretRef` naming the connection slot that\n * holds it (Box's enterprise id, Zoom's account id), read like the client id: from the application's environment for\n * the application's connection, from the organization's credential for an organization's.\n */\nexport type ProviderClientCredentialsTokenRequestParameter =\n | { readonly value: string; readonly secretRef?: never }\n | { readonly secretRef: string; readonly value?: never };\n\n/**\n * The algorithms a client assertion is signed with (#3402). The JWS names (RFC 7518 §3.1) of the two asymmetric\n * families every vendor measured accepts: Okta lists \"RS256, RS384, RS512, ES256, ES384, and ES512\" for a service app's\n * key. A member joins when a vendor needs it.\n * spec-cite: RFC 7518 §3.1 — \"RS256 | RSASSA-PKCS1-v1_5 using SHA-256\" and \"ES256 | ECDSA using P-256 and SHA-256\";\n * https://developer.okta.com/docs/guides/implement-oauth-for-okta-serviceapp/main/ — the supported algorithms. Both\n * fetched 2026-11-09.\n */\nexport enum ProviderClientAssertionSigningAlgorithm {\n /** ECDSA on P-256 with SHA-256: a short key and signature, and the default to choose for a new key. */\n ES256 = 'ES256',\n /** RSASSA-PKCS1-v1_5 with SHA-256, for a vendor or key store that issues RSA keys. */\n RS256 = 'RS256',\n}\n\n/** The longest a client assertion may live: Okta refuses one whose `exp` is more than an hour away. */\nexport const PROVIDER_CLIENT_ASSERTION_MAXIMUM_LIFETIME_SECONDS = 3600;\n\n/** How long a client assertion lives when the declaration says nothing: long enough for one request, and no more. */\nexport const PROVIDER_CLIENT_ASSERTION_DEFAULT_LIFETIME_SECONDS = 300;\n\n/**\n * `private_key_jwt` client authentication for a client-credentials token request (#3402). The client signs, per token\n * request, a JWT whose `iss` and `sub` are its client id, whose `aud` is the token endpoint it is sent to, with a short\n * `exp` and a fresh `jti`, and sends it as `client_assertion`.\n *\n * The private key is read from a slot of the connection, as an unencrypted PEM (PKCS#8, or an RSA PKCS#1 / EC key the\n * signer re-wraps), like a secret: the application's configured provider secrets for its own connection, an organization's sealed\n * credential row for an organization's.\n *\n * ## Why the platform keyring does not hold this key (decided 2026-11-10, #3402)\n *\n * The key layer (#2916) holds keys by PURPOSE, each signing the platform's own claims under its own `typ` and verified\n * from public halves the platform publishes. A client key is the opposite: its public half is REGISTERED BY THE OPERATOR\n * at the vendor (Okta's app, a Google service account), the vendor is its only verifier, and the vendor fixes the\n * algorithm (Okta's console and Google's uploaded keys are RSA, while the keyring signs ES256 only). A keyring rotation\n * would also silently break every connection whose vendor still holds the old public half. So custody signing for vendor\n * clients is a key purpose of its own (RS256 across the keyring providers, a public half handed to the operator, rotation\n * coordinated with the vendor registration), recorded on #2916, and not a missing step of this declaration.\n *\n * spec-cite: RFC 7523 §2.2 — \"The value of the \"client_assertion_type\" is\n * \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\".\"; §3 — the JWT \"MUST contain an \"iss\" (issuer) claim\", for\n * client authentication \"the subject MUST be the \"client_id\" of the OAuth client\", an \"aud\" (audience) claim \"containing\n * a value that identifies the authorization server\", and an \"exp\" (expiration time) claim; OpenID Connect Core 1.0 §9,\n * `private_key_jwt` — `iss` and `sub` \"MUST contain the client_id of the OAuth Client\", \"The Audience SHOULD be the URL\n * of the Authorization Server's Token Endpoint\", `jti` REQUIRED: \"These tokens MUST only be used once\". Fetched\n * 2026-11-09 from https://www.rfc-editor.org/rfc/rfc7523 and https://openid.net/specs/openid-connect-core-1_0.html.\n */\nexport interface ProviderClientCredentialsPrivateKeyJwt {\n /** The slot holding the client's private key: an unencrypted PEM, PKCS#8 (`-----BEGIN PRIVATE KEY-----`) or PKCS#1 / EC. */\n readonly privateKeySecretRef: string;\n /** The JWS algorithm the key signs with. Must match the key: an EC P-256 key for ES256, an RSA key for RS256. */\n readonly algorithm: ProviderClientAssertionSigningAlgorithm;\n /**\n * The slot holding the key id sent as the assertion's `kid` header, when the vendor locates the key by it (Okta\n * requires a `kid` on every key registered with the app). Omitted, no `kid` is sent.\n */\n readonly keyIdSecretRef?: string;\n /** Seconds until the assertion's `exp`. Omitted, {@link PROVIDER_CLIENT_ASSERTION_DEFAULT_LIFETIME_SECONDS}. */\n readonly assertionLifetimeSeconds?: number;\n}\n\n/**\n * The slot of a client-credentials declaration's own CREDENTIAL: the client secret, or the private key (#3402).\n * `undefined` only for a declaration {@link describeProviderRestClientCredentialsDefects} refuses.\n */\nexport function providerClientCredentialsCredentialSlot(credentials: ProviderRestClientCredentials): string | undefined {\n return credentials.clientSecretSecretRef ?? credentials.privateKeyJwt?.privateKeySecretRef;\n}\n\n/**\n * The parameter names {@link ProviderRestClientCredentials.tokenRequestParameters} may not declare: each is written by\n * the grant itself (the grant type, the client's credential, the scope, a client assertion), so a second value would\n * either be ignored or override the declared one.\n */\nexport const PROVIDER_CLIENT_CREDENTIALS_RESERVED_PARAMETER_NAMES: readonly string[] = [\n 'grant_type', 'client_id', 'client_secret', 'scope', 'client_assertion', 'client_assertion_type',\n];\n\n/**\n * Whether the client-credentials door of a REST contract serves a connection of this owner scope (#3398).\n *\n * Alone, it serves every admitted connection: the application's own (from its environment) and an organization's (from\n * the credential the organization typed, as a Teams bot). Beside `oauth2`, a person or an organization connects through\n * the authorization-code exchange, and the client-credentials grant serves the APPLICATION's own account only, so that\n * account renews itself instead of resting on a pasted token that expires within the hour.\n */\nexport function providerClientCredentialsServesOwnerScope(\n contract: { readonly clientCredentials?: ProviderRestClientCredentials; readonly oauth2?: unknown },\n ownerScope: ExternalProvider_Connection_OwnerScope,\n): boolean {\n if (contract.clientCredentials === undefined) return false;\n return contract.oauth2 === undefined || ownerScope === ExternalProvider_Connection_OwnerScope.APPLICATION;\n}\n\n/**\n * The slot a connection of this owner scope AUTHENTICATES with, as the engine's REST access resolver reads it: the\n * client-credentials grant's own credential (its client secret or private key) when that door serves the owner scope\n * ({@link providerClientCredentialsServesOwnerScope}), else `apiKey.secretRef`, the stored or pasted token itself.\n *\n * For a contract declaring `clientCredentials` beside `oauth2` (Box, Zoom, #3398) the two differ by owner: the\n * application's own account mints from the server app's secret, while a person's connection reads its exchanged token\n * from `apiKey.secretRef`. A tool standing in for one connection (`wildo providers probe`, `connect`, the doctor's\n * configuration checks, all APPLICATION-owned) asks this instead of reading `apiKey.secretRef`, so it reads the slot the\n * engine would. `undefined` when the contract names neither.\n */\nexport function providerRestConnectionCredentialSlot(\n contract: { readonly clientCredentials?: ProviderRestClientCredentials; readonly oauth2?: unknown; readonly apiKey?: { readonly secretRef?: string } },\n ownerScope: ExternalProvider_Connection_OwnerScope,\n): string | undefined {\n return providerClientCredentialsServesOwnerScope(contract, ownerScope)\n ? providerClientCredentialsCredentialSlot(contract.clientCredentials!)\n : contract.apiKey?.secretRef;\n}\n\n/**\n * Why a client-credentials declaration cannot be honoured, or an empty list. Checked where a provider is composed:\n * a token URL that is not https, a token host that is not a DNS name or that the URL is not on, a tenant placeholder\n * with no tenant slot (or the reverse), or any other placeholder in the URL.\n */\nexport function describeProviderRestClientCredentialsDefects(credentials: ProviderRestClientCredentials): string[] {\n const defects: string[] = [];\n const hasTenant = credentials.tokenUrl.includes(PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER);\n // The deployment's origin forms the WHOLE origin or nothing (#3402): text before it, or anything but a path after it,\n // would compose a host the operator never named.\n const onDeploymentOrigin = credentials.tokenUrl.includes(PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER);\n if (onDeploymentOrigin && !credentials.tokenUrl.startsWith(`${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}/`)) {\n defects.push(`clientCredentials.tokenUrl carries ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} other than as its whole origin, followed by a path`);\n }\n if (onDeploymentOrigin && hasTenant) defects.push(`clientCredentials.tokenUrl carries both ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} and ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}; the token endpoint has one source`);\n const filled = credentials.tokenUrl\n .split(PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER).join('tenant.example')\n .split(PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER).join('https://deployment.example');\n if (/[{}]/.test(filled)) defects.push(`clientCredentials.tokenUrl '${credentials.tokenUrl}' carries a placeholder other than ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER} and ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}`);\n if (hasTenant && credentials.tenantSecretRef === undefined) defects.push(`clientCredentials.tokenUrl carries ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER} and no tenantSecretRef fills it`);\n if (!hasTenant && credentials.tenantSecretRef !== undefined) defects.push(`clientCredentials.tenantSecretRef '${credentials.tenantSecretRef}' fills nothing: the token URL carries no ${PROVIDER_CLIENT_CREDENTIALS_TENANT_PLACEHOLDER}`);\n const host = /^https:\\/\\/([^/:?#]+)(?::\\d+)?\\//.exec(filled)?.[1]?.toLowerCase();\n if (host === undefined) defects.push(`clientCredentials.tokenUrl '${credentials.tokenUrl}' is not an https URL with a path`);\n if (onDeploymentOrigin) {\n // The host is the deployment's, admitted where the engine resolves the operations' base URL; a fixed list would be\n // a second, unchecked statement of it.\n if (credentials.tokenHosts.length > 0) defects.push(`clientCredentials.tokenHosts names hosts beside ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}; the token host is the deployment's, so declare none`);\n } else {\n if (credentials.tokenHosts.length === 0) defects.push('clientCredentials.tokenHosts admits no host');\n for (const tokenHost of credentials.tokenHosts) {\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(tokenHost.toLowerCase())) defects.push(`clientCredentials.tokenHosts names '${tokenHost}', which is not a DNS name`);\n }\n if (host !== undefined && !credentials.tokenHosts.some((tokenHost) => tokenHost.toLowerCase() === host)) {\n defects.push(`clientCredentials.tokenUrl is on '${host}', which tokenHosts does not admit`);\n }\n }\n if (credentials.scope !== undefined && credentials.scope.trim() === '') defects.push('clientCredentials.scope is empty; omit it to send none');\n const grantTypes: readonly string[] = Object.values(ProviderClientCredentialsGrantType);\n if (credentials.grantType !== undefined && !grantTypes.includes(credentials.grantType)) {\n defects.push(`clientCredentials.grantType ${JSON.stringify(credentials.grantType)} is none of ${grantTypes.join(', ')}`);\n }\n // One credential: a secret or a private key (#3402), and the method agrees with which.\n if ((credentials.clientSecretSecretRef === undefined) === (credentials.privateKeyJwt === undefined)) {\n defects.push('clientCredentials declares exactly one of clientSecretSecretRef and privateKeyJwt');\n }\n const methods: readonly string[] = credentials.privateKeyJwt !== undefined\n ? [ProviderOAuth2ClientAuthenticationMethod.PRIVATE_KEY_JWT]\n : [ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST, ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC];\n if (credentials.tokenEndpointAuthMethod !== undefined && !methods.includes(credentials.tokenEndpointAuthMethod)) {\n defects.push(`clientCredentials.tokenEndpointAuthMethod ${JSON.stringify(credentials.tokenEndpointAuthMethod)} is none of ${methods.join(', ')} for ${credentials.privateKeyJwt !== undefined ? 'a private key' : 'a client secret'}`);\n }\n if (credentials.privateKeyJwt !== undefined) {\n const { privateKeySecretRef, algorithm, keyIdSecretRef, assertionLifetimeSeconds } = credentials.privateKeyJwt;\n const algorithms: readonly string[] = Object.values(ProviderClientAssertionSigningAlgorithm);\n if (privateKeySecretRef.trim() === '') defects.push('clientCredentials.privateKeyJwt.privateKeySecretRef names no slot');\n if (!algorithms.includes(algorithm)) defects.push(`clientCredentials.privateKeyJwt.algorithm ${JSON.stringify(algorithm)} is none of ${algorithms.join(', ')}`);\n if (keyIdSecretRef !== undefined && keyIdSecretRef.trim() === '') defects.push('clientCredentials.privateKeyJwt.keyIdSecretRef names no slot');\n if (assertionLifetimeSeconds !== undefined\n && !(Number.isInteger(assertionLifetimeSeconds) && assertionLifetimeSeconds > 0 && assertionLifetimeSeconds <= PROVIDER_CLIENT_ASSERTION_MAXIMUM_LIFETIME_SECONDS)) {\n defects.push(`clientCredentials.privateKeyJwt.assertionLifetimeSeconds is not a whole number of seconds from 1 to ${PROVIDER_CLIENT_ASSERTION_MAXIMUM_LIFETIME_SECONDS}`);\n }\n }\n for (const [name, parameter] of Object.entries(credentials.tokenRequestParameters ?? {})) {\n if (!/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(name)) defects.push(`clientCredentials.tokenRequestParameters names '${name}', which is not a parameter name`);\n if (PROVIDER_CLIENT_CREDENTIALS_RESERVED_PARAMETER_NAMES.includes(name)) {\n defects.push(`clientCredentials.tokenRequestParameters names '${name}', which the grant itself sends; declare it in its own field`);\n }\n const hasValue = typeof parameter.value === 'string';\n const hasSlot = typeof parameter.secretRef === 'string';\n if (hasValue === hasSlot) defects.push(`clientCredentials.tokenRequestParameters '${name}' must declare exactly one of value and secretRef`);\n else if ((parameter.value ?? parameter.secretRef ?? '').trim() === '') defects.push(`clientCredentials.tokenRequestParameters '${name}' is empty`);\n }\n for (const [name, fact] of Object.entries(credentials.verifiedAccountFacts ?? {})) {\n if (!/^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(name)) defects.push(`clientCredentials.verifiedAccountFacts names '${name}', which is not a fact name`);\n if (fact.source === ProviderClientCredentialsFactSource.TENANT && credentials.tenantSecretRef === undefined) {\n defects.push(`clientCredentials.verifiedAccountFacts '${name}' records the tenant, and no tenantSecretRef holds one`);\n }\n }\n if (credentials.tokenLifetimeFallbackSeconds !== undefined && !(credentials.tokenLifetimeFallbackSeconds > 0)) {\n defects.push('clientCredentials.tokenLifetimeFallbackSeconds is not a positive number');\n }\n return defects;\n}\n\n/**\n * Why a REST contract's `clientCredentials` sits wrongly beside the contract's other authentication fields, or an empty\n * list (#2663, #3398). Checked where a provider is composed, beside {@link describeProviderRestClientCredentialsDefects}.\n *\n * - beside `requestSigning`: two ways to authenticate one call;\n * - alone, `apiKey.secretRef` must be the client secret's slot, the one whose absence means \"not configured\";\n * - beside `oauth2` the grant serves the APPLICATION's own account only ({@link providerClientCredentialsServesOwnerScope}),\n * so the module must admit that connection; `apiKey.secretRef` names the exchanged tokens' slot and may not be the\n * client secret's (a person's token would be read from it); and `verifiedAccountFacts`, which only an organization's\n * connection records, would record nothing.\n * - a token URL on {@link PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER} (#3402) needs a base URL the\n * DEPLOYMENT names (`baseUrlHostEnvVarName` or `baseUrlEnvVarName`), and may serve the APPLICATION's connection only:\n * the deployment's instance is the application's own (its Okta org), so an organization minting there would\n * authenticate against the application's vendor tenant, never its own.\n */\nexport function describeProviderRestClientCredentialsPlacementDefects(\n contract: {\n readonly clientCredentials?: ProviderRestClientCredentials;\n readonly oauth2?: unknown;\n readonly requestSigning?: unknown;\n readonly apiKey: { readonly secretRef: string };\n readonly baseUrlHostEnvVarName?: string;\n readonly baseUrlEnvVarName?: string;\n },\n admitsApplicationConnection: boolean,\n /** Whether the module admits an ORGANIZATION or USER connection. Omitted, `false`. */\n admitsNonApplicationConnection = false,\n): string[] {\n const credentials = contract.clientCredentials;\n if (credentials === undefined) return [];\n const defects: string[] = [];\n if (contract.requestSigning !== undefined) {\n defects.push('declares clientCredentials beside requestSigning; a call authenticates one way');\n }\n if (credentials.tokenUrl.includes(PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER)) {\n if (contract.baseUrlHostEnvVarName === undefined && contract.baseUrlEnvVarName === undefined) {\n defects.push(`clientCredentials.tokenUrl is on ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}, and the contract's base URL is not one the deployment names (baseUrlHostEnvVarName or baseUrlEnvVarName)`);\n }\n if (!admitsApplicationConnection) {\n defects.push(`clientCredentials.tokenUrl is on ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}, which serves the application's own connection only, and the module admits none`);\n }\n if (contract.oauth2 === undefined && admitsNonApplicationConnection) {\n defects.push(`clientCredentials.tokenUrl is on ${PROVIDER_CLIENT_CREDENTIALS_DEPLOYMENT_ORIGIN_PLACEHOLDER}, the application's own vendor instance, and the module admits an organization or user connection that would mint there`);\n }\n }\n const credentialSlot = providerClientCredentialsCredentialSlot(credentials);\n if (contract.oauth2 === undefined) {\n if (contract.apiKey.secretRef !== credentialSlot) {\n defects.push(`apiKey.secretRef '${contract.apiKey.secretRef}' is not the client's credential slot '${credentialSlot}' (its secret or private key); that is the slot whose absence means not configured`);\n }\n return defects;\n }\n if (!admitsApplicationConnection) defects.push('declares clientCredentials beside oauth2 and admits no APPLICATION connection, the only one that grant serves');\n if (contract.apiKey.secretRef === credentialSlot) {\n defects.push(`apiKey.secretRef '${contract.apiKey.secretRef}' is the client-credentials secret or key; beside oauth2 it names the slot of the exchanged access tokens`);\n }\n if (credentials.verifiedAccountFacts !== undefined) {\n defects.push('declares clientCredentials.verifiedAccountFacts beside oauth2; an organization connects through oauth2, so no client-credentials fact is ever recorded');\n }\n return defects;\n}\n\nfunction readDotPath(body: unknown, path: string): unknown {\n let current: unknown = body;\n for (const segment of path.split('.')) {\n if (current === null || typeof current !== 'object' || !Object.hasOwn(current, segment)) return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * The vendor's error code at `errorCodePath` in a parsed answer, when it is code-shaped. Used for a refused 2xx and for\n * a non-2xx answer alike: a vendor that states its code in the body states it in the same place whatever the status.\n */\nexport function readProviderVendorErrorCode(body: unknown, errorCodePath: string): string | undefined {\n const code = readDotPath(body, errorCodePath);\n return typeof code === 'string' && PROVIDER_VENDOR_ERROR_CODE_SHAPE.test(code) ? code : undefined;\n}\n\n/** Reads the verdict a parsed JSON answer carries. The ONE reader: the transport and every test go through it. */\nexport function readProviderRestApplicationOutcome(\n body: unknown,\n outcome: Pick<ProviderRestApplicationOutcome, 'successFlagPath' | 'errorCodePath'>,\n): ProviderRestApplicationOutcomeVerdict {\n const flag = readDotPath(body, outcome.successFlagPath);\n if (flag === true) return { kind: ProviderRestApplicationOutcomeKind.SUCCEEDED };\n if (flag !== false) return { kind: ProviderRestApplicationOutcomeKind.UNSTATED };\n const errorCode = readProviderVendorErrorCode(body, outcome.errorCodePath);\n return errorCode === undefined\n ? { kind: ProviderRestApplicationOutcomeKind.REFUSED }\n : { kind: ProviderRestApplicationOutcomeKind.REFUSED, errorCode };\n}\n/** @wildo_source:part:end external-connectors.models.rest-operation-contract */\n\n/**\n * The lazy catalogue loader — the seam #330's host loader consumes (interface note on #331).\n *\n * MUST NOT be called during composition, discovery or boot: it exists so a provider package can\n * `import()` its own operation module only when a run needs it, and calling it at boot puts every\n * provider's operations back into every process's boot graph, which is the thing on-demand\n * loading exists to remove. Async, idempotent, and memoized by the executor per\n * `(providerRef, domain)` — a loader may assume one call per pair and must stay correct on two.\n *\n * The values it returns carry live Zod schemas, so a catalogue is an IN-PROCESS value and is\n * never serializable into a runtime artifact or any JSON the CLI emits.\n */\nexport type ProviderRestOperationCatalogueLoader = (domain?: string) => Promise<ProviderRestOperationCatalogue>;\n\n/**\n * The QUERY parameters an operation declares under a name its provider places a credential in, compared IGNORING CASE\n * (#2123, #2707). Empty when there is none.\n *\n * Such a parameter asks the caller for the credential the contract already places, so the operation would send the key\n * twice, or send the caller's value instead of the configured one. A name differing only in case travels BESIDE the\n * credential, and a vendor that reads names without regard to case may read the caller's value. Both are a declaration\n * defect.\n *\n * ONE comparison for every place that refuses it, so they cannot drift apart:\n * - the operation executor, once per catalogue load, against the contract's `apiKey.queryParameterName`;\n * - the operation request builder, on every call, against the resolved access's query-placed names (the backstop for a\n * placement that does not come from the contract);\n * - `wildo` registry module checks, at publish, against the module's own contract.\n *\n * A PATH or HEADER parameter is not compared: a path token is a resource id that may merely be spelled like a\n * credential, and a header credential is refused by its own placement rules.\n */\nexport function providerRestOperationCredentialQueryParameters(\n operation: Pick<ProviderRestOperation, 'parameters'>,\n credentialQueryParameterNames: Iterable<string>,\n): string[] {\n const credentialNames = new Set([...credentialQueryParameterNames].map((name) => name.toLowerCase()));\n if (credentialNames.size === 0) return [];\n return (operation.parameters ?? [])\n .filter((parameter) => parameter.in === ProviderRestParameterLocation.QUERY && credentialNames.has(parameter.name.toLowerCase()))\n .map((parameter) => parameter.name);\n}\n\n/**\n * Provider-level call semantics: the defaults every operation of this provider runs under.\n *\n * Structurally the executable subset of the ETL's `HttpApiRemoteCallSemantics`, and deliberately\n * NOT that type: the ETL's lives in `@wildo-ai/saas-models/external-data` and carries\n * `maxIdSetSize`, an ETL query-translation bound that means nothing to a provider operation.\n * Importing it here would point the PROVIDER contract at the ETL read surface — backwards, since\n * the ETL references provider operations and not the reverse. Three fields is the price of\n * keeping that arrow pointing the right way.\n */\nexport interface ProviderRestCallSemantics {\n /** Per-attempt timeout. */\n readonly timeoutMs: number;\n readonly retry: {\n /** Total attempts including the first; 1 disables retry. */\n readonly maxAttempts: number;\n /** Linear backoff base — attempt N waits `backoffMs * (N - 1)`. */\n readonly backoffMs: number;\n };\n /**\n * This REF's share of its connection's allowance: a sliding-window ceiling counted for every call made\n * through this ref, whichever account it spends (#1729).\n *\n * It is a CEILING UNDER the connection's own budgets ({@link ProviderRateBudgetDeclaration}, declared by\n * the connection's base), never a statement of the vendor's limit: several refs of one shared connection\n * each keep their own ceiling and all draw on the one vendor allowance together.\n */\n readonly maxRequestsPerMinute?: number;\n}\n\n/** @wildo_source:part:start external-connectors.models.connection-rate-budgets facet:layer:shared facet:family:provider facet:audience:app-developer */\n/**\n * WHOSE allowance a vendor counts a request against, under one connection (#1729).\n *\n * A connection is one application registration at the vendor (one OAuth client, one API project) — the\n * base provider's, however many refs spend it. Vendors meter on two axes of it, and a provider declares the\n * one each of its limits uses:\n *\n * | vendor wording | member |\n * |---|---|\n * | Microsoft Graph \"per app across all tenants\"; Google \"per minute per project\" | {@link CONNECTION} |\n * | Google \"per minute per user per project\"; Dataverse \"for each user\"; Graph \"per app per tenant\" / \"per app and mailbox\" when the grant owner IS that tenant or mailbox | {@link OWNER} |\n *\n * spec-cite: https://learn.microsoft.com/en-us/graph/throttling-limits — the global-limits table (\"Per app across all\n * tenants\") and the scope list \"per app across all tenants, per tenant for all apps, per app per tenant\"; and\n * https://developers.google.com/workspace/drive/api/guides/limits — \"per minute per project\" / \"per minute per user per\n * project\". Fetched 2026-09-28.\n *\n * Deliberately NOT a member: \"per tenant for all apps\" (Graph). It counts OTHER applications' calls, which this\n * deployment cannot see, so no local counter can hold it; the vendor's `429` is the only honest signal there.\n */\nexport enum ProviderRateBudgetPartition {\n /** One allowance for the whole connection — every ref, every account it acts for, every process. */\n CONNECTION = 'connection',\n /** One allowance per account the connection acts for — the grant's owner (a person, an organization, the deployment). */\n OWNER = 'owner',\n}\n\n/**\n * One limit a vendor publishes, as the connection's BASE provider declares it (#1729).\n *\n * Read only from the connection's base: a member ref's declaration is inert, exactly like a member's OAuth client,\n * because the limit belongs to the registration and the base owns the registration. Declared on the REST contract\n * (`rest.rateBudgets`) for a connection whose tokens serve one resource, and on each OAuth2 AUDIENCE\n * (`oauth2.audiences.<id>.rateBudgets`) for a connection spanning several — Microsoft Graph and a Dataverse\n * environment are metered by different services with different numbers, so one list for both would be wrong for one.\n *\n * Counted by the engine BEFORE a request leaves: a call waits for room (bounded, see the executor's\n * `rateBudgetWaitMs`) instead of spending a request the vendor would answer with `429`. The window is SLIDING, which\n * is at least as strict as a vendor's fixed window of the same length.\n */\nexport interface ProviderRateBudgetDeclaration {\n /** How many requests the window admits. */\n readonly maxRequests: number;\n /** The window's length, in seconds, as the vendor states it (Graph's global limit is per 10 s, Dataverse's per 300 s). */\n readonly windowSeconds: number;\n /** Whose allowance it is — see {@link ProviderRateBudgetPartition}. */\n readonly partition: ProviderRateBudgetPartition;\n}\n\n/**\n * Where a budget was COUNTED, as the call that spent it observed (#1729): `shared` when the deployment's shared store\n * (Redis) counted it for every process of the application — backend replicas, minions, workers — and `process` when\n * only this process did, because no shared store is configured here or it did not answer. Recorded on the call's audit\n * row, so a per-process count is visible rather than implied.\n */\nexport enum RateBudgetCounting {\n SHARED = 'shared',\n PROCESS = 'process',\n}\n\n/**\n * The defects of a connection's rate-budget declarations: a non-positive number, and a contract-level list beside\n * `oauth2.audiences` — which would apply to nothing, since every call of such a connection is on one audience. A pure\n * function so the registry refuses it at boot and a test pins it without a host.\n */\nexport function describeProviderRateBudgetDefects(input: {\n readonly contractRateBudgets?: readonly ProviderRateBudgetDeclaration[];\n readonly audiences?: Readonly<Record<string, { readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[] }>>;\n}): string[] {\n const defects: string[] = [];\n const check = (where: string, declarations: readonly ProviderRateBudgetDeclaration[] | undefined): void => {\n for (const [index, declaration] of (declarations ?? []).entries()) {\n if (!Number.isInteger(declaration.maxRequests) || declaration.maxRequests < 1) {\n defects.push(`${where}[${index}].maxRequests must be a positive integer (got ${String(declaration.maxRequests)})`);\n }\n if (!Number.isFinite(declaration.windowSeconds) || declaration.windowSeconds <= 0) {\n defects.push(`${where}[${index}].windowSeconds must be positive (got ${String(declaration.windowSeconds)})`);\n }\n if (!Object.values(ProviderRateBudgetPartition).includes(declaration.partition)) {\n defects.push(`${where}[${index}].partition '${String(declaration.partition)}' is not a ProviderRateBudgetPartition`);\n }\n }\n };\n check('rest.rateBudgets', input.contractRateBudgets);\n for (const [id, audience] of Object.entries(input.audiences ?? {})) check(`oauth2.audiences.${id}.rateBudgets`, audience.rateBudgets);\n if ((input.contractRateBudgets?.length ?? 0) > 0 && Object.keys(input.audiences ?? {}).length > 0) {\n defects.push('rest.rateBudgets is declared beside oauth2.audiences and would apply to no call — declare each limit on the audience it meters');\n }\n return defects;\n}\n\n/**\n * The declarations that apply to one call: the audience's own when the call's token is for an audience, else the\n * contract's. Nothing is inherited between the two — see {@link describeProviderRateBudgetDefects}.\n */\nexport function selectProviderRateBudgetDeclarations(input: {\n readonly contractRateBudgets?: readonly ProviderRateBudgetDeclaration[];\n readonly audience?: { readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[] };\n}): readonly ProviderRateBudgetDeclaration[] {\n return input.audience !== undefined ? input.audience.rateBudgets ?? [] : input.contractRateBudgets ?? [];\n}\n/** @wildo_source:part:end external-connectors.models.connection-rate-budgets */\n\n\n/**\n * A provider whose credential is MINTED by an authorization-code exchange rather than pasted.\n *\n * Recorded because the source catalogues state it and nothing else does. 131 of the 699 transposed\n * vendors declare OAuth2, and their authorize URL, token URL and scopes exist nowhere in this\n * repository except the catalogue that was read — so extracting them and keeping them only in a\n * comment (which is what the transposer did until 2026-09-07) means the delegated-authorization lane\n * re-derives 131 vendors' endpoints by hand.\n *\n * ## What it does NOT change\n *\n * The wire placement. An OAuth2 access token rides in the same header as an API key —\n * `Authorization: Bearer …` — so `apiKey.headerName` and `apiKey.prefix` still describe the request,\n * and `apiKey.secretRef` still names the slot the credential is read from. What this block adds is\n * where that value COMES FROM: an exchange, per organization or per user, refreshable — rather than\n * an operator pasting a long-lived token into an environment variable.\n *\n * That distinction is the whole point. Without it a provider declares a static bearer key and, if an\n * operator happens to paste a long-lived token, WORKS — while advertising a credential model the\n * vendor does not offer, with no authorize step, no refresh and no per-tenant token. A wrong\n * configuration that works is worse than one that fails, because nothing surfaces it.\n *\n * The FLOW is not here and is not implied: connected accounts, the authorization round trip, refresh\n * and revocation are their own lane. This is the declaration that lane consumes.\n */\nexport interface ProviderRestOAuth2 {\n /** Where the user is sent to grant access. Carries the vendor's own default scopes when it states them. */\n readonly authorizeUrl: string;\n /** Where an authorization code (or a refresh token) is exchanged for an access token. */\n readonly tokenUrl: string;\n /**\n * Where a token is handed back to the vendor so the GRANT ends there too (#545).\n *\n * Deleting our copy of a token stops US using it. It does not stop the token working, and a\n * refresh token frequently never expires on its own — so without this, \"Disconnect\" leaves the\n * application listed in the person's own connected-apps screen at the vendor, and their belief\n * that they have withdrawn access is not quite true.\n *\n * ## Why the field names RFC 7009 rather than \"revocation\"\n *\n * The name is the CONTRACT, not decoration. A URL here is POSTed\n * `application/x-www-form-urlencoded` with a `token` parameter and an optional\n * `token_type_hint`, and a 200 means the grant is gone — including for a token the server does\n * not recognise.\n * spec-cite: RFC 7009 §2.1 (revocation request) and §2.2 (revocation response), fetched\n * 2026-09-18 — §2.2: *\"The authorization server responds with HTTP status code 200 if the token\n * has been revoked successfully or if the client submitted an invalid token\"*, and *\"invalid\n * tokens do not cause an error response since the client cannot handle such an error in a\n * reasonable way.\"*\n *\n * That last sentence is why the caller is best-effort and never branches on the body: there is\n * nothing to branch on.\n *\n * **A vendor whose revocation is NOT RFC 7009 declares nothing here, deliberately.** Slack's\n * `auth.revoke` is a Web API method and GitHub's is `DELETE /applications/{client_id}/token` with\n * basic auth and a JSON body; neither is expressible as this URL, and bending the field to fit\n * them would make a declaration that names RFC 7009 and means something else entirely. Those vendors\n * need a per-vendor revocation ACTION, which is a bigger surface and is not built on speculation —\n * until then the honest answer is an absent field, and the disconnect surface says so.\n *\n * Absent — not empty — when no revocation is declared, so \"this vendor cannot be told\" stays\n * distinguishable from \"nobody has looked\".\n *\n * The client authenticates here exactly as it does at the token endpoint ({@link tokenEndpointAuthMethod}), and the\n * body is form-encoded unless {@link revocationRequestBodyEncoding} says otherwise: a vendor that takes RFC 7009's\n * `token` parameter and answers its 200, but wants Basic or a JSON body, is still declared here.\n */\n readonly rfc7009RevocationUrl?: string;\n /**\n * The vendor's USERINFO endpoint (#3397): a GET carrying the access token the authorization just minted as a Bearer\n * credential, whose JSON answer is read by every fact declared with\n * {@link ProviderOAuth2ReportedFactSource.USERINFO_RESPONSE}. DocuSign names the connected account and its API host\n * nowhere else: `GET https://account(-d).docusign.com/oauth/userinfo` lists the person's `accounts`, each with its\n * `account_id` and `base_uri`.\n *\n * Called ONCE, at the authorization-code exchange that makes (or remakes) the connection, and only when some fact\n * reads it; never at a refresh. The vendor's own guidance is to call it at setup and store the answer, and DocuSign\n * enforces an hourly limit on these requests per user and per integration key, so a call per refresh would spend that\n * limit to restate facts that change \"very infrequently\".\n * spec-cite: DocuSign, \"UserInfo\" (https://developers.docusign.com/platform/auth/reference/user-info/, fetched\n * 2026-11-09) — \"Your integration should call this method to get the information needed to begin making API calls\n * during setup, then store it for use in future calls\" and \"Docusign enforces hourly limits on the number of\n * `/oauth/userinfo` requests per user ID and per integration key\".\n *\n * Resolved like {@link tokenUrl}, through the same {@link endpointHostAllowances} and deployment values, because it\n * receives a credential too (the person's access token). It belongs to the same authorization server, so it may carry\n * only the host-forming placeholders the token endpoint carries, each in the same position\n * ({@link describeProviderOAuth2ReportedFactUseDefects}); every reader of \"which placeholders does this client have\"\n * therefore stays complete reading the authorize and token endpoints alone. A redirect is refused, never followed.\n */\n readonly userInfoUrl?: string;\n /**\n * How the client authenticates to the vendor's token endpoint: at the code exchange, at every refresh (and every\n * per-audience mint, which is a refresh), and at the revocation endpoint. Named after the client metadata field\n * `token_endpoint_auth_method`, whose values it uses. See {@link ProviderOAuth2ClientAuthenticationMethod}.\n *\n * Absent means {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST}: `client_id` and `client_secret` in\n * the body, the engine's behaviour before this field existed, so no existing provider sends a different byte. Declare\n * {@link ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC} for a vendor that documents the Basic header\n * (Zoom, Notion, Intuit). With Basic the body carries neither `client_id` nor `client_secret`: the header identifies\n * the client, and a credential is sent on one channel only.\n * spec-cite: RFC 6749 §4.1.3 — `client_id` is \"REQUIRED, if the client is not authenticating with the authorization\n * server\" as Section 3.2.1 describes. Fetched 2026-11-06.\n *\n * ## Why the revocation endpoint does not get a method of its own\n *\n * RFC 7009 sends the client's credentials at the revocation endpoint \"as described in Section 2.3. of [RFC6749]\", the\n * same section as the token endpoint, and every vendor measured on 2026-11-06 (Zoom, Notion, Intuit) authenticates\n * both endpoints the same way. A separate member would be a choice no vendor has needed; it is added when one does.\n * spec-cite: RFC 7009 §2.1 — \"The client also includes its authentication credentials as described in Section 2.3.\n * of [RFC6749].\" Fetched 2026-11-06.\n */\n readonly tokenEndpointAuthMethod?: ProviderOAuth2ClientAuthenticationMethod;\n /**\n * How the token request's parameters are written (exchange, refresh, per-audience mint). Absent means\n * {@link ProviderOAuth2RequestBodyEncoding.FORM}, as RFC 6749 specifies. Notion's token endpoint takes JSON only.\n */\n readonly tokenRequestBodyEncoding?: ProviderOAuth2RequestBodyEncoding;\n /**\n * Extra parameters the AUTHORIZATION-CODE exchange carries beside the specification's own (follow-up to #3392), each a\n * fixed value the provider module owns: a vendor that issues a different kind of token when asked in the exchange.\n * Shopify issues an expiring offline token (an hour, with a refresh token) only when the exchange carries `expiring=1`,\n * and a non-expiring one otherwise; a public app on non-expiring tokens is refused from April 2027.\n * spec-cite: https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens — the `expiring` row: \"Set\n * to `1` for an expiring offline token, or `0` (default) for a non-expiring one.\", fetched 2026-11-10.\n *\n * Sent at the code exchange only: a refresh renews the grant the exchange made and Shopify's refresh request carries no\n * such parameter. A name the engine writes itself (`grant_type`, `code`, `redirect_uri`, `code_verifier`, the client's\n * credentials, `refresh_token`, `scope`) is refused, so a declaration cannot change what the exchange is\n * ({@link describeProviderOAuth2TokenRequestDefects}).\n *\n * @example\n * codeExchangeParameters: { expiring: '1' }\n */\n readonly codeExchangeParameters?: Readonly<Record<string, string>>;\n /**\n * The refusals of a REFRESH that the vendor documents as a dead refresh token, beside the specification's\n * `invalid_grant` (follow-up to #3392). A refresh refused with one of them retires the stored connection the way\n * `invalid_grant` does, rather than being retried at every call. Shopify answers a refresh token that can no longer be\n * used with `invalid_request` and a fixed description, and says to treat it as final.\n * spec-cite: https://shopify.dev/docs/api/usage/response-codes — \"A refresh token that can no longer be used returns this\n * status with the error code `invalid_request` and the description `This request requires an active refresh_token`.\n * Treat it as final rather than retrying.\", fetched 2026-11-10.\n *\n * `error` is the OAuth2 `error` code. `errorDescription`, when given, must equal the answer's `error_description`\n * exactly: `invalid_request` alone also names a malformed request, which says nothing about the person's grant, so a\n * vendor that reuses a generic code is matched on its description too. Read at a refresh only, never at the exchange.\n * `invalid_client` is refused: it names the APPLICATION's registration, and retiring every connection over it would\n * blame the people who connected (see `providerOAuth2GrantWasPermanentlyRejected`).\n *\n * @example\n * refreshRefusals: [{ error: 'invalid_request', errorDescription: 'This request requires an active refresh_token' }]\n */\n readonly refreshRefusals?: readonly ProviderOAuth2RefreshRefusal[];\n /**\n * How the revocation request's parameters are written. Absent means {@link ProviderOAuth2RequestBodyEncoding.FORM}, as\n * RFC 7009 specifies, whatever {@link tokenRequestBodyEncoding} says: the two encodings are declared separately because\n * a vendor can differ between its two endpoints. Intuit's own client library form-encodes the token request and sends\n * the revocation request as JSON.\n * spec-cite: intuit/oauth-jsclient `OAuthClient.prototype.revoke` and `_tokenRequestHeaders`\n * (https://raw.githubusercontent.com/intuit/oauth-jsclient/e65c49b0fd1c5356ba24ddbbe910b8bc71b6f75f/src/OAuthClient.js,\n * fetched 2026-11-06).\n */\n readonly revocationRequestBodyEncoding?: ProviderOAuth2RequestBodyEncoding;\n /**\n * Scopes the vendor's own catalogue entry asked for. An application may request FEWER (a subset of\n * these, once resolved), and an operation's `requiredScopes` is the finer statement. Kept because\n * it is the only record of what the vendor expects for the operations transposed beside it.\n *\n * ## A scope may carry a placeholder, and it is resolved like an endpoint's (#991)\n *\n * Two shapes exist, classified by {@link classifyProviderOAuth2ScopePlaceholder}:\n *\n * - `{hostUrl}/.default` — the placeholder BEGINS the scope and is followed by `/`, so its value is\n * an ORIGIN (Microsoft Dataverse names the resource a token is minted FOR by the environment URL).\n * It is filled only within {@link endpointHostAllowances}, exactly like an origin in an endpoint:\n * a caller-chosen resource would have the vendor mint a token for a host nobody declared.\n * - `{permissions}` — the placeholder IS the whole scope entry, and its value is one or more scope\n * tokens chosen from {@link scopeValueAllowances}. Such a value can itself name a resource\n * (`https://graph.microsoft.com/.default`), so it is a closed choice, never free text.\n *\n * Any other placement (`api://{x}`, `{a}{b}`, `{x}.default`) is refused as malformed.\n */\n readonly scopes?: readonly string[];\n /**\n * How this vendor lets an EXISTING grant grow by one permission (#1671) — declared by the provider module that\n * owns the OAuth client, never guessed by the engine. See {@link ProviderOAuth2IncrementalConsent}.\n *\n * Absent means the vendor's behaviour is not recorded, so a re-authorization for a missing scope RESTATES what the\n * grant already holds beside the addition: an ordinary authorization that replaces the previous one, which every\n * RFC 6749 server honours. Declared, the re-authorization asks for the missing scope only and the stored granted\n * set ACCUMULATES the previous consent with the new answer.\n */\n readonly incrementalConsent?: ProviderOAuth2IncrementalConsent;\n /**\n * How this vendor is asked for a refresh token, when it is an authorize-request PARAMETER rather than a scope (#2546).\n * See {@link ProviderOAuth2OfflineAccess}. Absent means the vendor needs no parameter: it issues a refresh token to\n * every authorization code, or asks for it through a scope the provider lists in `scopes` (Microsoft's\n * `offline_access`).\n */\n readonly offlineAccess?: ProviderOAuth2OfflineAccess;\n /**\n * How the token answer's `scope` lists what was granted, when it is not the specification's space-delimited list\n * (#2546). Absent means RFC 6749's encoding. Read only from the answer; the request is {@link authorizeScopesDelimiter}.\n */\n readonly grantedScopesDelimiter?: ProviderOAuth2ScopeListDelimiter;\n /**\n * How the AUTHORIZE request's `scope` must list the scopes asked for, when the vendor does not take the specification's\n * space-delimited list (#2661). Absent means RFC 6749's encoding, which most vendors accept even when their token\n * answer uses another (GitHub). Slack documents commas for the request: \"a comma-separated list of scopes, such as:\n * `scope=incoming-webhook,commands`\".\n * spec-cite: https://docs.slack.dev/authentication/installing-with-oauth — the authorize step, fetched 2026-10-06.\n */\n readonly authorizeScopesDelimiter?: ProviderOAuth2ScopeListDelimiter;\n /**\n * Whether the vendor accepts PKCE from this application's (confidential) client (#2661). Absent means\n * {@link ProviderOAuth2PkceSupport.S256}: the authorize request carries an S256 `code_challenge` and the code exchange its\n * `code_verifier`, which RFC 9700 recommends for every client and every vendor that ignores unknown parameters accepts.\n *\n * {@link ProviderOAuth2PkceSupport.NOT_ACCEPTED} is a vendor that REFUSES PKCE unless the application registered as a public\n * client: Slack answers `pkce_not_allowed` (\"The app is not allowed to use the PKCE flow\"), and turning PKCE on there\n * is irreversible (\"Enabling PKCE marks your app as a public client, which is is a one-way operation\"), drops the\n * client secret, and makes every refresh token expire in 30 days. The install then relies on `state`, the exact\n * `redirect_uri` and the client secret at the exchange, which is what a confidential client has without PKCE.\n * spec-cite: https://docs.slack.dev/reference/methods/oauth.v2.access — the `pkce_not_allowed` row, and\n * https://docs.slack.dev/authentication/using-pkce — the quoted sentence, both fetched 2026-10-06.\n */\n readonly pkce?: ProviderOAuth2PkceSupport;\n /**\n * Scopes a person cannot grant for themselves: only an administrator of the account can (#1671). Microsoft's\n * application permissions and its admin-restricted delegated permissions are the case — \"Application permissions\n * always require admin consent\", and a delegated permission that requires admin consent answers a user with \"an\n * 'unauthorized to consent' error\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — \"Admin Consent for\n * Application permissions\" and \"Admin Consent for Delegated Permissions\", fetched 2026-09-27.\n *\n * Never put in a re-authorization request a person is sent to: an operation needing one is refused with the\n * statement that an administrator must grant it, which is the only thing the person can act on.\n */\n readonly administratorConsentScopes?: readonly string[];\n /**\n * Env-var names resolving the APPLICATION's registration with the vendor. These are the two values\n * an operator genuinely does paste — they identify the integration, not the end user — and they\n * are separate from `apiKey.secretRef`, which names the minted access token.\n */\n readonly clientIdSecretRef?: string;\n readonly clientSecretSecretRef?: string;\n /**\n * Placeholders the endpoints above carry, which a CONNECTION must answer before either URL is a\n * URL at all — `{cloud}`, `{tenantId}`, `{region}`, `{domain}`. A PATH placeholder is answered freely;\n * a HOST or ORIGIN one only from {@link ProviderRestOAuth2.endpointHostAllowances}.\n *\n * Re-measured over the generated catalogue on 2026-09-12: of the 99 vendors that recovered both\n * endpoints, **20 carry at least one placeholder**, led by `{cloud}` (18 occurrences), `{location}`\n * (10) and `{tenantId}` (6). Microsoft's authorize URL is\n * `https://{cloud}/{tenantId}/oauth2/v2.0/authorize`, and no amount of application configuration\n * supplies those: which Azure cloud and which directory are facts about the ACCOUNT BEING\n * CONNECTED, known only to the person connecting it.\n *\n * So this is not decoration on the endpoint strings — it is the difference between a vendor that\n * can be connected and one that cannot. Without it the flow would build\n * `https://{cloud}/…/authorize`, send somebody to a hostname containing a brace, and fail in the\n * browser rather than at the point where the missing input could have been asked for.\n *\n * DERIVED from the endpoint strings rather than authored, so a vendor whose URL gains a\n * placeholder declares one the next time the batch runs. Absent — not empty — when the endpoints\n * are plain, which is the common case and must stay distinguishable from \"nobody has looked\".\n *\n * Deliberately NOT a judgement about which connections a provider admits. That is a recorded\n * decision in the catalogue record and is never read from a vendor's API surface; this is a\n * mechanical fact about a string.\n *\n * A placeholder filled from {@link ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL} or\n * {@link ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED} is NOT listed: nobody\n * connecting an account is asked for it, and a value they supply is refused.\n *\n * Derived from the {@link scopes} as well as the endpoints (#991): Dataverse's `{hostUrl}/.default`\n * names a fact about the account (its environment URL) that no endpoint carries, and a placeholder\n * only a scope mentions was otherwise never asked for — so the authorize request carried the literal\n * brace to the vendor.\n */\n readonly connectionParameters?: readonly string[];\n /**\n * How each placeholder that forms an endpoint's HOST or ORIGIN may be filled, keyed by\n * placeholder name. A host/origin placeholder with NO entry here cannot be filled at all, and the\n * connect flow refuses it.\n *\n * ## Why this exists: the token endpoint receives the application's client secret\n *\n * The exchange sends `client_id` and the APPLICATION's `client_secret` to the resolved `tokenUrl`, in the body or in a\n * Basic header ({@link ProviderRestOAuth2.tokenEndpointAuthMethod}); either way the host receives the secret.\n * Until 2026-09-12 every placeholder was answered from the connect-start request body, so where a\n * placeholder formed the HOST — Microsoft's `https://{cloud}/…/token`, Salesforce's\n * `https://{environment}/…`, Zoho's `https://accounts.{location}/…` — any user allowed to start a\n * connection chose where that secret was sent (`cloud=attacker.tld`). Measured over the generated\n * catalogue that day: 34 host-position occurrences across 17 vendors (9 Microsoft, 6 Zoho,\n * Salesforce, Workday), plus two whole-origin\n * placeholders (`gitea`, `bigin-by-zoho`) that were safe only because percent-encoding made them\n * undialable (#623).\n *\n * So a host/origin value is chosen from what the PROVIDER declares, never from what a caller\n * types. Path and query placeholders (`{tenantId}`, Workday's `{tenant}`) stay free and are\n * percent-encoded, because an encoded path segment cannot move the request to another host.\n *\n * Derived by the transposer where the source catalogue states a closed choice (a dropdown), and\n * otherwise taken from a recorded human decision in the catalogue record — never guessed.\n *\n * Also governs a placeholder that forms the ORIGIN of a SCOPE (`{hostUrl}/.default`, #991). One\n * allow-list per placeholder name, wherever the name forms a host: a scope's resource URI decides\n * which host the vendor mints the token for, which is the same question an endpoint's host answers.\n */\n readonly endpointHostAllowances?: Readonly<Record<string, ProviderOAuth2EndpointHostAllowance>>;\n /**\n * The closed set of values a WHOLE-SCOPE placeholder (`scopes: ['{permissions}']`) may be answered\n * with, keyed by placeholder name (#991).\n *\n * Each value is substituted verbatim as that scope entry and may hold several space-delimited scope\n * tokens — Microsoft Entra ID's permission presets are one such string each. Matched exactly, because\n * scope values are case-sensitive.\n * spec-cite: RFC 6749 §3.3 (the scope parameter is a list of space-delimited, case-sensitive strings).\n *\n * Closed rather than free because a scope value can itself name a resource\n * (`https://graph.microsoft.com/.default`), and a whole-scope placeholder with NO entry here cannot be\n * answered at all. Derived by the transposer from the source's own dropdown; never guessed.\n */\n readonly scopeValueAllowances?: Readonly<Record<string, ProviderOAuth2ScopeValueAllowance>>;\n /**\n * Dot-path, inside the TOKEN ENDPOINT'S JSON answer, to the vendor's own identifier for the account\n * that was just authorized — Slack's `team.id` (#333).\n *\n * Read once, at the exchange, into the stored grant's `accountRef`, so a person holding two\n * connections to one vendor can tell which is which and the grant audit names the account. Absent\n * means the vendor reports no account identity in its token answer (Asana's names only the user).\n *\n * Identity only: nothing looks a credential up by it, and an answer that lacks the path stores the\n * grant without it — a missing label is not a reason to discard an authorization the person just gave.\n */\n readonly accountRefResponsePath?: string;\n /**\n * Facts about the connected ACCOUNT that the vendor reports in its token answer and OPERATIONS consume,\n * keyed by the fact's name (#333, #1047) — Salesforce's `instance_url`, Pipedrive's `api_domain`.\n *\n * Captured at the authorization-code exchange and again at every refresh, into the credential row's\n * `connectionFacts` with provenance `REPORTED_BY_VENDOR`. Distinct from {@link accountRefResponsePath}:\n * that is a LABEL a person reads, sealed in the grant; these are values requests are built from, kept\n * client-readable beside the answers a person typed at connect.\n *\n * A fact that carries an `origin` allowance is an https ORIGIN operations may dial, so it decides where a\n * request carrying the credential goes. It is therefore admitted exactly as an ORIGIN placeholder is\n * ({@link endpointHostAllowances}): refused at connect when absent or outside the allowance, and\n * re-checked on every call that uses it.\n */\n readonly reportedAccountFacts?: Readonly<Record<string, ProviderOAuth2ReportedAccountFact>>;\n /**\n * Conditions the ID token of the sign-in that makes a connection must meet (#2663), every one of them, or the\n * connect is refused before anything is stored. See {@link ProviderOAuth2IdTokenRequirement}. Needs `openid` among\n * {@link scopes}.\n */\n readonly idTokenRequirements?: readonly ProviderOAuth2IdTokenRequirement[];\n /**\n * The issuer (`iss`) an ID token this client reads claims from must name (#2663 re-review I1). Required when it reads\n * any: an {@link idTokenRequirements} entry, or a {@link reportedAccountFacts} fact sourced from ID token claims.\n *\n * A claim is used only from a token that names this issuer, names this client as its only audience (`aud`), and has\n * not expired (`exp`): the checks OpenID Connect requires of a client. A token listing any other audience is refused\n * too, since a client trusts no audience but itself unless it says so, and nothing here says so. Only the signature\n * check may be replaced by TLS, which is the one this exchange relies on. A `{claim}` placeholder is filled from the token's own claims, for\n * an issuer that varies per tenant: Microsoft's multi-tenant `https://login.microsoftonline.com/{tid}/v2.0`.\n * spec-cite: OpenID Connect Core 1.0 §3.1.3.7, items 2 (\"MUST exactly match the value of the iss (issuer) Claim\"),\n * 3 (\"MUST validate that the aud (audience) Claim contains its client_id\"; \"The ID Token MUST be rejected if the ID\n * Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the\n * Client\"), 6 (TLS in place of the signature) and 9\n * (\"The current time MUST be before the time represented by the exp Claim\").\n */\n readonly idTokenIssuer?: string;\n /**\n * The RESOURCE AUDIENCES one grant of this client can mint tokens for, keyed by audience id (#1725), and the\n * HOSTS a token of each may be sent to.\n *\n * ## Why a grant needs more than one access token\n *\n * Microsoft issues an access token for ONE resource per request: the token redemption's scopes \"must all be from a\n * single resource\", and a refresh request spanning several resources returns \"a token for the resource specified\n * in the first scope\". A refresh token, though, is not tied to a resource: \"A client can use a refresh token to\n * acquire access tokens across any combination of resource and tenant where it has permission to do so.\" So a\n * connection spanning Graph and Dataverse keeps ONE refresh token and mints a token per audience from it.\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow — the `scope` rows\n * of \"Redeem a code for an access token\" and \"Refresh the access token\"; and\n * https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens — the opening section. Fetched 2026-09-27.\n *\n * ## Why the HOSTS are part of the declaration\n *\n * An access token is a bearer credential for its resource. Declaring which hosts receive a token of each audience is\n * what lets the engine attach a token only to a request bound for its own resource (the token-host binding), so an\n * operation — the base's own, a member's, or an augmentation's (#1672) — can never carry a Graph token to another\n * host.\n *\n * Absent means the provider mints one token for one resource, which is every provider except a connection base that\n * spans several. When present, {@link primaryAudience} names the audience the AUTHORIZATION grants — the resource of\n * the connect request's scopes — whose token is the one stored with the grant; every other audience's token is minted\n * from the refresh token on demand and cached, never stored.\n */\n readonly audiences?: Readonly<Record<string, ProviderRestOAuth2Audience>>;\n /** The audience the authorization itself grants — see {@link audiences}. Required when `audiences` is declared. */\n readonly primaryAudience?: string;\n /**\n * What this vendor's URI scopes NAME (#2546) — see {@link ProviderOAuth2ScopeMeaning}. Read only with `audiences`:\n * it decides which audience a scope belongs to. Absent means {@link ProviderOAuth2ScopeMeaning.RESOURCE}, Microsoft's\n * model, where `https://graph.microsoft.com/Mail.Send` is a permission ON the Graph resource.\n */\n readonly scopeMeaning?: ProviderOAuth2ScopeMeaning;\n}\n\n/** @wildo_source:part:start external-connectors.models.oauth2-audiences facet:layer:shared facet:family:provider facet:audience:app-developer */\n/** The placeholder a {@link ProviderRestOAuth2Audience.mintScopes} entry uses for the https origin of the request's host. */\nexport const PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER = '{audienceOrigin}';\n\n/** What a vendor's URI scopes name, which decides the audience a scope belongs to — see {@link ProviderRestOAuth2.scopeMeaning}. */\nexport enum ProviderOAuth2ScopeMeaning {\n /**\n * A URI scope names the RESOURCE a token is minted for: the scope without its last path segment\n * (`https://graph.microsoft.com/Mail.Send` is Graph's). Microsoft's model, and the default.\n */\n RESOURCE = 'RESOURCE',\n /**\n * A URI scope names a PERMISSION of the vendor's one grant, not a resource: Google's scopes are URIs on several hosts\n * (`https://www.googleapis.com/auth/gmail.readonly`, `https://mail.google.com/`, `https://spreadsheets.google.com/feeds`)\n * and every one is consented on the same grant, whose one token serves every Google API. So every scope belongs to the\n * PRIMARY audience, whatever host its URI names. Declared with a single audience only.\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/scopes — the scope tables, which list both forms\n * (fetched 2026-10-05).\n */\n PERMISSION = 'PERMISSION',\n}\n\n/** One resource audience of a connection's grant. See {@link ProviderRestOAuth2.audiences}. */\nexport interface ProviderRestOAuth2Audience {\n /**\n * The hosts a token of this audience may be sent to: exact lower-case hosts, and dotted suffixes admitting\n * `<dns-labels><suffix>` (never the bare suffix). Every host is https.\n */\n readonly hosts: {\n readonly values: readonly string[];\n readonly hostSuffixes?: readonly string[];\n /**\n * The most DNS labels a host may carry before one of `hostSuffixes`; absent, any number (#3640). The same bound,\n * with the same meaning, as a host allowance's `hostSuffixMaxLabels`: declare it where the vendor documents its\n * hosts as one shape (`<store>.myshopify.com`), so a token is never sent to a deeper name under the suffix.\n */\n readonly hostSuffixMaxLabels?: number;\n };\n /**\n * The scopes that mint a token for this audience, all of ONE resource. An entry may begin with\n * {@link PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER} — the https origin of the request's own host, admitted by\n * {@link hosts} first — for a resource named per customer (a Dataverse environment's `<environment-url>/.default`).\n */\n readonly mintScopes: readonly string[];\n /**\n * The vendor's published limits for THIS resource (#1729) — see {@link ProviderRateBudgetDeclaration}. Per audience\n * because each resource is metered by its own service: Graph's limits say nothing about a Dataverse environment.\n */\n readonly rateBudgets?: readonly ProviderRateBudgetDeclaration[];\n}\n\n/** The audience a request host belongs to, with its id — see {@link selectProviderOAuth2AudienceForHost}. */\nexport interface ProviderOAuth2AudienceSelection {\n readonly id: string;\n readonly audience: ProviderRestOAuth2Audience;\n readonly primary: boolean;\n}\n\n/**\n * Whether `host` is admitted by one audience's hosts: an exact value, or `<labels><suffix>` for a declared suffix, with\n * no more labels than `hostSuffixMaxLabels` allows (#3640).\n */\nexport function providerOAuth2AudienceAdmitsHost(audience: ProviderRestOAuth2Audience, host: string): boolean {\n const candidate = host.toLowerCase();\n if (audience.hosts.values.some((value) => value.toLowerCase() === candidate)) return true;\n return (audience.hosts.hostSuffixes ?? []).some((suffix) => providerHostIsUnderSuffix(candidate, suffix, audience.hosts.hostSuffixMaxLabels));\n}\n\n/**\n * The ONE audience whose hosts admit `host`, or `undefined` when none does. The declaration guarantees at most one\n * ({@link describeProviderOAuth2AudienceDefects} refuses overlapping hosts), so the answer never depends on order.\n */\nexport function selectProviderOAuth2AudienceForHost(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience'>,\n host: string,\n): ProviderOAuth2AudienceSelection | undefined {\n for (const [id, audience] of Object.entries(oauth2.audiences ?? {})) {\n if (providerOAuth2AudienceAdmitsHost(audience, host)) return { id, audience, primary: id === oauth2.primaryAudience };\n }\n return undefined;\n}\n\n/** Whether `audience` mints its token per request ORIGIN (a mint scope beginning {@link PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER}). */\nexport function providerOAuth2AudienceIsOriginScoped(audience: Pick<ProviderRestOAuth2Audience, 'mintScopes'>): boolean {\n return audience.mintScopes.some((scope) => scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER));\n}\n\n/**\n * The scopes that mint `audience`'s token for a request to `origin` — `{audienceOrigin}` replaced by that origin.\n * The caller has already admitted the origin's host through {@link selectProviderOAuth2AudienceForHost}; nothing a\n * caller supplies reaches a scope any other way.\n */\nexport function resolveProviderOAuth2AudienceMintScopes(audience: ProviderRestOAuth2Audience, origin: string): readonly string[] {\n return audience.mintScopes.map((scope) => (scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)\n ? `${origin}${scope.slice(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER.length)}`\n : scope));\n}\n\n/**\n * The declared audience a scope a connection might REQUEST names (#1671): its id, or `undefined` when the scope names a\n * resource none of the connection's audiences covers. Only meaningful when `audiences` is declared.\n *\n * A scope that is an absolute URI names the resource a token is minted for (`https://graph.microsoft.com/Mail.Send`,\n * `https://contoso.crm.dynamics.com/user_impersonation`): the resource of one of an audience's fixed mint scopes (the\n * mint scope without its last path segment), or — for a mint scope beginning `{audienceOrigin}` — an https origin whose\n * host the audience admits. A scope that is not an absolute URI (`offline_access`, `Files.Read`) names no resource, and\n * the vendor reads it against its default one, the PRIMARY audience: \"omitting the resource identifier in the `scope`\n * parameter defaults to Microsoft Graph\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — the note under\n * \"Admin Consent for Delegated Permissions\", fetched 2026-09-27.\n */\nexport function findProviderOAuth2ScopeAudience(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopeMeaning'>,\n scope: string,\n): string | undefined {\n const audiences = oauth2.audiences ?? {};\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(scope)) return oauth2.primaryAudience;\n // A vendor whose scopes name permissions of one grant (Google): every scope is the primary audience's (#2546).\n if (oauth2.scopeMeaning === ProviderOAuth2ScopeMeaning.PERMISSION) return oauth2.primaryAudience;\n // The https origin's host, read by the same shape the audiences declare (a DNS name, no port, no credentials) rather\n // than by a URL parser: this package runs in a browser-neutral program with no URL global, and a scope that is not\n // that shape names no host an audience could admit.\n const origin = /^https:\\/\\/([^/?#:@]+)(?:\\/|$)/i.exec(scope);\n const host = origin?.[1]?.toLowerCase();\n for (const [id, audience] of Object.entries(audiences)) {\n for (const mintScope of audience.mintScopes) {\n if (mintScope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)) {\n if (host !== undefined && PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host) && providerOAuth2AudienceAdmitsHost(audience, host)) return id;\n continue;\n }\n const resource = mintScope.slice(0, mintScope.lastIndexOf('/'));\n if (resource.length > 0 && scope.startsWith(`${resource}/`)) return id;\n }\n }\n return undefined;\n}\n\n/**\n * Whether a scope a connection might REQUEST names a resource among the connection's declared audiences (#1671) — see\n * {@link findProviderOAuth2ScopeAudience}. Asking a person to consent to it is asking them to let this application reach\n * THAT resource, so a scope from a member ref or an opted-in augmentation (#1672) is requestable only when it names one\n * the connection declares. `true` without looking further when the connection declares no audiences: it mints one token\n * for one resource and its scopes are the vendor's own vocabulary (Google's scope URIs name permissions, not resources).\n */\nexport function providerOAuth2ScopeNamesDeclaredAudience(\n oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopeMeaning'>,\n scope: string,\n): boolean {\n if (oauth2.audiences === undefined) return true;\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(scope)) return true;\n return findProviderOAuth2ScopeAudience(oauth2, scope) !== undefined;\n}\n/**\n * Why an operation's {@link ProviderRestOperation.host} cannot be used on a provider whose REST binding is `contract`, or\n * `undefined` when it can (#2546). The token a call carries is chosen by the base URL's host, so the operation's host\n * must belong to that same audience: then the same token is valid there and nothing is minted for it.\n */\nexport function describeProviderRestOperationHostDefect(\n host: string,\n contract: { readonly baseUrl?: string; readonly oauth2?: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience'> },\n): string | undefined {\n if (host !== host.toLowerCase() || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host)) {\n return `host '${host}' is not a lower-case DNS name (no scheme, port, path or placeholder)`;\n }\n if (contract.oauth2?.audiences === undefined) {\n return `host '${host}' is declared on a provider whose connection declares no OAuth2 audiences, so its credential is valid only on the base URL's own host`;\n }\n // The base URL's https host, read without a URL parser (this package carries no DOM or Node types): the authority up to\n // the first '/', '?' or '#'. Anything that is not a plain DNS name there (a placeholder, userinfo, a port) has no fixed\n // audience and is refused.\n const authority = contract.baseUrl === undefined ? undefined : /^https:\\/\\/([^/?#]*)/i.exec(contract.baseUrl)?.[1]?.toLowerCase();\n const baseHost = authority !== undefined && PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(authority) ? authority : undefined;\n if (baseHost === undefined) return `host '${host}' is declared on a provider whose base URL is not one fixed https URL, so the audience its token belongs to is not known`;\n const baseAudience = selectProviderOAuth2AudienceForHost(contract.oauth2, baseHost);\n const hostAudience = selectProviderOAuth2AudienceForHost(contract.oauth2, host);\n if (hostAudience === undefined) return `host '${host}' is admitted by none of the connection's audiences (${Object.keys(contract.oauth2.audiences).join(', ')})`;\n if (baseAudience?.id !== hostAudience.id) {\n return `host '${host}' belongs to the audience '${hostAudience.id}', not to '${baseAudience?.id ?? '(none)'}' that the base URL's token is for; an operation on another audience is a provider of its own sharing the connection`;\n }\n // An audience whose token is minted per ORIGIN (`{audienceOrigin}/.default`, a Dataverse environment) gives the base\n // URL's origin its own token, which is not valid on another origin the same audience admits.\n if (host !== baseHost && providerOAuth2AudienceIsOriginScoped(hostAudience.audience)) {\n return `host '${host}' is another origin of the audience '${hostAudience.id}', whose token is minted for one origin at a time (the base URL's)`;\n }\n return undefined;\n}\n\n/** @wildo_source:part:end external-connectors.models.oauth2-audiences */\n\n/** @wildo_source:part:start external-connectors.models.oauth2-incremental-consent facet:layer:shared facet:family:provider facet:audience:app-developer */\n/**\n * How a vendor extends an existing delegated grant with more scopes — see {@link ProviderRestOAuth2.incrementalConsent}.\n */\nexport enum ProviderOAuth2IncrementalConsentForm {\n /**\n * The vendor keeps what the person already consented to, and a new authorization request naming only the added\n * scopes ADDS them: Microsoft's delegated permissions \"will be granted in addition to any other permissions that\n * were already granted for that app (i.e. incremental)\".\n * spec-cite: https://learn.microsoft.com/en-us/entra/identity-platform/consent-types-developer — \"Incremental and\n * dynamic user consent\", fetched 2026-09-27.\n */\n ADDITIVE = 'ADDITIVE',\n /**\n * The vendor adds the new scopes to the existing grant only when the request carries `include_granted_scopes=true`:\n * \"If you set this parameter's value to `true` and the authorization request is granted, then the new access token\n * will also cover any scopes to which the user previously granted the application access.\"\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/web-server#incrementalAuth — the\n * `include_granted_scopes` parameter row, fetched 2026-09-27.\n */\n INCLUDE_GRANTED_SCOPES = 'INCLUDE_GRANTED_SCOPES',\n}\n\n/**\n * How a vendor is asked for a refresh token, when a scope does not do it — see {@link ProviderRestOAuth2.offlineAccess}.\n */\nexport enum ProviderOAuth2OfflineAccessForm {\n /**\n * Google: the authorize request carries `access_type=offline`, without which no refresh token is issued. The parameter\n * \"Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid\n * parameter values are `online`, which is the default value, and `offline`.\"; and \"the refresh token is only returned\n * if your application set the `access_type` parameter to `offline`\".\n * spec-cite: https://developers.google.com/identity/protocols/oauth2/web-server — Step 1 (`access_type` row) and\n * Step 5, fetched 2026-10-05.\n *\n * Google issues the refresh token at the FIRST exchange for a consent, so a request that does not grow an existing grant\n * (a first connect, or a reconnect replacing a grant) also carries `prompt=consent`: a reconnect of an account that had\n * already consented would otherwise store a grant with no refresh token, which expires within the hour. A request that\n * grows a grant (`include_granted_scopes`) does not need it, because the stored grant keeps its refresh token.\n * Decided by practice: the established Google integrations ask for `access_type=offline` with `prompt=consent` for\n * exactly this reason.\n */\n ACCESS_TYPE_OFFLINE = 'ACCESS_TYPE_OFFLINE',\n}\n\n/** Whether a vendor takes PKCE from a confidential client. See {@link ProviderRestOAuth2.pkce}. */\nexport enum ProviderOAuth2PkceSupport {\n /** An S256 challenge on the authorize request and its verifier on the exchange: the default. */\n S256 = 'S256',\n /** The vendor refuses PKCE from a confidential client (Slack): neither is sent. */\n NOT_ACCEPTED = 'NOT_ACCEPTED',\n}\n\n/**\n * How this application's client authenticates to a vendor's token and revocation endpoints. See\n * {@link ProviderRestOAuth2.tokenEndpointAuthMethod}.\n *\n * The values are the names the \"OAuth Token Endpoint Authentication Methods\" registry gives these two methods, which\n * is what OpenID Connect and dynamic client registration call `token_endpoint_auth_method`, so a vendor's discovery\n * document (`token_endpoint_auth_methods_supported`) can be compared with a declaration by eye.\n * spec-cite: RFC 7591 §2 — `token_endpoint_auth_method`: \"client_secret_post\": \"The client uses the HTTP POST parameters\n * as defined in OAuth 2.0, Section 2.3.1.\"; \"client_secret_basic\": \"The client uses HTTP Basic as defined in OAuth 2.0,\n * Section 2.3.1.\" Fetched 2026-11-06.\n *\n * Narrower than `OAuth2_TokenEndpoint_AuthMethod` on purpose: that vocabulary also names `client_secret_jwt` and\n * `none`, which nothing here performs. `private_key_jwt` joined with #3402, performed by the client-credentials grant\n * only; the connected-account exchange refuses it at startup. A member nothing honours would\n * be a declaration that looks like a client-authentication choice and changes nothing, so each method joins this\n * vocabulary in the change that implements it.\n */\nexport enum ProviderOAuth2ClientAuthenticationMethod {\n /**\n * `client_id` and `client_secret` as parameters of the request body: the engine's behaviour when nothing is declared,\n * and what most vendors' own documentation shows. RFC 6749 calls it \"NOT RECOMMENDED\", which is why a vendor that\n * documents Basic declares {@link CLIENT_SECRET_BASIC} rather than being met with this.\n * spec-cite: RFC 6749 §2.3.1 — sending the two parameters in the body \"is NOT RECOMMENDED and SHOULD be limited to\n * clients unable to directly utilize the HTTP Basic authentication scheme\". Fetched 2026-11-06.\n */\n CLIENT_SECRET_POST = 'client_secret_post',\n /**\n * `Authorization: Basic base64(client_id \":\" client_secret)`, each half form-urlencoded BEFORE base64, and neither in\n * the body: one credential on one channel. Every authorization server must accept it (Zoom, Notion and Intuit document\n * it as their client authentication).\n * spec-cite: RFC 6749 §2.3.1 — \"The client identifier is encoded using the \"application/x-www-form-urlencoded\"\n * encoding algorithm per Appendix B\", and so is the password, before both become the Basic user-id and password; \"The\n * authorization server MUST support the HTTP Basic authentication scheme\". Appendix B encodes UTF-8 first, so `£` is\n * `%C2%A3` and a space is `+`. Fetched 2026-11-06.\n */\n CLIENT_SECRET_BASIC = 'client_secret_basic',\n /**\n * A JWT the client signs with its own private key, sent as `client_assertion` (#3402). Performed by the\n * client-credentials grant only ({@link ProviderRestClientCredentials.privateKeyJwt}); the connected-account exchange\n * does not sign assertions, so `oauth2.tokenEndpointAuthMethod` refuses it at startup.\n * spec-cite: OpenID Connect Core 1.0 §9 — `private_key_jwt`: \"Clients that have registered a public key sign a JWT\n * using that key.\" Fetched 2026-11-09 from https://openid.net/specs/openid-connect-core-1_0.html.\n */\n PRIVATE_KEY_JWT = 'private_key_jwt',\n}\n\n/**\n * How the parameters of a request to a vendor's token or revocation endpoint are written in its body. See\n * {@link ProviderRestOAuth2.tokenRequestBodyEncoding} and {@link ProviderRestOAuth2.revocationRequestBodyEncoding}.\n *\n * The parameters are the same in both encodings (`grant_type`, `code`, `refresh_token`, `token`, …); only their\n * serialization and the `Content-Type` change.\n */\nexport enum ProviderOAuth2RequestBodyEncoding {\n /**\n * `application/x-www-form-urlencoded`, which RFC 6749 and RFC 7009 specify: the default for both requests.\n * spec-cite: RFC 6749 §4.1.3 (the client makes the token request \"by sending the following parameters using the\n * \"application/x-www-form-urlencoded\" format\"; §6 does the same for a refresh), and RFC 7009 §2.1 (the revocation\n * request uses \"the \"application/x-www-form-urlencoded\" format in the HTTP request entity-body\"). Fetched 2026-11-06.\n */\n FORM = 'FORM',\n /**\n * `application/json`, an object whose members are the same parameters as string values. A deviation some vendors\n * document: Notion's token endpoint takes only JSON, and Intuit's own client library revokes with a JSON body.\n * spec-cite: https://developers.notion.com/docs/authorization — the token request's `Content-Type: application/json`,\n * fetched 2026-11-06.\n */\n JSON = 'JSON',\n}\n\n/**\n * A `scope` list encoding that deviates from RFC 6749's space-delimited list, in either direction: the token answer\n * ({@link ProviderRestOAuth2.grantedScopesDelimiter}) or the authorize request ({@link ProviderRestOAuth2.authorizeScopesDelimiter}).\n * One vocabulary for both, because it is one question (how a vendor writes a list of scopes) asked of two messages.\n */\nexport enum ProviderOAuth2ScopeListDelimiter {\n /**\n * GitHub's token answer is `{\"access_token\":\"gho_…\",\"scope\":\"repo,gist\",\"token_type\":\"bearer\"}`, while its authorize\n * request takes \"A space-delimited list of scopes\". Slack's authorize URL takes \"a comma-separated list of scopes, such\n * as: `scope=incoming-webhook,commands`\".\n * spec-cite: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps — step 2's JSON\n * response example and step 1's `scope` row, fetched 2026-10-05; https://docs.slack.dev/authentication/installing-with-oauth\n * — the authorize step's `scope` parameter, fetched 2026-10-06.\n */\n COMMA = 'COMMA',\n}\n\n/**\n * What makes a client-authentication declaration unusable (see {@link ProviderRestOAuth2.tokenEndpointAuthMethod}):\n *\n * - a method or an encoding outside its vocabulary. The request builder tests for the declared member, so an unknown\n * value (a misspelling in a module written without types) would silently fall back to the default and send the\n * secret the way the vendor said not to;\n * - a revocation encoding with no revocation URL, a setting that changes nothing.\n */\nexport function describeProviderOAuth2ClientAuthenticationDefects(\n oauth2: Pick<ProviderRestOAuth2, 'tokenEndpointAuthMethod' | 'tokenRequestBodyEncoding' | 'revocationRequestBodyEncoding' | 'rfc7009RevocationUrl'>,\n): string[] {\n const defects: string[] = [];\n // The exchange signs no assertion: a key-based client (#3402) authenticates only on the client-credentials grant.\n const methods: readonly string[] = [ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_POST, ProviderOAuth2ClientAuthenticationMethod.CLIENT_SECRET_BASIC];\n const encodings: readonly string[] = Object.values(ProviderOAuth2RequestBodyEncoding);\n if (oauth2.tokenEndpointAuthMethod !== undefined && !methods.includes(oauth2.tokenEndpointAuthMethod)) {\n defects.push(`declares tokenEndpointAuthMethod ${JSON.stringify(oauth2.tokenEndpointAuthMethod)}, which is none of ${methods.join(', ')}`);\n }\n for (const [field, value] of [['tokenRequestBodyEncoding', oauth2.tokenRequestBodyEncoding], ['revocationRequestBodyEncoding', oauth2.revocationRequestBodyEncoding]] as const) {\n if (value !== undefined && !encodings.includes(value)) defects.push(`declares ${field} ${JSON.stringify(value)}, which is none of ${encodings.join(', ')}`);\n }\n if (oauth2.revocationRequestBodyEncoding !== undefined && oauth2.rfc7009RevocationUrl === undefined) {\n defects.push('declares revocationRequestBodyEncoding without rfc7009RevocationUrl, so no revocation request uses it');\n }\n return defects;\n}\n\n/** A refresh refusal the vendor documents as a dead refresh token. See {@link ProviderRestOAuth2.refreshRefusals}. */\nexport interface ProviderOAuth2RefreshRefusal {\n /** The OAuth2 `error` code of the refusal. */\n readonly error: string;\n /** The `error_description` the refusal must carry, exactly, when the code alone is not specific to a dead token. */\n readonly errorDescription?: string;\n}\n\n/**\n * The parameter names the token request writes itself, which {@link ProviderRestOAuth2.codeExchangeParameters} may not\n * name: the exchange's own parameters (RFC 6749 §4.1.3), the client's credentials (§2.3.1) and assertion (RFC 7523 §2.2),\n * and the refresh's (§6). A declared value for one of them would change what the request IS.\n * semantic-literal-boundary: OAuth2 wire parameter names, as RFC 6749 and RFC 7523 spell them.\n */\nconst PROVIDER_OAUTH2_ENGINE_WRITTEN_TOKEN_PARAMETERS: ReadonlySet<string> = new Set([\n 'grant_type', 'code', 'redirect_uri', 'code_verifier', 'client_id', 'client_secret', 'client_assertion', 'client_assertion_type', 'refresh_token', 'scope',\n]);\n\n/** An OAuth2 error code's shape (RFC 6749 §5.2: `error` values are `%x20-21 / %x23-5B / %x5D-7E`, no space in practice). */\nconst PROVIDER_OAUTH2_ERROR_CODE_SHAPE = /^[A-Za-z0-9_.:-]{1,128}$/;\n/** A token-request parameter name a declaration may add: a plain identifier, so it cannot smuggle structure into a body. */\nconst PROVIDER_OAUTH2_EXTRA_PARAMETER_NAME = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;\n\n/**\n * What makes a token-request declaration unusable (follow-up to #3392), checked where the provider registry composes:\n *\n * - a {@link ProviderRestOAuth2.codeExchangeParameters} name that is not a plain identifier, that names a parameter the\n * engine writes itself, or whose value is empty;\n * - a {@link ProviderRestOAuth2.refreshRefusals} entry whose code is not code-shaped (it would never match), is\n * `invalid_grant` (already a refusal, so the entry says nothing) or `invalid_client` (the application's registration,\n * never one person's grant), or whose description is empty.\n */\nexport function describeProviderOAuth2TokenRequestDefects(\n oauth2: Pick<ProviderRestOAuth2, 'codeExchangeParameters' | 'refreshRefusals'>,\n): string[] {\n const defects: string[] = [];\n for (const [name, value] of Object.entries(oauth2.codeExchangeParameters ?? {})) {\n if (!PROVIDER_OAUTH2_EXTRA_PARAMETER_NAME.test(name)) defects.push(`declares the code-exchange parameter ${JSON.stringify(name)}, which is not a plain parameter name`);\n else if (PROVIDER_OAUTH2_ENGINE_WRITTEN_TOKEN_PARAMETERS.has(name)) defects.push(`declares the code-exchange parameter '${name}', which the engine writes itself`);\n if (typeof value !== 'string' || value.length === 0) defects.push(`declares the code-exchange parameter ${JSON.stringify(name)} with no value`);\n }\n for (const refusal of oauth2.refreshRefusals ?? []) {\n if (typeof refusal.error !== 'string' || !PROVIDER_OAUTH2_ERROR_CODE_SHAPE.test(refusal.error)) {\n defects.push(`declares the refresh refusal ${JSON.stringify(refusal.error)}, which is not an OAuth2 error code and would never match`);\n } else if (refusal.error === 'invalid_grant') {\n defects.push('declares the refresh refusal \\'invalid_grant\\', which already retires a connection');\n } else if (refusal.error === 'invalid_client') {\n defects.push('declares the refresh refusal \\'invalid_client\\', which names the application\\'s registration, not a person\\'s grant');\n }\n if (refusal.errorDescription !== undefined && refusal.errorDescription.trim().length === 0) {\n defects.push(`declares the refresh refusal '${refusal.error}' with an empty errorDescription`);\n }\n }\n return defects;\n}\n\n/**\n * Whether a refresh's refusal is one the provider declares as a dead refresh token ({@link ProviderRestOAuth2.refreshRefusals}).\n * The one reading, shared by the refresh and its tests.\n */\nexport function providerOAuth2RefreshRefusalIsDeclared(\n oauth2: Pick<ProviderRestOAuth2, 'refreshRefusals'>,\n answer: { readonly error: string; readonly errorDescription?: string },\n): boolean {\n return (oauth2.refreshRefusals ?? []).some((refusal) => refusal.error === answer.error\n && (refusal.errorDescription === undefined || refusal.errorDescription === answer.errorDescription));\n}\n\n/**\n * The granted scopes a token answer's `scope` string names, read with the vendor's declared delimiter: whitespace (RFC\n * 6749 §5.1) when none is declared, a comma for {@link ProviderOAuth2ScopeListDelimiter.COMMA}.\n */\nexport function splitProviderOAuth2GrantedScopes(scope: string, delimiter: ProviderOAuth2ScopeListDelimiter | undefined): string[] {\n const separator = delimiter === ProviderOAuth2ScopeListDelimiter.COMMA ? /\\s*,\\s*/ : /\\s+/;\n return scope.split(separator).map((token) => token.trim()).filter((token) => token.length > 0);\n}\n\n/**\n * The authorize request's `scope` value for the scopes asked for, written with the vendor's declared delimiter: a single\n * space (RFC 6749 §3.3) when none is declared, a comma for {@link ProviderOAuth2ScopeListDelimiter.COMMA}.\n * spec-cite: RFC 6749 §3.3 (scope is expressed as a list of space-delimited, case-sensitive strings).\n */\nexport function joinProviderOAuth2RequestedScopes(scopes: readonly string[], delimiter: ProviderOAuth2ScopeListDelimiter | undefined): string {\n return scopes.join(delimiter === ProviderOAuth2ScopeListDelimiter.COMMA ? ',' : ' ');\n}\n\n/** A vendor's refresh-token request form. See {@link ProviderRestOAuth2.offlineAccess}. */\nexport interface ProviderOAuth2OfflineAccess {\n readonly form: ProviderOAuth2OfflineAccessForm;\n}\n\n/** A vendor's incremental-consent behaviour. See {@link ProviderRestOAuth2.incrementalConsent}. */\nexport interface ProviderOAuth2IncrementalConsent {\n readonly form: ProviderOAuth2IncrementalConsentForm;\n /**\n * Scopes every re-authorization request repeats beside the added ones — protocol scopes the answer needs rather than\n * permissions (Microsoft's `offline_access`, without which a code redemption returns no refresh token). Each must be\n * among the provider's declared {@link ProviderRestOAuth2.scopes}.\n */\n readonly restatedScopes?: readonly string[];\n}\n/** @wildo_source:part:end external-connectors.models.oauth2-incremental-consent */\n\n/**\n * Why a declared audience set cannot be honoured, or an empty list. Checked where a provider is composed, so a\n * malformed declaration never reaches a request:\n * - `primaryAudience` names no declared audience, or is missing while audiences are declared;\n * - the primary audience's mint scopes are not among the authorization's own `scopes` (its token is the one the\n * code redemption returns, so the authorization must be FOR that resource) or use the origin placeholder;\n * - an audience with no host or no mint scope, a suffix without a leading dot, an origin placeholder anywhere but\n * the start of a scope, or any other `{placeholder}` in a mint scope;\n * - two audiences admitting one host — a request host must select exactly one token.\n */\nexport function describeProviderOAuth2AudienceDefects(oauth2: Pick<ProviderRestOAuth2, 'audiences' | 'primaryAudience' | 'scopes' | 'scopeMeaning'>): string[] {\n const audiences = oauth2.audiences;\n if (audiences === undefined) {\n return oauth2.primaryAudience === undefined ? [] : [`primaryAudience '${oauth2.primaryAudience}' is declared with no audiences`];\n }\n // Under PERMISSION every scope is the primary audience's, so a second audience could never be asked for (#2546).\n if (oauth2.scopeMeaning === ProviderOAuth2ScopeMeaning.PERMISSION && Object.keys(audiences).length > 1) {\n return [`scopeMeaning PERMISSION reads every scope as the primary audience's, so it is declared with one audience; this declares ${Object.keys(audiences).length}`];\n }\n const defects: string[] = [];\n const primary = oauth2.primaryAudience === undefined ? undefined : audiences[oauth2.primaryAudience];\n if (primary === undefined) defects.push(`primaryAudience '${String(oauth2.primaryAudience)}' names no declared audience`);\n for (const [id, audience] of Object.entries(audiences)) {\n if (audience.hosts.values.length === 0 && (audience.hosts.hostSuffixes ?? []).length === 0) defects.push(`audience '${id}' admits no host`);\n for (const suffix of audience.hosts.hostSuffixes ?? []) {\n if (!suffix.startsWith('.') || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(suffix.slice(1).toLowerCase())) defects.push(`audience '${id}' declares the host suffix '${suffix}', which is not '.<dns-name>'`);\n }\n for (const value of audience.hosts.values) {\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(value.toLowerCase())) defects.push(`audience '${id}' declares the host '${value}', which is not a DNS name`);\n }\n for (const defect of describeProviderHostSuffixMaxLabelsDefects(audience.hosts.hostSuffixMaxLabels, audience.hosts.hostSuffixes)) defects.push(`audience '${id}': ${defect}`);\n if (audience.mintScopes.length === 0) defects.push(`audience '${id}' declares no mint scope`);\n for (const scope of audience.mintScopes) {\n const rest = scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER) ? scope.slice(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER.length) : scope;\n if (rest.includes('{') || rest.includes('}')) defects.push(`audience '${id}' mint scope '${scope}' carries a placeholder other than a leading ${PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER}`);\n }\n }\n if (primary !== undefined) {\n for (const scope of primary.mintScopes) {\n if (scope.startsWith(PROVIDER_OAUTH2_AUDIENCE_ORIGIN_PLACEHOLDER)) defects.push(`the primary audience '${oauth2.primaryAudience}' mint scope '${scope}' names a per-request origin; the authorization must be for one fixed resource`);\n else if (!(oauth2.scopes ?? []).includes(scope)) defects.push(`the primary audience '${oauth2.primaryAudience}' mint scope '${scope}' is not among the authorization's own scopes`);\n }\n }\n const entries = Object.entries(audiences);\n for (let left = 0; left < entries.length; left += 1) {\n for (let right = left + 1; right < entries.length; right += 1) {\n const [leftId, leftAudience] = entries[left]!;\n const [rightId, rightAudience] = entries[right]!;\n const overlap = leftAudience.hosts.values.some((host) => providerOAuth2AudienceAdmitsHost(rightAudience, host))\n || rightAudience.hosts.values.some((host) => providerOAuth2AudienceAdmitsHost(leftAudience, host))\n || (leftAudience.hosts.hostSuffixes ?? []).some((suffix) => (rightAudience.hosts.hostSuffixes ?? []).some((other) => providerHostSuffixesOverlap(\n { suffix, ...(leftAudience.hosts.hostSuffixMaxLabels === undefined ? {} : { maxLabels: leftAudience.hosts.hostSuffixMaxLabels }) },\n { suffix: other, ...(rightAudience.hosts.hostSuffixMaxLabels === undefined ? {} : { maxLabels: rightAudience.hosts.hostSuffixMaxLabels }) },\n )));\n if (overlap) defects.push(`audiences '${leftId}' and '${rightId}' admit a common host; a request host must select one token`);\n }\n }\n return defects;\n}\n\n/** Where in the token endpoint's answer a {@link ProviderOAuth2ReportedAccountFact} is read. */\nexport enum ProviderOAuth2ReportedFactSource {\n /** The token endpoint's JSON answer itself: Slack's `team.id`, Salesforce's `instance_url`. The default. */\n TOKEN_RESPONSE = 'token_response',\n /**\n * The claims of the `id_token` that answer carries (OpenID Connect): Microsoft's `tid`, the tenant the person signed\n * in to. Read without checking the token's signature, which the specification permits for an ID token received\n * directly from the token endpoint, because TLS has already authenticated who sent it. An answer carrying no\n * `id_token` reports no such fact. This is how a vendor's account identity becomes VENDOR-REPORTED when its token\n * answer names the account only inside the ID token (#2660).\n * spec-cite: OpenID Connect Core 1.0 §3.1.3.7, item 6.\n */\n ID_TOKEN_CLAIMS = 'id_token_claims',\n /**\n * A query parameter of the AUTHORIZATION REDIRECT that brings the person back with the code (#3397): Intuit's\n * `realmId`, the QuickBooks company the person chose on the consent screen. `responsePath` is the parameter's name,\n * one segment. Read by the callback leg, kept with the attempt until the completion leg redeems the code, and recorded\n * only from that exchange: a refresh has no redirect, so it never restates such a fact and the stored value stands.\n *\n * The weakest of the three sources, and restricted for it. The redirect reaches this application through the\n * browser of the person who authorized, so that person could change the value before it arrives, exactly as they\n * could type an answer. Such a fact is therefore admitted only where a wrong value harms nobody but the person who\n * forged it: as a PATH value ({@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern}) of a vendor that checks it\n * against the token on every call (Intuit answers a realm the token was not granted for with an authorization fault).\n * It may never be an `origin`, fill a base URL host, or route inbound deliveries, since each of those decides where a\n * credential goes or which organization receives a message; `describeProviderOAuth2ReportedFactUseDefects` refuses it.\n */\n AUTHORIZATION_REDIRECT_QUERY = 'authorization_redirect_query',\n /**\n * The JSON answer of the vendor's USERINFO endpoint ({@link ProviderRestOAuth2.userInfoUrl}, #3397), fetched with the\n * access token the authorization just minted: DocuSign's `accounts[…].account_id` and `base_uri`. As trustworthy as\n * the token answer (the vendor answers over TLS, to a request the person's own token authorized), so it may be placed\n * wherever a token fact may. Read at the authorization-code exchange only: a refresh does not call the endpoint, so it\n * never restates such a fact and the stored value stands until the person connects again.\n */\n USERINFO_RESPONSE = 'userinfo_response',\n}\n\n/** What reading a {@link ProviderOAuth2ReportedAccountFact.responsePath} out of a vendor's answer found (#3397). */\nexport enum ProviderReportedFactReadOutcome {\n /** A non-empty string or a finite number stood at the path; `value` is its text. */\n FOUND = 'FOUND',\n /** Nothing usable stood at the path: a missing key, a `null`, an object, an empty string. The fact is not reported. */\n ABSENT = 'ABSENT',\n /**\n * A selection segment (`accounts[is_default=true]`) met an array in which NOT EXACTLY ONE element matched. The vendor's\n * answer does not name one element, so no fact is read from it: guessing the first would address a request to an\n * account nobody chose. `matched` is how many did.\n */\n SELECTION_NOT_SINGLE = 'SELECTION_NOT_SINGLE',\n}\n\n/** The result of {@link readProviderReportedFactValue}. */\nexport type ProviderReportedFactRead =\n | { readonly outcome: ProviderReportedFactReadOutcome.FOUND; readonly value: string }\n | { readonly outcome: ProviderReportedFactReadOutcome.ABSENT }\n | { readonly outcome: ProviderReportedFactReadOutcome.SELECTION_NOT_SINGLE; readonly segment: string; readonly matched: number };\n\n/** One step of a parsed {@link ProviderOAuth2ReportedAccountFact.responsePath}. */\nexport interface ProviderReportedFactPathSegment {\n /** The own property read at this step. */\n readonly key: string;\n /** Present on a SELECTION step: the property is an array, and the one element whose `field` reads as `equals` is kept. */\n readonly select?: { readonly field: string; readonly equals: string };\n}\n\n/** `name` or `name[field=value]`; no `.`, `[`, `]` or `=` inside a name, a field or a value. */\nconst PROVIDER_REPORTED_FACT_PATH_SEGMENT_PATTERN = /^([^.[\\]=]+)(?:\\[([^.[\\]=]+)=([^.[\\]=]*)\\])?$/;\n\n/**\n * The steps of a reported fact's `responsePath`, or `undefined` when it is not one (#3397). A path is dot-separated;\n * each step is an own property name, optionally followed by ONE selection `[field=value]` that picks, out of the array\n * at that property, the single element whose `field` reads as `value`: `accounts[is_default=true].account_id`.\n *\n * Names, fields and values may not contain `.`, `[`, `]` or `=`; a value may be empty. Kept this small on purpose: it\n * addresses one element by one stated condition, which is what a vendor documenting \"the default account\" means, and\n * nothing that would need a query language.\n */\nexport function parseProviderReportedFactPath(path: string): readonly ProviderReportedFactPathSegment[] | undefined {\n if (typeof path !== 'string' || path.length === 0) return undefined;\n const segments: ProviderReportedFactPathSegment[] = [];\n for (const text of path.split('.')) {\n const match = PROVIDER_REPORTED_FACT_PATH_SEGMENT_PATTERN.exec(text);\n if (match === null) return undefined;\n segments.push(match[2] === undefined ? { key: match[1]! } : { key: match[1]!, select: { field: match[2], equals: match[3]! } });\n }\n return segments;\n}\n\n/** The text a scalar reads as: a non-empty string, a finite number's decimal text, a boolean's `true`/`false`. */\nfunction providerReportedScalarText(value: unknown, admitBoolean: boolean): string | undefined {\n if (typeof value === 'string') return value.length > 0 ? value : undefined;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (admitBoolean && typeof value === 'boolean') return String(value);\n return undefined;\n}\n\n/**\n * The value at a reported fact's `responsePath` inside a vendor's JSON answer (#3397): a token answer, the claims of\n * its ID token, or a userinfo answer. Own properties only (the answer is a vendor's JSON, and `constructor` is not a\n * fact). A FOUND value is a non-empty string or a finite number's decimal text.\n *\n * A selection step keeps the ONE array element whose field reads as the stated value (a string as itself, a number as\n * its decimal text, a boolean as `true` / `false`, so DocuSign's `is_default: true` matches `[is_default=true]` whether\n * it is sent as a boolean or a string). Zero or several matches is {@link ProviderReportedFactReadOutcome.SELECTION_NOT_SINGLE}:\n * two facts selected with the same condition (`accounts[is_default=true].account_id` and `….base_uri`) are therefore\n * read from the same element or not at all. Anything else that does not lead to a scalar (a missing key, a property\n * that is not an array where a selection is written, an unparsable path) is ABSENT.\n */\nexport function readProviderReportedFactValue(payload: unknown, path: string): ProviderReportedFactRead {\n const segments = parseProviderReportedFactPath(path);\n if (segments === undefined) return { outcome: ProviderReportedFactReadOutcome.ABSENT };\n let current: unknown = payload;\n for (const segment of segments) {\n if (current === null || typeof current !== 'object' || Array.isArray(current) || !Object.hasOwn(current, segment.key)) {\n return { outcome: ProviderReportedFactReadOutcome.ABSENT };\n }\n current = (current as Record<string, unknown>)[segment.key];\n if (segment.select === undefined) continue;\n if (!Array.isArray(current)) return { outcome: ProviderReportedFactReadOutcome.ABSENT };\n const { field, equals } = segment.select;\n const matches = current.filter((element: unknown) => element !== null && typeof element === 'object' && !Array.isArray(element)\n && Object.hasOwn(element, field) && providerReportedScalarText((element as Record<string, unknown>)[field], true) === equals);\n if (matches.length !== 1) {\n return { outcome: ProviderReportedFactReadOutcome.SELECTION_NOT_SINGLE, segment: `${segment.key}[${field}=${equals}]`, matched: matches.length };\n }\n current = matches[0];\n }\n const value = providerReportedScalarText(current, false);\n return value === undefined ? { outcome: ProviderReportedFactReadOutcome.ABSENT } : { outcome: ProviderReportedFactReadOutcome.FOUND, value };\n}\n\n/**\n * The query parameters an authorization redirect carries for the OAuth protocol itself, never as an account fact: a\n * redirect-sourced fact named like one would read the code, the state or the error as the account.\n * spec-cite: RFC 6749 §4.1.2 (`code`, `state`) and §4.1.2.1 (`error`, `error_description`, `error_uri`); RFC 9207 §2\n * (`iss`).\n * semantic-literal-boundary: the OAuth protocol's own redirect parameter names, compared with a module's declaration.\n */\nexport const PROVIDER_OAUTH2_REDIRECT_PROTOCOL_PARAMETERS: readonly string[] = ['code', 'state', 'error', 'error_description', 'error_uri', 'iss'];\n\n/** One vendor-reported account fact. See {@link ProviderRestOAuth2.reportedAccountFacts}. */\nexport interface ProviderOAuth2ReportedAccountFact {\n /**\n * Dot-path inside the fact's {@link source}: the token endpoint's JSON answer by default, the claims of its\n * `id_token`, or the userinfo endpoint's JSON answer. A string or finite number there is the value. A step may select\n * ONE element of an array by a stated condition, `accounts[is_default=true].account_id` (#3397); zero or several\n * matching elements report nothing and refuse the connect ({@link readProviderReportedFactValue}). For\n * {@link ProviderOAuth2ReportedFactSource.AUTHORIZATION_REDIRECT_QUERY}, the redirect's query parameter name.\n */\n readonly responsePath: string;\n /** Where {@link responsePath} is read. Omitted, the token endpoint's JSON answer. */\n readonly source?: ProviderOAuth2ReportedFactSource;\n /**\n * Present when the value is an https ORIGIN operations dial. The same DECLARED_VALUES vocabulary an\n * ORIGIN placeholder uses: exact origins, or `https://<dns-labels><suffix>` for each dotted suffix.\n */\n readonly origin?: Extract<ProviderOAuth2EndpointHostAllowance, { readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES }>;\n /**\n * Present when operations may place the value as ONE PATH SEGMENT (#3397): QuickBooks' `/v3/company/{realmId}/…`. An\n * operation names the fact on a PATH parameter ({@link ProviderRestOperationParameter.connectionFact}) and the caller\n * never supplies it. A JavaScript regular expression the WHOLE value must match (it is anchored for you), checked when\n * the connection is made (a value that does not match, or no value, refuses the connect) and again on every call, as\n * an origin is. A value that matches is still refused when it is `.` or `..` or holds a `/`, so it can never move the\n * request to another path. Keep it as narrow as the vendor documents: `\\d+` for a QuickBooks company id.\n *\n * Without this a vendor-reported fact fills nothing: what the vendor reported is not an answer the person gave, and\n * only a declared shape keeps a value that would otherwise go unexamined out of a URL.\n */\n readonly pathSegmentPattern?: string;\n /**\n * `true` when the value may fill the base URL's `{<this fact's name>}` HOST placeholder (#3397), admitted against the\n * REST contract's `baseUrlHostAllowances` entry for that name on every call: the same allowance, and the same\n * resolver, that admit a host a person typed at connect. Needs a `DECLARED_VALUES` allowance under the fact's name.\n * Never filled into an OAuth2 endpoint (authorize, token, revocation): those carry the client secret, and only the\n * person's answers or the deployment fill them. An `origin` is the other way to address the account; a fact is one\n * or the other.\n */\n readonly fillsBaseUrlHost?: true;\n /**\n * `true` when the inbound receiver routes the vendor's deliveries to an organization by this fact: Slack's\n * `team.id`, the workspace an event comes from (#2660). Such a fact may name ONE organization only, so an\n * organization's connection reporting a value another organization's enabled connection already reports is\n * refused at connect, naming why. Routing fails closed on a value two organizations hold either way; the refusal is\n * what makes that a clear answer at connect instead of deliveries that silently route nowhere.\n */\n readonly routesInboundDeliveries?: true;\n}\n\n/** What a {@link ProviderOAuth2IdTokenRequirement} asks of the sign-in's ID token claims. */\nexport enum ProviderOAuth2IdTokenRequirementKind {\n /**\n * The claim is an array holding at least one of `values`, compared exactly. Microsoft's `wids`, the directory roles\n * the person holds: a tenant claim requires a role that administers the tenant.\n */\n CLAIM_CONTAINS_ANY = 'claim_contains_any',\n /**\n * When the claim is present, it equals `equalsClaim`. Microsoft's `idp` against `iss`: they differ for a guest, an\n * account another tenant authenticated, who speaks for nothing in this one.\n */\n CLAIM_EQUALS_CLAIM_WHEN_PRESENT = 'claim_equals_claim_when_present',\n}\n\n/**\n * One condition the ID token of the sign-in that MAKES a connection must meet, or the connect is refused before\n * anything is stored (#2663). For a connection whose reported fact routes deliveries (a Microsoft tenant), proving\n * the account is not enough: the person must also have the authority to bind it to an organization, and the vendor's\n * signed claims are where that authority is stated.\n *\n * Checked at the authorization-code exchange only. A refresh does not re-make the connection, and a vendor need not\n * return an ID token with it; a person whose authority lapsed is caught the next time the connection is made.\n */\nexport type ProviderOAuth2IdTokenRequirement =\n | { readonly kind: ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY; readonly claim: string; readonly values: readonly string[] }\n | { readonly kind: ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT; readonly claim: string; readonly equalsClaim: string };\n\n/** Why an ID token's claims may not be used (#2663 re-review I1). See {@link providerOAuth2IdTokenRejection}. */\nexport enum ProviderOAuth2IdTokenRejection {\n /** The token endpoint's answer carries no ID token, or not one whose payload is a JSON object. */\n ABSENT = 'absent',\n /** `iss` is not the declared issuer, with its placeholders filled from the token's claims. */\n ISSUER_MISMATCH = 'issuer_mismatch',\n /** `aud` does not name this client, or names another audience beside it. */\n AUDIENCE_MISMATCH = 'audience_mismatch',\n /** `exp` is missing, or not after the current time. */\n EXPIRED = 'expired',\n}\n\n/**\n * Why these ID token claims may not be used, or `undefined` when they may: the token names the declared issuer, this\n * client as its only audience, and an expiry still ahead. See {@link ProviderRestOAuth2.idTokenIssuer}.\n *\n * A placeholder of the issuer naming a claim the token does not carry as a non-empty string fails the issuer check:\n * an issuer that cannot be written cannot be matched.\n */\nexport function providerOAuth2IdTokenRejection(\n claims: Readonly<Record<string, unknown>> | undefined,\n expected: { readonly issuer: string; readonly clientId: string; readonly nowEpochSeconds: number },\n): ProviderOAuth2IdTokenRejection | undefined {\n if (claims === undefined) return ProviderOAuth2IdTokenRejection.ABSENT;\n const claimOf = (name: string): unknown => (Object.hasOwn(claims, name) ? claims[name] : undefined);\n let unfillable = false;\n const issuer = expected.issuer.replace(/\\{([^{}]+)\\}/g, (_placeholder, name: string) => {\n const value = claimOf(name);\n if (typeof value !== 'string' || value.length === 0) {\n unfillable = true;\n return '';\n }\n return value;\n });\n if (unfillable || claimOf('iss') !== issuer) return ProviderOAuth2IdTokenRejection.ISSUER_MISMATCH;\n const audience = claimOf('aud');\n const audiences: readonly unknown[] = Array.isArray(audience) ? audience : [audience];\n // Every listed audience must be this client: OpenID Connect rejects a token that lists \"additional audiences not\n // trusted by the Client\", and this client trusts none but itself (no declaration names another).\n if (audiences.length === 0 || !audiences.every((entry) => entry === expected.clientId)) return ProviderOAuth2IdTokenRejection.AUDIENCE_MISMATCH;\n const expiry = claimOf('exp');\n if (typeof expiry !== 'number' || !Number.isFinite(expiry) || expiry <= expected.nowEpochSeconds) return ProviderOAuth2IdTokenRejection.EXPIRED;\n return undefined;\n}\n\n/** Whether ID token claims meet one requirement. An absent ID token meets none. */\nexport function providerOAuth2IdTokenRequirementHolds(requirement: ProviderOAuth2IdTokenRequirement, claims: Readonly<Record<string, unknown>> | undefined): boolean {\n if (claims === undefined) return false;\n const value = Object.hasOwn(claims, requirement.claim) ? claims[requirement.claim] : undefined;\n switch (requirement.kind) {\n case ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY:\n return Array.isArray(value) && value.some((entry) => typeof entry === 'string' && requirement.values.includes(entry));\n case ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT: {\n if (value === undefined) return true;\n const other = Object.hasOwn(claims, requirement.equalsClaim) ? claims[requirement.equalsClaim] : undefined;\n return typeof value === 'string' && value === other;\n }\n default: {\n const unhandled: never = requirement;\n return unhandled;\n }\n }\n}\n\n/**\n * What makes a declaration of ID token requirements unusable: a requirement with no claim or no value, and any\n * requirement on a contract that does not ask for `openid`, without which \"the behavior is entirely unspecified\" and\n * no ID token is returned to read.\n * spec-cite: OpenID Connect Core 1.0 §3.1.2.1 — the `scope` parameter row (\"If the openid scope value is not present,\n * the behavior is entirely unspecified\").\n */\nexport function describeProviderOAuth2IdTokenRequirementDefects(oauth2: Pick<ProviderRestOAuth2, 'idTokenRequirements' | 'scopes' | 'reportedAccountFacts' | 'idTokenIssuer'>): string[] {\n const requirements = oauth2.idTokenRequirements ?? [];\n const readsIdTokenFacts = Object.values(oauth2.reportedAccountFacts ?? {}).some((fact) => fact.source === ProviderOAuth2ReportedFactSource.ID_TOKEN_CLAIMS);\n if (requirements.length === 0 && !readsIdTokenFacts) return [];\n const defects: string[] = [];\n if (!(oauth2.scopes ?? []).includes('openid')) defects.push('reads ID token claims without asking for the `openid` scope, so no ID token is returned to read them from');\n // OpenID Connect Core §3.1.3.7 item 2: a claim is used only from a token naming the expected issuer.\n if (oauth2.idTokenIssuer === undefined || oauth2.idTokenIssuer.trim().length === 0) {\n defects.push('reads ID token claims without declaring `idTokenIssuer`, the issuer a token must name before any of its claims is used');\n } else if (!oauth2.idTokenIssuer.startsWith('https://')) {\n defects.push(`declares \\`idTokenIssuer\\` ${JSON.stringify(oauth2.idTokenIssuer)}, which is not an https URL as an OpenID issuer identifier is`);\n }\n for (const [index, requirement] of requirements.entries()) {\n if (requirement.claim.trim().length === 0) defects.push(`ID token requirement ${index} names no claim`);\n if (requirement.kind === ProviderOAuth2IdTokenRequirementKind.CLAIM_CONTAINS_ANY && requirement.values.length === 0) {\n defects.push(`ID token requirement ${index} (${requirement.claim}) admits no value, so no sign-in could meet it`);\n }\n if (requirement.kind === ProviderOAuth2IdTokenRequirementKind.CLAIM_EQUALS_CLAIM_WHEN_PRESENT && requirement.equalsClaim.trim().length === 0) {\n defects.push(`ID token requirement ${index} (${requirement.claim}) names no claim to equal`);\n }\n }\n return defects;\n}\n\n/**\n * Whether a vendor-reported value may stand as one path segment under its fact's declared\n * {@link ProviderOAuth2ReportedAccountFact.pathSegmentPattern} (#3397): the WHOLE value matches the pattern, and it is\n * not empty, not a dot-segment and holds no `/`, whatever the pattern admits. The one admission, applied where the value\n * is captured (the authorization) and where it is spent (every call). A pattern that does not compile admits nothing.\n */\nexport function providerReportedPathSegmentAdmits(pattern: string, value: string): boolean {\n if (value.length === 0 || value === '.' || value === '..' || value.includes('/')) return false;\n let expression: RegExp;\n try {\n expression = new RegExp(`^(?:${pattern})$`, 'u');\n } catch {\n return false;\n }\n return expression.test(value);\n}\n\n/** The REST-contract slice {@link describeProviderOAuth2ReportedFactUseDefects} reads. */\nexport interface ProviderReportedFactUseContract {\n readonly baseUrl?: string;\n readonly baseUrlConnectionFact?: string;\n readonly baseUrlHostAllowances?: Readonly<Record<string, ProviderOAuth2EndpointHostAllowance>>;\n readonly oauth2?: Pick<ProviderRestOAuth2, 'reportedAccountFacts' | 'connectionParameters'> & Partial<Pick<ProviderRestOAuth2, 'tokenUrl' | 'userInfoUrl'>>;\n}\n\n/**\n * What makes the declared USES of a connection's vendor-reported facts unsafe or unusable (#3397), checked at boot with\n * the contract's other declarations:\n *\n * - a fact read from the authorization redirect is something the person who authorized could change, so it may not be\n * an `origin`, fill a base URL host, or route inbound deliveries, and its name must be one query parameter that is\n * not the OAuth protocol's own (`code`, `state`, …);\n * - a `pathSegmentPattern` must compile, admit no empty value, and not sit beside an `origin`;\n * - a `fillsBaseUrlHost` fact must name a `{placeholder}` of the base URL that a `DECLARED_VALUES` allowance governs,\n * must not also be an `origin` or something the person is asked at connect, and cannot share a contract with\n * `baseUrlConnectionFact`, which already decides where calls go;\n * - every other `responsePath` must parse ({@link parseProviderReportedFactPath});\n * - a fact read from the userinfo answer needs a `userInfoUrl`, a `userInfoUrl` needs a fact that reads it (a request\n * carrying the person's token that nothing uses is not made), and the userinfo endpoint may carry only the\n * host-forming placeholders the token endpoint carries, in the same position (it is the same authorization server).\n */\nexport function describeProviderOAuth2ReportedFactUseDefects(contract: ProviderReportedFactUseContract): string[] {\n const defects: string[] = [];\n for (const [name, fact] of Object.entries(contract.oauth2?.reportedAccountFacts ?? {})) {\n const at = `reported fact '${name}'`;\n if (fact.source === ProviderOAuth2ReportedFactSource.AUTHORIZATION_REDIRECT_QUERY) {\n if (fact.responsePath.length === 0 || fact.responsePath.includes('.') || PROVIDER_OAUTH2_REDIRECT_PROTOCOL_PARAMETERS.includes(fact.responsePath)) {\n defects.push(`${at} reads the redirect query parameter '${fact.responsePath}', which is not one parameter name outside the OAuth protocol's own`);\n }\n if (fact.origin !== undefined || fact.fillsBaseUrlHost === true || fact.routesInboundDeliveries === true) {\n defects.push(`${at} comes from the authorization redirect, which the person authorizing could alter, so it may not decide an origin, a host or delivery routing`);\n }\n if (fact.responsePath.includes('[')) defects.push(`${at} selects inside the redirect query parameter '${fact.responsePath}', which is one string`);\n } else if (parseProviderReportedFactPath(fact.responsePath) === undefined) {\n defects.push(`${at} reads the responsePath ${JSON.stringify(fact.responsePath)}, which is not a dot path of names, each optionally selecting one element as name[field=value]`);\n }\n if (fact.source === ProviderOAuth2ReportedFactSource.USERINFO_RESPONSE && contract.oauth2?.userInfoUrl === undefined) {\n defects.push(`${at} reads the userinfo answer, and the OAuth2 contract declares no userInfoUrl`);\n }\n if (fact.pathSegmentPattern !== undefined) {\n let compiles = true;\n try {\n new RegExp(`^(?:${fact.pathSegmentPattern})$`, 'u');\n } catch {\n compiles = false;\n }\n if (!compiles) defects.push(`${at} declares the pathSegmentPattern ${JSON.stringify(fact.pathSegmentPattern)}, which does not compile`);\n else if (new RegExp(`^(?:${fact.pathSegmentPattern})$`, 'u').test('')) defects.push(`${at} declares a pathSegmentPattern that admits an empty value`);\n if (fact.origin !== undefined) defects.push(`${at} is both an origin and a path value; a fact addresses the account one way`);\n }\n if (fact.fillsBaseUrlHost === true) {\n if (fact.origin !== undefined) defects.push(`${at} is both an origin and a base URL host; a fact addresses the account one way`);\n if (contract.baseUrlConnectionFact !== undefined) defects.push(`${at} fills a base URL host beside baseUrlConnectionFact, and only one may decide where a call goes`);\n if (contract.baseUrl === undefined || !contract.baseUrl.includes(`{${name}}`)) defects.push(`${at} fills a base URL host, and the base URL carries no '{${name}}' placeholder`);\n const allowance = contract.baseUrlHostAllowances !== undefined && Object.hasOwn(contract.baseUrlHostAllowances, name) ? contract.baseUrlHostAllowances[name] : undefined;\n if (allowance?.kind !== ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES) {\n defects.push(`${at} fills a base URL host that no DECLARED_VALUES baseUrlHostAllowances entry governs`);\n }\n if ((contract.oauth2?.connectionParameters ?? []).includes(name)) defects.push(`${at} fills a base URL host the person is also asked for at connect`);\n }\n }\n const userInfoUrl = contract.oauth2?.userInfoUrl;\n if (userInfoUrl !== undefined) {\n const facts = Object.values(contract.oauth2?.reportedAccountFacts ?? {});\n if (!facts.some((fact) => fact.source === ProviderOAuth2ReportedFactSource.USERINFO_RESPONSE)) {\n defects.push('declares a userInfoUrl that no reported fact reads, so the person\\'s token would be sent there for nothing');\n }\n const templateDefects = findProviderOAuth2EndpointTemplateDefects(userInfoUrl);\n if (templateDefects.length > 0 || !userInfoUrl.toLowerCase().startsWith('https://')) {\n defects.push(`declares the userInfoUrl '${userInfoUrl}', which is not an https endpoint template (${templateDefects.join(', ') || 'not https'})`);\n } else {\n const tokenPositions = new Map<string, ProviderOAuth2EndpointPlaceholderPosition>();\n if (contract.oauth2?.tokenUrl !== undefined && findProviderOAuth2EndpointTemplateDefects(contract.oauth2.tokenUrl).length === 0) {\n for (const occurrence of classifyProviderOAuth2EndpointPlaceholders(contract.oauth2.tokenUrl)) tokenPositions.set(occurrence.name, occurrence.position);\n }\n for (const occurrence of classifyProviderOAuth2EndpointPlaceholders(userInfoUrl)) {\n if (occurrence.position === ProviderOAuth2EndpointPlaceholderPosition.PATH_OR_QUERY) {\n defects.push(`the userInfoUrl carries the path placeholder '{${occurrence.name}}'; it is one fixed endpoint of the authorization server`);\n } else if (tokenPositions.get(occurrence.name) !== occurrence.position) {\n defects.push(`the userInfoUrl's host placeholder '{${occurrence.name}}' is not the token endpoint's own, in the same position; both belong to one authorization server`);\n }\n }\n }\n }\n return defects;\n}\n\n/** The values a whole-scope placeholder admits. See {@link ProviderRestOAuth2.scopeValueAllowances}. */\nexport interface ProviderOAuth2ScopeValueAllowance {\n readonly values: readonly string[];\n /** Values the vendor's source offers and the catalogue declines, matched exactly. See {@link ProviderOAuth2UnsupportedValues}. */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n}\n\n/**\n * Values the vendor's OWN source offers for a placeholder and this catalogue deliberately does NOT admit, each mapped\n * to the reason (#1937). Keyed by the value as the source writes it.\n *\n * Not a second allow-list: the admitted set (`values`, `hosts`) alone decides what is admitted, and a value found\n * here is refused exactly as any other unadmitted value is (`VALUE_NOT_ADMITTED`, which also retires a STORED\n * connection that carries it). What this adds is the WHY. A person who chose, or a connection that stored, a value\n * the catalogue declined is told that it is unsupported and for what reason, instead of being handed a list of other\n * values as though they had made a typing mistake.\n *\n * The first entry is the US Government Microsoft clouds (`login.microsoftonline.us`, GCC High and DoD), declared out\n * of scope by product decision on 2026-09-29. The transposer writes these from the vendor record's declared\n * exclusion (`_code_archive/providers/catalogue-record/vendors/<vendor>.json` since #2019 archived the catalogue; a\n * registry provider adopted from it states them in its own module under `providers-registry/<ref>/`), so reversing a\n * decision is record edits and a regeneration, never an engine change. How many edits depends on what the decline also removed: for the US\n * Government clouds, three (the catalogue README lists them).\n */\nexport type ProviderOAuth2UnsupportedValues = Readonly<Record<string, string>>;\n\n/** How a placeholder's value is compared with a declared one. */\nexport enum ProviderOAuth2ValueComparison {\n /** A host or an origin: DNS names compare case-insensitively. spec-cite: RFC 4343 §2. */\n CASE_INSENSITIVE = 'CASE_INSENSITIVE',\n /** A scope value: scope strings are case-sensitive. spec-cite: RFC 6749 §3.3. */\n EXACT = 'EXACT',\n}\n\n/**\n * The declared reason a value is unsupported, or `undefined` when it is not declared unsupported. Compared as the\n * placeholder's values are: case-insensitively for a host or origin, exactly for a scope value.\n */\nexport function findProviderOAuth2UnsupportedValueReason(\n unsupportedValues: ProviderOAuth2UnsupportedValues | undefined,\n value: string,\n comparison: ProviderOAuth2ValueComparison,\n): string | undefined {\n if (unsupportedValues === undefined) return undefined;\n const key = comparison === ProviderOAuth2ValueComparison.EXACT\n ? (Object.hasOwn(unsupportedValues, value) ? value : undefined)\n : Object.keys(unsupportedValues).find((candidate) => candidate.toLowerCase() === value.toLowerCase());\n return key === undefined ? undefined : unsupportedValues[key];\n}\n\n/**\n * Why a declared unsupported-value map contradicts the admitted set it sits beside, or an empty list: a value both\n * admitted and declined would make the refusal reason a lie, and a declined value with no reason says nothing.\n */\nfunction describeProviderOAuth2UnsupportedValueDefects(\n unsupportedValues: ProviderOAuth2UnsupportedValues | undefined,\n admitted: readonly string[],\n comparison: ProviderOAuth2ValueComparison,\n): readonly string[] {\n if (unsupportedValues === undefined) return [];\n const defects: string[] = [];\n const normalise = (value: string): string => (comparison === ProviderOAuth2ValueComparison.EXACT ? value : value.toLowerCase());\n const admittedSet = new Set(admitted.map(normalise));\n for (const [value, reason] of Object.entries(unsupportedValues)) {\n if (admittedSet.has(normalise(value))) defects.push(`'${value}' is both admitted and declared unsupported`);\n if (typeof reason !== 'string' || reason.trim() === '') defects.push(`unsupported value '${value}' states no reason`);\n }\n return defects;\n}\n\n/**\n * Where a `{placeholder}` sits inside one OAuth2 SCOPE entry. See {@link classifyProviderOAuth2ScopePlaceholder}.\n *\n * Deliberately not {@link ProviderOAuth2EndpointPlaceholderPosition}: a scope is not a URL, and the\n * endpoint scan would call `{permissions}` an ORIGIN (it begins the string and nothing follows it).\n */\nexport enum ProviderOAuth2ScopePlaceholderPosition {\n /**\n * The placeholder begins the scope and is followed by `/` — `{hostUrl}/.default`. Its value is an\n * https ORIGIN, admitted only within {@link ProviderRestOAuth2.endpointHostAllowances}.\n */\n ORIGIN = 'ORIGIN',\n /**\n * The placeholder is the entire scope entry — `{permissions}`. Its value is one of\n * {@link ProviderRestOAuth2.scopeValueAllowances}.\n */\n WHOLE_SCOPE = 'WHOLE_SCOPE',\n}\n\n/** Why a scope entry cannot be resolved safely, whatever is supplied. See {@link findProviderOAuth2ScopeTemplateDefects}. */\nexport enum ProviderOAuth2ScopeTemplateDefect {\n /**\n * A placeholder sits anywhere except at the start of the scope followed by `/` or the end —\n * `api://{x}/.default`, `{x}.default`, `openid {x}`. Such a value would be concatenated with text\n * around it into a resource or scope nobody declared.\n */\n UNSUPPORTED_PLACEHOLDER_POSITION = 'UNSUPPORTED_PLACEHOLDER_POSITION',\n /** More than one placeholder in one scope entry: each value validated alone can compose an undeclared one. */\n SEVERAL_PLACEHOLDERS = 'SEVERAL_PLACEHOLDERS',\n /** A `{` or `}` that is not part of a well-formed placeholder: a vendor can never grant a scope carrying one. */\n STRAY_BRACE = 'STRAY_BRACE',\n}\n\n/** One `{placeholder}` in a scope entry. */\nexport interface ProviderOAuth2ScopePlaceholderOccurrence {\n readonly name: string;\n readonly position: ProviderOAuth2ScopePlaceholderPosition;\n /** The whole `{name}` token, for substitution. */\n readonly token: string;\n}\n\n/**\n * The defects that make a scope entry unsafe to resolve, or an empty list. Shared by the runtime (which\n * refuses) and the transposer (which refuses to emit), so neither admits a shape the other rejects.\n */\nexport function findProviderOAuth2ScopeTemplateDefects(scope: string): readonly ProviderOAuth2ScopeTemplateDefect[] {\n const occurrences = [...scope.matchAll(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN)];\n const withoutPlaceholders = scope.replace(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN, '');\n const defects: ProviderOAuth2ScopeTemplateDefect[] = [];\n if (withoutPlaceholders.includes('{') || withoutPlaceholders.includes('}')) defects.push(ProviderOAuth2ScopeTemplateDefect.STRAY_BRACE);\n if (occurrences.length > 1) defects.push(ProviderOAuth2ScopeTemplateDefect.SEVERAL_PLACEHOLDERS);\n const first = occurrences[0];\n if (first !== undefined) {\n const next = scope.charAt((first.index ?? 0) + first[0].length);\n if ((first.index ?? 0) !== 0 || (next !== '' && next !== '/')) defects.push(ProviderOAuth2ScopeTemplateDefect.UNSUPPORTED_PLACEHOLDER_POSITION);\n }\n return defects;\n}\n\n/**\n * Classify the one placeholder a scope entry may carry, or `undefined` when it carries none.\n *\n * ONE function, shared by the transposer and the runtime, like its endpoint counterpart. Meaningful only\n * for a scope with no {@link findProviderOAuth2ScopeTemplateDefects}; every consumer refuses those first.\n */\nexport function classifyProviderOAuth2ScopePlaceholder(scope: string): ProviderOAuth2ScopePlaceholderOccurrence | undefined {\n const match = /^\\{([A-Za-z_][A-Za-z0-9_]*)\\}/.exec(scope);\n if (match === null) return undefined;\n return {\n name: match[1]!,\n position: match[0].length === scope.length ? ProviderOAuth2ScopePlaceholderPosition.WHOLE_SCOPE : ProviderOAuth2ScopePlaceholderPosition.ORIGIN,\n token: match[0],\n };\n}\n\n/**\n * One scope token: printable ASCII except space, `\"` and backslash.\n * spec-cite: RFC 6749 §3.3 (scope-token = 1*( %x21 / %x23-5B / %x5D-7E )).\n * Braces are additionally refused: a value carrying one would read as a placeholder nobody resolves.\n */\nconst PROVIDER_OAUTH2_SCOPE_TOKEN_PATTERN = /^[\\x21\\x23-\\x5B\\x5D-\\x7A\\x7C\\x7E]+$/;\n\n/**\n * Why a declared whole-scope allowance cannot be applied, or an empty list. Enforced at generation so a\n * broken set refuses the batch; the runtime matches exactly and never trusts a value it did not declare.\n */\nexport function describeProviderOAuth2ScopeValueAllowanceDefects(allowance: ProviderOAuth2ScopeValueAllowance): readonly string[] {\n const defects: string[] = [];\n if (!Array.isArray(allowance.values) || allowance.values.length === 0) return ['a scope value allowance admits nothing'];\n for (const value of allowance.values) {\n const tokens = typeof value === 'string' ? value.split(' ') : [];\n if (typeof value !== 'string' || value.length === 0 || !tokens.every((token) => PROVIDER_OAUTH2_SCOPE_TOKEN_PATTERN.test(token))) {\n defects.push(`'${String(value)}' is not a space-delimited list of scope tokens`);\n }\n }\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, allowance.values, ProviderOAuth2ValueComparison.EXACT));\n return defects;\n}\n\n/**\n * Where a `{placeholder}` sits inside an OAuth2 endpoint template — the classification the host\n * allow-list keys on. See {@link classifyProviderOAuth2EndpointPlaceholders}.\n */\nexport enum ProviderOAuth2EndpointPlaceholderPosition {\n /**\n * The placeholder BEGINS the template, so its value is the whole scheme + authority (+ any path\n * prefix): `{baseUrl}/login/oauth/authorize`. The most dangerous position — the value names the\n * scheme as well as the host.\n */\n ORIGIN = 'ORIGIN',\n /**\n * The placeholder sits between `://` and the first `/`, `?` or `#` after it:\n * `https://{cloud}/common/…`, `https://accounts.{location}/…`. Its value decides which host\n * receives the request.\n */\n HOST = 'HOST',\n /** Anywhere after the authority. Percent-encoded, so it cannot move the request to another host. */\n PATH_OR_QUERY = 'PATH_OR_QUERY',\n}\n\n/** How a host- or origin-forming placeholder may be filled. See {@link ProviderRestOAuth2.endpointHostAllowances}. */\nexport enum ProviderOAuth2EndpointHostAllowanceKind {\n /**\n * Chosen at connect time from values the provider DECLARES — Microsoft's commercial login cloud,\n * Zoho's data centres. A value outside the set is refused; a declared value is substituted\n * verbatim (it is a hostname or origin, not a path segment to encode).\n *\n * `hostSuffixes` additionally admits `<dns-label>(.<dns-label>)*` followed by one of the suffixes,\n * for a vendor whose per-customer host is a subdomain it controls (Salesforce My Domain,\n * `<name>.my.salesforce.com`). On a HOST placeholder a suffix applies only when the placeholder is\n * the WHOLE host. On an ORIGIN placeholder it admits exactly `https://<dns-labels><suffix>` — the\n * scheme fixed to https, no port, path, userinfo, query or fragment — which is what a per-customer\n * origin such as a Dataverse environment URL (`https://<org>.crm4.dynamics.com`, #991) needs.\n */\n DECLARED_VALUES = 'DECLARED_VALUES',\n /**\n * Filled from the DEPLOYMENT's configured base URL for this provider — the REST contract's\n * `baseUrl`, or the environment variable its `baseUrlEnvVarName` names. For a self-hosted vendor\n * (Gitea) the operator names the instance once; a person connecting an account is never asked, and\n * a value they supply is refused. Admitted in the ORIGIN position only.\n */\n DEPLOYMENT_BASE_URL = 'DEPLOYMENT_BASE_URL',\n /**\n * Filled from a deployment environment variable dedicated to THIS placeholder, named by the\n * allowance's `envVarName` (#992). For a vendor whose endpoints sit on more than one per-tenant host\n * — Workday's `https://{authHost}/…/authorize` and `https://{apiHost}/…/token` — one base URL cannot\n * name both, so each host is its own operator setting (`WORKDAY_AUTH_HOST`, `WORKDAY_API_HOST`).\n *\n * Like DEPLOYMENT_BASE_URL, never asked of a person connecting, and a value they supply is refused.\n * The trade is explicit: the application serves the one vendor tenant (data centre) the operator\n * names. Admitted on a HOST placeholder that is the whole host, with a DNS-name value.\n */\n DEPLOYMENT_CONFIGURED = 'DEPLOYMENT_CONFIGURED',\n /**\n * DERIVED from another connect-time answer through a declared table (#1937): Microsoft Graph's operation host follows\n * the login cloud the connection chose (`login.microsoftonline.com` → `graph.microsoft.com`), because a token minted by\n * one national cloud is not accepted by another. The Microsoft source also maps the US Government login cloud; that\n * row is declined (`unsupportedValues`), because US Government clouds are out of scope (decision of 2026-09-29).\n *\n * Never asked of a person and never taken from a request: the value is looked up from the ANSWER the connection\n * stored for `answer`, and an answer the table does not name is refused. `whenUnanswered` is the host for a connection\n * that answered nothing (the application's own pasted credential); absent, such a connection is refused. The table is\n * the allow-list, so no other host can result. Admitted on a HOST placeholder that is the whole host.\n *\n * spec-cite: https://learn.microsoft.com/en-us/graph/deployments — \"Access tokens acquired for a national cloud\n * deployment are not interchangeable with those acquired for the global service or any other national cloud.\"\n */\n DERIVED_FROM_CONNECTION_ANSWER = 'DERIVED_FROM_CONNECTION_ANSWER',\n}\n\nexport type ProviderOAuth2EndpointHostAllowance =\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DECLARED_VALUES;\n /** Exact admitted values, compared case-insensitively. A hostname for HOST, an origin for ORIGIN. */\n readonly values: readonly string[];\n /**\n * A whole HOST, or an ORIGIN (admitting `https://<labels><suffix>` only). Each MUST begin with `.`,\n * so `evilmy.salesforce.com` never matches `.my.salesforce.com`.\n */\n readonly hostSuffixes?: readonly string[];\n /**\n * The MOST DNS labels an admitted host may carry before its suffix (#3640); absent, any number. Applies to every\n * entry of `hostSuffixes`, and only to them (an exact `values` entry is admitted as written).\n *\n * Declared only where the VENDOR documents the shape. Shopify does: a store host is exactly one label under\n * `.myshopify.com` (\"Confirm the `shop` parameter matches `^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com$`\"), so it\n * declares `1`. Without the bound, a person answering `shop` with the full domain they see, `acme.myshopify.com`,\n * composed `acme.myshopify.com.myshopify.com`: a host under the suffix that does not exist, which failed every\n * request on DNS. (That answer is now also stripped to its handle, see `stripProviderHostAnswerTemplateSuffix`; the\n * bound is what refuses `acme.evil.myshopify.com`, naming the expected form.)\n * spec-cite: https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant —\n * the `shop` parameter check, as quoted in the Shopify module's header (fetched 2026-11-10).\n *\n * Every place a suffix admits a host reads it, through `providerHostIsUnderSuffix`: the answer filled into an endpoint\n * or base URL, the token-endpoint host description, the declined-value check. A positive integer, with at least one\n * suffix (`describeProviderOAuth2EndpointHostAllowanceDefects`).\n */\n readonly hostSuffixMaxLabels?: number;\n /**\n * ORIGIN only: an admitted value must ALSO have the same origin as the deployment's configured base\n * URL (the REST contract's `baseUrl` / `baseUrlEnvVarName`) (#991 review F4).\n *\n * For a vendor whose token is minted for a per-customer environment and whose operations dial the\n * operator's configured instance — Dataverse mints for the scope's `{hostUrl}` while operations go to\n * `MICROSOFT_DYNAMICS_CRM_BASE_URL` — a connection naming another environment would hold a token that\n * fails every call. So the two are required to agree at connect, and an unset base URL refuses the\n * connect as a deployment gap rather than minting a token nothing can use.\n */\n readonly originMatchesDeploymentBaseUrl?: true;\n /** Values the vendor's source offers and the catalogue declines, with the reason. See {@link ProviderOAuth2UnsupportedValues}. */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED;\n /**\n * The deployment environment variable holding the host — derived by the transposer as\n * `<PROVIDER_ENV_PREFIX>_<PLACEHOLDER_IN_SCREAMING_SNAKE>` and declared as a REGISTRATION secret slot,\n * without which the runtime environment builder would strip it.\n */\n readonly envVarName: string;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DERIVED_FROM_CONNECTION_ANSWER;\n /** The connect-time answer the host is derived from (`cloud`) — itself a placeholder of the same provider. */\n readonly answer: string;\n /** Per answer value (compared case-insensitively), the host it selects. DNS names. */\n readonly hosts: Readonly<Record<string, string>>;\n /** The host when the connection answered nothing; absent, an unanswered connection is refused. */\n readonly whenUnanswered?: string;\n /**\n * ANSWER values the vendor's source maps to a host and the catalogue declines, with the reason — so a stored\n * connection carrying one is refused at use naming why. See {@link ProviderOAuth2UnsupportedValues}.\n */\n readonly unsupportedValues?: ProviderOAuth2UnsupportedValues;\n }\n | {\n readonly kind: ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL;\n /**\n * A path the configured base URL carries and the OAuth2 endpoints do NOT — stripped before\n * substitution, and REQUIRED to be present. Gitea's operation base is `<instance>/api/v1` while\n * its OAuth2 endpoints hang off `<instance>`; stripping keeps an instance served under a sub-path\n * correct, where taking only the origin would drop it.\n */\n readonly baseUrlPathSuffix?: string;\n };\n\n/** One `{placeholder}` occurrence in an OAuth2 endpoint template. */\nexport interface ProviderOAuth2EndpointPlaceholderOccurrence {\n readonly name: string;\n readonly position: ProviderOAuth2EndpointPlaceholderPosition;\n /** Offset of the opening brace in the template. */\n readonly index: number;\n /** The whole `{name}` token, for substitution. */\n readonly token: string;\n /**\n * HOST only: the token is the ENTIRE authority (`https://{cloud}/…`), as opposed to one part of it\n * (`https://accounts.{location}/…`). A declared host SUFFIX is only meaningful for a whole host — on a\n * partial one it would be concatenated with the text around it and admit a host nobody declared.\n */\n readonly occupiesWholeHost: boolean;\n /**\n * HOST only: when the token OPENS the authority and is followed by literal text up to the end of the authority —\n * `https://{subdomain}.zendesk.com/…` → `.zendesk.com` — that literal text (#1015). A declared host SUFFIX equal to it\n * bounds the composed host exactly as it bounds a whole host: the value is DNS labels, the template's own literal\n * supplies the suffix, and `<labels>.zendesk.com` is the only shape that can result. Absent for a whole host, for a\n * token that does not open the host (`accounts.{location}`), and for an ORIGIN or PATH token.\n */\n readonly literalHostSuffix?: string;\n}\n\n/**\n * Why an OAuth2 endpoint TEMPLATE cannot be resolved safely, whatever values are supplied.\n * See {@link findProviderOAuth2EndpointTemplateDefects}.\n */\nexport enum ProviderOAuth2EndpointTemplateDefect {\n /**\n * The template neither begins `http://` / `https://` nor begins with a placeholder. The WHATWG URL\n * parser reads `https:/{h}/t`, `https:{h}/t` and `https:` + two backslashes + `{h}/t` as `https://h/t`, so a string scan\n * for `://` would call `{h}` a PATH placeholder, encode it (a hostname survives encoding untouched),\n * and send the request — and the client secret — to whatever a caller typed.\n */\n NOT_AN_ABSOLUTE_TEMPLATE = 'NOT_AN_ABSOLUTE_TEMPLATE',\n /**\n * An ORIGIN placeholder is followed by something other than `/`, `?`, `#` or the end —\n * `{baseUrl}.evil.test/…`, `{baseUrl}:8443/…`, `{a}{b}/…`. The text after it would extend the host\n * the origin value names.\n */\n ORIGIN_NOT_TERMINATED = 'ORIGIN_NOT_TERMINATED',\n /**\n * One authority carries more than one placeholder (`https://{a}{b}/…`, `https://{sub}.{domain}/…`).\n * Each value validated alone can still compose a host no declaration admits.\n */\n SEVERAL_PLACEHOLDERS_IN_AUTHORITY = 'SEVERAL_PLACEHOLDERS_IN_AUTHORITY',\n /**\n * The authority after `://` is empty, begins with `/` or a backslash, or carries a backslash or `@`\n * before the first `/`, `?` or `#`. The parser skips extra slashes (`https:///{h}/t` dials `{h}` as the\n * HOST, while the `://` scan sees an empty authority and calls `{h}` a PATH), reads a backslash as a\n * path separator, and\n * reads text before `@` as userinfo — each makes the scan and the parser disagree about the host.\n */\n MALFORMED_AUTHORITY = 'MALFORMED_AUTHORITY',\n}\n\n/**\n * A DNS name: one or more LDH labels, lower-case (callers lower-case first).\n * spec-cite: RFC 1123 §2.1 (a label may begin with a digit) and RFC 1035 §2.3.1 (letters, digits,\n * hyphen; 63 octets per label).\n */\nexport const PROVIDER_OAUTH2_DNS_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/;\n\n/**\n * Whether `host` is `<labels><suffix>`: it ends with the dotted `suffix`, what precedes the suffix is a DNS name (never\n * empty, so the bare suffix is not admitted), and that DNS name carries at most `maxLabels` labels (#3640).\n *\n * THE one suffix test. Every place a declared host suffix admits a host — an answer filled into an endpoint or a base URL,\n * an audience selecting a request host, the token-endpoint host description, a declined value a suffix would still admit —\n * asks this function, so a label bound declared once holds at all of them. `maxLabels` absent means unbounded, which is\n * what every suffix meant before the bound existed. A bound that is not a positive integer admits nothing (fail closed):\n * the declaration checks refuse it where a person is reading a diff, and this keeps the runtime closed regardless.\n *\n * Case-insensitive; the caller need not lower-case.\n */\nexport function providerHostIsUnderSuffix(host: string, suffix: string, maxLabels?: number): boolean {\n const candidate = host.toLowerCase();\n const lowered = suffix.toLowerCase();\n if (!lowered.startsWith('.') || !candidate.endsWith(lowered) || candidate.length === lowered.length) return false;\n const labels = candidate.slice(0, candidate.length - lowered.length);\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(labels)) return false;\n return maxLabels === undefined || labels.split('.').length <= maxLabels;\n}\n\n/** One declared host suffix with its label bound, as {@link providerHostSuffixesOverlap} compares them. */\nexport interface ProviderHostSuffixBound {\n readonly suffix: string;\n /** At most this many DNS labels before the suffix; absent, unbounded. See {@link providerHostIsUnderSuffix}. */\n readonly maxLabels?: number;\n}\n\n/**\n * Whether some host is admitted under BOTH suffixes (#3640). Two suffixes can only share a host when one ends with the\n * other (`.a.b` and `.b`): a host under the longer one carries the extra labels (`.a`) before the shorter one, so the\n * shorter one's bound must leave room for one label of its own plus those. Equal suffixes always share a host.\n */\nexport function providerHostSuffixesOverlap(left: ProviderHostSuffixBound, right: ProviderHostSuffixBound): boolean {\n const leftSuffix = left.suffix.toLowerCase();\n const rightSuffix = right.suffix.toLowerCase();\n const [longer, shorter] = leftSuffix.length >= rightSuffix.length ? [left, right] : [right, left];\n const longerSuffix = longer.suffix.toLowerCase();\n const shorterSuffix = shorter.suffix.toLowerCase();\n if (!longerSuffix.endsWith(shorterSuffix)) return false;\n // The probe host: one label under the longer suffix, which is the fewest labels any host under it carries.\n return providerHostIsUnderSuffix(`a${longerSuffix}`, longerSuffix, longer.maxLabels) && providerHostIsUnderSuffix(`a${longerSuffix}`, shorterSuffix, shorter.maxLabels);\n}\n\n/**\n * The bare answer for a placeholder that OPENS a host, when the person typed the whole host (#3640).\n *\n * `https://{shop}.myshopify.com` asks for the store's handle, and the person connecting sees `acme.myshopify.com` in the\n * vendor's own screens. Filled verbatim, that answer dials `acme.myshopify.com.myshopify.com`: a host the suffix admits\n * (it ends in `.myshopify.com`) that does not exist, so every request fails on DNS naming a host rather than the answer.\n * The literal text the template writes after the placeholder (`literalHostSuffix`) is therefore stripped ONCE from an\n * answer that ends with it: `acme.myshopify.com` → `acme`. Nothing else is rewritten; the result is then admitted like\n * any other answer, so an answer with too many labels left (`acme.evil.myshopify.com` → `acme.evil` under a one-label\n * bound) is still refused.\n *\n * Generic rather than per vendor, because it is a property of the TEMPLATE: every provider whose host opens with a\n * placeholder (Shopify, Zendesk) asks for the part before a literal the vendor shows people with it attached. Done where\n * the template is filled, not in a connect prompt, so the OAuth start, the stored-answer re-admission and every\n * operation's base URL read the same answer the same way, whichever screen or flag supplied it. A host that literally\n * repeated its suffix is never a real vendor host, so nothing a person could mean is lost.\n */\nexport function stripProviderHostAnswerTemplateSuffix(value: string, literalHostSuffix: string | undefined): string {\n if (literalHostSuffix === undefined || literalHostSuffix === '') return value;\n return value.length > literalHostSuffix.length && value.toLowerCase().endsWith(literalHostSuffix.toLowerCase())\n ? value.slice(0, value.length - literalHostSuffix.length)\n : value;\n}\n\n/**\n * The words a refusal uses for the answer a bounded suffix expects (#3640): `a single DNS label before .myshopify.com\n * (the 'acme' of acme.myshopify.com)`. Shared so every refusal names the same form.\n */\nexport function describeProviderHostSuffixExpectedForm(suffix: string, maxLabels: number | undefined, answerExcludesSuffix: boolean): string {\n const count = maxLabels === undefined ? 'DNS labels' : maxLabels === 1 ? 'a single DNS label' : `at most ${maxLabels} DNS labels`;\n const example = answerExcludesSuffix ? `the 'acme' of acme${suffix}` : `acme${suffix}`;\n return `${count} before ${suffix} (${example})`;\n}\n\n/**\n * Why a declared label bound on host suffixes cannot be honoured (#3640): it is not a positive integer, or there is no\n * suffix for it to bound. Shared by the endpoint allowances and the audiences, so both refuse the same shapes.\n */\nexport function describeProviderHostSuffixMaxLabelsDefects(maxLabels: number | undefined, hostSuffixes: readonly string[] | undefined): string[] {\n if (maxLabels === undefined) return [];\n const defects: string[] = [];\n if (!Number.isInteger(maxLabels) || maxLabels < 1) defects.push(`hostSuffixMaxLabels ${String(maxLabels)} is not a positive integer, which admits no host`);\n if ((hostSuffixes ?? []).length === 0) defects.push('hostSuffixMaxLabels is declared with no hostSuffixes to bound');\n return defects;\n}\n\n/**\n * Why a DECLARED host allowance cannot be applied where its placeholder sits — the position rules the\n * transposer enforces at GENERATION time, so a broken declaration refuses the batch instead of being\n * emitted and refused at every connect. Empty when the allowance is sound.\n *\n * The runtime resolver refuses each of these too; this exists so they are caught where a human is\n * already looking at a diff rather than where a person is pressing Connect.\n */\nexport function describeProviderOAuth2EndpointHostAllowanceDefects(\n placeholder: { readonly position: ProviderOAuth2EndpointPlaceholderPosition; readonly occupiesWholeHost: boolean; readonly literalHostSuffix?: string },\n allowance: ProviderOAuth2EndpointHostAllowance,\n): readonly string[] {\n const defects: string[] = [];\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.PATH_OR_QUERY) {\n return ['a PATH or QUERY placeholder takes no host allowance'];\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_BASE_URL) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n defects.push('DEPLOYMENT_BASE_URL fills an ORIGIN only, and this placeholder does not begin its endpoint');\n }\n if (allowance.baseUrlPathSuffix !== undefined && !/^\\/[^?#]*[^/?#]$/.test(allowance.baseUrlPathSuffix)) {\n defects.push(`baseUrlPathSuffix '${allowance.baseUrlPathSuffix}' must begin with '/' and name a path (no trailing '/', query or fragment)`);\n }\n return defects;\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DERIVED_FROM_CONNECTION_ANSWER) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.HOST || !placeholder.occupiesWholeHost) {\n defects.push('DERIVED_FROM_CONNECTION_ANSWER fills a WHOLE HOST only, and this placeholder is not one');\n }\n if (typeof allowance.answer !== 'string' || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(allowance.answer)) {\n defects.push(`answer '${String(allowance.answer)}' is not a placeholder name`);\n }\n const hosts = Object.values(allowance.hosts ?? {});\n if (hosts.length === 0) defects.push('DERIVED_FROM_CONNECTION_ANSWER maps no answer to a host, which admits nothing');\n for (const host of [...hosts, ...(allowance.whenUnanswered === undefined ? [] : [allowance.whenUnanswered])]) {\n if (typeof host !== 'string' || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(host.toLowerCase())) defects.push(`'${String(host)}' is not a DNS name`);\n }\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, Object.keys(allowance.hosts ?? {}), ProviderOAuth2ValueComparison.CASE_INSENSITIVE));\n return defects;\n }\n if (allowance.kind === ProviderOAuth2EndpointHostAllowanceKind.DEPLOYMENT_CONFIGURED) {\n if (placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.HOST || !placeholder.occupiesWholeHost) {\n defects.push('DEPLOYMENT_CONFIGURED fills a WHOLE HOST only, and this placeholder is not one');\n }\n if (typeof allowance.envVarName !== 'string' || !/^[A-Z][A-Z0-9_]*$/.test(allowance.envVarName)) {\n defects.push(`envVarName '${String(allowance.envVarName)}' is not an upper-case environment variable name`);\n }\n return defects;\n }\n if (allowance.originMatchesDeploymentBaseUrl === true && placeholder.position !== ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n defects.push('originMatchesDeploymentBaseUrl applies to an ORIGIN only, and this placeholder is not one');\n }\n if (allowance.values.length === 0 && (allowance.hostSuffixes ?? []).length === 0) {\n defects.push('DECLARED_VALUES admits nothing');\n }\n for (const value of allowance.values) {\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.ORIGIN) {\n // Matched as text, not with `URL`: this package compiles without a DOM or Node lib. A lower-case\n // `https://` + DNS name, with nothing after the host but an optional port, is exactly an origin as\n // `URL#origin` would print it back.\n const match = /^https:\\/\\/([^:/?#@]+)(?::\\d{1,5})?$/.exec(value);\n if (match === null || !PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(match[1]!)) {\n defects.push(`'${value}' is not an https origin (scheme and lower-case host only)`);\n }\n } else if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(value.toLowerCase())) {\n defects.push(`'${value}' is not a DNS name`);\n }\n }\n for (const suffix of allowance.hostSuffixes ?? []) {\n // An ORIGIN is a whole authority by construction (the scheme is then fixed to https); a HOST\n // placeholder qualifies only when nothing surrounds it inside the authority.\n // A placeholder that OPENS the host qualifies too, but only for the ONE suffix the template itself writes after\n // it (#1015): any other suffix would be concatenated with that literal into a host nobody declared.\n const opensHostWithThisSuffix = placeholder.literalHostSuffix !== undefined && placeholder.literalHostSuffix.toLowerCase() === suffix.toLowerCase();\n if (placeholder.position === ProviderOAuth2EndpointPlaceholderPosition.HOST && !placeholder.occupiesWholeHost && !opensHostWithThisSuffix) {\n defects.push(`host suffix '${suffix}' on a placeholder that is not the whole host`);\n continue;\n }\n const labels = suffix.startsWith('.') ? suffix.slice(1) : '';\n if (!PROVIDER_OAUTH2_DNS_NAME_PATTERN.test(labels.toLowerCase()) || !labels.includes('.')) {\n defects.push(`host suffix '${suffix}' must begin with '.' and name at least two DNS labels (a bare '.com' admits every host under a TLD)`);\n }\n }\n defects.push(...describeProviderHostSuffixMaxLabelsDefects(allowance.hostSuffixMaxLabels, allowance.hostSuffixes));\n defects.push(...describeProviderOAuth2UnsupportedValueDefects(allowance.unsupportedValues, allowance.values, ProviderOAuth2ValueComparison.CASE_INSENSITIVE));\n for (const declined of Object.keys(allowance.unsupportedValues ?? {})) {\n // A declined value a declared SUFFIX would still admit is admitted, whatever the reason says.\n // ORIGIN values carry the scheme; the suffix is matched against the host they name.\n const declinedHost = declined.toLowerCase().replace(/^https:\\/\\//, '');\n const coveringSuffix = (allowance.hostSuffixes ?? []).find((suffix) => providerHostIsUnderSuffix(declinedHost, suffix, allowance.hostSuffixMaxLabels));\n if (coveringSuffix !== undefined) defects.push(`'${declined}' is declared unsupported but the host suffix '${coveringSuffix}' admits it`);\n }\n return defects;\n}\n\n/**\n * The defects that make a template unsafe to resolve, or an empty list. Shared by the runtime (which\n * refuses) and the transposer (which refuses to emit), so neither can admit a shape the other rejects.\n */\nexport function findProviderOAuth2EndpointTemplateDefects(template: string): readonly ProviderOAuth2EndpointTemplateDefect[] {\n const defects: ProviderOAuth2EndpointTemplateDefect[] = [];\n const leadingPlaceholder = /^\\{[A-Za-z_][A-Za-z0-9_]*\\}/.exec(template);\n if (!/^https?:\\/\\//i.test(template) && leadingPlaceholder === null) {\n return [ProviderOAuth2EndpointTemplateDefect.NOT_AN_ABSOLUTE_TEMPLATE];\n }\n if (leadingPlaceholder !== null) {\n const next = template.charAt(leadingPlaceholder[0].length);\n if (next !== '' && next !== '/' && next !== '?' && next !== '#') defects.push(ProviderOAuth2EndpointTemplateDefect.ORIGIN_NOT_TERMINATED);\n } else {\n const afterScheme = template.slice(template.indexOf('://') + 3);\n const authorityEnd = afterScheme.search(/[/?#]/);\n const authority = authorityEnd < 0 ? afterScheme : afterScheme.slice(0, authorityEnd);\n if (authority === '' || authority.includes('\\\\') || authority.includes('@')) {\n defects.push(ProviderOAuth2EndpointTemplateDefect.MALFORMED_AUTHORITY);\n return defects;\n }\n const hostPlaceholders = classifyProviderOAuth2EndpointPlaceholders(template)\n .filter((occurrence) => occurrence.position === ProviderOAuth2EndpointPlaceholderPosition.HOST);\n if (hostPlaceholders.length > 1) defects.push(ProviderOAuth2EndpointTemplateDefect.SEVERAL_PLACEHOLDERS_IN_AUTHORITY);\n }\n return defects;\n}\n\n/** The placeholder syntax an endpoint template uses — the same braces the operation path templates use. */\nexport const PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN = /\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g;\n\n/**\n * Classify every placeholder in an OAuth2 endpoint template by the URL component it forms.\n *\n * ONE function, shared by the transposer (which decides which placeholders need an allowance) and\n * the runtime (which refuses an unallowed one), so the two cannot disagree about what a host is.\n *\n * Deliberately a string scan, not a URL parse: a template whose host is still `{cloud}` is not a\n * parseable URL, which is exactly the population this classifies.\n *\n * - offset 0 → {@link ProviderOAuth2EndpointPlaceholderPosition.ORIGIN};\n * - between the first `://` and the next `/`, `?` or `#` → HOST;\n * - otherwise → PATH_OR_QUERY.\n *\n * This classification is only meaningful for a template with no\n * {@link findProviderOAuth2EndpointTemplateDefects}: a template that does not begin `http(s)://` or a\n * placeholder has no authority this scan can find, and every consumer must refuse it FIRST rather than\n * trust the PATH_OR_QUERY answer it would get here.\n */\nexport function classifyProviderOAuth2EndpointPlaceholders(template: string): readonly ProviderOAuth2EndpointPlaceholderOccurrence[] {\n const schemeSeparator = template.indexOf('://');\n let authorityEnd = -1;\n if (schemeSeparator >= 0) {\n const rest = template.slice(schemeSeparator + 3);\n const end = rest.search(/[/?#]/);\n authorityEnd = end < 0 ? template.length : schemeSeparator + 3 + end;\n }\n const occurrences: ProviderOAuth2EndpointPlaceholderOccurrence[] = [];\n for (const match of template.matchAll(PROVIDER_OAUTH2_ENDPOINT_PLACEHOLDER_PATTERN)) {\n const index = match.index ?? 0;\n const position = index === 0\n ? ProviderOAuth2EndpointPlaceholderPosition.ORIGIN\n : schemeSeparator >= 0 && index > schemeSeparator && index < authorityEnd\n ? ProviderOAuth2EndpointPlaceholderPosition.HOST\n : ProviderOAuth2EndpointPlaceholderPosition.PATH_OR_QUERY;\n const occupiesWholeHost = position === ProviderOAuth2EndpointPlaceholderPosition.HOST\n && index === schemeSeparator + 3\n && index + match[0].length === authorityEnd;\n const followingLiteral = position === ProviderOAuth2EndpointPlaceholderPosition.HOST && !occupiesWholeHost && index === schemeSeparator + 3\n ? template.slice(index + match[0].length, authorityEnd)\n : undefined;\n // Only a PURELY literal remainder qualifies: a second placeholder in the authority is refused as malformed anyway.\n const literalHostSuffix = followingLiteral !== undefined && followingLiteral.startsWith('.') && !followingLiteral.includes('{') ? followingLiteral : undefined;\n occurrences.push({ name: match[1]!, position, index, token: match[0], occupiesWholeHost, ...(literalHostSuffix === undefined ? {} : { literalHostSuffix }) });\n }\n return occurrences;\n}\n\n\n/**\n * Vendors whose credential is COMPUTED per request rather than sent as a fixed header.\n *\n * A static header covers bearer tokens and API keys, which is most of the world. It cannot express a\n * signature: AWS Signature Version 4 signs the method, the canonical path, the sorted query, a\n * subset of headers, a SHA-256 of the payload and a timestamp, with a key derived from the secret,\n * the date, the region and the service — so the header's VALUE differs for every request and none of\n * its inputs exist when a provider module is authored.\n *\n * Until this existed, such a vendor could not be expressed at all — not badly, not partially. There\n * was no `if` to write, because the field where the answer goes did not exist. 45 transposed actions\n * across `amazon-s3`, `amazon-ses`, `amazon-textract`, `amazon-secrets-manager`, `amazon-sqs`,\n * `amazon-bedrock`, `azure-blob-storage`, `azure-communication-services` and `azure-openai` are\n * blocked on it (#373).\n */\nexport enum ProviderRestSigningScheme {\n /**\n * AWS Signature Version 4 — the `Authorization: AWS4-HMAC-SHA256 …` scheme used by every current\n * AWS service API.\n * spec-cite: AWS General Reference, \"Signature Version 4 signing process\"\n * (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv4-signing-process.html)\n */\n AWS_SIGV4 = 'AWS_SIGV4',\n /**\n * Azure Storage shared-key — `Authorization: SharedKey <account>:<signature>` over a canonicalized\n * request and resource.\n * spec-cite: Azure Storage REST, \"Authorize with Shared Key\"\n * (https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key)\n */\n AZURE_SHARED_KEY = 'AZURE_SHARED_KEY',\n}\n\n/**\n * How a provider signs each request.\n *\n * Declared by the provider module and executed by the engine, with NO vendor branch in the executor:\n * the scheme is data, and the signer dispatches on it exhaustively. That is the same discipline the\n * rest of the provider contract keeps — a consumer branches on a contract field, never on a\n * provider ref.\n *\n * The credential is TWO values for both schemes (an identity and a secret), and optionally a third\n * for temporary credentials, which is why it cannot ride in the single `apiKey.secretRef` slot.\n */\nexport interface ProviderRestRequestSigning {\n readonly scheme: ProviderRestSigningScheme;\n /** Env-var naming the identity half — an AWS access-key id, an Azure storage account name. */\n readonly keyIdSecretRef: string;\n /** Env-var naming the secret half. */\n readonly secretKeySecretRef: string;\n /**\n * Env-var naming a session token, for temporary credentials (STS, a role assumption). Absent means\n * long-lived credentials; present-but-unset is treated as long-lived rather than as an error,\n * because the same provider serves both.\n */\n readonly sessionTokenSecretRef?: string;\n /**\n * AWS_SIGV4: the region and service that scope the derived key. Both are part of the SIGNATURE,\n * not merely of the URL, so a wrong value fails authentication rather than routing — which is why\n * they are declared rather than parsed out of the host.\n */\n readonly region?: string;\n readonly service?: string;\n /**\n * Env-var overriding {@link region} per deployment, for an application that runs in more than one.\n * The declared value is the default.\n */\n readonly regionEnvVarName?: string;\n}\n\n/**\n * The one function a generated typed client needs, as a TYPE.\n *\n * A generated provider package must not import the engine's runtime to be callable: that would put\n * the whole backend into the module graph of anything that touches a vendor, which is precisely the\n * weight #378 removed (models 20.8 MB against the backend barrel's 160.7 MB). So a client is a\n * FACTORY that takes the executor as an argument — the application wires its own, the package\n * declares only this signature, and nothing crosses at runtime.\n *\n * R3's ergonomics bought with a type rather than a dependency.\n *\n * ## The connection is a parameter, and OPTIONAL for a reason that is not convenience\n *\n * Omitted means the application's own account, acting as itself — the floor, and the only connection\n * that needs no store and no authorization. That default is what keeps the ordinary single-account\n * call as short as it should be.\n *\n * It could not be anything BUT a parameter. One execution may legitimately spend several tenants'\n * accounts — a user action pushing a message to every organization that user belongs to — so a client\n * that read the owner from ambient state could not vary it per call, and the fan-out would be\n * inexpressible through the generated surface even though the engine beneath it supports one.\n */\nexport type ProviderOperationExecute = (\n providerRef: string,\n operationId: string,\n input: Readonly<Record<string, unknown>>,\n connection?: ExternalProvider_ConnectionTarget,\n) => Promise<unknown>;\n"]}
|