@open-mercato/events 0.7.1-develop.7193.1.910a5b0a1e → 0.7.1-develop.7194.1.ab4fc81f82

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.
@@ -4,6 +4,15 @@ const metadata = {
4
4
  path: "/events",
5
5
  GET: { requireAuth: true, requireFeatures: ["workflows.view"] }
6
6
  };
7
+ const eventPayloadFieldSchema = z.object({
8
+ path: z.string(),
9
+ type: z.enum(["text", "number", "boolean", "select", "date", "object", "unknown"]),
10
+ label: z.string().optional(),
11
+ optional: z.boolean().optional()
12
+ });
13
+ const eventPayloadSchemaSchema = z.object({
14
+ fields: z.array(eventPayloadFieldSchema)
15
+ });
7
16
  const eventDefinitionSchema = z.object({
8
17
  id: z.string(),
9
18
  label: z.string(),
@@ -14,7 +23,8 @@ const eventDefinitionSchema = z.object({
14
23
  excludeFromTriggers: z.boolean().optional(),
15
24
  clientBroadcast: z.boolean().optional(),
16
25
  crossProcessBroadcast: z.boolean().optional(),
17
- portalBroadcast: z.boolean().optional()
26
+ portalBroadcast: z.boolean().optional(),
27
+ payloadSchema: eventPayloadSchemaSchema.optional()
18
28
  });
19
29
  const eventsResponseSchema = z.object({
20
30
  data: z.array(eventDefinitionSchema),
@@ -46,7 +56,7 @@ const openApi = {
46
56
  methods: {
47
57
  GET: {
48
58
  summary: "List declared events",
49
- description: "Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true).",
59
+ description: "Returns every declared event, including its declared payloadSchema when the module (or the generated CRUD default) provides one. Filters: category, module, excludeTriggerExcluded (default true).",
50
60
  responses: [{ status: 200, description: "Declared events", schema: eventsResponseSchema }]
51
61
  }
52
62
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/events/api/route.ts"],
4
- "sourcesContent": ["/**\n * Events registry API \u2014 returns declared events from module `events.ts` files.\n *\n * Uses the globally registered event configs (populated during bootstrap). Data\n * leaked here (event ids, module ids, entity ids, broadcast flags) is\n * recon-grade and MUST NOT be served to anonymous callers; the route\n * is protected by the standard `[...slug]` dispatcher with `requireAuth: true`.\n * Consumer: `packages/ui/src/backend/inputs/EventSelect.tsx` (workflow triggers,\n * business rules, webhook config).\n */\n\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getDeclaredEvents } from '@open-mercato/shared/modules/events'\n\nexport const metadata = {\n path: '/events',\n GET: { requireAuth: true, requireFeatures: ['workflows.view'] },\n}\n\nconst eventDefinitionSchema = z.object({\n id: z.string(),\n label: z.string(),\n description: z.string().optional(),\n category: z.enum(['crud', 'lifecycle', 'system', 'custom']).optional(),\n module: z.string().optional(),\n entity: z.string().optional(),\n excludeFromTriggers: z.boolean().optional(),\n clientBroadcast: z.boolean().optional(),\n crossProcessBroadcast: z.boolean().optional(),\n portalBroadcast: z.boolean().optional(),\n})\n\nconst eventsResponseSchema = z.object({\n data: z.array(eventDefinitionSchema),\n total: z.number().int().nonnegative(),\n})\n\nexport async function GET(req: Request): Promise<Response> {\n const { searchParams } = new URL(req.url)\n const category = searchParams.get('category')\n const moduleId = searchParams.get('module')\n const excludeTriggerExcluded = searchParams.get('excludeTriggerExcluded') !== 'false'\n\n let filteredEvents = getDeclaredEvents()\n\n if (excludeTriggerExcluded) {\n filteredEvents = filteredEvents.filter((e) => !e.excludeFromTriggers)\n }\n if (category) {\n filteredEvents = filteredEvents.filter((e) => e.category === category)\n }\n if (moduleId) {\n filteredEvents = filteredEvents.filter((e) => e.module === moduleId)\n }\n\n return Response.json({\n data: filteredEvents,\n total: filteredEvents.length,\n })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'List declared platform events',\n description: 'Returns all declared platform events from every enabled module. Supports optional category and module filters.',\n methods: {\n GET: {\n summary: 'List declared events',\n description: 'Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true).',\n responses: [{ status: 200, description: 'Declared events', schema: eventsResponseSchema }],\n },\n },\n}\n"],
5
- "mappings": "AAWA,SAAS,SAAS;AAElB,SAAS,yBAAyB;AAE3B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,gBAAgB,EAAE;AAChE;AAEA,MAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,EAAE,KAAK,CAAC,QAAQ,aAAa,UAAU,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrE,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,qBAAqB,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC1C,iBAAiB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACtC,uBAAuB,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC5C,iBAAiB,EAAE,QAAQ,EAAE,SAAS;AACxC,CAAC;AAED,MAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,MAAM,EAAE,MAAM,qBAAqB;AAAA,EACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACtC,CAAC;AAED,eAAsB,IAAI,KAAiC;AACzD,QAAM,EAAE,aAAa,IAAI,IAAI,IAAI,IAAI,GAAG;AACxC,QAAM,WAAW,aAAa,IAAI,UAAU;AAC5C,QAAM,WAAW,aAAa,IAAI,QAAQ;AAC1C,QAAM,yBAAyB,aAAa,IAAI,wBAAwB,MAAM;AAE9E,MAAI,iBAAiB,kBAAkB;AAEvC,MAAI,wBAAwB;AAC1B,qBAAiB,eAAe,OAAO,CAAC,MAAM,CAAC,EAAE,mBAAmB;AAAA,EACtE;AACA,MAAI,UAAU;AACZ,qBAAiB,eAAe,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAAA,EACvE;AACA,MAAI,UAAU;AACZ,qBAAiB,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AAAA,EACrE;AAEA,SAAO,SAAS,KAAK;AAAA,IACnB,MAAM;AAAA,IACN,OAAO,eAAe;AAAA,EACxB,CAAC;AACH;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,qBAAqB,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/**\n * Events registry API \u2014 returns declared events from module `events.ts` files.\n *\n * Uses the globally registered event configs (populated during bootstrap). Data\n * leaked here (event ids, module ids, entity ids, broadcast flags) is\n * recon-grade and MUST NOT be served to anonymous callers; the route\n * is protected by the standard `[...slug]` dispatcher with `requireAuth: true`.\n * Consumer: `packages/ui/src/backend/inputs/EventSelect.tsx` (workflow triggers,\n * business rules, webhook config).\n */\n\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getDeclaredEvents } from '@open-mercato/shared/modules/events'\n\nexport const metadata = {\n path: '/events',\n GET: { requireAuth: true, requireFeatures: ['workflows.view'] },\n}\n\nconst eventPayloadFieldSchema = z.object({\n path: z.string(),\n type: z.enum(['text', 'number', 'boolean', 'select', 'date', 'object', 'unknown']),\n label: z.string().optional(),\n optional: z.boolean().optional(),\n})\n\nconst eventPayloadSchemaSchema = z.object({\n fields: z.array(eventPayloadFieldSchema),\n})\n\nconst eventDefinitionSchema = z.object({\n id: z.string(),\n label: z.string(),\n description: z.string().optional(),\n category: z.enum(['crud', 'lifecycle', 'system', 'custom']).optional(),\n module: z.string().optional(),\n entity: z.string().optional(),\n excludeFromTriggers: z.boolean().optional(),\n clientBroadcast: z.boolean().optional(),\n crossProcessBroadcast: z.boolean().optional(),\n portalBroadcast: z.boolean().optional(),\n payloadSchema: eventPayloadSchemaSchema.optional(),\n})\n\nconst eventsResponseSchema = z.object({\n data: z.array(eventDefinitionSchema),\n total: z.number().int().nonnegative(),\n})\n\nexport async function GET(req: Request): Promise<Response> {\n const { searchParams } = new URL(req.url)\n const category = searchParams.get('category')\n const moduleId = searchParams.get('module')\n const excludeTriggerExcluded = searchParams.get('excludeTriggerExcluded') !== 'false'\n\n let filteredEvents = getDeclaredEvents()\n\n if (excludeTriggerExcluded) {\n filteredEvents = filteredEvents.filter((e) => !e.excludeFromTriggers)\n }\n if (category) {\n filteredEvents = filteredEvents.filter((e) => e.category === category)\n }\n if (moduleId) {\n filteredEvents = filteredEvents.filter((e) => e.module === moduleId)\n }\n\n return Response.json({\n data: filteredEvents,\n total: filteredEvents.length,\n })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'List declared platform events',\n description: 'Returns all declared platform events from every enabled module. Supports optional category and module filters.',\n methods: {\n GET: {\n summary: 'List declared events',\n description: 'Returns every declared event, including its declared payloadSchema when the module (or the generated CRUD default) provides one. Filters: category, module, excludeTriggerExcluded (default true).',\n responses: [{ status: 200, description: 'Declared events', schema: eventsResponseSchema }],\n },\n },\n}\n"],
5
+ "mappings": "AAWA,SAAS,SAAS;AAElB,SAAS,yBAAyB;AAE3B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,gBAAgB,EAAE;AAChE;AAEA,MAAM,0BAA0B,EAAE,OAAO;AAAA,EACvC,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,KAAK,CAAC,QAAQ,UAAU,WAAW,UAAU,QAAQ,UAAU,SAAS,CAAC;AAAA,EACjF,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,QAAQ,EAAE,MAAM,uBAAuB;AACzC,CAAC;AAED,MAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,EAAE,KAAK,CAAC,QAAQ,aAAa,UAAU,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrE,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,qBAAqB,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC1C,iBAAiB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACtC,uBAAuB,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC5C,iBAAiB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACtC,eAAe,yBAAyB,SAAS;AACnD,CAAC;AAED,MAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,MAAM,EAAE,MAAM,qBAAqB;AAAA,EACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACtC,CAAC;AAED,eAAsB,IAAI,KAAiC;AACzD,QAAM,EAAE,aAAa,IAAI,IAAI,IAAI,IAAI,GAAG;AACxC,QAAM,WAAW,aAAa,IAAI,UAAU;AAC5C,QAAM,WAAW,aAAa,IAAI,QAAQ;AAC1C,QAAM,yBAAyB,aAAa,IAAI,wBAAwB,MAAM;AAE9E,MAAI,iBAAiB,kBAAkB;AAEvC,MAAI,wBAAwB;AAC1B,qBAAiB,eAAe,OAAO,CAAC,MAAM,CAAC,EAAE,mBAAmB;AAAA,EACtE;AACA,MAAI,UAAU;AACZ,qBAAiB,eAAe,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAAA,EACvE;AACA,MAAI,UAAU;AACZ,qBAAiB,eAAe,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ;AAAA,EACrE;AAEA,SAAO,SAAS,KAAK;AAAA,IACnB,MAAM;AAAA,IACN,OAAO,eAAe;AAAA,EACxB,CAAC;AACH;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,qBAAqB,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/events",
3
- "version": "0.7.1-develop.7193.1.910a5b0a1e",
3
+ "version": "0.7.1-develop.7194.1.ab4fc81f82",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,8 +33,8 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@open-mercato/queue": "0.7.1-develop.7193.1.910a5b0a1e",
37
- "@open-mercato/shared": "0.7.1-develop.7193.1.910a5b0a1e",
36
+ "@open-mercato/queue": "0.7.1-develop.7194.1.ab4fc81f82",
37
+ "@open-mercato/shared": "0.7.1-develop.7194.1.ab4fc81f82",
38
38
  "pg": "8.23.0"
39
39
  },
40
40
  "devDependencies": {
@@ -6,6 +6,13 @@ jest.mock('@open-mercato/shared/modules/events', () => ({
6
6
  entity: 'person',
7
7
  label: 'Person Created',
8
8
  category: 'crud',
9
+ payloadSchema: {
10
+ fields: [
11
+ { path: 'id', type: 'text' },
12
+ { path: 'organizationId', type: 'text', optional: true },
13
+ { path: 'tenantId', type: 'text', optional: true },
14
+ ],
15
+ },
9
16
  },
10
17
  {
11
18
  id: 'sales.order.placed',
@@ -69,4 +76,22 @@ describe('GET /api/events (core events module route)', () => {
69
76
  expect(body.total).toBe(1)
70
77
  expect(body.data[0].module).toBe('customers')
71
78
  })
79
+
80
+ it('exposes payloadSchema for events that declare one and omits it otherwise', async () => {
81
+ const res = await GET(makeReq())
82
+ const body = (await res.json()) as {
83
+ data: Array<{ id: string; payloadSchema?: { fields: Array<{ path: string; type: string; optional?: boolean }> } }>
84
+ }
85
+ const typed = body.data.find((e) => e.id === 'customers.person.created')
86
+ expect(typed?.payloadSchema).toEqual({
87
+ fields: [
88
+ { path: 'id', type: 'text' },
89
+ { path: 'organizationId', type: 'text', optional: true },
90
+ { path: 'tenantId', type: 'text', optional: true },
91
+ ],
92
+ })
93
+ const untyped = body.data.find((e) => e.id === 'sales.order.placed')
94
+ expect(untyped).toBeDefined()
95
+ expect(untyped?.payloadSchema).toBeUndefined()
96
+ })
72
97
  })
@@ -18,6 +18,17 @@ export const metadata = {
18
18
  GET: { requireAuth: true, requireFeatures: ['workflows.view'] },
19
19
  }
20
20
 
21
+ const eventPayloadFieldSchema = z.object({
22
+ path: z.string(),
23
+ type: z.enum(['text', 'number', 'boolean', 'select', 'date', 'object', 'unknown']),
24
+ label: z.string().optional(),
25
+ optional: z.boolean().optional(),
26
+ })
27
+
28
+ const eventPayloadSchemaSchema = z.object({
29
+ fields: z.array(eventPayloadFieldSchema),
30
+ })
31
+
21
32
  const eventDefinitionSchema = z.object({
22
33
  id: z.string(),
23
34
  label: z.string(),
@@ -29,6 +40,7 @@ const eventDefinitionSchema = z.object({
29
40
  clientBroadcast: z.boolean().optional(),
30
41
  crossProcessBroadcast: z.boolean().optional(),
31
42
  portalBroadcast: z.boolean().optional(),
43
+ payloadSchema: eventPayloadSchemaSchema.optional(),
32
44
  })
33
45
 
34
46
  const eventsResponseSchema = z.object({
@@ -66,7 +78,7 @@ export const openApi: OpenApiRouteDoc = {
66
78
  methods: {
67
79
  GET: {
68
80
  summary: 'List declared events',
69
- description: 'Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true).',
81
+ description: 'Returns every declared event, including its declared payloadSchema when the module (or the generated CRUD default) provides one. Filters: category, module, excludeTriggerExcluded (default true).',
70
82
  responses: [{ status: 200, description: 'Declared events', schema: eventsResponseSchema }],
71
83
  },
72
84
  },