@geekmidas/constructs 10.0.0-alpha.41 → 10.0.0-alpha.43
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/{Cron-CMEGfRs8.d.cts → Cron-DI3nKoic.d.cts} +3 -2
- package/dist/Cron-DI3nKoic.d.cts.map +1 -0
- package/dist/{Cron-D6X4-xjB.d.mts → Cron-uYAHPnp7.d.mts} +3 -2
- package/dist/Cron-uYAHPnp7.d.mts.map +1 -0
- package/dist/{CronBuilder-DB35T5dL.cjs → CronBuilder-BoHzlWU_.cjs} +8 -3
- package/dist/CronBuilder-BoHzlWU_.cjs.map +1 -0
- package/dist/{CronBuilder-Dv0IlZs0.mjs → CronBuilder-CCgt0wCE.mjs} +9 -4
- package/dist/CronBuilder-CCgt0wCE.mjs.map +1 -0
- package/dist/{CronBuilder-O_gvButp.d.mts → CronBuilder-DaSUm2Na.d.mts} +5 -4
- package/dist/CronBuilder-DaSUm2Na.d.mts.map +1 -0
- package/dist/{CronBuilder-CEK7aOqD.d.cts → CronBuilder-g1lZLWyG.d.cts} +5 -4
- package/dist/CronBuilder-g1lZLWyG.d.cts.map +1 -0
- package/dist/{Endpoint-CQAeh1Rh.mjs → Endpoint-BDgmfml0.mjs} +2 -2
- package/dist/{Endpoint-CQAeh1Rh.mjs.map → Endpoint-BDgmfml0.mjs.map} +1 -1
- package/dist/{Endpoint-Dp5AKIXl.d.cts → Endpoint-BkzU6nn1.d.cts} +5 -4
- package/dist/Endpoint-BkzU6nn1.d.cts.map +1 -0
- package/dist/{Endpoint-DtI7heFm.d.mts → Endpoint-BpboleFh.d.mts} +5 -4
- package/dist/Endpoint-BpboleFh.d.mts.map +1 -0
- package/dist/{Endpoint-D1L9qu5C.cjs → Endpoint-wSCHSnqb.cjs} +2 -2
- package/dist/{Endpoint-D1L9qu5C.cjs.map → Endpoint-wSCHSnqb.cjs.map} +1 -1
- package/dist/{EndpointFactory-FeFRmlDZ.d.cts → EndpointFactory-BZZOleQT.d.cts} +4 -4
- package/dist/{EndpointFactory-CgMDvERK.d.mts.map → EndpointFactory-BZZOleQT.d.cts.map} +1 -1
- package/dist/{EndpointFactory-BBdNeaGJ.mjs → EndpointFactory-C9G2pz86.mjs} +3 -3
- package/dist/{EndpointFactory-BBdNeaGJ.mjs.map → EndpointFactory-C9G2pz86.mjs.map} +1 -1
- package/dist/{EndpointFactory-CgMDvERK.d.mts → EndpointFactory-DnNlYflU.d.mts} +4 -4
- package/dist/{EndpointFactory-FeFRmlDZ.d.cts.map → EndpointFactory-DnNlYflU.d.mts.map} +1 -1
- package/dist/{EndpointFactory-BZOCOaK6.cjs → EndpointFactory-G1g1kiqC.cjs} +3 -3
- package/dist/{EndpointFactory-BZOCOaK6.cjs.map → EndpointFactory-G1g1kiqC.cjs.map} +1 -1
- package/dist/Function-DuqGcbOI.d.mts +76 -0
- package/dist/Function-DuqGcbOI.d.mts.map +1 -0
- package/dist/Function-Pu-1kKZz.d.cts +76 -0
- package/dist/Function-Pu-1kKZz.d.cts.map +1 -0
- package/dist/{HonoEndpointAdaptor-Cq99r9H7.cjs → HonoEndpointAdaptor-CBoSm3TM.cjs} +3 -3
- package/dist/{HonoEndpointAdaptor-Cq99r9H7.cjs.map → HonoEndpointAdaptor-CBoSm3TM.cjs.map} +1 -1
- package/dist/{HonoEndpointAdaptor-Aui-x9Lg.mjs → HonoEndpointAdaptor-DL_fCB9O.mjs} +3 -3
- package/dist/{HonoEndpointAdaptor-Aui-x9Lg.mjs.map → HonoEndpointAdaptor-DL_fCB9O.mjs.map} +1 -1
- package/dist/{Queue-Ckmudcm8.cjs → Queue-D5jcw0mu.cjs} +6 -2
- package/dist/Queue-D5jcw0mu.cjs.map +1 -0
- package/dist/{Queue-YmvN2vEP.d.mts → Queue-DlsHRzUp.d.mts} +22 -10
- package/dist/Queue-DlsHRzUp.d.mts.map +1 -0
- package/dist/{Queue-CpQIGB_2.d.cts → Queue-HPyi0e1i.d.cts} +22 -10
- package/dist/Queue-HPyi0e1i.d.cts.map +1 -0
- package/dist/{Queue-C1uDgjxt.mjs → Queue-hwPN-t31.mjs} +6 -2
- package/dist/Queue-hwPN-t31.mjs.map +1 -0
- package/dist/{QueueBuilder-CJNcv4dy.cjs → QueueBuilder-BFQn3OzZ.cjs} +27 -4
- package/dist/QueueBuilder-BFQn3OzZ.cjs.map +1 -0
- package/dist/{QueueBuilder-XuPKZwKH.mjs → QueueBuilder-DCuYdjMw.mjs} +28 -5
- package/dist/QueueBuilder-DCuYdjMw.mjs.map +1 -0
- package/dist/{QueueBuilder-XEnnOWGe.d.cts → QueueBuilder-OSi6LkV9.d.cts} +24 -11
- package/dist/QueueBuilder-OSi6LkV9.d.cts.map +1 -0
- package/dist/{QueueBuilder-CM0WUxfw.d.mts → QueueBuilder-QHsnVt1P.d.mts} +24 -11
- package/dist/QueueBuilder-QHsnVt1P.d.mts.map +1 -0
- package/dist/{Subscriber-B91YSkZt.d.cts → Subscriber-Bpp02cGr.d.cts} +20 -9
- package/dist/Subscriber-Bpp02cGr.d.cts.map +1 -0
- package/dist/{Subscriber-BjHYe5hK.d.mts → Subscriber-CtN9R48-.d.mts} +20 -9
- package/dist/Subscriber-CtN9R48-.d.mts.map +1 -0
- package/dist/{SubscriberBuilder-Duk028pD.cjs → SubscriberBuilder-C2PwqwIl.cjs} +31 -3
- package/dist/SubscriberBuilder-C2PwqwIl.cjs.map +1 -0
- package/dist/{SubscriberBuilder-BhMphk4z.d.mts → SubscriberBuilder-CuCMFpYW.d.mts} +23 -11
- package/dist/SubscriberBuilder-CuCMFpYW.d.mts.map +1 -0
- package/dist/{SubscriberBuilder-DzQUWE08.mjs → SubscriberBuilder-DMFk_Ap1.mjs} +32 -4
- package/dist/SubscriberBuilder-DMFk_Ap1.mjs.map +1 -0
- package/dist/{SubscriberBuilder-BSpQX1JT.d.cts → SubscriberBuilder-g3fAVWgs.d.cts} +23 -11
- package/dist/SubscriberBuilder-g3fAVWgs.d.cts.map +1 -0
- package/dist/adaptors/aws.cjs +20 -4
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +17 -13
- package/dist/adaptors/aws.d.cts.map +1 -1
- package/dist/adaptors/aws.d.mts +17 -13
- package/dist/adaptors/aws.d.mts.map +1 -1
- package/dist/adaptors/aws.mjs +20 -4
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/adaptors/hono.cjs +1 -1
- package/dist/adaptors/hono.d.cts +1 -1
- package/dist/adaptors/hono.d.mts +1 -1
- package/dist/adaptors/hono.mjs +1 -1
- package/dist/adaptors/testing.cjs +170 -13
- package/dist/adaptors/testing.cjs.map +1 -1
- package/dist/adaptors/testing.d.cts +38 -21
- package/dist/adaptors/testing.d.cts.map +1 -1
- package/dist/adaptors/testing.d.mts +38 -21
- package/dist/adaptors/testing.d.mts.map +1 -1
- package/dist/adaptors/testing.mjs +170 -13
- package/dist/adaptors/testing.mjs.map +1 -1
- package/dist/{auth-CMwml9QN.d.mts → auth-3OAmK42n.d.cts} +4 -4
- package/dist/{auth-CMwml9QN.d.mts.map → auth-3OAmK42n.d.cts.map} +1 -1
- package/dist/{auth-rVRDjIw_.d.cts → auth-BWbiewHa.d.mts} +4 -4
- package/dist/{auth-rVRDjIw_.d.cts.map → auth-BWbiewHa.d.mts.map} +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.mts +1 -1
- package/dist/{cache-C9a_hVCc.d.cts → cache-CXh6GIgb.d.mts} +3 -3
- package/dist/{cache-C9a_hVCc.d.cts.map → cache-CXh6GIgb.d.mts.map} +1 -1
- package/dist/{cache-CeTMI8LR.d.mts → cache-DnGDGly3.d.cts} +3 -3
- package/dist/{cache-CeTMI8LR.d.mts.map → cache-DnGDGly3.d.cts.map} +1 -1
- package/dist/cache.d.cts +1 -1
- package/dist/cache.d.mts +1 -1
- package/dist/{construct-interface-_3zgxzXl.d.mts → construct-interface-B1AfqRl4.d.cts} +25 -3
- package/dist/{construct-interface-_3zgxzXl.d.mts.map → construct-interface-B1AfqRl4.d.cts.map} +1 -1
- package/dist/{construct-interface-_xi4BPN8.d.cts → construct-interface-DluK3_da.d.mts} +25 -3
- package/dist/{construct-interface-_xi4BPN8.d.cts.map → construct-interface-DluK3_da.d.mts.map} +1 -1
- package/dist/construct-interface.cjs +26 -0
- package/dist/construct-interface.cjs.map +1 -1
- package/dist/construct-interface.d.cts +2 -2
- package/dist/construct-interface.d.mts +2 -2
- package/dist/construct-interface.mjs +26 -1
- package/dist/construct-interface.mjs.map +1 -1
- package/dist/credential.d.cts +1 -1
- package/dist/credential.d.mts +1 -1
- package/dist/crons/index.cjs +1 -1
- package/dist/crons/index.d.cts +2 -2
- package/dist/crons/index.d.mts +2 -2
- package/dist/crons/index.mjs +1 -1
- package/dist/database/kysely.d.cts +1 -1
- package/dist/database/kysely.d.mts +1 -1
- package/dist/email.d.cts +1 -1
- package/dist/email.d.mts +1 -1
- package/dist/endpoints/index.cjs +3 -3
- package/dist/endpoints/index.d.cts +2 -2
- package/dist/endpoints/index.d.mts +2 -2
- package/dist/endpoints/index.mjs +3 -3
- package/dist/{external-api-DS3mujT5.d.mts → external-api-CWY9orcO.d.mts} +2 -2
- package/dist/{external-api-DS3mujT5.d.mts.map → external-api-CWY9orcO.d.mts.map} +1 -1
- package/dist/{external-api-LBfE-q3g.d.cts → external-api-D-5WB-sr.d.cts} +2 -2
- package/dist/{external-api-LBfE-q3g.d.cts.map → external-api-D-5WB-sr.d.cts.map} +1 -1
- package/dist/external-api.d.cts +1 -1
- package/dist/external-api.d.mts +1 -1
- package/dist/file-server.d.cts +1 -1
- package/dist/file-server.d.mts +1 -1
- package/dist/functions/index.cjs +1 -1
- package/dist/functions/index.d.cts +2 -1
- package/dist/functions/index.d.mts +2 -1
- package/dist/functions/index.mjs +1 -1
- package/dist/{functions-ZH60FE7H.cjs → functions-CbP5ZKma.cjs} +15 -3
- package/dist/functions-CbP5ZKma.cjs.map +1 -0
- package/dist/{functions-DCIfCRR-.mjs → functions-Di6n5ltG.mjs} +16 -4
- package/dist/{functions-DCIfCRR-.mjs.map → functions-Di6n5ltG.mjs.map} +1 -1
- package/dist/{index-B0kxstwf.d.cts → index-BuzRvKOQ.d.cts} +9 -71
- package/dist/index-BuzRvKOQ.d.cts.map +1 -0
- package/dist/{index-CjVEjOw0.d.mts → index-CTkKOer4.d.mts} +9 -71
- package/dist/index-CTkKOer4.d.mts.map +1 -0
- package/dist/{kysely-BJ8IQ_1P.d.mts → kysely-Bqov3fwv.d.mts} +3 -3
- package/dist/{kysely-BJ8IQ_1P.d.mts.map → kysely-Bqov3fwv.d.mts.map} +1 -1
- package/dist/{kysely-DVF8wOT4.d.cts → kysely-DTnkZsub.d.cts} +3 -3
- package/dist/{kysely-DVF8wOT4.d.cts.map → kysely-DTnkZsub.d.cts.map} +1 -1
- package/dist/mobile-app.d.cts +1 -1
- package/dist/mobile-app.d.mts +1 -1
- package/dist/object-storage.d.cts +1 -1
- package/dist/object-storage.d.mts +1 -1
- package/dist/queue/index.cjs +2 -2
- package/dist/queue/index.d.cts +2 -2
- package/dist/queue/index.d.mts +2 -2
- package/dist/queue/index.mjs +2 -2
- package/dist/rest-api.cjs +1 -1
- package/dist/rest-api.d.cts +3 -3
- package/dist/rest-api.d.mts +3 -3
- package/dist/rest-api.mjs +1 -1
- package/dist/site.d.cts +1 -1
- package/dist/site.d.mts +1 -1
- package/dist/subscribers/index.cjs +1 -1
- package/dist/subscribers/index.d.cts +2 -2
- package/dist/subscribers/index.d.mts +2 -2
- package/dist/subscribers/index.mjs +1 -1
- package/dist/worker.cjs +26 -10
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +38 -22
- package/dist/worker.d.cts.map +1 -1
- package/dist/worker.d.mts +38 -22
- package/dist/worker.d.mts.map +1 -1
- package/dist/worker.mjs +26 -10
- package/dist/worker.mjs.map +1 -1
- package/package.json +31 -31
- package/dist/Cron-CMEGfRs8.d.cts.map +0 -1
- package/dist/Cron-D6X4-xjB.d.mts.map +0 -1
- package/dist/CronBuilder-CEK7aOqD.d.cts.map +0 -1
- package/dist/CronBuilder-DB35T5dL.cjs.map +0 -1
- package/dist/CronBuilder-Dv0IlZs0.mjs.map +0 -1
- package/dist/CronBuilder-O_gvButp.d.mts.map +0 -1
- package/dist/Endpoint-Dp5AKIXl.d.cts.map +0 -1
- package/dist/Endpoint-DtI7heFm.d.mts.map +0 -1
- package/dist/Queue-C1uDgjxt.mjs.map +0 -1
- package/dist/Queue-Ckmudcm8.cjs.map +0 -1
- package/dist/Queue-CpQIGB_2.d.cts.map +0 -1
- package/dist/Queue-YmvN2vEP.d.mts.map +0 -1
- package/dist/QueueBuilder-CJNcv4dy.cjs.map +0 -1
- package/dist/QueueBuilder-CM0WUxfw.d.mts.map +0 -1
- package/dist/QueueBuilder-XEnnOWGe.d.cts.map +0 -1
- package/dist/QueueBuilder-XuPKZwKH.mjs.map +0 -1
- package/dist/Subscriber-B91YSkZt.d.cts.map +0 -1
- package/dist/Subscriber-BjHYe5hK.d.mts.map +0 -1
- package/dist/SubscriberBuilder-BSpQX1JT.d.cts.map +0 -1
- package/dist/SubscriberBuilder-BhMphk4z.d.mts.map +0 -1
- package/dist/SubscriberBuilder-Duk028pD.cjs.map +0 -1
- package/dist/SubscriberBuilder-DzQUWE08.mjs.map +0 -1
- package/dist/functions-ZH60FE7H.cjs.map +0 -1
- package/dist/index-B0kxstwf.d.cts.map +0 -1
- package/dist/index-CjVEjOw0.d.mts.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { t as StandardSchemaV1 } from "../index-CeEtxDmK.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { n as Function } from "../Function-DuqGcbOI.mjs";
|
|
3
3
|
import { t as HttpMethod } from "../types-DMuSQeLL.mjs";
|
|
4
|
-
import { c as EndpointSchemas, i as Endpoint } from "../Endpoint-
|
|
5
|
-
import { t as Queue } from "../Queue-
|
|
6
|
-
import { t as Subscriber } from "../Subscriber-
|
|
7
|
-
import { t as KyselyDatabase } from "../kysely-
|
|
8
|
-
import { r as Fake } from "../external-api-
|
|
4
|
+
import { c as EndpointSchemas, i as Endpoint } from "../Endpoint-BpboleFh.mjs";
|
|
5
|
+
import { t as Queue } from "../Queue-DlsHRzUp.mjs";
|
|
6
|
+
import { t as Subscriber } from "../Subscriber-CtN9R48-.mjs";
|
|
7
|
+
import { t as KyselyDatabase } from "../kysely-Bqov3fwv.mjs";
|
|
8
|
+
import { r as Fake } from "../external-api-CWY9orcO.mjs";
|
|
9
9
|
import { EventPublisher, ExtractPublisherMessage } from "@geekmidas/events";
|
|
10
10
|
import { Kysely } from "kysely";
|
|
11
11
|
import { Service, ServiceDiscovery, ServiceRecord } from "@geekmidas/services";
|
|
@@ -151,39 +151,46 @@ type TestFunctionRequest<TInput extends ComposableStandardSchema | undefined = u
|
|
|
151
151
|
/**
|
|
152
152
|
* In-memory test driver for a {@link Queue} worker. Hand it a batch of messages
|
|
153
153
|
* and it registers the queue's services, runs the handler in a request context,
|
|
154
|
-
* and returns the handler result — no SQS/pg-boss required.
|
|
154
|
+
* and returns the handler result — no SQS/pg-boss required. A queue with a
|
|
155
|
+
* database gets `db` registered from it, or the one the request passes.
|
|
155
156
|
*
|
|
156
157
|
* @example
|
|
157
158
|
* const adapter = new TestQueueAdaptor(ordersQueue);
|
|
158
159
|
* await adapter.invoke({ messages: [{ orderId: '123' }] });
|
|
159
160
|
*/
|
|
160
|
-
export declare class TestQueueAdaptor<TName extends string = string, TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger> {
|
|
161
|
+
export declare class TestQueueAdaptor<TName extends string = string, TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = [], TLogger extends Logger = Logger, TDatabase = undefined, TDatabaseServiceName extends string = string> {
|
|
161
162
|
private readonly queue;
|
|
162
163
|
private serviceDiscovery;
|
|
163
164
|
static getDefaultServiceDiscovery(): any;
|
|
164
|
-
constructor(queue: Queue<TName, TMessage, TServices, TLogger>, serviceDiscovery?: ServiceDiscovery<any>);
|
|
165
|
-
invoke(request: TestQueueRequest<TMessage, TServices>): Promise<unknown>;
|
|
165
|
+
constructor(queue: Queue<TName, TMessage, TServices, TLogger, TDatabase, TDatabaseServiceName>, serviceDiscovery?: ServiceDiscovery<any>);
|
|
166
|
+
invoke(request: TestQueueRequest<TMessage, TServices, TDatabase>): Promise<unknown>;
|
|
167
|
+
private getDatabase;
|
|
166
168
|
}
|
|
167
|
-
type TestQueueRequest<TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = []> = {
|
|
169
|
+
type TestQueueRequest<TMessage extends StandardSchemaV1 = StandardSchemaV1, TServices extends Service[] = [], TDatabase = undefined> = {
|
|
168
170
|
messages: InferStandardSchema<TMessage>[];
|
|
169
171
|
services?: ServiceRecord<TServices>;
|
|
172
|
+
/** Stands in for the queue's database — a transaction, say. */
|
|
173
|
+
db?: TDatabase;
|
|
170
174
|
};
|
|
171
175
|
//#endregion
|
|
172
176
|
//#region src/subscribers/TestSubscriberAdaptor.d.ts
|
|
173
177
|
type ExtractEventPayloads<TPublisher extends EventPublisher<any> | undefined, TEventTypes extends any[]> = TPublisher extends EventPublisher<any> ? Extract<ExtractPublisherMessage<TPublisher>, {
|
|
174
178
|
type: TEventTypes[number];
|
|
175
179
|
}> : never;
|
|
176
|
-
export declare class TestSubscriberAdaptor<TServices extends Service[] = [], TLogger extends Logger = Logger, OutSchema extends StandardSchemaV1 | undefined = undefined, TEventPublisher extends EventPublisher<any> | undefined = undefined, TSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][]> {
|
|
180
|
+
export declare class TestSubscriberAdaptor<TServices extends Service[] = [], TLogger extends Logger = Logger, OutSchema extends StandardSchemaV1 | undefined = undefined, TEventPublisher extends EventPublisher<any> | undefined = undefined, TSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][], TDatabase = undefined, TDatabaseServiceName extends string = string> {
|
|
177
181
|
private readonly subscriber;
|
|
178
182
|
private serviceDiscovery;
|
|
179
183
|
static getDefaultServiceDiscovery(): any;
|
|
180
|
-
constructor(subscriber: Subscriber<TServices, TLogger, OutSchema, TEventPublisher, TSubscribedEvents>, serviceDiscovery?: ServiceDiscovery<any>);
|
|
181
|
-
invoke(request: TestSubscriberRequest<TEventPublisher, TSubscribedEvents, TServices>): Promise<InferStandardSchema<OutSchema>>;
|
|
184
|
+
constructor(subscriber: Subscriber<TServices, TLogger, OutSchema, TEventPublisher, TSubscribedEvents, TDatabase, TDatabaseServiceName>, serviceDiscovery?: ServiceDiscovery<any>);
|
|
185
|
+
invoke(request: TestSubscriberRequest<TEventPublisher, TSubscribedEvents, TServices, TDatabase>): Promise<InferStandardSchema<OutSchema>>;
|
|
186
|
+
private getDatabase;
|
|
182
187
|
private filterEvents;
|
|
183
188
|
}
|
|
184
|
-
type TestSubscriberRequest<TEventPublisher extends EventPublisher<any> | undefined = undefined, TSubscribedEvents extends any[] = [], TServices extends Service[] = []> = {
|
|
189
|
+
type TestSubscriberRequest<TEventPublisher extends EventPublisher<any> | undefined = undefined, TSubscribedEvents extends any[] = [], TServices extends Service[] = [], TDatabase = undefined> = {
|
|
185
190
|
events: ExtractEventPayloads<TEventPublisher, TSubscribedEvents>[];
|
|
186
191
|
services?: ServiceRecord<TServices>;
|
|
192
|
+
/** Stands in for the subscriber's database — a transaction, say. */
|
|
193
|
+
db?: TDatabase;
|
|
187
194
|
};
|
|
188
195
|
//#endregion
|
|
189
196
|
//#region src/testing/manifest.d.ts
|
|
@@ -218,6 +225,14 @@ interface TestManifest {
|
|
|
218
225
|
surface: string;
|
|
219
226
|
source: TestManifestSource;
|
|
220
227
|
}[];
|
|
228
|
+
/**
|
|
229
|
+
* Every topic subscriber — what a topic's events are delivered to. Not a
|
|
230
|
+
* construct, so not in `constructs`: the build finds them, as it finds
|
|
231
|
+
* endpoints.
|
|
232
|
+
*/
|
|
233
|
+
subscribers?: {
|
|
234
|
+
source: TestManifestSource;
|
|
235
|
+
}[];
|
|
221
236
|
/**
|
|
222
237
|
* The test stage's environment — reconcile's output, keyed as the
|
|
223
238
|
* constructs derive their keys.
|
|
@@ -315,8 +330,10 @@ interface FeatureContext<TBrowser extends Browser, TDatabases extends DatabaseSc
|
|
|
315
330
|
mailbox: (address: string) => Mailbox;
|
|
316
331
|
/**
|
|
317
332
|
* What this test published to a topic or enqueued on a queue, in order.
|
|
318
|
-
*
|
|
319
|
-
*
|
|
333
|
+
*
|
|
334
|
+
* Also delivered: once each request the test makes has answered, a queue's
|
|
335
|
+
* messages reach its consumer and a topic's events every subscriber that
|
|
336
|
+
* named them, in this test's transaction — see {@link deliver}.
|
|
320
337
|
*/
|
|
321
338
|
published: (channel: {
|
|
322
339
|
id: string;
|
|
@@ -326,12 +343,12 @@ interface FeatureContext<TBrowser extends Browser, TDatabases extends DatabaseSc
|
|
|
326
343
|
* with this test's services: its databases resolve to this test's
|
|
327
344
|
* transactions, as an endpoint's do.
|
|
328
345
|
*/
|
|
329
|
-
subscriber: <S extends Subscriber<any, any, any, any, any>>(subscriber: S) => SubscriberAdaptorOf<S>;
|
|
346
|
+
subscriber: <S extends Subscriber<any, any, any, any, any, any, any>>(subscriber: S) => SubscriberAdaptorOf<S>;
|
|
330
347
|
/** A queue's worker, run on its own with this test's services. */
|
|
331
|
-
queue: <Q extends Queue<any, any, any, any>>(queue: Q) => QueueAdaptorOf<Q>;
|
|
348
|
+
queue: <Q extends Queue<any, any, any, any, any, any>>(queue: Q) => QueueAdaptorOf<Q>;
|
|
332
349
|
}
|
|
333
|
-
type SubscriberAdaptorOf<S> = S extends Subscriber<infer TServices, infer TLogger, infer OutSchema, infer TEventPublisher, infer TSubscribedEvents> ? TestSubscriberAdaptor<TServices, TLogger, OutSchema, TEventPublisher, TSubscribedEvents> : never;
|
|
334
|
-
type QueueAdaptorOf<Q> = Q extends Queue<infer TName, infer TMessage, infer TServices, infer TLogger> ? TestQueueAdaptor<TName, TMessage, TServices, TLogger> : never;
|
|
350
|
+
type SubscriberAdaptorOf<S> = S extends Subscriber<infer TServices, infer TLogger, infer OutSchema, infer TEventPublisher, infer TSubscribedEvents, infer TDatabase, infer TDatabaseServiceName> ? TestSubscriberAdaptor<TServices, TLogger, OutSchema, TEventPublisher, TSubscribedEvents, TDatabase, TDatabaseServiceName> : never;
|
|
351
|
+
type QueueAdaptorOf<Q> = Q extends Queue<infer TName, infer TMessage, infer TServices, infer TLogger, infer TDatabase, infer TDatabaseServiceName> ? TestQueueAdaptor<TName, TMessage, TServices, TLogger, TDatabase, TDatabaseServiceName> : never;
|
|
335
352
|
/** The schema a database construct was declared with — what `db` is typed by. */
|
|
336
353
|
type DatabaseOf<C> = C extends KyselyDatabase<infer DB, any> ? DB : unknown;
|
|
337
354
|
/** One message as it was published: its type and its payload. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.mts","names":["TestBrowser"],"sources":["../../src/endpoints/MswEndpointAdaptor.ts","../../src/endpoints/TestEndpointAdaptor.ts","../../src/functions/TestFunctionAdaptor.ts","../../src/queue/TestQueueAdaptor.ts","../../src/subscribers/TestSubscriberAdaptor.ts","../../src/testing/manifest.ts","../../src/testing/featureTest.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyDiB;;EAEhB;;;;;;;;;UAUgB;;EAEhB,WAAW;;EAEX;;EAEA;;;;;UAiBgB;;EAEhB,UAAU;;EAEV,kBAAkB,YAAY,SAAS;;;;;;;;;;;;;;;;;wBAkBxB,kBACf,WAAW,0CACX,SAAS,2BACP;;;KC9ES,iBAAiB;EAC5B,MAAM;EACN;EACA,SAAS;;qBAwCG,oBACZ,uBACA,gBAAgB,YAChB,eAAe,sBACf,mBAAmB,0CACnB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,oBACA,sBAAsB,sCACtB,kDACA,qBAAqB,mCAAmC,kCAIxD,uBACA;mBAqCkB;UAcT;SAjDF,0BACN,uBACA,gBAAgB,YAChB,eAAe,sBACf,mBAAmB,0CACnB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,oBACA,sBAAsB,sCACtB,kDACA,qBAAqB,mCAAmC,kCAIxD,uBACA,8CAEA,WAAW,SACV,QACA,SACA,QACA,YACA,WACA,SACA,UACA,eACA,0BACA,cACA,WACA;EAKF,YACkB,UAAU,SAC1B,QACA,SACA,QACA,YACA,WACA,SACA,UACA,eACA,0BACA,cACA,WACA,uBAEO,mBAAkB;EAKrB,YACL,KAAK,mBACJ,QACA,WACA,eACA,0BACA,WACA,wBAEC,QAAQ,iBAAiB,oBAAoB;EAsM1C,QACL,KAAK,mBACJ,QACA,WACA,eACA,0BACA,WACA,wBAEC,QAAQ,oBAAoB;;;;;KAS3B,wBACJ,sBAAsB,wCACnB;;EAID,gBAAgB;;;;;KAMd,oBAAoB,yBAAyB;;EAI/C,UAAU;;KAGD,mBACX,eAAe,sBACf,kBAAkB,gBAClB,sBAAsB,sCACtB,mDACA,uBACA;EAEA,UAAU,cAAc;EACxB,SAAS;IACN,8BAA8B,UACjC,wBAAwB,iBACxB,oBAAoB;;;qBCpYR,oBACZ,eAAe,kDACf,mBAAmB,0CACnB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC;mBAoCtC;UAYT;SA3CF,2BACN,eAAe,kDACf,mBAAmB,0CACnB,kBAAkB,gBAClB,gBAAgB,SAAS,QACzB,sBAAsB,sCACtB,kDACA,uBACA,8CACA,qBAAqB,mCAAmC,kCAKxD,KAAK,SACJ,QACA,WACA,SACA,YACA,eACA,0BACA,WACA,sBACA;EAOF,YACkB,IAAI,SACpB,QACA,WACA,SACA,YACA,eACA,0BACA,WACA,sBACA,oBAGO,mBAAkB;EAKrB,OACL,KAAK,oBAAoB,QAAQ,WAAW,WAAW,gBACrD,QAAQ,oBAAoB;;KAoGpB,oBACX,eAAe,kDACf,kBAAkB,gBAClB,uBACA,qBAAqB,mCAAmC;EAKxD,OAAO,8BAA8B;EACrC,UAAU,cAAc;EACxB,KAAK;EACL,UAAU,QAAQ;IACf;EAAgC,OAAO
|
|
1
|
+
{"version":3,"file":"testing.d.mts","names":["TestBrowser"],"sources":["../../src/endpoints/MswEndpointAdaptor.ts","../../src/endpoints/TestEndpointAdaptor.ts","../../src/functions/TestFunctionAdaptor.ts","../../src/queue/TestQueueAdaptor.ts","../../src/subscribers/TestSubscriberAdaptor.ts","../../src/testing/manifest.ts","../../src/testing/featureTest.ts"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { BetterAuth } from "../auth.mjs";
|
|
2
|
-
import { a as publishEvents, i as publishConstructEvents, t as FunctionBuilder } from "../functions-
|
|
3
|
-
import { n as ResponseBuilder, t as Endpoint } from "../Endpoint-
|
|
4
|
-
import { t as Queue } from "../Queue-
|
|
2
|
+
import { a as publishEvents, i as publishConstructEvents, t as FunctionBuilder } from "../functions-Di6n5ltG.mjs";
|
|
3
|
+
import { n as ResponseBuilder, t as Endpoint } from "../Endpoint-BDgmfml0.mjs";
|
|
4
|
+
import { t as Queue } from "../Queue-hwPN-t31.mjs";
|
|
5
5
|
import { Email } from "../email.mjs";
|
|
6
6
|
import { KyselyDatabase } from "../database/kysely.mjs";
|
|
7
7
|
import { c as createObjectHeaders, r as createCookieHeaderAccessor } from "../lazyAccessors-CFanua0O.mjs";
|
|
8
8
|
import { t as Topic } from "../Topic-hPffOsot.mjs";
|
|
9
|
-
import { t as HonoEndpoint } from "../HonoEndpointAdaptor-
|
|
9
|
+
import { t as HonoEndpoint } from "../HonoEndpointAdaptor-DL_fCB9O.mjs";
|
|
10
10
|
import { n as executeWithAuditTransaction } from "../processAudits-BpRlPQMW.mjs";
|
|
11
11
|
import { provideKey } from "@geekmidas/manifest";
|
|
12
12
|
import { ForbiddenError } from "@geekmidas/errors";
|
|
@@ -342,7 +342,8 @@ var TestFunctionAdaptor = class TestFunctionAdaptor {
|
|
|
342
342
|
/**
|
|
343
343
|
* In-memory test driver for a {@link Queue} worker. Hand it a batch of messages
|
|
344
344
|
* and it registers the queue's services, runs the handler in a request context,
|
|
345
|
-
* and returns the handler result — no SQS/pg-boss required.
|
|
345
|
+
* and returns the handler result — no SQS/pg-boss required. A queue with a
|
|
346
|
+
* database gets `db` registered from it, or the one the request passes.
|
|
346
347
|
*
|
|
347
348
|
* @example
|
|
348
349
|
* const adapter = new TestQueueAdaptor(ordersQueue);
|
|
@@ -361,6 +362,7 @@ var TestQueueAdaptor = class TestQueueAdaptor {
|
|
|
361
362
|
async invoke(request) {
|
|
362
363
|
const logger = this.queue.logger.child({ test: true });
|
|
363
364
|
const services = request.services ?? await this.serviceDiscovery.register(this.queue.services);
|
|
365
|
+
const db = request.db !== void 0 ? request.db : await this.getDatabase();
|
|
364
366
|
const requestId = `test-${Date.now()}`;
|
|
365
367
|
return runWithRequestContext({
|
|
366
368
|
logger,
|
|
@@ -369,9 +371,15 @@ var TestQueueAdaptor = class TestQueueAdaptor {
|
|
|
369
371
|
}, () => this.queue.handler({
|
|
370
372
|
messages: request.messages,
|
|
371
373
|
services,
|
|
372
|
-
logger
|
|
374
|
+
logger,
|
|
375
|
+
db
|
|
373
376
|
}));
|
|
374
377
|
}
|
|
378
|
+
async getDatabase() {
|
|
379
|
+
const service = this.queue.databaseService;
|
|
380
|
+
if (!service) return void 0;
|
|
381
|
+
return (await this.serviceDiscovery.register([service]))[service.serviceName];
|
|
382
|
+
}
|
|
375
383
|
};
|
|
376
384
|
//#endregion
|
|
377
385
|
//#region src/subscribers/TestSubscriberAdaptor.ts
|
|
@@ -390,6 +398,7 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
|
390
398
|
let services;
|
|
391
399
|
if (request.services) services = request.services;
|
|
392
400
|
else services = await this.serviceDiscovery.register(this.subscriber.services);
|
|
401
|
+
const db = request.db !== void 0 ? request.db : await this.getDatabase();
|
|
393
402
|
const filteredEvents = this.filterEvents(request.events);
|
|
394
403
|
if (filteredEvents.length === 0) return { batchItemFailures: [] };
|
|
395
404
|
const requestId = `test-${Date.now()}`;
|
|
@@ -401,7 +410,8 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
|
401
410
|
const result = await this.subscriber.handler({
|
|
402
411
|
events: filteredEvents,
|
|
403
412
|
services,
|
|
404
|
-
logger
|
|
413
|
+
logger,
|
|
414
|
+
db
|
|
405
415
|
});
|
|
406
416
|
let output = result;
|
|
407
417
|
if (this.subscriber.outputSchema && result) {
|
|
@@ -412,6 +422,11 @@ var TestSubscriberAdaptor = class TestSubscriberAdaptor {
|
|
|
412
422
|
return output;
|
|
413
423
|
});
|
|
414
424
|
}
|
|
425
|
+
async getDatabase() {
|
|
426
|
+
const service = this.subscriber.databaseService;
|
|
427
|
+
if (!service) return void 0;
|
|
428
|
+
return (await this.serviceDiscovery.register([service]))[service.serviceName];
|
|
429
|
+
}
|
|
415
430
|
filterEvents(events) {
|
|
416
431
|
if (!this.subscriber.subscribedEvents) return events;
|
|
417
432
|
return events.filter((event) => this.subscriber.subscribedEvents.includes(event.type));
|
|
@@ -515,7 +530,16 @@ function featureTest(options = {}) {
|
|
|
515
530
|
if (isLocal(new URL(request.url))) return;
|
|
516
531
|
print.error();
|
|
517
532
|
} });
|
|
518
|
-
|
|
533
|
+
const restoreStamp = installContextFetch();
|
|
534
|
+
const stamped = globalThis.fetch;
|
|
535
|
+
globalThis.fetch = deliveringFetch(stamped, (id) => {
|
|
536
|
+
const state = contexts.get(id);
|
|
537
|
+
return state ? deliver(app, state, id) : Promise.resolve();
|
|
538
|
+
});
|
|
539
|
+
restoreFetch = () => {
|
|
540
|
+
globalThis.fetch = stamped;
|
|
541
|
+
restoreStamp();
|
|
542
|
+
};
|
|
519
543
|
});
|
|
520
544
|
afterAll(() => {
|
|
521
545
|
restoreFetch();
|
|
@@ -530,7 +554,9 @@ function featureTest(options = {}) {
|
|
|
530
554
|
surfaces: /* @__PURE__ */ new Map(),
|
|
531
555
|
auth: /* @__PURE__ */ new Map(),
|
|
532
556
|
addresses: /* @__PURE__ */ new Set(),
|
|
533
|
-
published: /* @__PURE__ */ new Map()
|
|
557
|
+
published: /* @__PURE__ */ new Map(),
|
|
558
|
+
pending: [],
|
|
559
|
+
delivering: false
|
|
534
560
|
};
|
|
535
561
|
const readMail = app.readMail;
|
|
536
562
|
if (readMail) state.mailbox = (address) => {
|
|
@@ -570,8 +596,8 @@ function featureTest(options = {}) {
|
|
|
570
596
|
return state.mailbox(address);
|
|
571
597
|
},
|
|
572
598
|
published: (channel) => [...state.published.get(channel.id) ?? []],
|
|
573
|
-
subscriber: (subscriber) => new TestSubscriberAdaptor(subscriber, state.discovery),
|
|
574
|
-
queue: (queue) => new TestQueueAdaptor(queue, state.discovery)
|
|
599
|
+
subscriber: (subscriber) => thenDeliver(new TestSubscriberAdaptor(subscriber, state.discovery), () => deliver(app, state, id)),
|
|
600
|
+
queue: (queue) => thenDeliver(new TestQueueAdaptor(queue, state.discovery), () => deliver(app, state, id))
|
|
575
601
|
});
|
|
576
602
|
} finally {
|
|
577
603
|
restore();
|
|
@@ -607,6 +633,10 @@ async function load(manifest, modules) {
|
|
|
607
633
|
const imported = async ({ file, export: name }) => (modules[file] ?? await import(file))[name];
|
|
608
634
|
const constructs = await Promise.all(Object.values(manifest.constructs).map(({ source }) => imported(source)));
|
|
609
635
|
const endpoints = (await Promise.all(manifest.endpoints.map(({ source }) => imported(source)))).filter((value) => Endpoint.isEndpoint(value));
|
|
636
|
+
const subscribers = (await Promise.all((manifest.subscribers ?? []).map(async ({ source }) => ({
|
|
637
|
+
name: source.export,
|
|
638
|
+
subscriber: await imported(source)
|
|
639
|
+
})))).filter((entry) => entry.subscriber?.__IS_SUBSCRIBER__ === true);
|
|
610
640
|
const unique = (values) => [...new Set(values)];
|
|
611
641
|
const databases = unique(constructs.filter((value) => value instanceof KyselyDatabase));
|
|
612
642
|
const auths = unique(constructs.filter((value) => value instanceof BetterAuth));
|
|
@@ -620,6 +650,7 @@ async function load(manifest, modules) {
|
|
|
620
650
|
auths,
|
|
621
651
|
emails,
|
|
622
652
|
channels,
|
|
653
|
+
subscribers,
|
|
623
654
|
...inbox ? { readMail: createMailbox({ inbox }) } : {}
|
|
624
655
|
};
|
|
625
656
|
}
|
|
@@ -631,10 +662,15 @@ async function load(manifest, modules) {
|
|
|
631
662
|
function recorders(channels, state) {
|
|
632
663
|
return channels.map((channel) => {
|
|
633
664
|
const publisher = { async publish(messages) {
|
|
634
|
-
|
|
665
|
+
const sent = messages.map(({ type, payload }) => ({
|
|
635
666
|
type,
|
|
636
667
|
payload
|
|
637
|
-
}))
|
|
668
|
+
}));
|
|
669
|
+
state.published.set(channel.id, [...state.published.get(channel.id) ?? [], ...sent]);
|
|
670
|
+
state.pending.push({
|
|
671
|
+
channel,
|
|
672
|
+
messages: sent
|
|
673
|
+
});
|
|
638
674
|
} };
|
|
639
675
|
return {
|
|
640
676
|
serviceName: channel.service.serviceName,
|
|
@@ -668,6 +704,90 @@ function databasesFor(factories, databases) {
|
|
|
668
704
|
* the one place a test's connection can be handed over. Outside a test it is
|
|
669
705
|
* the database it always was.
|
|
670
706
|
*/
|
|
707
|
+
/** Rounds of delivery before a chain of consumers is called a loop. */
|
|
708
|
+
const MAX_DELIVERY_ROUNDS = 25;
|
|
709
|
+
/**
|
|
710
|
+
* Deliver what this test published, in-process, as the broker would — and
|
|
711
|
+
* keep delivering what the consumers publish in turn, until nothing is left.
|
|
712
|
+
*
|
|
713
|
+
* - A queue's messages go to its one consumer, as a batch.
|
|
714
|
+
* - A topic's events go to every subscriber that named their type, and only
|
|
715
|
+
* those: fan-out, as the filter policy (SNS) or the per-subscriber queue
|
|
716
|
+
* (pg-boss) does it.
|
|
717
|
+
* - Each payload is checked against the consumer's schema first. Turning an
|
|
718
|
+
* SNS envelope or an SQS record into `{ type, payload }` is each adaptor's
|
|
719
|
+
* job and tested there; what is tested here is what the handler is handed.
|
|
720
|
+
* - Consumers run as the server side of this test, so their databases are
|
|
721
|
+
* this test's transactions and their writes roll back with it.
|
|
722
|
+
* - A consumer that throws fails the test. Deployed, the message would be
|
|
723
|
+
* retried; here a retry would only hide the bug.
|
|
724
|
+
*/
|
|
725
|
+
async function deliver(app, state, id) {
|
|
726
|
+
if (state.delivering) return;
|
|
727
|
+
state.delivering = true;
|
|
728
|
+
try {
|
|
729
|
+
for (let round = 0; state.pending.length > 0; round++) {
|
|
730
|
+
if (round === MAX_DELIVERY_ROUNDS) throw new DeliveryDidNotSettle(MAX_DELIVERY_ROUNDS, [...new Set(state.pending.map(({ channel }) => channel.id))]);
|
|
731
|
+
for (const { channel, messages } of state.pending.splice(0)) if (channel instanceof Queue) await toQueue(channel, messages, state, id);
|
|
732
|
+
else await toSubscribers(channel, messages, app, state, id);
|
|
733
|
+
}
|
|
734
|
+
} finally {
|
|
735
|
+
state.delivering = false;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
async function toQueue(queue, messages, state, id) {
|
|
739
|
+
const payloads = [];
|
|
740
|
+
for (const message of messages) payloads.push(await accepted(queue.messageSchema, message, `queue '${queue.name}'`));
|
|
741
|
+
await runAsServer(id, () => new TestQueueAdaptor(queue, state.discovery).invoke({ messages: payloads })).catch((error) => {
|
|
742
|
+
throw new DeliveryFailed(`queue '${queue.name}'`, messages, error);
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
async function toSubscribers(topic, messages, app, state, id) {
|
|
746
|
+
for (const { name, subscriber } of app.subscribers) {
|
|
747
|
+
if (subscriber.topicName !== topic.name) continue;
|
|
748
|
+
const named = messages.filter(({ type }) => (subscriber.subscribedEvents ?? []).includes(type));
|
|
749
|
+
if (named.length === 0) continue;
|
|
750
|
+
const consumer = `subscriber '${name}'`;
|
|
751
|
+
const events = [];
|
|
752
|
+
for (const message of named) {
|
|
753
|
+
const schema = topic.eventSchemas[message.type];
|
|
754
|
+
events.push({
|
|
755
|
+
type: message.type,
|
|
756
|
+
payload: await accepted(schema, message, consumer)
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
await runAsServer(id, () => new TestSubscriberAdaptor(subscriber, state.discovery).invoke({ events })).catch((error) => {
|
|
760
|
+
throw new DeliveryFailed(consumer, named, error);
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
/** The payload, if the consumer's schema takes it — what the handler is handed. */
|
|
765
|
+
async function accepted(schema, message, consumer) {
|
|
766
|
+
const standard = schema?.["~standard"];
|
|
767
|
+
if (!standard) return message.payload;
|
|
768
|
+
const result = await standard.validate(message.payload);
|
|
769
|
+
if (result.issues) throw new MessageRejected(consumer, message, result.issues);
|
|
770
|
+
return result.value;
|
|
771
|
+
}
|
|
772
|
+
/** `fetch`, delivering what the test published once each of its requests answers. */
|
|
773
|
+
function deliveringFetch(inner, settle) {
|
|
774
|
+
return async (input, init) => {
|
|
775
|
+
const context = currentTestContext();
|
|
776
|
+
const response = await inner(input, init);
|
|
777
|
+
if (context?.side === "client") await settle(context.id);
|
|
778
|
+
return response;
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
/** An adaptor whose `invoke` delivers what it published before returning. */
|
|
782
|
+
function thenDeliver(adaptor, settle) {
|
|
783
|
+
const invoke = adaptor.invoke.bind(adaptor);
|
|
784
|
+
adaptor.invoke = (async (...args) => {
|
|
785
|
+
const result = await invoke(...args);
|
|
786
|
+
await settle();
|
|
787
|
+
return result;
|
|
788
|
+
});
|
|
789
|
+
return adaptor;
|
|
790
|
+
}
|
|
671
791
|
function bindToTests(database) {
|
|
672
792
|
if (bound.has(database)) return;
|
|
673
793
|
bound.add(database);
|
|
@@ -838,6 +958,43 @@ var UnknownFactory = class extends Error {
|
|
|
838
958
|
this.name = "UnknownFactory";
|
|
839
959
|
}
|
|
840
960
|
};
|
|
961
|
+
/** A published message the consumer's own schema refuses. */
|
|
962
|
+
var MessageRejected = class extends Error {
|
|
963
|
+
consumer;
|
|
964
|
+
published;
|
|
965
|
+
issues;
|
|
966
|
+
constructor(consumer, published, issues) {
|
|
967
|
+
super(`${consumer} refuses '${published.type}': ${issues.map((issue) => issue.message).join("; ")}. What is published must be what the consumer's schema takes — fix the producer, or the schema.`);
|
|
968
|
+
this.consumer = consumer;
|
|
969
|
+
this.published = published;
|
|
970
|
+
this.issues = issues;
|
|
971
|
+
this.name = "MessageRejected";
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
/** A consumer that threw while handling what the test published. */
|
|
975
|
+
var DeliveryFailed = class extends Error {
|
|
976
|
+
consumer;
|
|
977
|
+
messages;
|
|
978
|
+
cause;
|
|
979
|
+
constructor(consumer, messages, cause) {
|
|
980
|
+
super(`${consumer} failed handling ${messages.map(({ type }) => `'${type}'`).join(", ")}: ${cause?.message ?? String(cause)}. Deployed, the message would be retried; here the failure is the result.`, { cause });
|
|
981
|
+
this.consumer = consumer;
|
|
982
|
+
this.messages = messages;
|
|
983
|
+
this.cause = cause;
|
|
984
|
+
this.name = "DeliveryFailed";
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
/** Consumers that kept publishing to each other without settling. */
|
|
988
|
+
var DeliveryDidNotSettle = class extends Error {
|
|
989
|
+
rounds;
|
|
990
|
+
channels;
|
|
991
|
+
constructor(rounds, channels) {
|
|
992
|
+
super(`Delivery did not settle after ${rounds} rounds — consumers are still publishing to ${channels.join(", ")}. A consumer that publishes to what triggers it loops forever deployed too.`);
|
|
993
|
+
this.rounds = rounds;
|
|
994
|
+
this.channels = channels;
|
|
995
|
+
this.name = "DeliveryDidNotSettle";
|
|
996
|
+
}
|
|
997
|
+
};
|
|
841
998
|
//#endregion
|
|
842
999
|
export { NoInbox, NoTestManifest, SignInFailed, TEST_CONTEXT_HEADER, TEST_MANIFEST_ENV, TestEndpointAdaptor, TestFunctionAdaptor, TestQueueAdaptor, TestSubscriberAdaptor, UnknownDatabase, UnknownFactory, UnknownTestContext, createMswHandlers, featureTest, loadTestManifest, signInWithMagicLink };
|
|
843
1000
|
|