@motiadev/core 0.0.16 → 0.0.17

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.
@@ -54,7 +54,7 @@ const callStepFile = (stepPath, step, event, eventManager, state) => {
54
54
  const message = JSON.parse(data.toString());
55
55
  event.logger.log(message);
56
56
  }
57
- catch (error) {
57
+ catch {
58
58
  event.logger.info(Buffer.from(data).toString(), { step });
59
59
  }
60
60
  });
@@ -46,14 +46,14 @@ const setupCronHandlers = (steps, eventManager, socketServer) => {
46
46
  if (!cron.validate(cronExpression)) {
47
47
  logger_1.globalLogger.error('[cron handler] invalid cron expression', {
48
48
  expression: cronExpression,
49
- step: step.config.name
49
+ step: step.config.name,
50
50
  });
51
51
  return;
52
52
  }
53
53
  logger_1.globalLogger.debug('[cron handler] setting up cron job', {
54
54
  filePath,
55
55
  step: step.config.name,
56
- cron: cronExpression
56
+ cron: cronExpression,
57
57
  });
58
58
  const task = cron.schedule(cronExpression, async () => {
59
59
  const traceId = Math.random().toString(36).substring(7);
@@ -65,7 +65,7 @@ const setupCronHandlers = (steps, eventManager, socketServer) => {
65
65
  ...event,
66
66
  traceId,
67
67
  flows: config.flows,
68
- logger
68
+ logger,
69
69
  }, filePath);
70
70
  };
71
71
  if (handler) {
@@ -74,14 +74,15 @@ const setupCronHandlers = (steps, eventManager, socketServer) => {
74
74
  else {
75
75
  await emit({
76
76
  type: config.emits[0],
77
- data: { timestamp: Date.now() }
77
+ data: { timestamp: Date.now() },
78
78
  });
79
79
  }
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
80
81
  }
81
82
  catch (error) {
82
83
  logger.error('[cron handler] error executing cron job', {
83
84
  error: error.message,
84
- step: step.config.name
85
+ step: step.config.name,
85
86
  });
86
87
  }
87
88
  });
@@ -25,7 +25,7 @@ type FlowStepResponse = {
25
25
  virtualEmits?: Emit[];
26
26
  action?: 'webhook';
27
27
  webhookUrl?: string;
28
- bodySchema?: any;
28
+ bodySchema?: unknown;
29
29
  language?: string;
30
30
  nodeComponentPath?: string;
31
31
  cronExpression?: string;
@@ -115,7 +115,7 @@ const createCronStepResponse = (step, id) => {
115
115
  ...createBaseStepResponse(step, id),
116
116
  type: 'cron',
117
117
  emits: step.config.emits,
118
- cronExpression: step.config.cron
118
+ cronExpression: step.config.cron,
119
119
  };
120
120
  };
121
121
  const createStepResponse = (step) => {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isCronStep = exports.isNoopStep = exports.isEventStep = exports.isApiStep = void 0;
4
4
  const isApiStep = (step) => step.config.type === 'api';
5
5
  exports.isApiStep = isApiStep;
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
7
  const isEventStep = (step) => step.config.type === 'event';
7
8
  exports.isEventStep = isEventStep;
8
9
  const isNoopStep = (step) => step.config.type === 'noop';
@@ -1,11 +1,11 @@
1
1
  import { Server } from 'socket.io';
2
2
  declare class BaseLogger {
3
3
  private logger;
4
- constructor(meta?: any);
5
- info(message: string, args?: any): void;
6
- error(message: string, args?: any): void;
7
- debug(message: string, args?: any): void;
8
- warn(message: string, args?: any): void;
4
+ constructor(meta?: Record<string, unknown>);
5
+ info(message: string, args?: unknown): void;
6
+ error(message: string, args?: unknown): void;
7
+ debug(message: string, args?: unknown): void;
8
+ warn(message: string, args?: unknown): void;
9
9
  }
10
10
  export declare class Logger extends BaseLogger {
11
11
  private readonly traceId;
@@ -14,10 +14,10 @@ export declare class Logger extends BaseLogger {
14
14
  private emitLog;
15
15
  constructor(traceId: string, flows: string[], file: string, socketServer?: Server);
16
16
  log(message: any): void;
17
- info: (message: string, args?: any) => void;
18
- error: (message: string, args?: any) => void;
19
- debug: (message: string, args?: any) => void;
20
- warn: (message: string, args?: any) => void;
17
+ info: (message: string, args?: unknown) => void;
18
+ error: (message: string, args?: unknown) => void;
19
+ debug: (message: string, args?: unknown) => void;
20
+ warn: (message: string, args?: unknown) => void;
21
21
  }
22
22
  export declare const globalLogger: BaseLogger;
23
23
  export {};
@@ -67,6 +67,7 @@ class Logger extends BaseLogger {
67
67
  });
68
68
  };
