@particle-academy/fancy-connector-core 0.8.1 → 0.10.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
@@ -1256,6 +1256,92 @@ declare function classifyThrown(cause: unknown, ctx: ConnectorErrorContext): Con
1256
1256
  */
1257
1257
  declare function httpFailure(status: number, body: string, retryAfter?: string | null): Error;
1258
1258
 
1259
+ /**
1260
+ * RFC 5545 in, a structured invite and its join targets out — the read MOIC's
1261
+ * meeting bot needs from nothing but the text a calendar API hands back.
1262
+ *
1263
+ * Written from scratch (the owner: no third-party code), as ONE
1264
+ * implementation in two runtimes — `php/src/Ical.php` is the twin — and held
1265
+ * to the authored corpus under `fixtures/ical/`, which both must reproduce
1266
+ * exactly. `fixtures/ical/README.md` lists every decision a case pins; the
1267
+ * ones easy to get differently in two languages are restated here:
1268
+ *
1269
+ * - Folded lines (a line break followed by a single space or tab) join
1270
+ * before anything else runs; TEXT values are then RFC 5545-unescaped
1271
+ * (`\n`, `\,`, `\;`, `\\`).
1272
+ * - `DTSTART`/`DTEND` always come back as UTC instants. A `Z` suffix passes
1273
+ * through; a `TZID` parameter resolves through the calendar's own
1274
+ * `VTIMEZONE` (an unknown TZID is refused BY NAME, never guessed); a value
1275
+ * with neither — RFC 5545's FLOATING time — is treated as UTC, a decision
1276
+ * named here rather than left to look like an oversight: resolving a
1277
+ * floating time correctly needs the READER's timezone, which nothing in
1278
+ * the invite carries.
1279
+ * - `RRULE` support is intentionally narrow: `FREQ` daily/weekly/monthly/
1280
+ * yearly with `INTERVAL`, `COUNT` and `UNTIL`, and `BYDAY` for WEEKLY only.
1281
+ * No `BYMONTHDAY`, `BYSETPOS`, `BYWEEKNO`, `BYYEARDAY`, `WKST`, `EXDATE` or
1282
+ * `RDATE` — a recurring invite using one of those still parses (its RRULE
1283
+ * fields are read, never dropped), but `nextOccurrence` does not attempt
1284
+ * to walk it.
1285
+ * - Join targets are ALLOW-LISTED: Google Meet, Zoom (with its meeting id
1286
+ * and passcode read out of the URL), Microsoft Teams, and a dial-in phone
1287
+ * number with a passcode read from its own line. Anything else is ignored,
1288
+ * never guessed at — a bot that tried an unknown link shape would attempt
1289
+ * to join something it cannot handle.
1290
+ */
1291
+ type InviteMethod = "REQUEST" | "CANCEL";
1292
+ type Attendee = {
1293
+ name: string | null;
1294
+ email: string;
1295
+ role: string | null;
1296
+ partstat: string | null;
1297
+ };
1298
+ type RecurrenceRule = {
1299
+ freq: "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY";
1300
+ interval: number;
1301
+ count: number | null;
1302
+ until: string | null;
1303
+ byDay: string[] | null;
1304
+ };
1305
+ type Invite = {
1306
+ method: InviteMethod;
1307
+ uid: string;
1308
+ sequence: number;
1309
+ summary: string | null;
1310
+ description: string | null;
1311
+ location: string | null;
1312
+ status: string | null;
1313
+ dtstart: string;
1314
+ dtend: string | null;
1315
+ organizer: {
1316
+ name: string | null;
1317
+ email: string;
1318
+ } | null;
1319
+ attendees: Attendee[];
1320
+ rrule: RecurrenceRule | null;
1321
+ };
1322
+ type JoinTargetKind = "google-meet" | "zoom" | "teams" | "dial-in";
1323
+ type JoinTarget = {
1324
+ kind: JoinTargetKind;
1325
+ url: string | null;
1326
+ meetingId: string | null;
1327
+ passcode: string | null;
1328
+ phone: string | null;
1329
+ };
1330
+ declare function parseInvite(raw: string): Invite;
1331
+ /**
1332
+ * The next occurrence at or after `afterIso`, or `null` when the series (or
1333
+ * the single occurrence, for a non-recurring invite) has nothing left to
1334
+ * offer at or after that instant.
1335
+ */
1336
+ declare function nextOccurrence(invite: Invite, afterIso: string): string | null;
1337
+ /**
1338
+ * The allow-listed places a bot can actually join, in the order they appear
1339
+ * in the text. Anything else — Webex, a generic link, an unrecognised
1340
+ * dial-in shape — is not returned: a shape this package does not know is a
1341
+ * shape a bot should not guess at.
1342
+ */
1343
+ declare function joinTargets(invite: Invite): JoinTarget[];
1344
+
1259
1345
  /**
1260
1346
  * A run, a position inside it, and how many times that position has been tried.
1261
1347
  *
@@ -2347,13 +2433,33 @@ type HmacScheme = {
2347
2433
  /**
2348
2434
  * Build the exact string that gets signed. Providers differ here more than
2349
2435
  * anywhere else — Stripe signs `${timestamp}.${body}`, Slack signs
2350
- * `v0:${timestamp}:${body}`, GitHub signs the body alone.
2436
+ * `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
2437
+ * `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
2351
2438
  */
