@motiadev/core 0.1.0-beta.5 → 0.1.0-beta.7

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.
@@ -0,0 +1,3 @@
1
+ import { ApiMiddleware, ApiRequest, ApiResponse, FlowContext } from './types';
2
+ declare const _default: (...middlewares: ApiMiddleware[]) => (req: ApiRequest, ctx: FlowContext, handler: () => Promise<ApiResponse>) => Promise<ApiResponse>;
3
+ export default _default;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = (...middlewares) => {
4
+ return async (req, ctx, handler) => {
5
+ const composedHandler = middlewares.reduceRight((nextHandler, middleware) => () => middleware(req, ctx, nextHandler), handler);
6
+ return composedHandler();
7
+ };
8
+ };
@@ -17,6 +17,7 @@ const call_step_file_1 = require("./call-step-file");
17
17
  const LoggerFactory_1 = require("./LoggerFactory");
18
18
  const generate_trace_id_1 = require("./generate-trace-id");
19
19
  const flows_config_endpoint_1 = require("./flows-config-endpoint");
20
+ const middleware_composer_1 = __importDefault(require("./middleware-composer"));
20
21
  const createServer = async (lockedData, eventManager, state, config) => {
21
22
  const printer = lockedData.printer;
22
23
  const app = (0, express_1.default)();
@@ -37,22 +38,45 @@ const createServer = async (lockedData, eventManager, state, config) => {
37
38
  pathParams: req.params,
38
39
  queryParams: req.query,
39
40
  };
40
- try {
41
- const data = request;
42
- const result = await (0, call_step_file_1.callStepFile)({
43
- contextInFirstArg: false,
44
- data,
45
- step,
46
- printer,
47
- logger,
48
- eventManager,
49
- state,
50
- traceId,
51
- });
52
- if (!result) {
53
- res.status(500).json({ error: 'Internal server error' });
54
- return;
41
+ const ctx = {
42
+ emit: async (event) => {
43
+ await eventManager.emit({
44
+ topic: event.topic,
45
+ data: event.data,
46
+ traceId,
47
+ logger,
48
+ });
49
+ },
50
+ traceId,
51
+ state,
52
+ logger,
53
+ };
54
+ const finalHandler = async () => {
55
+ try {
56
+ const result = await (0, call_step_file_1.callStepFile)({
57
+ contextInFirstArg: false,
58
+ data: request,
59
+ step,
60
+ printer,
61
+ logger,
62
+ eventManager,
63
+ state,
64
+ traceId,
65
+ });
66
+ if (!result) {
67
+ return { status: 500, body: { error: 'Internal server error' } };
68
+ }
69
+ return result;
70
+ }
71
+ catch (error) {
72
+ logger.error('[API] Internal server error', { error });
73
+ console.log(error);
74
+ return { status: 500, body: { error: 'Internal server error' } };
55
75
  }
76
+ };
77
+ try {
78
+ const middleware = step.config.middleware || [];
79
+ const result = await (0, middleware_composer_1.default)(...middleware)(request, ctx, finalHandler);
56
80
  if (result.headers) {
57
81
  Object.entries(result.headers).forEach(([key, value]) => res.setHeader(key, value));
58
82
  }
@@ -60,8 +84,7 @@ const createServer = async (lockedData, eventManager, state, config) => {
60
84
  res.json(result.body);
61
85
  }
62
86
  catch (error) {
63
- logger.error('[API] Internal server error', { error });
64
- console.log(error);
87
+ logger.error('[API] Error in middleware chain', { error });
65
88
  res.status(500).json({ error: 'Internal server error' });
66
89
  }
67
90
  };
@@ -72,15 +95,15 @@ const createServer = async (lockedData, eventManager, state, config) => {
72
95
  const addRoute = (step) => {
73
96
  const { method, path } = step.config;
74
97
  logger_1.globalLogger.debug('[API] Registering route', step.config);
75
- const handler = asyncHandler(step);
98
+ const expressHandler = asyncHandler(step);
76
99
  const methods = {
77
- GET: () => router.get(path, handler),
78
- POST: () => router.post(path, handler),
79
- PUT: () => router.put(path, handler),
80
- DELETE: () => router.delete(path, handler),
81
- PATCH: () => router.patch(path, handler),
82
- OPTIONS: () => router.options(path, handler),
83
- HEAD: () => router.head(path, handler),
100
+ GET: () => router.get(path, expressHandler),
101
+ POST: () => router.post(path, expressHandler),
102
+ PUT: () => router.put(path, expressHandler),
103
+ DELETE: () => router.delete(path, expressHandler),
104
+ PATCH: () => router.patch(path, expressHandler),
105
+ OPTIONS: () => router.options(path, expressHandler),
106
+ HEAD: () => router.head(path, expressHandler),
84
107
  };
85
108
  const methodHandler = methods[method];
86
109
  if (!methodHandler) {
@@ -81,6 +81,7 @@ const apiSchema = zod_1.z
81
81
  flows: zod_1.z.array(zod_1.z.string()).optional(),
82
82
  bodySchema: zod_1.z.union([jsonSchema, zod_1.z.null()]).optional(),
83
83
  includeFiles: zod_1.z.array(zod_1.z.string()).optional(),
84
+ middleware: zod_1.z.array(zod_1.z.function()).optional(),
84
85
  })
85
86
  .strict();
86
87
  const cronSchema = zod_1.z
@@ -47,6 +47,7 @@ export type NoopConfig = {
47
47
  flows?: string[];
48
48
  };
49
49
  export type ApiRouteMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
50
+ export type ApiMiddleware = (req: ApiRequest, ctx: FlowContext, next: () => Promise<ApiResponse>) => Promise<ApiResponse>;
50
51
  export type ApiRouteConfig = {
51
52
  type: 'api';
52
53
  name: string;
@@ -57,6 +58,7 @@ export type ApiRouteConfig = {
57
58
  virtualEmits?: Emit[];
58
59
  virtualSubscribes?: string[];
59
60
  flows?: string[];
61
+ middleware?: ApiMiddleware[];
60
62
  bodySchema?: ZodObject<any>;
61
63
  /**
62
64
  * Files to include in the step bundle.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@motiadev/core",
3
3
  "description": "Core functionality for the Motia framework, providing the foundation for building event-driven workflows.",
4
4
  "main": "dist/index.js",
5
- "version": "0.1.0-beta.5",
5
+ "version": "0.1.0-beta.7",
6
6
  "dependencies": {
7
7
  "body-parser": "^1.20.3",
8
8
  "colors": "^1.4.0",