69
69
  }
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
71
  log(message) {
71
72
  console.log(JSON.stringify(message));
72
73
  this.emitLog(message.level, message.msg, message);
@@ -1,2 +1,2 @@
1
- import { StepConfig } from "../types";
1
+ import { StepConfig } from '../types';
2
2
  export declare const getNodeFileConfig: (filePath: string) => Promise<StepConfig>;
@@ -45,6 +45,7 @@ if (result.resultType !== 'success') {
45
45
  throw Error('Failed to load tsconfig.json');
46
46
  }
47
47
  const { absoluteBaseUrl, paths } = result;
48
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
48
49
  require('ts-node').register({
49
50
  transpileOnly: true,
50
51
  compilerOptions: { module: 'commonjs', baseUrl: absoluteBaseUrl, paths },
@@ -52,6 +53,7 @@ require('ts-node').register({
52
53
  const getModuleExport = async (filePath, exportName) => {
53
54
  try {
54
55
  const resolvedFilePath = require.resolve(filePath);
56
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
55
57
  const module = require(resolvedFilePath);
56
58
  return module[exportName];
57
59
  }
@@ -8,6 +8,7 @@ const logger_1 = require("./logger");
8
8
  const rpc_state_manager_1 = require("./rpc-state-manager");
9
9
  const rpc_1 = require("./rpc");
10
10
  // Add ts-node registration before dynamic imports
11
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
11
12
  require('ts-node').register({
12
13
  transpileOnly: true,
13
14
  compilerOptions: { module: 'commonjs' },
@@ -22,12 +23,13 @@ function parseArgs(arg) {
22
23
  }
23
24
  async function runTypescriptModule(filePath, args) {
24
25
  try {
25
- // Remove pathToFileURL since we'll use require
26
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
26
27
  const module = require(path_1.default.resolve(filePath));
27
28
  // Check if the specified function exists in the module
28
29
  if (typeof module.handler !== 'function') {
29
30
  throw new Error(`Function handler not found in module ${filePath}`);
30
31
  }
32
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
33
  const { stateConfig, ...event } = args;
32
34
  const { traceId, flows } = event;
33
35
  const logger = new logger_1.Logger(traceId, flows, filePath.split('/').pop());
@@ -2,6 +2,6 @@ export declare class RpcSender {
2
2
  private readonly process;
3
3
  private readonly pendingRequests;
4
4
  constructor(process: NodeJS.Process);
5
- send<T>(method: string, args: any): Promise<T>;
5
+ send<T>(method: string, args: unknown): Promise<T>;
6
6
  init(): void;
7
7
  }
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RpcSender = void 0;
7
+ /// <reference types="node" />
7
8
  const crypto_1 = __importDefault(require("crypto"));
8
9
  class RpcSender {
9
10
  constructor(process) {
@@ -14,13 +14,14 @@ const flows_endpoint_1 = require("./flows-endpoint");
14
14
  const guards_1 = require("./guards");
15
15
  const logger_1 = require("./logger");
16
16
  const get_module_export_1 = require("./node/get-module-export");
17
+ const steps_1 = require("./steps");
17
18
  const createServer = async (options) => {
18
19
  const { flows, steps, eventManager, state } = options;
19
20
  const app = (0, express_1.default)();
20
21
  const server = http_1.default.createServer(app);
21
22
  const io = new socket_io_1.Server(server);
22
- // Setup cron handlers with socket server
23
- const cleanupCronJobs = (0, cron_handler_1.setupCronHandlers)(steps, eventManager, io);
23
+ const allSteps = [...steps_1.systemSteps, ...steps];
24
+ const cleanupCronJobs = (0, cron_handler_1.setupCronHandlers)(allSteps, eventManager, io);
24
25
  const asyncHandler = (step, flows) => {
25
26
  return async (req, res) => {
26
27
  const traceId = (0, crypto_1.randomUUID)();
@@ -53,7 +54,7 @@ const createServer = async (options) => {
53
54
  };
54
55
  app.use(body_parser_1.default.json());
55
56
  app.use(body_parser_1.default.urlencoded({ extended: true }));
56
- const apiSteps = steps.filter(guards_1.isApiStep);
57
+ const apiSteps = allSteps.filter(guards_1.isApiStep);
57
58
  for (const step of apiSteps) {
58
59
  const { method, flows, path } = step.config;
59
60
  logger_1.globalLogger.debug('[API] Registering route', step.config);
@@ -7,7 +7,7 @@ export declare class FileStateAdapter implements StateAdapter {
7
7
  constructor(config: FileAdapterConfig);
8
8
  init(): Promise<void>;
9
9
  get(traceId: string, key: string): Promise<any>;
10
- set(traceId: string, key: string, value: any): Promise<void>;
10
+ set<T>(traceId: string, key: string, value: T): Promise<void>;
11
11
  delete(traceId: string, key: string): Promise<void>;
12
12
  clear(traceId: string): Promise<void>;
13
13
  cleanup(): Promise<void>;
@@ -48,13 +48,13 @@ class FileStateAdapter {
48
48
  try {
49
49
  fs_1.default.realpathSync(dir);
50
50
  }
51
- catch (err) {
51
+ catch {
52
52
  fs_1.default.mkdirSync(dir, { recursive: true });
53
53
  }
54
54
  try {
55
55
  fs_1.default.readFileSync(this.filePath, 'utf-8');
56
56
  }
57
- catch (err) {
57
+ catch {
58
58
  fs_1.default.writeFileSync(this.filePath, JSON.stringify({}), 'utf-8');
59
59
  }
60
60
  }
@@ -2,8 +2,8 @@ import { StateAdapter } from '../state-adapter';
2
2
  export declare class MemoryStateAdapter implements StateAdapter {
3
3
  private state;
4
4
  init(): Promise<void>;
5
- get(traceId: string, key: string): Promise<any>;
6
- set(traceId: string, key: string, value: any): Promise<void>;
5
+ get<T>(traceId: string, key: string): Promise<T | null>;
6
+ set<T>(traceId: string, key: string, value: T): Promise<void>;
7
7
  delete(traceId: string, key: string): Promise<void>;
8
8
  clear(traceId: string): Promise<void>;
9
9
  cleanup(): Promise<void>;
@@ -11,7 +11,7 @@ export declare class RedisStateAdapter implements StateAdapter {
11
11
  private ttl;
12
12
  constructor(config: RedisAdapterConfig);
13
13
  get(traceId: string, key: string): Promise<any>;
14
- set(traceId: string, key: string, value: any): Promise<void>;
14
+ set<T>(traceId: string, key: string, value: T): Promise<void>;
15
15
  delete(traceId: string, key: string): Promise<void>;
16
16
  clear(traceId: string): Promise<void>;
17
17
  cleanup(): Promise<void>;
@@ -1,11 +1,17 @@
1
1
  import { ChildProcess } from 'child_process';
2
2
  type RpcHandler<TInput, TOutput> = (input: TInput) => Promise<TOutput>;
3
+ export type RpcMessage = {
4
+ type: 'rpc_request';
5
+ id: string | undefined;
6
+ method: string;
7
+ args: unknown;
8
+ };
3
9
  export declare class RpcProcessor {
4
10
  private child;
5
11
  private handlers;
6
12
  constructor(child: ChildProcess);
7
13
  handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>): void;
8
- handle(method: string, input: any): Promise<any>;
14
+ handle(method: string, input: unknown): Promise<any>;
9
15
  private response;
10
16
  init(): Promise<void>;
11
17
  }
@@ -4,6 +4,7 @@ exports.RpcProcessor = void 0;
4
4
  class RpcProcessor {
5
5
  constructor(child) {
6
6
  this.child = child;
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
8
  this.handlers = {};
8
9
  }
9
10
  handler(method, handler) {
@@ -12,10 +12,12 @@ const createStepHandlers = (steps, eventManager, state) => {
12
12
  logger_1.globalLogger.debug('[step handler] establishing step subscriptions', { filePath, step: step.config.name });
13
13
  subscribes.forEach((subscribe) => {
14
14
  eventManager.subscribe(subscribe, step.config.name, async (event) => {
15
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
16
  const { logger, ...rest } = event;
16
17
  logger_1.globalLogger.debug('[step handler] received event', { event: rest, step: step.config.name });
17
18
  try {
18
19
  await (0, call_step_file_1.callStepFile)(filePath, step.config.name, event, eventManager, state);
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
21
  }
20
22
  catch (error) {
21
23
  logger_1.globalLogger.error(`[step handler] error calling step`, {
@@ -0,0 +1,3 @@
1
+ import { ApiRouteConfig, StepHandler } from '../types';
2
+ export declare const config: ApiRouteConfig;
3
+ export declare const handler: StepHandler<typeof config>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handler = exports.config = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.config = {
6
+ type: 'api',
7
+ name: 'Event Emitter',
8
+ description: 'System endpoint for emitting events',
9
+ path: '/emit',
10
+ method: 'POST',
11
+ emits: [], // Dynamic emissions
12
+ flows: ['_system'],
13
+ bodySchema: zod_1.z.object({
14
+ type: zod_1.z.string(),
15
+ data: zod_1.z.record(zod_1.z.unknown()),
16
+ }),
17
+ };
18
+ const handler = async (req, { emit, logger }) => {
19
+ const { type, data } = req.body;
20
+ logger.info('[Event Emitter] Emitting event', { type, data });
21
+ await emit({ type, data });
22
+ return {
23
+ status: 200,
24
+ body: { success: true, emitted: { type, data } },
25
+ };
26
+ };
27
+ exports.handler = handler;
@@ -0,0 +1,2 @@
1
+ import { Step } from '../types';
2
+ export declare const systemSteps: Step[];
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.systemSteps = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const emit_step_1 = require("./emit.step");
9
+ exports.systemSteps = [
10
+ {
11
+ filePath: path_1.default.join(__dirname, 'emit.step.ts'),
12
+ version: '1',
13
+ config: emit_step_1.config,
14
+ },
15
+ ];
@@ -78,7 +78,7 @@ export type CronConfig = {
78
78
  flows: string[];
79
79
  };
80
80
  export type StepHandler<T> = T extends EventConfig<any> ? EventHandler<T['input']> : T extends ApiRouteConfig ? ApiRouteHandler : T extends CronConfig ? never : never;
81
- export type MotiaServer = Server<any>;
81
+ export type MotiaServer = Server;
82
82
  export type MotiaSocketServer = SocketIOServer;
83
83
  export type Event<TData = unknown> = {
84
84
  type: string;
package/package.json CHANGED
@@ -1,25 +1,24 @@
1
1
  {
2
2
  "name": "@motiadev/core",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.16",
4
+ "version": "0.0.17",
5
5
  "dependencies": {
6
- "node-cron": "^3.0.3",
7
6
  "body-parser": "^1.20.3",
8
7
  "express": "^4.21.2",
9
8
  "ioredis": "^5.4.2",
9
+ "node-cron": "^3.0.3",
10
10
  "pino": "^9.6.0",
11
11
  "socket.io": "^4.8.1",
12
12
  "ts-node": "^10.9.2",
13
13
  "tsconfig-paths": "^4.2.0",
14
- "yaml": "^2.7.0",
15
14
  "zod": "^3.24.1",
16
15
  "zod-to-json-schema": "^3.24.1"
17
16
  },
18
17
  "devDependencies": {
19
- "@types/node-cron": "^3.0.11",
20
18
  "@types/body-parser": "^1.19.5",
21
19
  "@types/express": "^5.0.0",
22
20
  "@types/jest": "^29.5.14",
21
+ "@types/node-cron": "^3.0.11",
23
22
  "jest": "^29.7.0",
24
23
  "ts-jest": "^29.2.5",
25
24
  "typescript": "^5.7.2"
@@ -28,6 +27,7 @@
28
27
  "move:python": "cp src/python/*.py dist/src/python",
29
28
  "move:rb": "cp src/ruby/*.rb dist/src/ruby",
30
29
  "build": "rm -rf dist && tsc && npm run move:python && npm run move:rb",
30
+ "lint": "eslint --config ../../eslint.config.js",
31
31
  "watch": "tsc --watch",
32
32
  "test": "jest"
33
33
  }