2352
- payload: (raw: string, timestamp?: string) => string;
2439
+ payload: (raw: string, timestamp?: string, id?: string) => string;
2353
2440
  /** Seconds a delivery stays acceptable. */
2354
2441
  tolerance?: number;
2355
2442
  /** Encoding of the signature the provider sends. */
2356
2443
  encoding?: "hex" | "base64";
2444
+ /**
2445
+ * How the SECRET is spelled. `utf8` (the default, and every provider before
2446
+ * Svix): the key is the text's bytes. `base64`: the key is the DECODED
2447
+ * bytes — Svix hands out `whsec_<base64>`, and half of the decoded bytes are
2448
+ * not valid UTF-8, so encoding the text would sign with the wrong key and
2449
+ * fail exactly like a wrong secret.
2450
+ */
2451
+ secretEncoding?: "utf8" | "base64";
2452
+ /** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
2453
+ secretPrefix?: string;
2454
+ };
2455
+ /** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
2456
+ declare function secretKeyBytes(secret: string, options?: {
2457
+ secretEncoding?: "utf8" | "base64";
2458
+ secretPrefix?: string;
2459
+ }): {
2460
+ bytes: Uint8Array;
2461
+ } | {
2462
+ reason: string;
2357
2463
  };
2358
2464
  /**
2359
2465
  * Verify an HMAC-signed delivery.
@@ -2364,15 +2470,33 @@ type HmacScheme = {
2364
2470
  */
2365
2471
  declare function verifyHmac(options: {
2366
2472
  raw: string;
2367
- signature: string | undefined;
2473
+ /**
2474
+ * The signature(s) the delivery carried. A LIST when the provider sends
2475
+ * several — Stripe signs once per active secret while a secret is rolled
2476
+ * and Svix's header "could be any number of signatures" — and the delivery
2477
+ * is accepted when ANY matches. A first-only rule fails every delivery
2478
+ * whose first signature came from the new secret, for the whole roll, and
2479
+ * it reads exactly like a wrong secret.
2480
+ */
2481
+ signature: string | string[] | undefined;
2368
2482
  secret: string | undefined;
2369
2483
  scheme: HmacScheme;
2370
2484
  timestamp?: string;
2485
+ /** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
2486
+ id?: string;
2371
2487
  /** Seconds since the epoch. Injected so tests are not clock-dependent. */
2372
2488
  now?: number;
2373
2489
  }): Promise<WebhookVerification>;
2374
- /** HMAC of `payload` under `secret`, hex or base64 encoded. */
2375
- declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64"): Promise<string>;
2490
+ /**
2491
+ * HMAC of `payload` under `secret`, hex or base64 encoded. `options` says how
2492
+ * the secret is spelled (see `HmacScheme.secretEncoding`); a secret that
2493
+ * cannot be a key THROWS here — signing has no result to carry a reason in —
2494
+ * while `verifyHmac` names it in its result before ever calling this.
2495
+ */
2496
+ declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64", options?: {
2497
+ secretEncoding?: "utf8" | "base64";
2498
+ secretPrefix?: string;
2499
+ }): Promise<string>;
2376
2500
  /**
2377
2501
  * Compare two strings without leaking where they diverge.
2378
2502
  *
@@ -2503,13 +2627,23 @@ type HmacVerificationSpec = {
2503
2627
  signatureHeader: string;
2504
2628
  /** Header carrying the timestamp, when the scheme signs one. */
