@particle-academy/fancy-connector-core 0.11.0 → 0.13.0

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/index.d.cts CHANGED
@@ -1474,6 +1474,58 @@ declare function idempotencyKeyFor(ctx: unknown, nodeId: string, options?: Idemp
1474
1474
  */
1475
1475
  declare const NO_IDEMPOTENCY_KEY_WARNING: string;
1476
1476
 
1477
+ /**
1478
+ * RS256 JWT verification against keys the HOST supplies.
1479
+ *
1480
+ * Gmail's Pub/Sub push carries an OIDC token, and a Gmail add-on's requests
1481
+ * carry a Google-signed one; both are RS256 JWS compact tokens. This verifies
1482
+ * one. It NEVER fetches a key set: nothing in this package contacts a URL of
1483
+ * its own, so the host fetches and caches the provider's JWKS and passes the
1484
+ * keys in. The PHP twin is `Jwt::verify`, and both runtimes read
1485
+ * `fixtures/jwt/cases.json`, led by RFC 7515 Appendix A.2.
1486
+ *
1487
+ * Every rule fails CLOSED, and each is a known way JWT verification goes wrong:
1488
+ * - RS256 only. `none` and `HS256` are refused BY NAME before anything else;
1489
+ * HS256 keyed with the public key is the classic confusion attack.
1490
+ * - A `kid` must name a supplied key. An unknown kid is refused, never
1491
+ * "try every key".
1492
+ * - `exp` is REQUIRED: a token that never expires is refused. `nbf` is honoured.
1493
+ * Both allow `leeway` seconds of clock skew (default 60).
1494
+ * - The audience is REQUIRED. A caller that deliberately checks none must pass
1495
+ * `audience: null`, so forgetting it cannot happen by omission.
1496
+ * - The issuer is matched when one is given.
1497
+ */
1498
+ /** An RSA public key as a JWKS lists it. Extra members are ignored. */
1499
+ type Jwk = {
1500
+ kty: string;
1501
+ n?: string;
1502
+ e?: string;
1503
+ kid?: string;
1504
+ alg?: string;
1505
+ use?: string;
1506
+ };
1507
+ type JwtVerification = {
1508
+ ok: true;
1509
+ header: Record<string, unknown>;
1510
+ claims: Record<string, unknown>;
1511
+ } | {
1512
+ ok: false;
1513
+ reason: string;
1514
+ };
1515
+ type VerifyJwtOptions = {
1516
+ keys: readonly Jwk[];
1517
+ /** REQUIRED: the expected `aud` (any of a list), or `null` to check none ON PURPOSE. */
1518
+ audience: string | readonly string[] | null;
1519
+ issuer?: string | readonly string[];
1520
+ /** Seconds since the epoch. Injected so tests are not clock-dependent. */
1521
+ now?: number;
1522
+ /** Allowed clock skew for exp and nbf, in seconds. */
1523
+ leeway?: number;
1524
+ };
1525
+ /** The algorithms accepted. Closed, and shipped as data. */
1526
+ declare const JWT_ALGORITHMS: readonly ["RS256"];
1527
+ declare function verifyJwt(token: string, options: VerifyJwtOptions): Promise<JwtVerification>;
1528
+
1477
1529
  /**
1478
1530
  * A subscription that EXPIRES, and when the host must act on it.
1479
1531
  *
@@ -2319,105 +2371,15 @@ declare function decodeFormFieldJson(raw: Uint8Array | string, field: string): u
2319
2371
  * then calls `decodeDelivery` with the declaration, then starts the run.
2320
2372
  * Shipped as data too, for a host mirroring the union across a JSON boundary.
2321
2373
  */
2322
- declare const DELIVERY_DECODE_KINDS: readonly ["form-field-json"];
2374
+ declare const DELIVERY_DECODE_KINDS: readonly ["form-field-json", "pubsub-push"];
2323
2375
  type DeliveryDecode = {
2324
- kind: (typeof DELIVERY_DECODE_KINDS)[number];
2376
+ kind: "form-field-json";
2325
2377
  field: string;
2378
+ } | {
2379
+ kind: "pubsub-push";
2326
2380
  };
2327
2381
  declare function decodeDelivery(decode: DeliveryDecode, raw: Uint8Array | string): unknown;
2328
2382
 
2329
- /**
2330
- * Dry-verify — proving the transport with a credential that cannot work.
2331
- *
2332
- * ## The discipline, and why it beats a fake server
2333
- *
2334
- * A connector written from documentation can be wrong in three ways that look
2335
- * identical until a real credential arrives:
2336
- *
2337
- * 1. the URL is wrong,
2338
- * 2. the request shape is wrong,
2339
- * 3. the error handling never runs.
2340
- *
2341
- * **All three are invisible to a test with a fake server**, because a fake
2342
- * server agrees with whatever the code does. That is the single most important
2343
- * thing this module encodes: a green unit suite against a mock proves the code
2344
- * is consistent with itself.
2345
- *
2346
- * So a probe calls the REAL API with a deliberately invalid credential and
2347
- * requires an **auth-shaped refusal**. That proves the host resolved, the path
2348
- * exists, the method was accepted, and a failure was recognised as a failure.
2349
- *
2350
- * ## What counts as a pass, precisely
2351
- *
2352
- * An auth-shaped refusal is `401`, `403`, or a `404` on a provider that answers
2353
- * 404 for an unknown credential-in-the-path (a Discord webhook does exactly
2354
- * this). The provider declares which, because guessing here would let a genuine
2355
- * "this endpoint moved" 404 read as success — the one outcome a probe exists to
2356
- * catch.
2357
- *
2358
- * ## Offline is SKIPPED, never failed
2359
- *
2360
- * A check that goes red on a train gets ignored, and then it is worth nothing
2361
- * when it goes red for real. Unreachable is reported as skipped with the reason,
2362
- * and the assertions that need no network still run.
2363
- *
2364
- * ## And nothing is ever sent
2365
- *
2366
- * Every probe is a READ. A probe that wrote something would be a send, and sends
2367
- * are the host's to gate.
2368
- */
2369
-
2370
- type ProbeOutcome = "pass" | "fail" | "skip";
2371
- type ProbeResult = {
2372
- connector: string;
2373
- outcome: ProbeOutcome;
2374
- /** What happened, in the provider's own words where possible. */
2375
- detail: string;
2376
- status?: number;
2377
- kind?: FailureKind;
2378
- };
2379
- type ProbeSpec = {
2380
- /** Which connector this probes. */
2381
- connector: string;
2382
- /**
2383
- * The read-only request, fully formed, carrying a credential that cannot be
2384
- * valid. Built by the connector so the probe exercises the connector's own URL
2385
- * and auth placement rather than a second copy of them.
2386
- */
2387
- request: () => Promise<{
2388
- status: number;
2389
- body: string;
2390
- }>;
2391
- /**
2392
- * Statuses that count as an auth-shaped refusal for THIS provider.
2393
- *
2394
- * Declared rather than assumed. Discord answers `404` for an unknown webhook
2395
- * id, and on a provider that does not, a 404 means the endpoint moved — the
2396
- * exact drift a probe is for.
2397
- */
2398
- authStatuses: number[];
2399
- /** Why those statuses, for whoever reads a failure at 3am. */
2400
- why: string;
2401
- };
2402
- /**
2403
- * Run one probe.
2404
- *
2405
- * Never throws. A probe that threw would take the suite down with it, and the
2406
- * suite's whole value is that it runs everywhere including on a laptop with no
2407
- * network.
2408
- */
2409
- declare function probe(spec: ProbeSpec): Promise<ProbeResult>;
2410
- type ProbeReport = {
2411
- results: ProbeResult[];
2412
- passed: number;
2413
- failed: number;
2414
- skipped: number;
2415
- /** True when nothing failed. Skips do not fail a report. */
2416
- ok: boolean;
2417
- };
2418
- /** Run a set of probes and summarise. Sequential: probes hit real providers. */
2419
- declare function runProbes(specs: ProbeSpec[]): Promise<ProbeReport>;
2420
-
2421
2383
  /**
2422
2384
  * Verifying an inbound provider webhook.
2423
2385
  *
@@ -2468,7 +2430,7 @@ type HmacScheme = {
2468
2430
  * `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
2469
2431
  * `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
2470
2432
  */
2471
- payload: (raw: string, timestamp?: string, id?: string) => string;
2433
+ payload: (raw: string, timestamp?: string, id?: string, request?: SignedRequestLine) => string;
2472
2434
  /** Seconds a delivery stays acceptable. */
2473
2435
  tolerance?: number;
2474
2436
  /** Encoding of the signature the provider sends. */
@@ -2483,7 +2445,37 @@ type HmacScheme = {
2483
2445
  secretEncoding?: "utf8" | "base64";
2484
2446
  /** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
2485
2447
  secretPrefix?: string;
2448
+ /**
2449
+ * The unit the timestamp header is in. Seconds unless said otherwise:
2450
+ * HubSpot sends MILLISECONDS, and comparing those with a window in seconds
2451
+ * refuses every delivery ever made.
2452
+ */
2453
+ timestampUnit?: "s" | "ms";
2454
+ /**
2455
+ * The provider signs the REQUEST LINE too (HubSpot v3:
2456
+ * method + uri + body + timestamp). A delivery the host passed without its
2457
+ * method or URL is refused by name, never signed with a gap.
2458
+ */
2459
+ signsRequestLine?: boolean;
2460
+ /** How the signed URI is spelled from the URL the request was sent to. */
2461
+ uri?: SignedUriRule;
2462
+ };
2463
+ /** The URI rules a provider's signature can follow. Closed: each is a decision. */
2464
+ declare const SIGNED_URI_RULES: readonly ["hubspot-v3"];
2465
+ type SignedUriRule = (typeof SIGNED_URI_RULES)[number];
2466
+ /** The request line as signed: the method, and the URI after the scheme's rule. */
2467
+ type SignedRequestLine = {
2468
+ method: string;
2469
+ uri: string;
2486
2470
  };
2471
+ /**
2472
+ * The URI a provider signs, from the URL the request arrived on.
2473
+ *
2474
+ * `hubspot-v3`: only the QUERY portion is percent-decoded, and only for twelve
2475
+ * escapes (case-insensitive); never its leading `?`; any `#fragment` dropped.
2476
+ * Everything else, `%26` and `%3D` included, stays as sent.
2477
+ */
2478
+ declare function normaliseSignedUri(url: string, rule: SignedUriRule): string;
2487
2479
  /** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
2488
2480
  declare function secretKeyBytes(secret: string, options?: {
2489
2481
  secretEncoding?: "utf8" | "base64";
@@ -2516,6 +2508,11 @@ declare function verifyHmac(options: {
2516
2508
  timestamp?: string;
2517
2509
  /** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
2518
2510
  id?: string;
2511
+ /** The request line as RECEIVED, when the scheme signs it (HubSpot v3). */
2512
+ request?: {
2513
+ method: string;
2514
+ url: string;
2515
+ };
2519
2516
  /** Seconds since the epoch. Injected so tests are not clock-dependent. */
2520
2517
  now?: number;
2521
2518
  }): Promise<WebhookVerification>;
