@particle-academy/fancy-connector-core 0.10.1 → 0.12.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/CHANGELOG.md +61 -0
- package/dist/index.cjs +124 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -2
- package/dist/index.d.ts +109 -2
- package/dist/index.js +117 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2282,6 +2282,50 @@ type MimeMessage = {
|
|
|
2282
2282
|
};
|
|
2283
2283
|
declare function parseMime(raw: Uint8Array | string): MimeMessage;
|
|
2284
2284
|
|
|
2285
|
+
/**
|
|
2286
|
+
* A form-encoded body whose one named field holds JSON, decoded: the payload
|
|
2287
|
+
* TRANSFORM Slack's interactivity callbacks need (`payload=<json>`).
|
|
2288
|
+
*
|
|
2289
|
+
* ONE implementation in two runtimes (`php/src/FormFieldJson.php` is the
|
|
2290
|
+
* twin), held to the authored corpus under `fixtures/form-field-json/`. It
|
|
2291
|
+
* runs AFTER signature verification, over the same raw bytes: the provider
|
|
2292
|
+
* signed the form body as sent, so nothing here may be re-encoded before
|
|
2293
|
+
* verifying.
|
|
2294
|
+
*
|
|
2295
|
+
* The decisions, each pinned by a case:
|
|
2296
|
+
*
|
|
2297
|
+
* - `+` and `%20` are both a space; `%XX` decodes to a byte, and the result
|
|
2298
|
+
* must be valid UTF-8.
|
|
2299
|
+
* - The WHOLE body is decoded strictly. A `%` not followed by two hex digits,
|
|
2300
|
+
* anywhere, is `bad-encoding`. `decodeURIComponent` throws on `%zz` while
|
|
2301
|
+
* PHP's `urldecode` keeps it, so neither built-in is used.
|
|
2302
|
+
* - The field absent is `missing-field`; present twice is `duplicate-field`,
|
|
2303
|
+
* because first-wins and last-wins are both conventions and two runtimes
|
|
2304
|
+
* choosing differently would route one click two ways.
|
|
2305
|
+
* - A value that is not JSON is `not-json`, never the raw string.
|
|
2306
|
+
*/
|
|
2307
|
+
declare const FORM_FIELD_JSON_REASONS: readonly ["missing-field", "duplicate-field", "bad-encoding", "not-json"];
|
|
2308
|
+
type FormFieldJsonReason = (typeof FORM_FIELD_JSON_REASONS)[number];
|
|
2309
|
+
/** Refused BY NAME; `reason` is the same string PHP's exception carries. */
|
|
2310
|
+
declare class FormFieldJsonError extends Error {
|
|
2311
|
+
readonly reason: FormFieldJsonReason;
|
|
2312
|
+
readonly field: string;
|
|
2313
|
+
constructor(reason: FormFieldJsonReason, field: string, message: string);
|
|
2314
|
+
}
|
|
2315
|
+
declare function decodeFormFieldJson(raw: Uint8Array | string, field: string): unknown;
|
|
2316
|
+
/**
|
|
2317
|
+
* How a verified delivery is read, when its body is not plain JSON. Declared
|
|
2318
|
+
* on the trigger (`TriggerDescriptor.decode`); a host verifies the raw bytes,
|
|
2319
|
+
* then calls `decodeDelivery` with the declaration, then starts the run.
|
|
2320
|
+
* Shipped as data too, for a host mirroring the union across a JSON boundary.
|
|
2321
|
+
*/
|
|
2322
|
+
declare const DELIVERY_DECODE_KINDS: readonly ["form-field-json"];
|
|
2323
|
+
type DeliveryDecode = {
|
|
2324
|
+
kind: (typeof DELIVERY_DECODE_KINDS)[number];
|
|
2325
|
+
field: string;
|
|
2326
|
+
};
|
|
2327
|
+
declare function decodeDelivery(decode: DeliveryDecode, raw: Uint8Array | string): unknown;
|
|
2328
|
+
|
|
2285
2329
|
/**
|
|
2286
2330
|
* Dry-verify — proving the transport with a credential that cannot work.
|
|
2287
2331
|
*
|
|
@@ -2424,7 +2468,7 @@ type HmacScheme = {
|
|
|
2424
2468
|
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2425
2469
|
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2426
2470
|
*/
|
|
2427
|
-
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2471
|
+
payload: (raw: string, timestamp?: string, id?: string, request?: SignedRequestLine) => string;
|
|
2428
2472
|
/** Seconds a delivery stays acceptable. */
|
|
2429
2473
|
tolerance?: number;
|
|
2430
2474
|
/** Encoding of the signature the provider sends. */
|
|
@@ -2439,7 +2483,37 @@ type HmacScheme = {
|
|
|
2439
2483
|
secretEncoding?: "utf8" | "base64";
|
|
2440
2484
|
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2441
2485
|
secretPrefix?: string;
|
|
2486
|
+
/**
|
|
2487
|
+
* The unit the timestamp header is in. Seconds unless said otherwise:
|
|
2488
|
+
* HubSpot sends MILLISECONDS, and comparing those with a window in seconds
|
|
2489
|
+
* refuses every delivery ever made.
|
|
2490
|
+
*/
|
|
2491
|
+
timestampUnit?: "s" | "ms";
|
|
2492
|
+
/**
|
|
2493
|
+
* The provider signs the REQUEST LINE too (HubSpot v3:
|
|
2494
|
+
* method + uri + body + timestamp). A delivery the host passed without its
|
|
2495
|
+
* method or URL is refused by name, never signed with a gap.
|
|
2496
|
+
*/
|
|
2497
|
+
signsRequestLine?: boolean;
|
|
2498
|
+
/** How the signed URI is spelled from the URL the request was sent to. */
|
|
2499
|
+
uri?: SignedUriRule;
|
|
2500
|
+
};
|
|
2501
|
+
/** The URI rules a provider's signature can follow. Closed: each is a decision. */
|
|
2502
|
+
declare const SIGNED_URI_RULES: readonly ["hubspot-v3"];
|
|
2503
|
+
type SignedUriRule = (typeof SIGNED_URI_RULES)[number];
|
|
2504
|
+
/** The request line as signed: the method, and the URI after the scheme's rule. */
|
|
2505
|
+
type SignedRequestLine = {
|
|
2506
|
+
method: string;
|
|
2507
|
+
uri: string;
|
|
2442
2508
|
};
|
|
2509
|
+
/**
|
|
2510
|
+
* The URI a provider signs, from the URL the request arrived on.
|
|
2511
|
+
*
|
|
2512
|
+
* `hubspot-v3`: only the QUERY portion is percent-decoded, and only for twelve
|
|
2513
|
+
* escapes (case-insensitive); never its leading `?`; any `#fragment` dropped.
|
|
2514
|
+
* Everything else, `%26` and `%3D` included, stays as sent.
|
|
2515
|
+
*/
|
|
2516
|
+
declare function normaliseSignedUri(url: string, rule: SignedUriRule): string;
|
|
2443
2517
|
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2444
2518
|
declare function secretKeyBytes(secret: string, options?: {
|
|
2445
2519
|
secretEncoding?: "utf8" | "base64";
|
|
@@ -2472,6 +2546,11 @@ declare function verifyHmac(options: {
|
|
|
2472
2546
|
timestamp?: string;
|
|
2473
2547
|
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2474
2548
|
id?: string;
|
|
2549
|
+
/** The request line as RECEIVED, when the scheme signs it (HubSpot v3). */
|
|
2550
|
+
request?: {
|
|
2551
|
+
method: string;
|
|
2552
|
+
url: string;
|
|
2553
|
+
};
|
|
2475
2554
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2476
2555
|
now?: number;
|
|
2477
2556
|
}): Promise<WebhookVerification>;
|
|
@@ -2583,6 +2662,11 @@ declare function header(headers: Record<string, string | string[] | undefined>,
|
|
|
2583
2662
|
* SSE, CometD).
|
|
2584
2663
|
*/
|
|
2585
2664
|
type DeliveryMechanism = "webhook" | "subscription" | "poll" | "pubsub" | "stream";
|
|
2665
|
+
/** See `TriggerDescriptor.route`. `path` is dotted; `[]` means every element. */
|
|
2666
|
+
type DeliveryRoute = {
|
|
2667
|
+
by: string;
|
|
2668
|
+
path: string;
|
|
2669
|
+
};
|
|
2586
2670
|
type TriggerDescriptor = {
|
|
2587
2671
|
service: string;
|
|
2588
2672
|
operation: string;
|
|
@@ -2604,6 +2688,22 @@ type TriggerDescriptor = {
|
|
|
2604
2688
|
lease?: LeaseDeclaration;
|
|
2605
2689
|
/** For `webhook` / `subscription`: how a delivery is authenticated. */
|
|
2606
2690
|
verification?: WebhookVerificationSpec;
|
|
2691
|
+
/**
|
|
2692
|
+
* For `webhook`: how the VERIFIED body is read when it is not plain JSON —
|
|
2693
|
+
* Slack's interactivity is `payload=<json>`. Absent means the host reads the
|
|
2694
|
+
* body as it always has. Present means the host calls `decodeDelivery` with
|
|
2695
|
+
* it, over the same raw bytes the signature was checked against.
|
|
2696
|
+
*/
|
|
2697
|
+
decode?: DeliveryDecode;
|
|
2698
|
+
/**
|
|
2699
|
+
* For a delivery that reaches ONE endpoint on behalf of many tenants
|
|
2700
|
+
* (HubSpot app webhooks, Gmail's Pub/Sub topic): the ONLY key a host may
|
|
2701
|
+
* route by, and where it sits in the verified payload. The rule that goes
|
|
2702
|
+
* with it is fixed, not configurable: route only AFTER verification, only
|
|
2703
|
+
* to a connection or watch the host minted, and drop an unmapped key with a
|
|
2704
|
+
* 2xx and a log line, creating nothing. The package declares; the HOST routes.
|
|
2705
|
+
*/
|
|
2706
|
+
route?: DeliveryRoute;
|
|
2607
2707
|
/** For `poll`: the provider's smallest sane interval, in seconds. */
|
|
2608
2708
|
minPollSeconds?: number;
|
|
2609
2709
|
/** A faked sample event, so the node is runnable before any of the above. */
|
|
@@ -2652,6 +2752,13 @@ type InboundDelivery = {
|
|
|
2652
2752
|
/** The body EXACTLY as received. Not re-serialised. See `webhook.ts`. */
|
|
2653
2753
|
raw: string;
|
|
2654
2754
|
headers: Record<string, string | string[] | undefined>;
|
|
2755
|
+
/**
|
|
2756
|
+
* The request line as RECEIVED, for a provider that signs it (HubSpot v3).
|
|
2757
|
+
* Pass the full URL the provider called, scheme, host, path and query,
|
|
2758
|
+
* exactly as it arrived.
|
|
2759
|
+
*/
|
|
2760
|
+
method?: string;
|
|
2761
|
+
url?: string;
|
|
2655
2762
|
};
|
|
2656
2763
|
/**
|
|
2657
2764
|
* Verify an inbound delivery against a trigger's declared scheme.
|
|
@@ -2677,4 +2784,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2677
2784
|
*/
|
|
2678
2785
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2679
2786
|
|
|
2680
|
-
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, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, 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, 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 };
|
|
2787
|
+
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, 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, 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 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, 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, verifySharedToken, withResolvedLimit };
|
package/dist/index.d.ts
CHANGED
|
@@ -2282,6 +2282,50 @@ type MimeMessage = {
|
|
|
2282
2282
|
};
|
|
2283
2283
|
declare function parseMime(raw: Uint8Array | string): MimeMessage;
|
|
2284
2284
|
|
|
2285
|
+
/**
|
|
2286
|
+
* A form-encoded body whose one named field holds JSON, decoded: the payload
|
|
2287
|
+
* TRANSFORM Slack's interactivity callbacks need (`payload=<json>`).
|
|
2288
|
+
*
|
|
2289
|
+
* ONE implementation in two runtimes (`php/src/FormFieldJson.php` is the
|
|
2290
|
+
* twin), held to the authored corpus under `fixtures/form-field-json/`. It
|
|
2291
|
+
* runs AFTER signature verification, over the same raw bytes: the provider
|
|
2292
|
+
* signed the form body as sent, so nothing here may be re-encoded before
|
|
2293
|
+
* verifying.
|
|
2294
|
+
*
|
|
2295
|
+
* The decisions, each pinned by a case:
|
|
2296
|
+
*
|
|
2297
|
+
* - `+` and `%20` are both a space; `%XX` decodes to a byte, and the result
|
|
2298
|
+
* must be valid UTF-8.
|
|
2299
|
+
* - The WHOLE body is decoded strictly. A `%` not followed by two hex digits,
|
|
2300
|
+
* anywhere, is `bad-encoding`. `decodeURIComponent` throws on `%zz` while
|
|
2301
|
+
* PHP's `urldecode` keeps it, so neither built-in is used.
|
|
2302
|
+
* - The field absent is `missing-field`; present twice is `duplicate-field`,
|
|
2303
|
+
* because first-wins and last-wins are both conventions and two runtimes
|
|
2304
|
+
* choosing differently would route one click two ways.
|
|
2305
|
+
* - A value that is not JSON is `not-json`, never the raw string.
|
|
2306
|
+
*/
|
|
2307
|
+
declare const FORM_FIELD_JSON_REASONS: readonly ["missing-field", "duplicate-field", "bad-encoding", "not-json"];
|
|
2308
|
+
type FormFieldJsonReason = (typeof FORM_FIELD_JSON_REASONS)[number];
|
|
2309
|
+
/** Refused BY NAME; `reason` is the same string PHP's exception carries. */
|
|
2310
|
+
declare class FormFieldJsonError extends Error {
|
|
2311
|
+
readonly reason: FormFieldJsonReason;
|
|
2312
|
+
readonly field: string;
|
|
2313
|
+
constructor(reason: FormFieldJsonReason, field: string, message: string);
|
|
2314
|
+
}
|
|
2315
|
+
declare function decodeFormFieldJson(raw: Uint8Array | string, field: string): unknown;
|
|
2316
|
+
/**
|
|
2317
|
+
* How a verified delivery is read, when its body is not plain JSON. Declared
|
|
2318
|
+
* on the trigger (`TriggerDescriptor.decode`); a host verifies the raw bytes,
|
|
2319
|
+
* then calls `decodeDelivery` with the declaration, then starts the run.
|
|
2320
|
+
* Shipped as data too, for a host mirroring the union across a JSON boundary.
|
|
2321
|
+
*/
|
|
2322
|
+
declare const DELIVERY_DECODE_KINDS: readonly ["form-field-json"];
|
|
2323
|
+
type DeliveryDecode = {
|
|
2324
|
+
kind: (typeof DELIVERY_DECODE_KINDS)[number];
|
|
2325
|
+
field: string;
|
|
2326
|
+
};
|
|
2327
|
+
declare function decodeDelivery(decode: DeliveryDecode, raw: Uint8Array | string): unknown;
|
|
2328
|
+
|
|
2285
2329
|
/**
|
|
2286
2330
|
* Dry-verify — proving the transport with a credential that cannot work.
|
|
2287
2331
|
*
|
|
@@ -2424,7 +2468,7 @@ type HmacScheme = {
|
|
|
2424
2468
|
* `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
|
|
2425
2469
|
* `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
|
|
2426
2470
|
*/
|
|
2427
|
-
payload: (raw: string, timestamp?: string, id?: string) => string;
|
|
2471
|
+
payload: (raw: string, timestamp?: string, id?: string, request?: SignedRequestLine) => string;
|
|
2428
2472
|
/** Seconds a delivery stays acceptable. */
|
|
2429
2473
|
tolerance?: number;
|
|
2430
2474
|
/** Encoding of the signature the provider sends. */
|
|
@@ -2439,7 +2483,37 @@ type HmacScheme = {
|
|
|
2439
2483
|
secretEncoding?: "utf8" | "base64";
|
|
2440
2484
|
/** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
|
|
2441
2485
|
secretPrefix?: string;
|
|
2486
|
+
/**
|
|
2487
|
+
* The unit the timestamp header is in. Seconds unless said otherwise:
|
|
2488
|
+
* HubSpot sends MILLISECONDS, and comparing those with a window in seconds
|
|
2489
|
+
* refuses every delivery ever made.
|
|
2490
|
+
*/
|
|
2491
|
+
timestampUnit?: "s" | "ms";
|
|
2492
|
+
/**
|
|
2493
|
+
* The provider signs the REQUEST LINE too (HubSpot v3:
|
|
2494
|
+
* method + uri + body + timestamp). A delivery the host passed without its
|
|
2495
|
+
* method or URL is refused by name, never signed with a gap.
|
|
2496
|
+
*/
|
|
2497
|
+
signsRequestLine?: boolean;
|
|
2498
|
+
/** How the signed URI is spelled from the URL the request was sent to. */
|
|
2499
|
+
uri?: SignedUriRule;
|
|
2500
|
+
};
|
|
2501
|
+
/** The URI rules a provider's signature can follow. Closed: each is a decision. */
|
|
2502
|
+
declare const SIGNED_URI_RULES: readonly ["hubspot-v3"];
|
|
2503
|
+
type SignedUriRule = (typeof SIGNED_URI_RULES)[number];
|
|
2504
|
+
/** The request line as signed: the method, and the URI after the scheme's rule. */
|
|
2505
|
+
type SignedRequestLine = {
|
|
2506
|
+
method: string;
|
|
2507
|
+
uri: string;
|
|
2442
2508
|
};
|
|
2509
|
+
/**
|
|
2510
|
+
* The URI a provider signs, from the URL the request arrived on.
|
|
2511
|
+
*
|
|
2512
|
+
* `hubspot-v3`: only the QUERY portion is percent-decoded, and only for twelve
|
|
2513
|
+
* escapes (case-insensitive); never its leading `?`; any `#fragment` dropped.
|
|
2514
|
+
* Everything else, `%26` and `%3D` included, stays as sent.
|
|
2515
|
+
*/
|
|
2516
|
+
declare function normaliseSignedUri(url: string, rule: SignedUriRule): string;
|
|
2443
2517
|
/** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
|
|
2444
2518
|
declare function secretKeyBytes(secret: string, options?: {
|
|
2445
2519
|
secretEncoding?: "utf8" | "base64";
|
|
@@ -2472,6 +2546,11 @@ declare function verifyHmac(options: {
|
|
|
2472
2546
|
timestamp?: string;
|
|
2473
2547
|
/** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
|
|
2474
2548
|
id?: string;
|
|
2549
|
+
/** The request line as RECEIVED, when the scheme signs it (HubSpot v3). */
|
|
2550
|
+
request?: {
|
|
2551
|
+
method: string;
|
|
2552
|
+
url: string;
|
|
2553
|
+
};
|
|
2475
2554
|
/** Seconds since the epoch. Injected so tests are not clock-dependent. */
|
|
2476
2555
|
now?: number;
|
|
2477
2556
|
}): Promise<WebhookVerification>;
|
|
@@ -2583,6 +2662,11 @@ declare function header(headers: Record<string, string | string[] | undefined>,
|
|
|
2583
2662
|
* SSE, CometD).
|
|
2584
2663
|
*/
|
|
2585
2664
|
type DeliveryMechanism = "webhook" | "subscription" | "poll" | "pubsub" | "stream";
|
|
2665
|
+
/** See `TriggerDescriptor.route`. `path` is dotted; `[]` means every element. */
|
|
2666
|
+
type DeliveryRoute = {
|
|
2667
|
+
by: string;
|
|
2668
|
+
path: string;
|
|
2669
|
+
};
|
|
2586
2670
|
type TriggerDescriptor = {
|
|
2587
2671
|
service: string;
|
|
2588
2672
|
operation: string;
|
|
@@ -2604,6 +2688,22 @@ type TriggerDescriptor = {
|
|
|
2604
2688
|
lease?: LeaseDeclaration;
|
|
2605
2689
|
/** For `webhook` / `subscription`: how a delivery is authenticated. */
|
|
2606
2690
|
verification?: WebhookVerificationSpec;
|
|
2691
|
+
/**
|
|
2692
|
+
* For `webhook`: how the VERIFIED body is read when it is not plain JSON —
|
|
2693
|
+
* Slack's interactivity is `payload=<json>`. Absent means the host reads the
|
|
2694
|
+
* body as it always has. Present means the host calls `decodeDelivery` with
|
|
2695
|
+
* it, over the same raw bytes the signature was checked against.
|
|
2696
|
+
*/
|
|
2697
|
+
decode?: DeliveryDecode;
|
|
2698
|
+
/**
|
|
2699
|
+
* For a delivery that reaches ONE endpoint on behalf of many tenants
|
|
2700
|
+
* (HubSpot app webhooks, Gmail's Pub/Sub topic): the ONLY key a host may
|
|
2701
|
+
* route by, and where it sits in the verified payload. The rule that goes
|
|
2702
|
+
* with it is fixed, not configurable: route only AFTER verification, only
|
|
2703
|
+
* to a connection or watch the host minted, and drop an unmapped key with a
|
|
2704
|
+
* 2xx and a log line, creating nothing. The package declares; the HOST routes.
|
|
2705
|
+
*/
|
|
2706
|
+
route?: DeliveryRoute;
|
|
2607
2707
|
/** For `poll`: the provider's smallest sane interval, in seconds. */
|
|
2608
2708
|
minPollSeconds?: number;
|
|
2609
2709
|
/** A faked sample event, so the node is runnable before any of the above. */
|
|
@@ -2652,6 +2752,13 @@ type InboundDelivery = {
|
|
|
2652
2752
|
/** The body EXACTLY as received. Not re-serialised. See `webhook.ts`. */
|
|
2653
2753
|
raw: string;
|
|
2654
2754
|
headers: Record<string, string | string[] | undefined>;
|
|
2755
|
+
/**
|
|
2756
|
+
* The request line as RECEIVED, for a provider that signs it (HubSpot v3).
|
|
2757
|
+
* Pass the full URL the provider called, scheme, host, path and query,
|
|
2758
|
+
* exactly as it arrived.
|
|
2759
|
+
*/
|
|
2760
|
+
method?: string;
|
|
2761
|
+
url?: string;
|
|
2655
2762
|
};
|
|
2656
2763
|
/**
|
|
2657
2764
|
* Verify an inbound delivery against a trigger's declared scheme.
|
|
@@ -2677,4 +2784,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
|
|
|
2677
2784
|
*/
|
|
2678
2785
|
declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
|
|
2679
2786
|
|
|
2680
|
-
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, type DeliveryDeclaration, type DeliveryMechanism, type DeliveryOutcome, type DriftFinding, type DriftReport, EXPIRES_AT_UNITS, type ExpiresAtUnit, FAKE_EPOCH, type FailureKind, type FakeRequest, type FakeValues, 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, 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 };
|
|
2787
|
+
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, 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, 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 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, 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, verifySharedToken, withResolvedLimit };
|
package/dist/index.js
CHANGED
|
@@ -1666,6 +1666,77 @@ function parseMime(raw) {
|
|
|
1666
1666
|
};
|
|
1667
1667
|
}
|
|
1668
1668
|
|
|
1669
|
+
// src/form-field-json.ts
|
|
1670
|
+
var FORM_FIELD_JSON_REASONS = ["missing-field", "duplicate-field", "bad-encoding", "not-json"];
|
|
1671
|
+
var FormFieldJsonError = class extends Error {
|
|
1672
|
+
constructor(reason, field, message) {
|
|
1673
|
+
super(message);
|
|
1674
|
+
this.reason = reason;
|
|
1675
|
+
this.field = field;
|
|
1676
|
+
this.name = "FormFieldJsonError";
|
|
1677
|
+
}
|
|
1678
|
+
reason;
|
|
1679
|
+
field;
|
|
1680
|
+
};
|
|
1681
|
+
var UTF8 = new TextDecoder("utf-8", { fatal: true });
|
|
1682
|
+
var HEX = /^[0-9A-Fa-f]{2}$/;
|
|
1683
|
+
function decodeFormFieldJson(raw, field) {
|
|
1684
|
+
const text = typeof raw === "string" ? raw : latin12(raw);
|
|
1685
|
+
const found = [];
|
|
1686
|
+
for (const pair of text.split("&")) {
|
|
1687
|
+
if (pair === "") continue;
|
|
1688
|
+
const eq = pair.indexOf("=");
|
|
1689
|
+
const name = component(eq === -1 ? pair : pair.slice(0, eq), field);
|
|
1690
|
+
const value2 = component(eq === -1 ? "" : pair.slice(eq + 1), field);
|
|
1691
|
+
if (name === field) found.push(value2);
|
|
1692
|
+
}
|
|
1693
|
+
if (found.length === 0) {
|
|
1694
|
+
throw new FormFieldJsonError("missing-field", field, `the body has no "${field}" field`);
|
|
1695
|
+
}
|
|
1696
|
+
if (found.length > 1) {
|
|
1697
|
+
throw new FormFieldJsonError("duplicate-field", field, `the body has "${field}" ${found.length} times`);
|
|
1698
|
+
}
|
|
1699
|
+
const [value] = found;
|
|
1700
|
+
try {
|
|
1701
|
+
return JSON.parse(value);
|
|
1702
|
+
} catch (error) {
|
|
1703
|
+
throw new FormFieldJsonError("not-json", field, `"${field}" is not JSON: ${error.message}`);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
function component(encoded, field) {
|
|
1707
|
+
const bytes = [];
|
|
1708
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
1709
|
+
const char = encoded[i];
|
|
1710
|
+
if (char === "+") {
|
|
1711
|
+
bytes.push(32);
|
|
1712
|
+
} else if (char === "%") {
|
|
1713
|
+
const hex = encoded.slice(i + 1, i + 3);
|
|
1714
|
+
if (!HEX.test(hex)) {
|
|
1715
|
+
throw new FormFieldJsonError("bad-encoding", field, `a "%" at byte ${i} is not followed by two hex digits`);
|
|
1716
|
+
}
|
|
1717
|
+
bytes.push(parseInt(hex, 16));
|
|
1718
|
+
i += 2;
|
|
1719
|
+
} else {
|
|
1720
|
+
bytes.push(encoded.charCodeAt(i) & 255);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
try {
|
|
1724
|
+
return UTF8.decode(new Uint8Array(bytes));
|
|
1725
|
+
} catch {
|
|
1726
|
+
throw new FormFieldJsonError("bad-encoding", field, "the decoded bytes are not valid UTF-8");
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
var DELIVERY_DECODE_KINDS = ["form-field-json"];
|
|
1730
|
+
function decodeDelivery(decode, raw) {
|
|
1731
|
+
if (decode.kind === "form-field-json") return decodeFormFieldJson(raw, decode.field);
|
|
1732
|
+
throw new Error(`unknown decode kind ${JSON.stringify(decode.kind)}`);
|
|
1733
|
+
}
|
|
1734
|
+
function latin12(bytes) {
|
|
1735
|
+
let out = "";
|
|
1736
|
+
for (const byte of bytes) out += String.fromCharCode(byte);
|
|
1737
|
+
return out;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1669
1740
|
// src/probe.ts
|
|
1670
1741
|
async function probe(spec) {
|
|
1671
1742
|
let response;
|
|
@@ -1882,6 +1953,29 @@ var PROBLEM_SEVERITIES = ["block", "warn"];
|
|
|
1882
1953
|
var CANONICAL_METRICS = ["like", "share", "reply", "quote", "view"];
|
|
1883
1954
|
|
|
1884
1955
|
// src/webhook.ts
|
|
1956
|
+
var SIGNED_URI_RULES = ["hubspot-v3"];
|
|
1957
|
+
var HUBSPOT_V3_DECODE = {
|
|
1958
|
+
"%3A": ":",
|
|
1959
|
+
"%2F": "/",
|
|
1960
|
+
"%3F": "?",
|
|
1961
|
+
"%40": "@",
|
|
1962
|
+
"%21": "!",
|
|
1963
|
+
"%24": "$",
|
|
1964
|
+
"%27": "'",
|
|
1965
|
+
"%28": "(",
|
|
1966
|
+
"%29": ")",
|
|
1967
|
+
"%2A": "*",
|
|
1968
|
+
"%2C": ",",
|
|
1969
|
+
"%3B": ";"
|
|
1970
|
+
};
|
|
1971
|
+
function normaliseSignedUri(url, rule) {
|
|
1972
|
+
if (rule !== "hubspot-v3") throw new Error(`unknown signed-uri rule ${JSON.stringify(rule)}`);
|
|
1973
|
+
const withoutFragment = url.split("#", 1)[0] ?? "";
|
|
1974
|
+
const q = withoutFragment.indexOf("?");
|
|
1975
|
+
if (q === -1) return withoutFragment;
|
|
1976
|
+
const query = withoutFragment.slice(q + 1).replace(/%[0-9A-Fa-f]{2}/g, (e) => HUBSPOT_V3_DECODE[e.toUpperCase()] ?? e);
|
|
1977
|
+
return `${withoutFragment.slice(0, q)}?${query}`;
|
|
1978
|
+
}
|
|
1885
1979
|
function secretKeyBytes(secret, options = {}) {
|
|
1886
1980
|
let material = secret;
|
|
1887
1981
|
if (options.secretPrefix !== void 0) {
|
|
@@ -1916,13 +2010,26 @@ async function verifyHmac(options) {
|
|
|
1916
2010
|
const sent = Number(timestamp);
|
|
1917
2011
|
if (!Number.isFinite(sent)) return { ok: false, reason: "timestamp header is not a number" };
|
|
1918
2012
|
const now = options.now ?? Math.floor(Date.now() / 1e3);
|
|
1919
|
-
|
|
2013
|
+
const sentSeconds = scheme.timestampUnit === "ms" ? sent / 1e3 : sent;
|
|
2014
|
+
if (Math.abs(now - sentSeconds) > scheme.tolerance) {
|
|
1920
2015
|
return { ok: false, reason: `delivery is outside the ${scheme.tolerance}s replay window` };
|
|
1921
2016
|
}
|
|
1922
2017
|
}
|
|
1923
2018
|
const key = secretKeyBytes(secret, scheme);
|
|
1924
2019
|
if ("reason" in key) return { ok: false, reason: key.reason };
|
|
1925
|
-
|
|
2020
|
+
let line;
|
|
2021
|
+
if (scheme.signsRequestLine) {
|
|
2022
|
+
const { method, url } = options.request ?? {};
|
|
2023
|
+
if (!method || !url) return { ok: false, reason: "delivery carried no request method or url" };
|
|
2024
|
+
line = { method, uri: scheme.uri ? normaliseSignedUri(url, scheme.uri) : url };
|
|
2025
|
+
}
|
|
2026
|
+
const expected = await hmac(
|
|
2027
|
+
secret,
|
|
2028
|
+
scheme.payload(raw, timestamp, id, line),
|
|
2029
|
+
scheme.algorithm,
|
|
2030
|
+
scheme.encoding ?? "hex",
|
|
2031
|
+
scheme
|
|
2032
|
+
);
|
|
1926
2033
|
return signatures.some((candidate) => constantTimeEquals(expected, candidate)) ? { ok: true } : { ok: false, reason: "signature did not match" };
|
|
1927
2034
|
}
|
|
1928
2035
|
async function hmac(secret, payload, algorithm, encoding = "hex", options = {}) {
|
|
@@ -2047,6 +2154,7 @@ async function verifyDelivery(trigger, delivery, secret, now) {
|
|
|
2047
2154
|
scheme: spec.scheme,
|
|
2048
2155
|
timestamp,
|
|
2049
2156
|
id,
|
|
2157
|
+
...delivery.method === void 0 && delivery.url === void 0 ? {} : { request: { method: delivery.method ?? "", url: delivery.url ?? "" } },
|
|
2050
2158
|
...now === void 0 ? {} : { now }
|
|
2051
2159
|
});
|
|
2052
2160
|
}
|
|
@@ -2087,14 +2195,18 @@ export {
|
|
|
2087
2195
|
ConnectorUnreachable,
|
|
2088
2196
|
DEFAULT_IDEMPOTENCY_WINDOW_SECONDS,
|
|
2089
2197
|
DEFAULT_RETRY,
|
|
2198
|
+
DELIVERY_DECODE_KINDS,
|
|
2090
2199
|
EXPIRES_AT_UNITS,
|
|
2091
2200
|
FAKE_EPOCH,
|
|
2201
|
+
FORM_FIELD_JSON_REASONS,
|
|
2202
|
+
FormFieldJsonError,
|
|
2092
2203
|
MAX_IDEMPOTENCY_KEY_LENGTH,
|
|
2093
2204
|
NO_IDEMPOTENCY_KEY_WARNING,
|
|
2094
2205
|
PROBLEM_SEVERITIES,
|
|
2095
2206
|
RENDERER_VERSION,
|
|
2096
2207
|
REVIEW_STALE_DAYS,
|
|
2097
2208
|
SANDBOX_KINDS,
|
|
2209
|
+
SIGNED_URI_RULES,
|
|
2098
2210
|
SUPPORTED_CONNECTOR_API,
|
|
2099
2211
|
assertConnectorApi,
|
|
2100
2212
|
byteRangeOf,
|
|
@@ -2109,6 +2221,8 @@ export {
|
|
|
2109
2221
|
compareShape,
|
|
2110
2222
|
connectionsFor,
|
|
2111
2223
|
constantTimeEquals,
|
|
2224
|
+
decodeDelivery,
|
|
2225
|
+
decodeFormFieldJson,
|
|
2112
2226
|
deliver,
|
|
2113
2227
|
fakeRequest,
|
|
2114
2228
|
fakeValues,
|
|
@@ -2132,6 +2246,7 @@ export {
|
|
|
2132
2246
|
linkRanges,
|
|
2133
2247
|
measure,
|
|
2134
2248
|
nextOccurrence,
|
|
2249
|
+
normaliseSignedUri,
|
|
2135
2250
|
parseInvite,
|
|
2136
2251
|
parseMime,
|
|
2137
2252
|
payloadHash,
|