2505
2629
  timestampHeader?: string;
2630
+ /**
2631
+ * Header carrying the delivery's ID, when the scheme signs one — Svix
2632
+ * signs `${svix-id}.${svix-timestamp}.${body}`. A declared id header the
2633
+ * delivery does not carry is a refusal, never a payload with a hole in it.
2634
+ */
2635
+ idHeader?: string;
2506
2636
  scheme: HmacScheme;
2507
2637
  /**
2508
2638
  * Some schemes pack the timestamp INTO the signature header
2509
2639
  * (Stripe: `t=…,v1=…`). Given the raw header value, return the parts.
2640
+ * `signatures` carries EVERY signature the header held (a provider rolling
2641
+ * a secret sends one per active secret); `signature` alone is the 0.8.x
2642
+ * shape and still means one.
2510
2643
  */
2511
2644
  parse?: (raw: string) => {
2512
2645
  signature?: string;
2646
+ signatures?: string[];
2513
2647
  timestamp?: string;
2514
2648
  };
2515
2649
  /** A challenge the provider makes before it will deliver anything. */
@@ -2555,4 +2689,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
2555
2689
  */
2556
2690
  declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
2557
2691
 
2558
- export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, 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 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 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, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
2692
+ 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 };
package/dist/index.d.ts CHANGED
@@ -1256,6 +1256,92 @@ declare function classifyThrown(cause: unknown, ctx: ConnectorErrorContext): Con
1256
1256
  */
1257
1257
  declare function httpFailure(status: number, body: string, retryAfter?: string | null): Error;
1258
1258
 