@@ -2598,6 +2595,195 @@ declare function handshakeResponse(handshake: ChallengeHandshake | undefined, qu
2598
2595
  */
2599
2596
  declare function header(headers: Record<string, string | string[] | undefined>, name: string): string | undefined;
2600
2597
 
2598
+ /**
2599
+ * A delivery authenticated by an OIDC BEARER TOKEN rather than a signature over
2600
+ * its body: Google Cloud Pub/Sub push, which carries Gmail's `users.watch`
2601
+ * notifications, sends `Authorization: Bearer <JWT>` signed by Google.
2602
+ *
2603
+ * The PHP twin is `OidcDelivery::verify`; both read
2604
+ * `fixtures/oidc-delivery/cases.json`. The token itself is checked by
2605
+ * `verifyJwt`, so every JWT rule there applies here unchanged.
2606
+ *
2607
+ * What this adds, and why each piece fails closed:
2608
+ *
2609
+ * - **The audience is REQUIRED.** Google signs a token for any push
2610
+ * subscription anyone creates; without the audience, every Google-signed
2611
+ * token in the world verifies.
2612
+ * - **The principal is REQUIRED, and it is the check people skip.** A
2613
+ * stranger can create a push subscription in their OWN project, aimed at
2614
+ * your public URL, with your URL as its audience: Google signs that token
2615
+ * correctly. Only the service account (`email`) says it was yours.
2616
+ * Its verified flag (`email_verified`) must be the literal `true`.
2617
+ * - **The keys are the host's.** Nothing here fetches Google's JWKS: the host
2618
+ * fetches and caches it and passes the keys in.
2619
+ *
2620
+ * A host's own configuration is checked before the delivery is read, so a
2621
+ * misconfigured trigger refuses every push rather than accepting any of them.
2622
+ */
2623
+
2624
+ declare const OIDC_JWT_SCHEME_KIND: "oidc-jwt";
2625
+ type OidcJwtScheme = {
2626
+ kind: typeof OIDC_JWT_SCHEME_KIND;
2627
+ /** The header carrying `Bearer <token>`. */
2628
+ header: string;
2629
+ /** Accepted `iss` values. Google documents two spellings. */
2630
+ issuers: readonly string[];
2631
+ /** The claim naming WHO the token was minted for: Google push uses `email`. */
2632
+ principalClaim: string;
2633
+ /** A claim that must be the literal `true` beside it: `email_verified`. */
2634
+ verifiedClaim?: string;
2635
+ };
2636
+ /** What the HOST configured for this trigger. Never in the package. */
2637
+ type OidcExpectation = {
2638
+ keys: readonly Jwk[];
2639
+ /** The audience the subscription was created with. */
2640
+ audience: string | null;
2641
+ /** The service account the subscription pushes as. */
2642
+ principal: string | null;
2643
+ };
2644
+ declare function isOidcJwtScheme(scheme: unknown): scheme is OidcJwtScheme;
2645
+ declare function verifyOidcDelivery(options: {
2646
+ headers: Record<string, string | string[] | undefined>;
2647
+ scheme: OidcJwtScheme;
2648
+ expected: OidcExpectation | undefined;
2649
+ /** Seconds since the epoch. */
2650
+ now?: number;
2651
+ }): Promise<WebhookVerification>;
2652
+
2653
+ /**
2654
+ * Dry-verify — proving the transport with a credential that cannot work.
2655
+ *
2656
+ * ## The discipline, and why it beats a fake server
2657
+ *
2658
+ * A connector written from documentation can be wrong in three ways that look
2659
+ * identical until a real credential arrives:
2660
+ *
2661
+ * 1. the URL is wrong,
2662
+ * 2. the request shape is wrong,
2663
+ * 3. the error handling never runs.
2664
+ *
2665
+ * **All three are invisible to a test with a fake server**, because a fake
2666
+ * server agrees with whatever the code does. That is the single most important
2667
+ * thing this module encodes: a green unit suite against a mock proves the code
2668
+ * is consistent with itself.
2669
+ *
2670
+ * So a probe calls the REAL API with a deliberately invalid credential and
2671
+ * requires an **auth-shaped refusal**. That proves the host resolved, the path
2672
+ * exists, the method was accepted, and a failure was recognised as a failure.
2673
+ *
2674
+ * ## What counts as a pass, precisely
2675
+ *
2676
+ * An auth-shaped refusal is `401`, `403`, or a `404` on a provider that answers
2677
+ * 404 for an unknown credential-in-the-path (a Discord webhook does exactly
2678
+ * this). The provider declares which, because guessing here would let a genuine
2679
+ * "this endpoint moved" 404 read as success — the one outcome a probe exists to
2680
+ * catch.
2681
+ *
2682
+ * ## Offline is SKIPPED, never failed
2683
+ *
2684
+ * A check that goes red on a train gets ignored, and then it is worth nothing
2685
+ * when it goes red for real. Unreachable is reported as skipped with the reason,
2686
+ * and the assertions that need no network still run.
2687
+ *
2688
+ * ## And nothing is ever sent
2689
+ *
2690
+ * Every probe is a READ. A probe that wrote something would be a send, and sends
2691
+ * are the host's to gate.
2692
+ */
2693
+
2694
+ type ProbeOutcome = "pass" | "fail" | "skip";
2695
+ type ProbeResult = {
2696
+ connector: string;
2697
+ outcome: ProbeOutcome;
2698
+ /** What happened, in the provider's own words where possible. */
2699
+ detail: string;
2700
+ status?: number;
2701
+ kind?: FailureKind;
2702
+ };
2703
+ type ProbeSpec = {
2704
+ /** Which connector this probes. */
2705
+ connector: string;
2706
+ /**
2707
+ * The read-only request, fully formed, carrying a credential that cannot be
2708
+ * valid. Built by the connector so the probe exercises the connector's own URL
2709
+ * and auth placement rather than a second copy of them.
2710
+ */
2711
+ request: () => Promise<{
2712
+ status: number;
2713
+ body: string;
2714
+ }>;
2715
+ /**
2716
+ * Statuses that count as an auth-shaped refusal for THIS provider.
2717
+ *
2718
+ * Declared rather than assumed. Discord answers `404` for an unknown webhook
2719
+ * id, and on a provider that does not, a 404 means the endpoint moved — the
2720
+ * exact drift a probe is for.
2721
+ */
2722
+ authStatuses: number[];
2723
+ /** Why those statuses, for whoever reads a failure at 3am. */
2724
+ why: string;
2725
+ };
2726
+ /**
2727
+ * Run one probe.
2728
+ *
2729
+ * Never throws. A probe that threw would take the suite down with it, and the
2730
+ * suite's whole value is that it runs everywhere including on a laptop with no
2731
+ * network.
2732
+ */
2733
+ declare function probe(spec: ProbeSpec): Promise<ProbeResult>;
2734
+ type ProbeReport = {
2735
+ results: ProbeResult[];
2736
+ passed: number;
2737
+ failed: number;
2738
+ skipped: number;
2739
+ /** True when nothing failed. Skips do not fail a report. */
2740
+ ok: boolean;
2741
+ };
2742
+ /** Run a set of probes and summarise. Sequential: probes hit real providers. */
2743
+ declare function runProbes(specs: ProbeSpec[]): Promise<ProbeReport>;
2744
+
2745
+ /**
2746
+ * A Google Cloud Pub/Sub PUSH body, decoded to the message it carries: the
2747
+ * payload TRANSFORM Gmail's `users.watch` notifications need. Pub/Sub wraps
2748
+ * each message in an envelope and base64-encodes its `data`.
2749
+ *
2750
+ * ONE implementation in two runtimes (`php/src/PubSubPush.php` is the twin),
2751
+ * held to the authored corpus under `fixtures/pubsub-push/`, whose README
2752
+ * names the decision each case pins. It runs AFTER verification: a push is
2753
+ * authenticated by the OIDC token in its `Authorization` header, not by
2754
+ * anything in the body.
2755
+ *
2756
+ * The decisions:
2757
+ *
2758
+ * - `data` may be standard base64 or base64url, padded or not. The Gmail guide
2759
+ * says one, Pub/Sub's page the other. Anything outside both alphabets, and
2760
+ * bytes that are not UTF-8, are `bad-encoding`.
2761
+ * - `data` is parsed as JSON, and text that is not JSON is `data-not-json`,
2762
+ * never the raw string.
2763
+ * - `messageId` / `publishTime` are read camelCase first, snake_case second:
2764
+ * Google sends both spellings.
2765
+ * - Absent `attributes` is `{}` (Pub/Sub omits an empty map); absent
2766
+ * `deliveryAttempt` is `null` (it is only sent under a dead-letter policy,
2767
+ * and an attempt count nobody reported is not attempt one).
2768
+ */
2769
+ declare const PUBSUB_PUSH_REASONS: readonly ["not-json", "missing-message", "missing-data", "bad-encoding", "data-not-json"];
2770
+ type PubSubPushReason = (typeof PUBSUB_PUSH_REASONS)[number];
2771
+ /** Refused BY NAME; `reason` is the same string PHP's exception carries. */
2772
+ declare class PubSubPushError extends Error {
2773
+ readonly reason: PubSubPushReason;
2774
+ constructor(reason: PubSubPushReason, message: string);
2775
+ }
2776
+ type PubSubPushMessage = {
2777
+ subscription: string | null;
2778
+ messageId: string | null;
2779
+ publishTime: string | null;
2780
+ attributes: Record<string, string>;
2781
+ deliveryAttempt: number | null;
2782
+ /** The message's `data`, base64-decoded and parsed as JSON. */
2783
+ data: unknown;
2784
+ };
2785
+ declare function decodePubSubPush(raw: Uint8Array | string): PubSubPushMessage;
2786
+
2601
2787
  /**
2602
2788
  * How a connector trigger learns that something happened.
2603
2789
  *
@@ -2627,6 +2813,11 @@ declare function header(headers: Record<string, string | string[] | undefined>,
2627
2813
  * SSE, CometD).
2628
2814
  */
2629
2815
  type DeliveryMechanism = "webhook" | "subscription" | "poll" | "pubsub" | "stream";
2816
+ /** See `TriggerDescriptor.route`. `path` is dotted; `[]` means every element. */
2817
+ type DeliveryRoute = {
2818
+ by: string;
2819
+ path: string;
2820
+ };
2630
2821
  type TriggerDescriptor = {
2631
2822
  service: string;
2632
2823
  operation: string;
@@ -2655,6 +2846,15 @@ type TriggerDescriptor = {
2655
2846
  * it, over the same raw bytes the signature was checked against.
2656
2847
  */
2657
2848
  decode?: DeliveryDecode;
2849
+ /**
2850
+ * For a delivery that reaches ONE endpoint on behalf of many tenants
2851
+ * (HubSpot app webhooks, Gmail's Pub/Sub topic): the ONLY key a host may
2852
+ * route by, and where it sits in the verified payload. The rule that goes
2853
+ * with it is fixed, not configurable: route only AFTER verification, only
2854
+ * to a connection or watch the host minted, and drop an unmapped key with a
2855
+ * 2xx and a log line, creating nothing. The package declares; the HOST routes.
2856
+ */
2857
+ route?: DeliveryRoute;
2658
2858
  /** For `poll`: the provider's smallest sane interval, in seconds. */
2659
2859
  minPollSeconds?: number;
2660
2860
  /** A faked sample event, so the node is runnable before any of the above. */
@@ -2697,12 +2897,28 @@ type SharedTokenVerificationSpec = {
2697
2897
  /** A challenge the provider makes before it will deliver anything. */
2698
2898
  handshake?: ChallengeHandshake;
2699
2899
  };
2700
- type WebhookVerificationSpec = HmacVerificationSpec | SharedTokenVerificationSpec;
2900
+ /**
2901
+ * The provider sends a BEARER TOKEN it signed (Google Cloud Pub/Sub push). The
2902
+ * keys, audience and principal it is checked against are the HOST's, passed
2903
+ * to `verifyDelivery` as an `OidcExpectation`. See `verifyOidcDelivery`.
2904
+ */
2905
+ type OidcJwtVerificationSpec = {
2906
+ scheme: OidcJwtScheme;
2907
+ };
2908
+ type WebhookVerificationSpec = HmacVerificationSpec | SharedTokenVerificationSpec | OidcJwtVerificationSpec;
2909
+ declare function isOidcJwtSpec(spec: WebhookVerificationSpec): spec is OidcJwtVerificationSpec;
2701
2910
  declare function isSharedTokenSpec(spec: WebhookVerificationSpec): spec is SharedTokenVerificationSpec;
2702
2911
  type InboundDelivery = {
2703
2912
  /** The body EXACTLY as received. Not re-serialised. See `webhook.ts`. */
2704
2913
  raw: string;
2705
2914
  headers: Record<string, string | string[] | undefined>;
2915
+ /**
2916
+ * The request line as RECEIVED, for a provider that signs it (HubSpot v3).
2917
+ * Pass the full URL the provider called, scheme, host, path and query,
2918
+ * exactly as it arrived.
2919
+ */
2920
+ method?: string;
2921
+ url?: string;
2706
2922
  };
2707
2923
  /**
2708
2924
  * Verify an inbound delivery against a trigger's declared scheme.
@@ -2712,7 +2928,9 @@ type InboundDelivery = {
2712
2928
  * for starting workflows in your account, and defaulting to "allow" would make
2713
2929
  * every misconfiguration into an open door that looks shut.
2714
2930
  */
2715
- declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDelivery, secret: string | undefined, now?: number): Promise<WebhookVerification>;
2931
+ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDelivery, secret: string | undefined, now?: number,
2932
+ /** For an `oidc-jwt` scheme: the keys, audience and principal the host configured. `secret` is not read. */
2933
+ oidc?: OidcExpectation): Promise<WebhookVerification>;
2716
2934
  /**
2717
2935
  * The event a trigger node publishes when it runs.
2718
2936
  *
@@ -2728,4 +2946,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
2728
2946
  */
2729
2947
  declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
2730
2948
 
2731
- export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, type JoinTarget, type JoinTargetKind, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, PROBLEM_SEVERITIES, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RecurrenceRule, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, decodeDelivery, decodeFormFieldJson, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, parseInvite, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, secretKeyBytes, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
2949
+ export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, type Attendee, type ByteRange, CANONICAL_METRICS, CONNECTOR_API_VERSION, CONNECTOR_MODES, CREDENTIAL_SCOPES, type CallOptions, type CallResult, type Capabilities, type Catalogue, type ChainLinks, type ChainOutcome, type ChainRef, type ChallengeHandshake, type Citation, type Classified, type ConnectionCredentials, type ConnectionHost, type ConnectionSpec, type Connector, ConnectorAmbiguous, ConnectorApiMismatch, ConnectorAuthError, ConnectorConfigError, ConnectorError, type ConnectorErrorContext, type ConnectorFaker, ConnectorIdempotencyExpiredError, type ConnectorMode, ConnectorModeError, ConnectorRateLimited, type ConnectorRequest, ConnectorRequestError, type ConnectorResult, ConnectorTransient, ConnectorUnreachable, type ContractOperation, type CredentialField, type CredentialScope, DEFAULT_IDEMPOTENCY_WINDOW_SECONDS, DEFAULT_RETRY, DELIVERY_DECODE_KINDS, type DeliveryDeclaration, type DeliveryDecode, type DeliveryMechanism, type DeliveryOutcome, type DeliveryRoute, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, FORM_FIELD_JSON_REASONS, type FailureKind, type FakeRequest, type FakeValues, FormFieldJsonError, type FormFieldJsonReason, type HmacScheme, type HmacVerificationSpec, type HostEnvironment, type IdempotencyOptions, type InboundDelivery, type Invite, type InviteMethod, JWT_ALGORITHMS, type JoinTarget, type JoinTargetKind, type Jwk, type JwtVerification, type LeaseAction, type LeaseDeclaration, type LeaseState, MAX_IDEMPOTENCY_KEY_LENGTH, type MetricDescriptor, type MetricSample, type MimeAttachment, type MimeHeader, type MimeMessage, type MimePart, type ModeInputs, NO_IDEMPOTENCY_KEY_WARNING, OIDC_JWT_SCHEME_KIND, type OidcExpectation, type OidcJwtScheme, type OidcJwtVerificationSpec, PROBLEM_SEVERITIES, PUBSUB_PUSH_REASONS, type PreparedRequest, type ProbeOutcome, type ProbeReport, type ProbeResult, type ProbeSpec, type Problem, type ProviderAdapter, PubSubPushError, type PubSubPushMessage, type PubSubPushReason, RENDERER_VERSION, REVIEW_STALE_DAYS, type RecordedShape, type RecurrenceRule, type RenderRules, type RenderedPayload, type RequestedMode, type ResolveOptions, type ResolvedConnection, type RetryPolicy, type RunIdentity, SANDBOX_KINDS, SIGNED_URI_RULES, SUPPORTED_CONNECTOR_API, type SandboxKind, type Segment, type ServiceDescriptor, type SetupStep, type ShapeMismatch, type SharedTokenScheme, type SharedTokenVerificationSpec, type SignedRequestLine, type SignedUriRule, type SpecSource, type SubscriptionLease, type TextUnit, type Transport, type TransportResponse, type TriggerDescriptor, type VerifyJwtOptions, type VerifyResult, type WebhookVerification, type WebhookVerificationSpec, assertConnectorApi, byteRangeOf, callConnector, capabilityProblems, checkAgainstOpenApi, checkAgainstRecordedShape, classifyError, classifyHttp, classifyStatus, classifyThrown, compareShape, connectionsFor, constantTimeEquals, decodeDelivery, decodeFormFieldJson, decodePubSubPush, deliver, fakeRequest, fakeValues, getConnectionHost, graphemes, handshakeResponse, header, hmac, httpFailure, idempotencyKeyFor, isEmptyPayload, isOidcJwtScheme, isOidcJwtSpec, isRemote, isSharedTokenScheme, isSharedTokenSpec, isUnconditionallyRetryable, joinTargets, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, nextOccurrence, normaliseSignedUri, parseInvite, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, secretKeyBytes, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifyJwt, verifyOidcDelivery, verifySharedToken, withResolvedLimit };