@beignet/core 0.0.31 → 0.0.33
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 +115 -0
- package/README.md +346 -21
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +63 -47
- package/dist/application/index.js.map +1 -1
- package/dist/domain/entity.d.ts +37 -6
- package/dist/domain/entity.d.ts.map +1 -1
- package/dist/domain/entity.js +9 -7
- package/dist/domain/entity.js.map +1 -1
- package/dist/domain/index.d.ts +4 -4
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +4 -4
- package/dist/domain/index.js.map +1 -1
- package/dist/events/index.d.ts +6 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +20 -10
- package/dist/events/index.js.map +1 -1
- package/dist/flags/index.d.ts +5 -4
- package/dist/flags/index.d.ts.map +1 -1
- package/dist/flags/index.js +10 -9
- package/dist/flags/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +11 -1
- package/dist/idempotency/index.d.ts.map +1 -1
- package/dist/idempotency/index.js +4 -3
- package/dist/idempotency/index.js.map +1 -1
- package/dist/jobs/index.d.ts +449 -9
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +472 -12
- package/dist/jobs/index.js.map +1 -1
- package/dist/outbox/index.d.ts +170 -3
- package/dist/outbox/index.d.ts.map +1 -1
- package/dist/outbox/index.js +192 -8
- package/dist/outbox/index.js.map +1 -1
- package/dist/ports/events.d.ts +2 -2
- package/dist/ports/index.d.ts +6 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -0
- package/dist/ports/index.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +4 -0
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/provider.d.ts +10 -2
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +8 -7
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +47 -16
- package/dist/schedules/index.js.map +1 -1
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -0
- package/dist/search/index.js.map +1 -1
- package/dist/server/hooks/index.d.ts +1 -0
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +1 -0
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +26 -13
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +28 -34
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/hooks/security.d.ts +179 -0
- package/dist/server/hooks/security.d.ts.map +1 -0
- package/dist/server/hooks/security.js +225 -0
- package/dist/server/hooks/security.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/instrumentation.js +22 -6
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +15 -2
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/request-context.d.ts +4 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +3 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/runtime-integrity.d.ts +84 -0
- package/dist/server/runtime-integrity.d.ts.map +1 -0
- package/dist/server/runtime-integrity.js +160 -0
- package/dist/server/runtime-integrity.js.map +1 -0
- package/dist/server/server.d.ts +10 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +55 -1
- package/dist/server/server.js.map +1 -1
- package/dist/server/trusted-proxy.d.ts +77 -0
- package/dist/server/trusted-proxy.d.ts.map +1 -0
- package/dist/server/trusted-proxy.js +129 -0
- package/dist/server/trusted-proxy.js.map +1 -0
- package/dist/tasks/index.d.ts +6 -7
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +22 -5
- package/dist/tasks/index.js.map +1 -1
- package/dist/tenancy/index.d.ts +41 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +34 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +12 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/tracing/execution.d.ts +14 -0
- package/dist/tracing/execution.d.ts.map +1 -0
- package/dist/tracing/execution.js +17 -0
- package/dist/tracing/execution.js.map +1 -0
- package/dist/tracing/index.d.ts +49 -0
- package/dist/tracing/index.d.ts.map +1 -1
- package/dist/tracing/index.js +59 -0
- package/dist/tracing/index.js.map +1 -1
- package/dist/uploads/client.d.ts.map +1 -1
- package/dist/uploads/client.js +44 -6
- package/dist/uploads/client.js.map +1 -1
- package/dist/uploads/index.d.ts +182 -2
- package/dist/uploads/index.d.ts.map +1 -1
- package/dist/uploads/index.js +468 -76
- package/dist/uploads/index.js.map +1 -1
- package/dist/webhooks/index.d.ts +56 -4
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js +107 -2
- package/dist/webhooks/index.js.map +1 -1
- package/package.json +5 -1
- package/skills/app-architecture/SKILL.md +23 -2
- package/src/application/index.ts +88 -56
- package/src/domain/entity.ts +61 -13
- package/src/domain/index.ts +8 -7
- package/src/events/index.ts +27 -14
- package/src/flags/index.ts +23 -19
- package/src/idempotency/index.ts +17 -3
- package/src/jobs/index.ts +1022 -19
- package/src/outbox/index.ts +409 -9
- package/src/ports/events.ts +2 -2
- package/src/ports/index.ts +17 -0
- package/src/providers/instrumentation.ts +4 -0
- package/src/providers/provider.ts +11 -2
- package/src/schedules/index.ts +60 -26
- package/src/search/index.ts +3 -1
- package/src/server/hooks/index.ts +10 -0
- package/src/server/hooks/rate-limit.ts +52 -46
- package/src/server/hooks/security.ts +503 -0
- package/src/server/index.ts +8 -0
- package/src/server/instrumentation.ts +25 -5
- package/src/server/providers/loadProviderConfig.ts +19 -2
- package/src/server/request-context.ts +7 -0
- package/src/server/runtime-integrity.ts +322 -0
- package/src/server/server.ts +86 -1
- package/src/server/trusted-proxy.ts +249 -0
- package/src/tasks/index.ts +29 -12
- package/src/tenancy/index.ts +55 -0
- package/src/testing/index.ts +19 -3
- package/src/tracing/execution.ts +37 -0
- package/src/tracing/index.ts +137 -0
- package/src/uploads/client.ts +65 -6
- package/src/uploads/index.ts +713 -76
- package/src/webhooks/index.ts +240 -9
- package/src/domain/events.ts +0 -59
package/src/webhooks/index.ts
CHANGED
|
@@ -82,6 +82,7 @@ export interface WebhookDef<
|
|
|
82
82
|
Name extends string = string,
|
|
83
83
|
Events extends WebhookEventSchemas = WebhookEventSchemas,
|
|
84
84
|
> {
|
|
85
|
+
kind: "webhook";
|
|
85
86
|
name: Name;
|
|
86
87
|
provider?: string;
|
|
87
88
|
events: Events;
|
|
@@ -104,11 +105,72 @@ export interface DefineWebhookOptions<
|
|
|
104
105
|
/**
|
|
105
106
|
* Options accepted by `verifyWebhook(...)`.
|
|
106
107
|
*/
|
|
107
|
-
export interface VerifyWebhookOptions
|
|
108
|
+
export interface VerifyWebhookOptions<
|
|
109
|
+
AllowUnknownEvents extends boolean = boolean,
|
|
110
|
+
> {
|
|
108
111
|
verifier?: WebhookVerifier;
|
|
109
|
-
allowUnknownEvents?:
|
|
112
|
+
allowUnknownEvents?: AllowUnknownEvents;
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
type InferWebhookVerificationResult<
|
|
116
|
+
TWebhook extends WebhookDef<string, WebhookEventSchemas>,
|
|
117
|
+
AllowUnknownEvents extends boolean,
|
|
118
|
+
> = true extends AllowUnknownEvents
|
|
119
|
+
? InferWebhookEvent<TWebhook> | WebhookEvent
|
|
120
|
+
: InferWebhookEvent<TWebhook>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Timestamp formats accepted by the generic HMAC webhook verifier.
|
|
124
|
+
*/
|
|
125
|
+
export type HmacWebhookTimestampFormat =
|
|
126
|
+
| "unix-seconds"
|
|
127
|
+
| "unix-milliseconds"
|
|
128
|
+
| "iso8601";
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Timestamp source and tolerance for generic HMAC replay protection.
|
|
132
|
+
*/
|
|
133
|
+
export type HmacWebhookTimestampOptions =
|
|
134
|
+
| {
|
|
135
|
+
/**
|
|
136
|
+
* Header that carries the provider event timestamp.
|
|
137
|
+
*/
|
|
138
|
+
header: string;
|
|
139
|
+
payloadPath?: never;
|
|
140
|
+
/**
|
|
141
|
+
* Timestamp format.
|
|
142
|
+
*
|
|
143
|
+
* @default "unix-seconds"
|
|
144
|
+
*/
|
|
145
|
+
format?: HmacWebhookTimestampFormat;
|
|
146
|
+
/**
|
|
147
|
+
* Maximum absolute clock skew between the event timestamp and receipt.
|
|
148
|
+
*
|
|
149
|
+
* @default 300
|
|
150
|
+
*/
|
|
151
|
+
toleranceSec?: number;
|
|
152
|
+
}
|
|
153
|
+
| {
|
|
154
|
+
header?: never;
|
|
155
|
+
/**
|
|
156
|
+
* Dot path used to read the provider event timestamp from the JSON
|
|
157
|
+
* payload.
|
|
158
|
+
*/
|
|
159
|
+
payloadPath: string;
|
|
160
|
+
/**
|
|
161
|
+
* Timestamp format.
|
|
162
|
+
*
|
|
163
|
+
* @default "unix-seconds"
|
|
164
|
+
*/
|
|
165
|
+
format?: HmacWebhookTimestampFormat;
|
|
166
|
+
/**
|
|
167
|
+
* Maximum absolute clock skew between the event timestamp and receipt.
|
|
168
|
+
*
|
|
169
|
+
* @default 300
|
|
170
|
+
*/
|
|
171
|
+
toleranceSec?: number;
|
|
172
|
+
};
|
|
173
|
+
|
|
112
174
|
/**
|
|
113
175
|
* Options for the in-memory webhook verifier.
|
|
114
176
|
*/
|
|
@@ -162,6 +224,10 @@ export interface CreateHmacWebhookVerifierOptions {
|
|
|
162
224
|
* @default "type"
|
|
163
225
|
*/
|
|
164
226
|
eventTypePath?: string;
|
|
227
|
+
/**
|
|
228
|
+
* Optional timestamp source used to reject replayed generic HMAC webhooks.
|
|
229
|
+
*/
|
|
230
|
+
timestamp?: HmacWebhookTimestampOptions;
|
|
165
231
|
}
|
|
166
232
|
|
|
167
233
|
/**
|
|
@@ -235,6 +301,7 @@ export function defineWebhook<
|
|
|
235
301
|
if (!name) throw new WebhookOptionsError("Webhook name is required.");
|
|
236
302
|
|
|
237
303
|
return {
|
|
304
|
+
kind: "webhook",
|
|
238
305
|
name,
|
|
239
306
|
provider: options.provider,
|
|
240
307
|
events: (options.events ?? {}) as Events,
|
|
@@ -248,11 +315,12 @@ export function defineWebhook<
|
|
|
248
315
|
*/
|
|
249
316
|
export async function verifyWebhook<
|
|
250
317
|
TWebhook extends WebhookDef<string, WebhookEventSchemas>,
|
|
318
|
+
AllowUnknownEvents extends boolean = false,
|
|
251
319
|
>(
|
|
252
320
|
webhook: TWebhook,
|
|
253
321
|
input: VerifyWebhookInput,
|
|
254
|
-
options: VerifyWebhookOptions = {},
|
|
255
|
-
): Promise<
|
|
322
|
+
options: VerifyWebhookOptions<AllowUnknownEvents> = {},
|
|
323
|
+
): Promise<InferWebhookVerificationResult<TWebhook, AllowUnknownEvents>> {
|
|
256
324
|
validateWebhook(webhook);
|
|
257
325
|
const verifier = options.verifier ?? webhook.verifier;
|
|
258
326
|
if (!verifier) {
|
|
@@ -283,17 +351,26 @@ export async function verifyWebhook<
|
|
|
283
351
|
*/
|
|
284
352
|
export async function parseWebhookEvent<
|
|
285
353
|
TWebhook extends WebhookDef<string, WebhookEventSchemas>,
|
|
354
|
+
AllowUnknownEvents extends boolean = false,
|
|
286
355
|
>(
|
|
287
356
|
webhook: TWebhook,
|
|
288
357
|
event: WebhookEvent,
|
|
289
|
-
options: Pick<
|
|
290
|
-
|
|
358
|
+
options: Pick<
|
|
359
|
+
VerifyWebhookOptions<AllowUnknownEvents>,
|
|
360
|
+
"allowUnknownEvents"
|
|
361
|
+
> = {},
|
|
362
|
+
): Promise<InferWebhookVerificationResult<TWebhook, AllowUnknownEvents>> {
|
|
291
363
|
validateWebhook(webhook);
|
|
292
364
|
validateEvent(webhook, event);
|
|
293
365
|
|
|
294
366
|
const schema = webhook.events[event.type];
|
|
295
367
|
if (!schema) {
|
|
296
|
-
if (options.allowUnknownEvents
|
|
368
|
+
if (options.allowUnknownEvents === true) {
|
|
369
|
+
return event as InferWebhookVerificationResult<
|
|
370
|
+
TWebhook,
|
|
371
|
+
AllowUnknownEvents
|
|
372
|
+
>;
|
|
373
|
+
}
|
|
297
374
|
throw new WebhookVerificationError({
|
|
298
375
|
message: `Webhook "${webhook.name}" received unknown event type "${event.type}".`,
|
|
299
376
|
webhookName: webhook.name,
|
|
@@ -318,7 +395,7 @@ export async function parseWebhookEvent<
|
|
|
318
395
|
return {
|
|
319
396
|
...event,
|
|
320
397
|
payload: result.value,
|
|
321
|
-
}
|
|
398
|
+
} as InferWebhookVerificationResult<TWebhook, AllowUnknownEvents>;
|
|
322
399
|
}
|
|
323
400
|
|
|
324
401
|
/**
|
|
@@ -371,6 +448,7 @@ export function createHmacWebhookVerifier(
|
|
|
371
448
|
const algorithm = options.algorithm ?? "SHA-256";
|
|
372
449
|
const eventIdPath = options.eventIdPath ?? "id";
|
|
373
450
|
const eventTypePath = options.eventTypePath ?? "type";
|
|
451
|
+
const timestamp = normalizeHmacTimestampOptions(options.timestamp);
|
|
374
452
|
|
|
375
453
|
return {
|
|
376
454
|
async verify(input) {
|
|
@@ -394,6 +472,12 @@ export function createHmacWebhookVerifier(
|
|
|
394
472
|
}
|
|
395
473
|
|
|
396
474
|
const payload = parseJsonBody(input.rawBody);
|
|
475
|
+
const createdAt = validateHmacTimestamp({
|
|
476
|
+
input,
|
|
477
|
+
payload,
|
|
478
|
+
provider: options.provider,
|
|
479
|
+
timestamp,
|
|
480
|
+
});
|
|
397
481
|
const id = readStringPath(payload, eventIdPath);
|
|
398
482
|
const type = readStringPath(payload, eventTypePath);
|
|
399
483
|
|
|
@@ -416,6 +500,7 @@ export function createHmacWebhookVerifier(
|
|
|
416
500
|
id,
|
|
417
501
|
type,
|
|
418
502
|
provider: options.provider,
|
|
503
|
+
...(createdAt ? { createdAt } : {}),
|
|
419
504
|
payload,
|
|
420
505
|
raw: payload,
|
|
421
506
|
};
|
|
@@ -500,7 +585,7 @@ function parseJsonBody(rawBody: WebhookRawBody): unknown {
|
|
|
500
585
|
}
|
|
501
586
|
}
|
|
502
587
|
|
|
503
|
-
function
|
|
588
|
+
function readPath(input: unknown, path: string): unknown {
|
|
504
589
|
let value = input;
|
|
505
590
|
for (const segment of path.split(".")) {
|
|
506
591
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -509,9 +594,155 @@ function readStringPath(input: unknown, path: string): string | undefined {
|
|
|
509
594
|
value = (value as Record<string, unknown>)[segment];
|
|
510
595
|
}
|
|
511
596
|
|
|
597
|
+
return value;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function readStringPath(input: unknown, path: string): string | undefined {
|
|
601
|
+
const value = readPath(input, path);
|
|
512
602
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
513
603
|
}
|
|
514
604
|
|
|
605
|
+
type NormalizedHmacTimestampOptions =
|
|
606
|
+
| {
|
|
607
|
+
source: "header";
|
|
608
|
+
key: string;
|
|
609
|
+
format: HmacWebhookTimestampFormat;
|
|
610
|
+
toleranceSec: number;
|
|
611
|
+
}
|
|
612
|
+
| {
|
|
613
|
+
source: "payload";
|
|
614
|
+
path: string;
|
|
615
|
+
format: HmacWebhookTimestampFormat;
|
|
616
|
+
toleranceSec: number;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
function normalizeHmacTimestampOptions(
|
|
620
|
+
timestamp: HmacWebhookTimestampOptions | undefined,
|
|
621
|
+
): NormalizedHmacTimestampOptions | undefined {
|
|
622
|
+
if (!timestamp) return undefined;
|
|
623
|
+
|
|
624
|
+
const format = timestamp.format ?? "unix-seconds";
|
|
625
|
+
if (
|
|
626
|
+
format !== "unix-seconds" &&
|
|
627
|
+
format !== "unix-milliseconds" &&
|
|
628
|
+
format !== "iso8601"
|
|
629
|
+
) {
|
|
630
|
+
throw new WebhookOptionsError(
|
|
631
|
+
"Webhook HMAC timestamp format must be unix-seconds, unix-milliseconds, or iso8601.",
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
const toleranceSec = timestamp.toleranceSec ?? 300;
|
|
635
|
+
if (!Number.isInteger(toleranceSec) || toleranceSec <= 0) {
|
|
636
|
+
throw new WebhookOptionsError(
|
|
637
|
+
"Webhook HMAC timestamp toleranceSec must be a positive integer.",
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if ("header" in timestamp) {
|
|
642
|
+
if (!timestamp.header) {
|
|
643
|
+
throw new WebhookOptionsError(
|
|
644
|
+
"Webhook HMAC timestamp header is required.",
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
return {
|
|
649
|
+
source: "header",
|
|
650
|
+
key: normalizeHeaderName(timestamp.header),
|
|
651
|
+
format,
|
|
652
|
+
toleranceSec,
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (!timestamp.payloadPath) {
|
|
657
|
+
throw new WebhookOptionsError(
|
|
658
|
+
"Webhook HMAC timestamp payloadPath is required.",
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
source: "payload",
|
|
664
|
+
path: timestamp.payloadPath,
|
|
665
|
+
format,
|
|
666
|
+
toleranceSec,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
function validateHmacTimestamp(args: {
|
|
671
|
+
input: VerifyWebhookInput;
|
|
672
|
+
payload: unknown;
|
|
673
|
+
provider: string | undefined;
|
|
674
|
+
timestamp: NormalizedHmacTimestampOptions | undefined;
|
|
675
|
+
}): Date | undefined {
|
|
676
|
+
const { timestamp } = args;
|
|
677
|
+
if (!timestamp) return undefined;
|
|
678
|
+
|
|
679
|
+
const value =
|
|
680
|
+
timestamp.source === "header"
|
|
681
|
+
? args.input.headers?.[timestamp.key]
|
|
682
|
+
: readPath(args.payload, timestamp.path);
|
|
683
|
+
|
|
684
|
+
if (value === undefined || value === null || value === "") {
|
|
685
|
+
throw new WebhookVerificationError({
|
|
686
|
+
message:
|
|
687
|
+
timestamp.source === "header"
|
|
688
|
+
? `Missing ${timestamp.key} header.`
|
|
689
|
+
: `Webhook payload is missing timestamp at "${timestamp.path}".`,
|
|
690
|
+
provider: args.provider,
|
|
691
|
+
code: "missing_timestamp",
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const createdAt = parseHmacTimestampValue(
|
|
696
|
+
value,
|
|
697
|
+
timestamp.format,
|
|
698
|
+
args.provider,
|
|
699
|
+
);
|
|
700
|
+
const receivedAt = args.input.receivedAt ?? new Date();
|
|
701
|
+
const skewMs = Math.abs(receivedAt.getTime() - createdAt.getTime());
|
|
702
|
+
if (skewMs > timestamp.toleranceSec * 1000) {
|
|
703
|
+
throw new WebhookVerificationError({
|
|
704
|
+
message: `Webhook timestamp is outside the ${timestamp.toleranceSec}s tolerance.`,
|
|
705
|
+
provider: args.provider,
|
|
706
|
+
code: "timestamp_outside_tolerance",
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
return createdAt;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
function parseHmacTimestampValue(
|
|
714
|
+
value: unknown,
|
|
715
|
+
format: HmacWebhookTimestampFormat,
|
|
716
|
+
provider: string | undefined,
|
|
717
|
+
): Date {
|
|
718
|
+
const fail = () =>
|
|
719
|
+
new WebhookVerificationError({
|
|
720
|
+
message: "Webhook timestamp is invalid.",
|
|
721
|
+
provider,
|
|
722
|
+
code: "invalid_timestamp",
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
let millis: number;
|
|
726
|
+
if (format === "iso8601") {
|
|
727
|
+
if (typeof value !== "string") throw fail();
|
|
728
|
+
millis = Date.parse(value);
|
|
729
|
+
} else {
|
|
730
|
+
const numeric =
|
|
731
|
+
typeof value === "number"
|
|
732
|
+
? value
|
|
733
|
+
: typeof value === "string"
|
|
734
|
+
? Number(value)
|
|
735
|
+
: Number.NaN;
|
|
736
|
+
if (!Number.isFinite(numeric)) throw fail();
|
|
737
|
+
millis = format === "unix-seconds" ? numeric * 1000 : numeric;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
if (!Number.isFinite(millis)) throw fail();
|
|
741
|
+
const date = new Date(millis);
|
|
742
|
+
if (Number.isNaN(date.getTime())) throw fail();
|
|
743
|
+
return date;
|
|
744
|
+
}
|
|
745
|
+
|
|
515
746
|
async function hmacHex(
|
|
516
747
|
algorithm: CreateHmacWebhookVerifierOptions["algorithm"],
|
|
517
748
|
secret: string,
|
package/src/domain/events.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
EventDef,
|
|
3
|
-
InferEventPayload,
|
|
4
|
-
StandardSchema,
|
|
5
|
-
} from "../events/index.js";
|
|
6
|
-
import { defineEvent } from "../events/index.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Domain event definition with a stable name and payload schema.
|
|
10
|
-
*/
|
|
11
|
-
export type DomainEventDef<
|
|
12
|
-
Name extends string = string,
|
|
13
|
-
Payload extends StandardSchema = StandardSchema,
|
|
14
|
-
> = EventDef<Name, Payload>;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Infer the payload type from a DomainEventDef.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* const UserRegistered = defineDomainEvent(
|
|
22
|
-
* "user.registered",
|
|
23
|
-
* z.object({
|
|
24
|
-
* userId: z.string(),
|
|
25
|
-
* email: z.string().email(),
|
|
26
|
-
* })
|
|
27
|
-
* );
|
|
28
|
-
*
|
|
29
|
-
* type Payload = InferEventPayload<typeof UserRegistered>;
|
|
30
|
-
* // { userId: string; email: string }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export type { InferEventPayload };
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Create a new domain event definition.
|
|
37
|
-
*
|
|
38
|
-
* This is a domain-focused alias around `defineEvent(...)` for applications
|
|
39
|
-
* that separate domain events from integration events.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* const UserRegistered = defineDomainEvent(
|
|
44
|
-
* "user.registered",
|
|
45
|
-
* z.object({
|
|
46
|
-
* userId: z.string(),
|
|
47
|
-
* email: z.string().email(),
|
|
48
|
-
* })
|
|
49
|
-
* );
|
|
50
|
-
*
|
|
51
|
-
* type UserRegistered = typeof UserRegistered;
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export function defineDomainEvent<
|
|
55
|
-
Name extends string,
|
|
56
|
-
Payload extends StandardSchema,
|
|
57
|
-
>(name: Name, payload: Payload): DomainEventDef<Name, Payload> {
|
|
58
|
-
return defineEvent(name, { payload });
|
|
59
|
-
}
|