1259
+ /**
1260
+ * RFC 5545 in, a structured invite and its join targets out — the read MOIC's
1261
+ * meeting bot needs from nothing but the text a calendar API hands back.
1262
+ *
1263
+ * Written from scratch (the owner: no third-party code), as ONE
1264
+ * implementation in two runtimes — `php/src/Ical.php` is the twin — and held
1265
+ * to the authored corpus under `fixtures/ical/`, which both must reproduce
1266
+ * exactly. `fixtures/ical/README.md` lists every decision a case pins; the
1267
+ * ones easy to get differently in two languages are restated here:
1268
+ *
1269
+ * - Folded lines (a line break followed by a single space or tab) join
1270
+ * before anything else runs; TEXT values are then RFC 5545-unescaped
1271
+ * (`\n`, `\,`, `\;`, `\\`).
1272
+ * - `DTSTART`/`DTEND` always come back as UTC instants. A `Z` suffix passes
1273
+ * through; a `TZID` parameter resolves through the calendar's own
1274
+ * `VTIMEZONE` (an unknown TZID is refused BY NAME, never guessed); a value
1275
+ * with neither — RFC 5545's FLOATING time — is treated as UTC, a decision
1276
+ * named here rather than left to look like an oversight: resolving a
1277
+ * floating time correctly needs the READER's timezone, which nothing in
1278
+ * the invite carries.
1279
+ * - `RRULE` support is intentionally narrow: `FREQ` daily/weekly/monthly/
1280
+ * yearly with `INTERVAL`, `COUNT` and `UNTIL`, and `BYDAY` for WEEKLY only.
1281
+ * No `BYMONTHDAY`, `BYSETPOS`, `BYWEEKNO`, `BYYEARDAY`, `WKST`, `EXDATE` or
1282
+ * `RDATE` — a recurring invite using one of those still parses (its RRULE
1283
+ * fields are read, never dropped), but `nextOccurrence` does not attempt
1284
+ * to walk it.
1285
+ * - Join targets are ALLOW-LISTED: Google Meet, Zoom (with its meeting id
1286
+ * and passcode read out of the URL), Microsoft Teams, and a dial-in phone
1287
+ * number with a passcode read from its own line. Anything else is ignored,
1288
+ * never guessed at — a bot that tried an unknown link shape would attempt
1289
+ * to join something it cannot handle.
1290
+ */
1291
+ type InviteMethod = "REQUEST" | "CANCEL";
1292
+ type Attendee = {
1293
+ name: string | null;
1294
+ email: string;
1295
+ role: string | null;
1296
+ partstat: string | null;
1297
+ };
1298
+ type RecurrenceRule = {
1299
+ freq: "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY";
1300
+ interval: number;
1301
+ count: number | null;
1302
+ until: string | null;
1303
+ byDay: string[] | null;
1304
+ };
1305
+ type Invite = {
1306
+ method: InviteMethod;
1307
+ uid: string;
1308
+ sequence: number;
1309
+ summary: string | null;
1310
+ description: string | null;
1311
+ location: string | null;
1312
+ status: string | null;
1313
+ dtstart: string;
1314
+ dtend: string | null;
1315
+ organizer: {
1316
+ name: string | null;
1317
+ email: string;
1318
+ } | null;
1319
+ attendees: Attendee[];
1320
+ rrule: RecurrenceRule | null;
1321
+ };
1322
+ type JoinTargetKind = "google-meet" | "zoom" | "teams" | "dial-in";
1323
+ type JoinTarget = {
1324
+ kind: JoinTargetKind;
1325
+ url: string | null;
1326
+ meetingId: string | null;
1327
+ passcode: string | null;
1328
+ phone: string | null;
1329
+ };
1330
+ declare function parseInvite(raw: string): Invite;
1331
+ /**
1332
+ * The next occurrence at or after `afterIso`, or `null` when the series (or
1333
+ * the single occurrence, for a non-recurring invite) has nothing left to
1334
+ * offer at or after that instant.
1335
+ */
1336
+ declare function nextOccurrence(invite: Invite, afterIso: string): string | null;
1337
+ /**
1338
+ * The allow-listed places a bot can actually join, in the order they appear
1339
+ * in the text. Anything else — Webex, a generic link, an unrecognised
1340
+ * dial-in shape — is not returned: a shape this package does not know is a
1341
+ * shape a bot should not guess at.
1342
+ */
1343
+ declare function joinTargets(invite: Invite): JoinTarget[];
1344
+
1259
1345
  /**
1260
1346
  * A run, a position inside it, and how many times that position has been tried.
1261
1347
  *
@@ -2347,13 +2433,33 @@ type HmacScheme = {
2347
2433
  /**
2348
2434
  * Build the exact string that gets signed. Providers differ here more than
2349
2435
  * anywhere else — Stripe signs `${timestamp}.${body}`, Slack signs
2350
- * `v0:${timestamp}:${body}`, GitHub signs the body alone.
2436
+ * `v0:${timestamp}:${body}`, GitHub signs the body alone, and Svix signs
2437
+ * `${id}.${timestamp}.${body}` where `id` is the delivery's own id header.
2351
2438
  */
2352
- payload: (raw: string, timestamp?: string) => string;
2439
+ payload: (raw: string, timestamp?: string, id?: string) => string;
2353
2440
  /** Seconds a delivery stays acceptable. */
2354
2441
  tolerance?: number;
2355
2442
  /** Encoding of the signature the provider sends. */
2356
2443
  encoding?: "hex" | "base64";
2444
+ /**
2445
+ * How the SECRET is spelled. `utf8` (the default, and every provider before
2446
+ * Svix): the key is the text's bytes. `base64`: the key is the DECODED
2447
+ * bytes — Svix hands out `whsec_<base64>`, and half of the decoded bytes are
2448
+ * not valid UTF-8, so encoding the text would sign with the wrong key and
2449
+ * fail exactly like a wrong secret.
2450
+ */
2451
+ secretEncoding?: "utf8" | "base64";
2452
+ /** A prefix to strip before decoding (`whsec_`). Its absence is a refusal, never a guess. */
2453
+ secretPrefix?: string;
2454
+ };
2455
+ /** The HMAC key a scheme's secret spells, or the reason it cannot be one. */
2456
+ declare function secretKeyBytes(secret: string, options?: {
2457
+ secretEncoding?: "utf8" | "base64";
2458
+ secretPrefix?: string;
2459
+ }): {
2460
+ bytes: Uint8Array;
2461
+ } | {
2462
+ reason: string;
2357
2463
  };
2358
2464
  /**
2359
2465
  * Verify an HMAC-signed delivery.
@@ -2364,15 +2470,33 @@ type HmacScheme = {
2364
2470
  */
