@whooshbang/contracts 2.2.0 → 2.3.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 +6 -0
- package/contract-manifest.json +32 -32
- package/dist/generated/artifact-index.d.ts +33 -33
- package/dist/generated/artifact-index.js +32 -32
- package/dist/generated/interaction-v1.d.ts +72 -4
- package/dist/generated/validators-standalone.d.ts +492 -480
- package/dist/generated/validators-standalone.js +4191 -2276
- package/dist/generated/validators-standalone.js.map +1 -1
- package/dist/generated/validators.d.ts +2 -1
- package/dist/generated/validators.js +2 -1
- package/dist/generated/validators.js.map +1 -1
- package/dist/generated/whooshbang-v1.d.ts +94 -17
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interaction-expiry.d.ts +17 -0
- package/dist/interaction-expiry.js +67 -0
- package/dist/interaction-expiry.js.map +1 -0
- package/fixtures/core-v1/fixture-index.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +1 -1
- package/fixtures/core-v1/scenarios/cancellation-too-late.json +1 -1
- package/fixtures/core-v1/scenarios/cross-organization-project.json +1 -1
- package/fixtures/core-v1/scenarios/cross-project-resource.json +1 -1
- package/fixtures/core-v1/scenarios/environment-mismatch.json +1 -1
- package/fixtures/core-v1/scenarios/idempotency-conflict.json +1 -1
- package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +1 -1
- package/fixtures/core-v1/scenarios/malformed-bearer.json +1 -1
- package/fixtures/core-v1/scenarios/metadata-overrun.json +1 -1
- package/fixtures/core-v1/scenarios/missing-scope.json +1 -1
- package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +1 -1
- package/fixtures/core-v1/scenarios/project-slug-conflict.json +1 -1
- package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-activation-replay.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-authorization-capability-opacity.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-cross-connection-callback-rejected.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-expired-replay.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-selected-connection-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/membership-broadcast-snapshot.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/preferred-binding-resolution.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/recipient-session-security.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/subscriber-initial-groups-transaction.json +1 -1
- package/openapi/generated/whooshbang-v1.bundle.json +128 -20
- package/openapi/whooshbang-v1.yaml +4 -2
- package/package.json +1 -1
- package/schemas/core-scenario.schema.json +1 -1
- package/schemas/events/agent-binding-degraded-v1.schema.json +1 -1
- package/schemas/events/interaction-expired-v1.schema.json +1 -1
- package/schemas/events/interaction-received-v1.schema.json +1 -1
- package/schemas/events/message-delivered-v1.schema.json +1 -1
- package/schemas/events/message-expired-v1.schema.json +1 -1
- package/schemas/events/message-failed-v1.schema.json +1 -1
- package/schemas/events/message-provider-accepted-v1.schema.json +1 -1
- package/schemas/events/subscription-activated-v1.schema.json +1 -1
- package/schemas/events/subscription-revoked-v1.schema.json +1 -1
- package/schemas/events/whooshbang-event-v1.schema.json +1 -1
- package/schemas/fixture-index.schema.json +1 -1
- package/schemas/interaction-machine-scenario.schema.json +1 -1
- package/schemas/interaction-v1.schema.json +151 -19
- package/schemas/machine-v1.schema.json +1 -1
- package/schemas/provider-capabilities-v1.schema.json +1 -1
- package/schemas/webhooks/webhook-delivery-case-v1.schema.json +1 -1
- package/schemas/webhooks/webhook-signing-vector-v1.schema.json +1 -1
- package/schemas/whooshbang-v1.schema.json +52 -48
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { InteractionRequest } from "./generated/interaction-v1.js";
|
|
2
|
+
import type { CreateMessageRequest } from "./generated/whooshbang-v1.js";
|
|
3
|
+
/** Compatibility default, never a ceiling on a sender-selected answer window. */
|
|
4
|
+
export declare const DEFAULT_INTERACTION_EXPIRY_SECONDS = 86400;
|
|
5
|
+
/** The public RFC3339 timestamp vocabulary has four-digit years. */
|
|
6
|
+
export declare const MAX_INTERACTION_TIMESTAMP_MILLISECONDS = 253402300799999;
|
|
7
|
+
export declare class InteractionExpiryError extends RangeError {
|
|
8
|
+
readonly field: "expires_at" | "expires_in_seconds";
|
|
9
|
+
constructor(field: "expires_at" | "expires_in_seconds", message: string);
|
|
10
|
+
}
|
|
11
|
+
/** Resolve once at acceptance, after idempotency lookup, never at dispatch/replay. */
|
|
12
|
+
export declare function resolveInteractionExpiry(acceptedAt: Date, input: {
|
|
13
|
+
readonly expires_at?: string;
|
|
14
|
+
readonly expires_in_seconds?: number;
|
|
15
|
+
}): string;
|
|
16
|
+
/** Canonical retained/provider request: relative input never escapes acceptance. */
|
|
17
|
+
export declare function resolveInteractionRequest(acceptedAt: Date, input: NonNullable<CreateMessageRequest["interaction"]>): InteractionRequest;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** Compatibility default, never a ceiling on a sender-selected answer window. */
|
|
2
|
+
export const DEFAULT_INTERACTION_EXPIRY_SECONDS = 86_400;
|
|
3
|
+
/** The public RFC3339 timestamp vocabulary has four-digit years. */
|
|
4
|
+
export const MAX_INTERACTION_TIMESTAMP_MILLISECONDS = 253_402_300_799_999;
|
|
5
|
+
const timestampPattern = /^(\d{4})-(\d{2})-(\d{2})T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,3})?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/u;
|
|
6
|
+
export class InteractionExpiryError extends RangeError {
|
|
7
|
+
field;
|
|
8
|
+
constructor(field, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.field = field;
|
|
11
|
+
this.name = "InteractionExpiryError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Resolve once at acceptance, after idempotency lookup, never at dispatch/replay. */
|
|
15
|
+
export function resolveInteractionExpiry(acceptedAt, input) {
|
|
16
|
+
const absolute = input.expires_at;
|
|
17
|
+
const relative = input.expires_in_seconds;
|
|
18
|
+
const field = absolute === undefined ? "expires_in_seconds" : "expires_at";
|
|
19
|
+
const fail = (message) => {
|
|
20
|
+
throw new InteractionExpiryError(field, message);
|
|
21
|
+
};
|
|
22
|
+
if (absolute !== undefined && relative !== undefined)
|
|
23
|
+
fail("Supply expires_at or expires_in_seconds, not both.");
|
|
24
|
+
const base = acceptedAt.getTime();
|
|
25
|
+
if (!Number.isFinite(base))
|
|
26
|
+
fail("The acceptance clock is invalid.");
|
|
27
|
+
let deadline;
|
|
28
|
+
if (absolute !== undefined) {
|
|
29
|
+
const match = timestampPattern.exec(absolute);
|
|
30
|
+
if (!match)
|
|
31
|
+
return fail("Use an RFC3339 timestamp with an explicit timezone and at most three fractional digits.");
|
|
32
|
+
// Date.parse normalizes impossible dates such as February 30; refuse them.
|
|
33
|
+
const year = Number(match[1]);
|
|
34
|
+
const month = Number(match[2]);
|
|
35
|
+
const day = Number(match[3]);
|
|
36
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
37
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
38
|
+
if (year < 1 ||
|
|
39
|
+
month < 1 ||
|
|
40
|
+
month > 12 ||
|
|
41
|
+
day < 1 ||
|
|
42
|
+
day > (days[month - 1] ?? 0))
|
|
43
|
+
fail("Use a real calendar date in years 0001 through 9999.");
|
|
44
|
+
deadline = Date.parse(absolute);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const seconds = relative ?? DEFAULT_INTERACTION_EXPIRY_SECONDS;
|
|
48
|
+
if (!Number.isSafeInteger(seconds) || seconds < 30)
|
|
49
|
+
fail("Use a whole number of seconds, at least 30.");
|
|
50
|
+
deadline = base + seconds * 1000;
|
|
51
|
+
}
|
|
52
|
+
if (!Number.isSafeInteger(deadline) ||
|
|
53
|
+
deadline > MAX_INTERACTION_TIMESTAMP_MILLISECONDS ||
|
|
54
|
+
deadline < -62_135_596_800_000)
|
|
55
|
+
fail("The resolved expiry must be representable in years 0001 through 9999.");
|
|
56
|
+
if (deadline - base < 30_000)
|
|
57
|
+
fail("Interaction expiry must be at least 30 seconds after server acceptance.");
|
|
58
|
+
return new Date(deadline).toISOString();
|
|
59
|
+
}
|
|
60
|
+
/** Canonical retained/provider request: relative input never escapes acceptance. */
|
|
61
|
+
export function resolveInteractionRequest(acceptedAt, input) {
|
|
62
|
+
const expires_at = resolveInteractionExpiry(acceptedAt, input);
|
|
63
|
+
const request = { ...input };
|
|
64
|
+
delete request.expires_in_seconds;
|
|
65
|
+
return { ...request, expires_at };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=interaction-expiry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-expiry.js","sourceRoot":"","sources":["../src/interaction-expiry.ts"],"names":[],"mappings":"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"}
|