@voyantjs/plugin-payload-cms 0.24.0 → 0.24.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/plugin-payload-cms",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "zod": "^4.3.6",
30
- "@voyantjs/core": "0.24.0"
30
+ "@voyantjs/core": "0.24.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "typescript": "^6.0.2",
package/dist/client.d.ts DELETED
@@ -1,48 +0,0 @@
1
- import type { PayloadDocBody, PayloadFetch } from "./types.js";
2
- /**
3
- * Options for {@link createPayloadClient}.
4
- */
5
- export interface PayloadClientOptions {
6
- /**
7
- * Base URL of the Payload REST API including `/api` suffix.
8
- * Example: `"https://cms.example.com/api"`.
9
- */
10
- apiUrl: string;
11
- /** Payload API key. Sent as `Authorization: ${apiKeyHeader} API-Key ${apiKey}`. */
12
- apiKey: string;
13
- /**
14
- * Field on the Payload collection that stores the Voyant record's ID.
15
- * Defaults to `"voyantId"`. The Payload collection must declare this
16
- * field (unique recommended).
17
- */
18
- voyantIdField?: string;
19
- /**
20
- * Header used to carry the API key. Defaults to `"users API-Key"` which
21
- * matches Payload's default `users` auth collection. Override if your
22
- * Payload deployment uses a different auth collection.
23
- */
24
- apiKeyAuthScheme?: string;
25
- /** Override `fetch` (e.g. in tests). Defaults to global `fetch`. */
26
- fetch?: PayloadFetch;
27
- }
28
- export interface PayloadClient {
29
- /**
30
- * Create or update a document whose {@link PayloadClientOptions.voyantIdField}
31
- * equals `voyantId`.
32
- */
33
- upsertByVoyantId(collection: string, voyantId: string, body: PayloadDocBody): Promise<{
34
- id: string;
35
- created: boolean;
36
- }>;
37
- /**
38
- * Delete a document whose `voyantId` field equals the given value. Returns
39
- * `false` if no matching document was found.
40
- */
41
- deleteByVoyantId(collection: string, voyantId: string): Promise<boolean>;
42
- /** Find at most one document whose `voyantId` field equals the given value. */
43
- findByVoyantId(collection: string, voyantId: string): Promise<{
44
- id: string;
45
- } | null>;
46
- }
47
- export declare function createPayloadClient(options: PayloadClientOptions): PayloadClient;
48
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oEAAoE;IACpE,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAUD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,gBAAgB,CACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IAC5C;;;OAGG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACxE,+EAA+E;IAC/E,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CACrF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA+FhF"}
package/dist/client.js DELETED
@@ -1,79 +0,0 @@
1
- export function createPayloadClient(options) {
2
- const voyantIdField = options.voyantIdField ?? "voyantId";
3
- const authScheme = options.apiKeyAuthScheme ?? "users API-Key";
4
- const apiUrl = options.apiUrl.replace(/\/$/, "");
5
- const fetchImpl = options.fetch ?? globalThis.fetch;
6
- function headers() {
7
- return {
8
- Authorization: `${authScheme} ${options.apiKey}`,
9
- "Content-Type": "application/json",
10
- };
11
- }
12
- async function request(method, path, body) {
13
- if (!fetchImpl) {
14
- throw new Error("Payload client requires a fetch implementation");
15
- }
16
- const init = {
17
- method,
18
- headers: headers(),
19
- };
20
- if (body !== undefined)
21
- init.body = JSON.stringify(body);
22
- const response = await fetchImpl(`${apiUrl}${path}`, init);
23
- // Payload sends JSON for all 2xx/4xx; pull both eagerly.
24
- let text = "";
25
- let json = null;
26
- try {
27
- text = await response.text();
28
- json = text ? JSON.parse(text) : null;
29
- }
30
- catch {
31
- // leave json as null, surface text
32
- }
33
- return { ok: response.ok, status: response.status, json, text };
34
- }
35
- async function findByVoyantId(collection, voyantId) {
36
- const query = `where[${encodeURIComponent(voyantIdField)}][equals]=${encodeURIComponent(voyantId)}&limit=1&depth=0`;
37
- const res = await request("GET", `/${collection}?${query}`);
38
- if (!res.ok) {
39
- throw new Error(`Payload findByVoyantId(${collection}) failed (${res.status}): ${res.text}`);
40
- }
41
- const body = (res.json ?? {});
42
- const first = body.docs?.[0];
43
- if (!first)
44
- return null;
45
- return { id: first.id };
46
- }
47
- async function upsertByVoyantId(collection, voyantId, body) {
48
- const existing = await findByVoyantId(collection, voyantId);
49
- const fullBody = { ...body, [voyantIdField]: voyantId };
50
- if (existing) {
51
- const res = await request("PATCH", `/${collection}/${existing.id}`, fullBody);
52
- if (!res.ok) {
53
- throw new Error(`Payload update(${collection}/${existing.id}) failed (${res.status}): ${res.text}`);
54
- }
55
- return { id: existing.id, created: false };
56
- }
57
- const res = await request("POST", `/${collection}`, fullBody);
58
- if (!res.ok) {
59
- throw new Error(`Payload create(${collection}) failed (${res.status}): ${res.text}`);
60
- }
61
- const json = (res.json ?? {});
62
- const id = json.doc?.id ?? json.id;
63
- if (!id) {
64
- throw new Error(`Payload create(${collection}) response missing id`);
65
- }
66
- return { id, created: true };
67
- }
68
- async function deleteByVoyantId(collection, voyantId) {
69
- const existing = await findByVoyantId(collection, voyantId);
70
- if (!existing)
71
- return false;
72
- const res = await request("DELETE", `/${collection}/${existing.id}`);
73
- if (!res.ok && res.status !== 404) {
74
- throw new Error(`Payload delete(${collection}/${existing.id}) failed (${res.status}): ${res.text}`);
75
- }
76
- return true;
77
- }
78
- return { upsertByVoyantId, deleteByVoyantId, findByVoyantId };
79
- }
package/dist/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export type { PayloadClient, PayloadClientOptions } from "./client.js";
2
- export { createPayloadClient } from "./client.js";
3
- export type { PayloadCmsPluginOptions, PayloadLogger, PayloadMapFn, PayloadSyncEventNames, } from "./plugin.js";
4
- export { payloadCmsPlugin } from "./plugin.js";
5
- export type { PayloadSyncRuntime, ResolvedPayloadSyncEventNames } from "./runtime.js";
6
- export { createPayloadSyncRuntime } from "./runtime.js";
7
- export type { PayloadDocBody, PayloadFetch, VoyantEntityEvent } from "./types.js";
8
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EACV,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,YAAY,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAA;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js DELETED
@@ -1,3 +0,0 @@
1
- export { createPayloadClient } from "./client.js";
2
- export { payloadCmsPlugin } from "./plugin.js";
3
- export { createPayloadSyncRuntime } from "./runtime.js";
package/dist/plugin.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { Plugin } from "@voyantjs/core";
2
- import type { PayloadClientOptions } from "./client.js";
3
- import type { PayloadDocBody, VoyantEntityEvent } from "./types.js";
4
- export interface PayloadSyncEventNames {
5
- created?: string;
6
- updated?: string;
7
- deleted?: string;
8
- }
9
- export type PayloadMapFn = (event: VoyantEntityEvent) => PayloadDocBody;
10
- export interface PayloadLogger {
11
- error: (message: string, meta?: unknown) => void;
12
- info?: (message: string, meta?: unknown) => void;
13
- }
14
- export interface PayloadCmsPluginOptions extends PayloadClientOptions {
15
- collection: string;
16
- events?: PayloadSyncEventNames;
17
- mapEvent?: PayloadMapFn;
18
- logger?: PayloadLogger;
19
- }
20
- export declare function payloadCmsPlugin(options: PayloadCmsPluginOptions): Plugin;
21
- //# sourceMappingURL=plugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,gBAAgB,CAAA;AAGxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGnE,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,cAAc,CAAA;AAEvE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAChD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACjD;AAED,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,qBAAqB,CAAA;IAC9B,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB;AASD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAyDzE"}
package/dist/plugin.js DELETED
@@ -1,81 +0,0 @@
1
- import { ZodError } from "zod";
2
- import { createPayloadSyncRuntime } from "./runtime.js";
3
- import { payloadCmsPluginOptionsSchema } from "./validation.js";
4
- function coerceEvent(data) {
5
- if (data == null || typeof data !== "object")
6
- return null;
7
- const maybe = data;
8
- if (typeof maybe.id !== "string")
9
- return null;
10
- return maybe;
11
- }
12
- export function payloadCmsPlugin(options) {
13
- const validatedOptions = parsePayloadCmsPluginOptions(options);
14
- const { client, mapEvent, logger, eventNames } = createPayloadSyncRuntime(validatedOptions);
15
- const subscribers = [
16
- {
17
- event: eventNames.created,
18
- handler: async (envelope) => {
19
- const event = coerceEvent(envelope.data);
20
- if (!event)
21
- return;
22
- try {
23
- await client.upsertByVoyantId(validatedOptions.collection, event.id, mapEvent(event));
24
- }
25
- catch (err) {
26
- logger.error(`[payload-cms] upsert on "${eventNames.created}" failed for ${event.id}`, err);
27
- }
28
- },
29
- },
30
- {
31
- event: eventNames.updated,
32
- handler: async (envelope) => {
33
- const event = coerceEvent(envelope.data);
34
- if (!event)
35
- return;
36
- try {
37
- await client.upsertByVoyantId(validatedOptions.collection, event.id, mapEvent(event));
38
- }
39
- catch (err) {
40
- logger.error(`[payload-cms] upsert on "${eventNames.updated}" failed for ${event.id}`, err);
41
- }
42
- },
43
- },
44
- {
45
- event: eventNames.deleted,
46
- handler: async (envelope) => {
47
- const event = coerceEvent(envelope.data);
48
- if (!event)
49
- return;
50
- try {
51
- await client.deleteByVoyantId(validatedOptions.collection, event.id);
52
- }
53
- catch (err) {
54
- logger.error(`[payload-cms] delete on "${eventNames.deleted}" failed for ${event.id}`, err);
55
- }
56
- },
57
- },
58
- ];
59
- return {
60
- name: "payload-cms",
61
- version: "0.1.0",
62
- subscribers,
63
- };
64
- }
65
- function parsePayloadCmsPluginOptions(options) {
66
- try {
67
- return payloadCmsPluginOptionsSchema.parse(options);
68
- }
69
- catch (error) {
70
- if (error instanceof ZodError) {
71
- const detail = error.issues
72
- .map((issue) => {
73
- const path = issue.path.join(".") || "options";
74
- return `${path}: ${issue.message}`;
75
- })
76
- .join("; ");
77
- throw new Error(`Invalid Payload CMS plugin options: ${detail}`);
78
- }
79
- throw error;
80
- }
81
- }
package/dist/runtime.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { createPayloadClient } from "./client.js";
2
- import type { PayloadCmsPluginOptions, PayloadLogger, PayloadMapFn } from "./plugin.js";
3
- export interface ResolvedPayloadSyncEventNames {
4
- created: string;
5
- updated: string;
6
- deleted: string;
7
- }
8
- export interface PayloadSyncRuntime {
9
- client: ReturnType<typeof createPayloadClient>;
10
- logger: PayloadLogger;
11
- mapEvent: PayloadMapFn;
12
- eventNames: ResolvedPayloadSyncEventNames;
13
- }
14
- export declare function createPayloadSyncRuntime(options: PayloadCmsPluginOptions): PayloadSyncRuntime;
15
- //# sourceMappingURL=runtime.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;IAC9C,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,YAAY,CAAA;IACtB,UAAU,EAAE,6BAA6B,CAAA;CAC1C;AAOD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,uBAAuB,GAAG,kBAAkB,CAW7F"}
package/dist/runtime.js DELETED
@@ -1,17 +0,0 @@
1
- import { createPayloadClient } from "./client.js";
2
- function defaultMapEvent(event) {
3
- const { id: _id, ...rest } = event;
4
- return rest;
5
- }
6
- export function createPayloadSyncRuntime(options) {
7
- return {
8
- client: createPayloadClient(options),
9
- logger: options.logger ?? console,
10
- mapEvent: options.mapEvent ?? defaultMapEvent,
11
- eventNames: {
12
- created: options.events?.created ?? "product.created",
13
- updated: options.events?.updated ?? "product.updated",
14
- deleted: options.events?.deleted ?? "product.deleted",
15
- },
16
- };
17
- }
package/dist/types.d.ts DELETED
@@ -1,31 +0,0 @@
1
- /**
2
- * Minimal shape Voyant events expose when carrying a record identifier.
3
- * The plugin accepts anything with `id: string`; everything else is passed
4
- * through to `mapProduct` untouched.
5
- */
6
- export interface VoyantEntityEvent {
7
- id: string;
8
- [key: string]: unknown;
9
- }
10
- /**
11
- * A Payload document, as a bag of properties. Payload always assigns its own
12
- * `id`; the plugin additionally sets a `voyantId` (configurable) for
13
- * idempotent lookups.
14
- */
15
- export type PayloadDocBody = Record<string, unknown>;
16
- /**
17
- * Minimal `fetch` shape the Payload client depends on. Works with the global
18
- * `fetch` in Node 18+ / Cloudflare Workers / browsers, and is trivially
19
- * stubbable in tests.
20
- */
21
- export type PayloadFetch = (input: string, init: {
22
- method: string;
23
- headers: Record<string, string>;
24
- body?: string;
25
- }) => Promise<{
26
- ok: boolean;
27
- status: number;
28
- json: () => Promise<unknown>;
29
- text: () => Promise<string>;
30
- }>;
31
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEpD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,KACE,OAAO,CAAC;IACX,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAC5B,CAAC,CAAA"}
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,15 +0,0 @@
1
- import { z } from "zod";
2
- import type { PayloadLogger, PayloadMapFn, PayloadSyncEventNames } from "./plugin.js";
3
- import type { PayloadFetch } from "./types.js";
4
- export declare const payloadCmsPluginOptionsSchema: z.ZodObject<{
5
- apiUrl: z.ZodString;
6
- apiKey: z.ZodString;
7
- collection: z.ZodString;
8
- voyantIdField: z.ZodOptional<z.ZodString>;
9
- apiKeyAuthScheme: z.ZodOptional<z.ZodString>;
10
- fetch: z.ZodOptional<z.ZodCustom<PayloadFetch | undefined, PayloadFetch | undefined>>;
11
- events: z.ZodOptional<z.ZodCustom<PayloadSyncEventNames | undefined, PayloadSyncEventNames | undefined>>;
12
- mapEvent: z.ZodOptional<z.ZodCustom<PayloadMapFn | undefined, PayloadMapFn | undefined>>;
13
- logger: z.ZodOptional<z.ZodCustom<PayloadLogger | undefined, PayloadLogger | undefined>>;
14
- }, z.core.$strip>;
15
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAEV,aAAa,EACb,YAAY,EACZ,qBAAqB,EACtB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAkC9C,eAAO,MAAM,6BAA6B;;;;;;;;;;iBAUK,CAAA"}
@@ -1,29 +0,0 @@
1
- import { z } from "zod";
2
- const optionalString = z.string().trim().min(1).optional();
3
- const optionalFetch = z.custom((value) => value === undefined || typeof value === "function", "Expected a fetch implementation function");
4
- const optionalLogger = z.custom((value) => value === undefined ||
5
- (typeof value === "object" &&
6
- value !== null &&
7
- typeof value.error === "function" &&
8
- ((value.info ?? undefined) === undefined ||
9
- typeof value.info === "function")), "Expected a logger with an error function");
10
- const optionalMapEvent = z.custom((value) => value === undefined || typeof value === "function", "Expected a mapEvent function");
11
- const optionalEvents = z.custom((value) => {
12
- if (value === undefined)
13
- return true;
14
- if (typeof value !== "object" || value === null)
15
- return false;
16
- const events = value;
17
- return [events.created, events.updated, events.deleted].every((entry) => entry === undefined || (typeof entry === "string" && entry.trim().length > 0));
18
- }, "Expected event names to be non-empty strings");
19
- export const payloadCmsPluginOptionsSchema = z.object({
20
- apiUrl: z.string().trim().url(),
21
- apiKey: z.string().trim().min(1),
22
- collection: z.string().trim().min(1),
23
- voyantIdField: optionalString,
24
- apiKeyAuthScheme: optionalString,
25
- fetch: optionalFetch.optional(),
26
- events: optionalEvents.optional(),
27
- mapEvent: optionalMapEvent.optional(),
28
- logger: optionalLogger.optional(),
29
- });