2365
2471
  declare function verifyHmac(options: {
2366
2472
  raw: string;
2367
- signature: string | undefined;
2473
+ /**
2474
+ * The signature(s) the delivery carried. A LIST when the provider sends
2475
+ * several — Stripe signs once per active secret while a secret is rolled
2476
+ * and Svix's header "could be any number of signatures" — and the delivery
2477
+ * is accepted when ANY matches. A first-only rule fails every delivery
2478
+ * whose first signature came from the new secret, for the whole roll, and
2479
+ * it reads exactly like a wrong secret.
2480
+ */
2481
+ signature: string | string[] | undefined;
2368
2482
  secret: string | undefined;
2369
2483
  scheme: HmacScheme;
2370
2484
  timestamp?: string;
2485
+ /** The delivery's id, when the scheme signs one (Svix's `svix-id`). */
2486
+ id?: string;
2371
2487
  /** Seconds since the epoch. Injected so tests are not clock-dependent. */
2372
2488
  now?: number;
2373
2489
  }): Promise<WebhookVerification>;
2374
- /** HMAC of `payload` under `secret`, hex or base64 encoded. */
2375
- declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64"): Promise<string>;
2490
+ /**
2491
+ * HMAC of `payload` under `secret`, hex or base64 encoded. `options` says how
2492
+ * the secret is spelled (see `HmacScheme.secretEncoding`); a secret that
2493
+ * cannot be a key THROWS here — signing has no result to carry a reason in —
2494
+ * while `verifyHmac` names it in its result before ever calling this.
2495
+ */
2496
+ declare function hmac(secret: string, payload: string, algorithm: HmacScheme["algorithm"], encoding?: "hex" | "base64", options?: {
2497
+ secretEncoding?: "utf8" | "base64";
2498
+ secretPrefix?: string;
2499
+ }): Promise<string>;
2376
2500
  /**
2377
2501
  * Compare two strings without leaking where they diverge.
2378
2502
  *
@@ -2503,13 +2627,23 @@ type HmacVerificationSpec = {
2503
2627
  signatureHeader: string;
2504
2628
  /** Header carrying the timestamp, when the scheme signs one. */
2505
2629
  timestampHeader?: string;
2630
+ /**
2631
+ * Header carrying the delivery's ID, when the scheme signs one — Svix
2632
+ * signs `${svix-id}.${svix-timestamp}.${body}`. A declared id header the
2633
+ * delivery does not carry is a refusal, never a payload with a hole in it.
2634
+ */
2635
+ idHeader?: string;
2506
2636
  scheme: HmacScheme;
2507
2637
  /**
2508
2638
  * Some schemes pack the timestamp INTO the signature header
2509
2639
  * (Stripe: `t=…,v1=…`). Given the raw header value, return the parts.
2640
+ * `signatures` carries EVERY signature the header held (a provider rolling
2641
+ * a secret sends one per active secret); `signature` alone is the 0.8.x
2642
+ * shape and still means one.
2510
2643
  */
2511
2644
  parse?: (raw: string) => {
2512
2645
  signature?: string;
2646
+ signatures?: string[];
2513
2647
  timestamp?: string;
2514
2648
  };
2515
2649
  /** A challenge the provider makes before it will deliver anything. */
@@ -2555,4 +2689,4 @@ declare function verifyDelivery(trigger: TriggerDescriptor, delivery: InboundDel
2555
2689
  */
2556
2690
  declare function triggerEvent(trigger: TriggerDescriptor, connection: ResolvedConnection, injected: unknown, config: Record<string, unknown>): unknown;
2557
2691
 
2558
- export { AMBIGUOUS_REFUSAL, type ApiContract, type Attempt, 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 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 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, leaseAction, leaseFromResponse, leaseRenewAt, leaseState, linkRanges, measure, parseMime, payloadHash, postChain, probe, providerProblems, providerSandboxIsSelectable, registerConnectionHost, registerTransport, render, reported, resetRateState, resolveConnection, resolveConnectorMode, respectRate, runIdentityFrom, runKeyFrom, runProbes, sandboxIsSelectable, sandboxRefusal, satisfiesMinimum, seedFrom, shapeOf, shouldRetry, sliceByteRange, splitToFit, subscriptionLease, triggerEvent, unchecked, utf8Length, verifyDelivery, verifyHmac, verifySharedToken, withResolvedLimit };
2692
+ 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 };