motia 0.7.2-beta.135-685562 → 0.7.2-beta.135-014583

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.
Files changed (145) hide show
  1. package/dist/cjs/create/templates/generate.js +2 -2
  2. package/dist/cjs/create/templates/generate.ts +2 -2
  3. package/dist/cjs/create/templates/nodejs/.cursor/architecture/database/database-migration.mdc +49 -0
  4. package/dist/cjs/create/templates/nodejs/.cursor/architecture/database/database.mdc +83 -0
  5. package/dist/cjs/create/templates/nodejs/src/services/pet-store/create-order.ts.txt +15 -0
  6. package/dist/cjs/create/templates/nodejs/src/services/pet-store/create-pet.ts.txt +14 -0
  7. package/dist/cjs/create/templates/nodejs/src/services/pet-store/index.ts.txt +9 -0
  8. package/dist/{esm/create/templates/nodejs/steps → cjs/create/templates/nodejs/steps/petstore}/api.step.ts-features.json.txt +9 -9
  9. package/dist/{esm/create/templates/nodejs/steps → cjs/create/templates/nodejs/steps/petstore}/api.step.ts.txt +1 -2
  10. package/dist/{esm/create/templates/nodejs/steps → cjs/create/templates/nodejs/steps/petstore}/process-food-order.step.ts.txt +1 -1
  11. package/dist/cjs/cursor-rules/dot-files/.cursor/architecture/architecture.mdc +96 -0
  12. package/dist/cjs/cursor-rules/dot-files/.cursor/architecture/error-handling.mdc +122 -0
  13. package/dist/cjs/cursor-rules/dot-files/.cursor/index.mdc +26 -0
  14. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/api-steps.mdc +317 -0
  15. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/cron-steps.mdc +144 -0
  16. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/event-steps.mdc +157 -0
  17. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/middlewares.mdc +122 -0
  18. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/realtime-streaming.mdc +231 -0
  19. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/state-management.mdc +73 -0
  20. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/ui-steps.mdc +76 -0
  21. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/motia/virtual-steps.mdc +172 -0
  22. package/dist/esm/create/templates/generate.js +2 -2
  23. package/dist/esm/create/templates/generate.ts +2 -2
  24. package/dist/esm/create/templates/nodejs/.cursor/architecture/database/database-migration.mdc +49 -0
  25. package/dist/esm/create/templates/nodejs/.cursor/architecture/database/database.mdc +83 -0
  26. package/dist/esm/create/templates/nodejs/src/services/pet-store/create-order.ts.txt +15 -0
  27. package/dist/esm/create/templates/nodejs/src/services/pet-store/create-pet.ts.txt +14 -0
  28. package/dist/esm/create/templates/nodejs/src/services/pet-store/index.ts.txt +9 -0
  29. package/dist/{cjs/create/templates/nodejs/steps → esm/create/templates/nodejs/steps/petstore}/api.step.ts-features.json.txt +9 -9
  30. package/dist/{cjs/create/templates/nodejs/steps → esm/create/templates/nodejs/steps/petstore}/api.step.ts.txt +1 -2
  31. package/dist/{cjs/create/templates/nodejs/steps → esm/create/templates/nodejs/steps/petstore}/process-food-order.step.ts.txt +1 -1
  32. package/dist/esm/cursor-rules/dot-files/.cursor/architecture/architecture.mdc +96 -0
  33. package/dist/esm/cursor-rules/dot-files/.cursor/architecture/error-handling.mdc +122 -0
  34. package/dist/esm/cursor-rules/dot-files/.cursor/index.mdc +26 -0
  35. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/api-steps.mdc +317 -0
  36. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/cron-steps.mdc +144 -0
  37. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/event-steps.mdc +157 -0
  38. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/middlewares.mdc +122 -0
  39. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/realtime-streaming.mdc +231 -0
  40. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/state-management.mdc +73 -0
  41. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/ui-steps.mdc +76 -0
  42. package/dist/esm/cursor-rules/dot-files/.cursor/rules/motia/virtual-steps.mdc +172 -0
  43. package/package.json +4 -4
  44. package/dist/cjs/create/templates/nodejs/services/pet-store.ts.txt +0 -29
  45. package/dist/cjs/cursor-rules/dot-files/.claude/CLAUDE.md +0 -467
  46. package/dist/cjs/cursor-rules/dot-files/.claude/README.md +0 -97
  47. package/dist/cjs/cursor-rules/dot-files/.claude/agents/code-reviewer.md +0 -153
  48. package/dist/cjs/cursor-rules/dot-files/.claude/agents/debugger.md +0 -259
  49. package/dist/cjs/cursor-rules/dot-files/.claude/agents/test-runner.md +0 -268
  50. package/dist/cjs/cursor-rules/dot-files/.claude/commands/add-authentication.md +0 -491
  51. package/dist/cjs/cursor-rules/dot-files/.claude/commands/ai-ml-patterns.md +0 -748
  52. package/dist/cjs/cursor-rules/dot-files/.claude/commands/authentication.md +0 -515
  53. package/dist/cjs/cursor-rules/dot-files/.claude/commands/backend-types.md +0 -719
  54. package/dist/cjs/cursor-rules/dot-files/.claude/commands/build-api.md +0 -407
  55. package/dist/cjs/cursor-rules/dot-files/.claude/commands/claude-workflows.md +0 -1032
  56. package/dist/cjs/cursor-rules/dot-files/.claude/commands/complete-backend.md +0 -345
  57. package/dist/cjs/cursor-rules/dot-files/.claude/commands/create-api.md +0 -96
  58. package/dist/cjs/cursor-rules/dot-files/.claude/commands/data-processing.md +0 -977
  59. package/dist/cjs/cursor-rules/dot-files/.claude/commands/integrate-ai.md +0 -852
  60. package/dist/cjs/cursor-rules/dot-files/.claude/commands/javascript-patterns.md +0 -678
  61. package/dist/cjs/cursor-rules/dot-files/.claude/commands/multi-language-workflow.md +0 -756
  62. package/dist/cjs/cursor-rules/dot-files/.claude/commands/multi-language.md +0 -141
  63. package/dist/cjs/cursor-rules/dot-files/.claude/commands/process-background-jobs.md +0 -587
  64. package/dist/cjs/cursor-rules/dot-files/.claude/commands/process-events.md +0 -89
  65. package/dist/cjs/cursor-rules/dot-files/.claude/hooks/pre-commit.sh +0 -84
  66. package/dist/cjs/cursor-rules/dot-files/.claude/settings.json +0 -37
  67. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/ai-agent-patterns.mdc +0 -725
  68. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/api-design-patterns.mdc +0 -740
  69. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/api-steps.mdc +0 -230
  70. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/architecture.mdc +0 -189
  71. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/authentication-patterns.mdc +0 -620
  72. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/background-job-patterns.mdc +0 -628
  73. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/complete-application-patterns.mdc +0 -433
  74. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/complete-backend-generator.mdc +0 -415
  75. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/cron-steps.mdc +0 -257
  76. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/event-steps.mdc +0 -504
  77. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/instructions.mdc +0 -15
  78. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/multi-language-workflows.mdc +0 -1059
  79. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/noop-steps.mdc +0 -57
  80. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/production-deployment.mdc +0 -668
  81. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/realtime-streaming.mdc +0 -656
  82. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/state-management.mdc +0 -371
  83. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/steps.mdc +0 -373
  84. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/testing.mdc +0 -329
  85. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/typescript.mdc +0 -409
  86. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/ui-steps.mdc +0 -429
  87. package/dist/cjs/cursor-rules/dot-files/.cursor/rules/workflow-patterns.mdc +0 -938
  88. package/dist/cjs/cursor-rules/dot-files/AGENTS.md +0 -397
  89. package/dist/cjs/cursor-rules/dot-files/README.md +0 -58
  90. package/dist/esm/create/templates/nodejs/services/pet-store.ts.txt +0 -29
  91. package/dist/esm/cursor-rules/dot-files/.claude/CLAUDE.md +0 -467
  92. package/dist/esm/cursor-rules/dot-files/.claude/README.md +0 -97
  93. package/dist/esm/cursor-rules/dot-files/.claude/agents/code-reviewer.md +0 -153
  94. package/dist/esm/cursor-rules/dot-files/.claude/agents/debugger.md +0 -259
  95. package/dist/esm/cursor-rules/dot-files/.claude/agents/test-runner.md +0 -268
  96. package/dist/esm/cursor-rules/dot-files/.claude/commands/add-authentication.md +0 -491
  97. package/dist/esm/cursor-rules/dot-files/.claude/commands/ai-ml-patterns.md +0 -748
  98. package/dist/esm/cursor-rules/dot-files/.claude/commands/authentication.md +0 -515
  99. package/dist/esm/cursor-rules/dot-files/.claude/commands/backend-types.md +0 -719
  100. package/dist/esm/cursor-rules/dot-files/.claude/commands/build-api.md +0 -407
  101. package/dist/esm/cursor-rules/dot-files/.claude/commands/claude-workflows.md +0 -1032
  102. package/dist/esm/cursor-rules/dot-files/.claude/commands/complete-backend.md +0 -345
  103. package/dist/esm/cursor-rules/dot-files/.claude/commands/create-api.md +0 -96
  104. package/dist/esm/cursor-rules/dot-files/.claude/commands/data-processing.md +0 -977
  105. package/dist/esm/cursor-rules/dot-files/.claude/commands/integrate-ai.md +0 -852
  106. package/dist/esm/cursor-rules/dot-files/.claude/commands/javascript-patterns.md +0 -678
  107. package/dist/esm/cursor-rules/dot-files/.claude/commands/multi-language-workflow.md +0 -756
  108. package/dist/esm/cursor-rules/dot-files/.claude/commands/multi-language.md +0 -141
  109. package/dist/esm/cursor-rules/dot-files/.claude/commands/process-background-jobs.md +0 -587
  110. package/dist/esm/cursor-rules/dot-files/.claude/commands/process-events.md +0 -89
  111. package/dist/esm/cursor-rules/dot-files/.claude/hooks/pre-commit.sh +0 -84
  112. package/dist/esm/cursor-rules/dot-files/.claude/settings.json +0 -37
  113. package/dist/esm/cursor-rules/dot-files/.cursor/rules/ai-agent-patterns.mdc +0 -725
  114. package/dist/esm/cursor-rules/dot-files/.cursor/rules/api-design-patterns.mdc +0 -740
  115. package/dist/esm/cursor-rules/dot-files/.cursor/rules/api-steps.mdc +0 -230
  116. package/dist/esm/cursor-rules/dot-files/.cursor/rules/architecture.mdc +0 -189
  117. package/dist/esm/cursor-rules/dot-files/.cursor/rules/authentication-patterns.mdc +0 -620
  118. package/dist/esm/cursor-rules/dot-files/.cursor/rules/background-job-patterns.mdc +0 -628
  119. package/dist/esm/cursor-rules/dot-files/.cursor/rules/complete-application-patterns.mdc +0 -433
  120. package/dist/esm/cursor-rules/dot-files/.cursor/rules/complete-backend-generator.mdc +0 -415
  121. package/dist/esm/cursor-rules/dot-files/.cursor/rules/cron-steps.mdc +0 -257
  122. package/dist/esm/cursor-rules/dot-files/.cursor/rules/event-steps.mdc +0 -504
  123. package/dist/esm/cursor-rules/dot-files/.cursor/rules/instructions.mdc +0 -15
  124. package/dist/esm/cursor-rules/dot-files/.cursor/rules/multi-language-workflows.mdc +0 -1059
  125. package/dist/esm/cursor-rules/dot-files/.cursor/rules/noop-steps.mdc +0 -57
  126. package/dist/esm/cursor-rules/dot-files/.cursor/rules/production-deployment.mdc +0 -668
  127. package/dist/esm/cursor-rules/dot-files/.cursor/rules/realtime-streaming.mdc +0 -656
  128. package/dist/esm/cursor-rules/dot-files/.cursor/rules/state-management.mdc +0 -371
  129. package/dist/esm/cursor-rules/dot-files/.cursor/rules/steps.mdc +0 -373
  130. package/dist/esm/cursor-rules/dot-files/.cursor/rules/testing.mdc +0 -329
  131. package/dist/esm/cursor-rules/dot-files/.cursor/rules/typescript.mdc +0 -409
  132. package/dist/esm/cursor-rules/dot-files/.cursor/rules/ui-steps.mdc +0 -429
  133. package/dist/esm/cursor-rules/dot-files/.cursor/rules/workflow-patterns.mdc +0 -938
  134. package/dist/esm/cursor-rules/dot-files/AGENTS.md +0 -397
  135. package/dist/esm/cursor-rules/dot-files/README.md +0 -58
  136. /package/dist/cjs/create/templates/nodejs/{services → src/services/pet-store}/types.ts.txt +0 -0
  137. /package/dist/cjs/create/templates/nodejs/steps/{notification.step.ts.txt → petstore/notification.step.ts.txt} +0 -0
  138. /package/dist/cjs/create/templates/nodejs/steps/{process-food-order.step.ts-features.json.txt → petstore/process-food-order.step.ts-features.json.txt} +0 -0
  139. /package/dist/cjs/create/templates/nodejs/steps/{state-audit-cron.step.ts-features.json.txt → petstore/state-audit-cron.step.ts-features.json.txt} +0 -0
  140. /package/dist/cjs/create/templates/nodejs/steps/{state-audit-cron.step.ts.txt → petstore/state-audit-cron.step.ts.txt} +0 -0
  141. /package/dist/esm/create/templates/nodejs/{services → src/services/pet-store}/types.ts.txt +0 -0
  142. /package/dist/esm/create/templates/nodejs/steps/{notification.step.ts.txt → petstore/notification.step.ts.txt} +0 -0
  143. /package/dist/esm/create/templates/nodejs/steps/{process-food-order.step.ts-features.json.txt → petstore/process-food-order.step.ts-features.json.txt} +0 -0
  144. /package/dist/esm/create/templates/nodejs/steps/{state-audit-cron.step.ts-features.json.txt → petstore/state-audit-cron.step.ts-features.json.txt} +0 -0
  145. /package/dist/esm/create/templates/nodejs/steps/{state-audit-cron.step.ts.txt → petstore/state-audit-cron.step.ts.txt} +0 -0
@@ -40,7 +40,7 @@ const glob_1 = require("glob");
40
40
  const generateTemplateSteps = (templateFolder) => {
41
41
  return async (rootDir, context) => {
42
42
  const templatePath = path.join(__dirname, templateFolder);
43
- const files = (0, glob_1.globSync)('**/*', { absolute: false, cwd: templatePath });
43
+ const files = (0, glob_1.globSync)('**/*', { absolute: false, cwd: templatePath, dot: true });
44
44
  try {
45
45
  for (const fileName of files) {
46
46
  const filePath = path.join(templatePath, fileName);
@@ -54,7 +54,7 @@ const generateTemplateSteps = (templateFolder) => {
54
54
  (0, fs_1.mkdirSync)(targetDir, { recursive: true });
55
55
  }
56
56
  if ((0, fs_1.statSync)(filePath).isDirectory()) {
57
- const folderPath = path.basename(filePath);
57
+ const folderPath = filePath.replace(templatePath, '');
58
58
  (0, fs_1.mkdirSync)(path.join(rootDir, folderPath), { recursive: true });
59
59
  continue;
60
60
  }
@@ -8,7 +8,7 @@ export type Generator = (rootDir: string, context: CliContext) => Promise<void>
8
8
  export const generateTemplateSteps = (templateFolder: string): Generator => {
9
9
  return async (rootDir: string, context: CliContext): Promise<void> => {
10
10
  const templatePath = path.join(__dirname, templateFolder)
11
- const files = globSync('**/*', { absolute: false, cwd: templatePath })
11
+ const files = globSync('**/*', { absolute: false, cwd: templatePath, dot: true })
12
12
 
13
13
  try {
14
14
  for (const fileName of files) {
@@ -24,7 +24,7 @@ export const generateTemplateSteps = (templateFolder: string): Generator => {
24
24
  }
25
25
 
26
26
  if (statSync(filePath).isDirectory()) {
27
- const folderPath = path.basename(filePath)
27
+ const folderPath = filePath.replace(templatePath, '')
28
28
  mkdirSync(path.join(rootDir, folderPath), { recursive: true })
29
29
  continue
30
30
  }
@@ -0,0 +1,49 @@
1
+ ---
2
+ description: How to configure database migrations in the project
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+ # Configuring database migrations
7
+
8
+ When configuring database in the project, create a `knexfile.ts` file in the root of the project.
9
+
10
+ ```typescript
11
+ import type { Knex } from 'knex'
12
+ import * as dotenv from 'dotenv'
13
+
14
+ dotenv.config({ path: '.env' })
15
+
16
+ const config: Knex.Config = {
17
+ client: 'postgresql',
18
+ connection: {
19
+ host: process.env.DB_HOST,
20
+ port: process.env.DB_PORT,
21
+ database: process.env.DB_NAME,
22
+ user: process.env.DB_USER,
23
+ password: process.env.DB_PASS,
24
+ },
25
+ pool: {
26
+ min: 2,
27
+ max: 10,
28
+ },
29
+ migrations: {
30
+ tableName: 'knex_migrations',
31
+ },
32
+ }
33
+
34
+ export default config
35
+ ```
36
+
37
+ ## Creating a new migration
38
+
39
+ Prefix should be timestamp in milliseconds.
40
+
41
+ ```bash
42
+ npm run migrate:make 1727115600000_create_users_table
43
+ ```
44
+
45
+ ## Running migrations
46
+
47
+ ```bash
48
+ npm run migrate:latest
49
+ ```
@@ -0,0 +1,83 @@
1
+ ---
2
+ description: Database connections and queries
3
+ globs: src/repositories/**/*.ts
4
+ alwaysApply: false
5
+ ---
6
+ # Database Guide
7
+
8
+ - Prefer knex to interact with the database
9
+ - http://npmjs.com/package/knex
10
+ - Use knex migrations to manage database schema changes
11
+ - Do NOT create DB calls directly in steps or services, ALWAYS create a repository file to handle the database calls. Follow DDD principles.
12
+
13
+ ## Add commands to package.json
14
+
15
+ ```json
16
+ {
17
+ "scripts": {
18
+ "migrate:up": "knex migrate:latest",
19
+ "migrate:down": "knex migrate:rollback",
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Creating base database connection
25
+
26
+ - When SQL database is used, create a database connection file in the `src/repositories/database.ts` file.
27
+ - All columns in code are cammelCase, however, in the database and in the migration, we use snake_case.
28
+ - Avoid numeric incremental IDs, use UUIDs instead. Make sure to add foreign key with cascade delete when applicable.
29
+
30
+ ```typescript
31
+ import knex, { Knex } from 'knex'
32
+ /**
33
+ * Create these functions to convert between camelCase and snake_case.
34
+ * This is important to keep the consistency of the data.
35
+ */
36
+ import { camelToSnake, snakeToCamelObject } from '../utils/case-conversion'
37
+
38
+ const isProduction = process.env.NODE_ENV === 'production'
39
+ const isDevelopment = process.env.NODE_ENV === 'development'
40
+
41
+ // Knex configuration
42
+ const knexConfig: Knex.Config = {
43
+ client: 'pg',
44
+ connection: {
45
+ host: process.env.DB_HOST,
46
+ port: process.env.DB_PORT,
47
+ user: process.env.DB_USER,
48
+ password: process.env.DB_PASSWORD,
49
+ database: process.env.DB_NAME,
50
+ ssl: process.env.DB_SSL ? {
51
+ /** In development, we might use self-signed certs */
52
+ rejectUnauthorized: isProduction,
53
+ /** Add CA certificate if needed */
54
+ ca: undefined,
55
+ } : false,
56
+ },
57
+ pool: {
58
+ min: 2,
59
+ max: 10,
60
+ idleTimeoutMillis: 30000,
61
+ },
62
+ debug: isDevelopment,
63
+ wrapIdentifier: (value, origImpl) => origImpl(camelToSnake(value)),
64
+ postProcessResponse: result =>
65
+ Array.isArray(result)
66
+ ? result.map(row => snakeToCamelObject(row))
67
+ : snakeToCamelObject(result),
68
+ }
69
+
70
+ // Create a singleton instance
71
+ let db: Knex | null = null
72
+
73
+ /**
74
+ * Get the database instance
75
+ * @returns Knex instance
76
+ */
77
+ export const getDb = (): Knex => {
78
+ if (!db) {
79
+ db = knex(knexConfig)
80
+ }
81
+ return db
82
+ }
83
+ ```
@@ -0,0 +1,15 @@
1
+ import { Order } from './types'
2
+
3
+ export const createOrder = async (order: Omit<Order, 'id'>): Promise<Order> => {
4
+ const response = await fetch('https://petstore.swagger.io/v2/store/order', {
5
+ method: 'POST',
6
+ body: JSON.stringify({
7
+ quantity: order?.quantity ?? 1,
8
+ petId: 1,
9
+ shipDate: order?.shipDate ?? new Date().toISOString(),
10
+ status: order?.status ?? 'placed',
11
+ }),
12
+ headers: { 'Content-Type': 'application/json' },
13
+ })
14
+ return response.json()
15
+ }
@@ -0,0 +1,14 @@
1
+ import { Pet } from './types'
2
+
3
+ export const createPet = async (pet: Omit<Pet, 'id'>): Promise<Pet> => {
4
+ const response = await fetch('https://petstore.swagger.io/v2/pet', {
5
+ method: 'POST',
6
+ body: JSON.stringify({
7
+ name: pet?.name ?? '',
8
+ photoUrls: [pet?.photoUrl ?? ''],
9
+ status: 'available',
10
+ }),
11
+ headers: { 'Content-Type': 'application/json' },
12
+ })
13
+ return response.json()
14
+ }
@@ -0,0 +1,9 @@
1
+ import { createPet } from './create-pet'
2
+ import { createOrder } from './create-order'
3
+
4
+ export * from './types'
5
+
6
+ export const petStoreService = {
7
+ createPet,
8
+ createOrder,
9
+ }
@@ -4,7 +4,7 @@
4
4
  "title": "Step Configuration",
5
5
  "description": "All steps should have a defined configuration, this is how you define the step's behavior and how it will be triggered.",
6
6
  "lines": [
7
- "6-30"
7
+ "5-29"
8
8
  ]
9
9
  },
10
10
  {
@@ -12,7 +12,7 @@
12
12
  "title": "API Step",
13
13
  "description": "Definition of an API endpoint",
14
14
  "lines": [
15
- "12-13"
15
+ "11-12"
16
16
  ]
17
17
  },
18
18
  {
@@ -20,7 +20,7 @@
20
20
  "title": "Request body",
21
21
  "description": "Definition of the expected request body. Motia will automatically generate types based on this schema.",
22
22
  "lines": [
23
- "14-25"
23
+ "13-24"
24
24
  ]
25
25
  },
26
26
  {
@@ -28,7 +28,7 @@
28
28
  "title": "Response Payload",
29
29
  "description": "Definition of the expected response payload, Motia will generate the types automatically based on this schema. This is also important to create the Open API spec later.",
30
30
  "lines": [
31
- "26-28"
31
+ "25-27"
32
32
  ]
33
33
  },
34
34
  {
@@ -36,8 +36,8 @@
36
36
  "title": "Emits",
37
37
  "description": "We can define the events that this step will emit, this is how we can trigger other Motia Steps.",
38
38
  "lines": [
39
- "29",
40
- "39-46"
39
+ "28",
40
+ "38-45"
41
41
  ]
42
42
  },
43
43
  {
@@ -45,7 +45,7 @@
45
45
  "title": "Handler",
46
46
  "description": "The handler is the function that will be executed when the step is triggered. This one receives the request body and emits events.",
47
47
  "lines": [
48
- "32-50"
48
+ "31-49"
49
49
  ]
50
50
  },
51
51
  {
@@ -53,7 +53,7 @@
53
53
  "title": "Logger",
54
54
  "description": "The logger is a utility that allows you to log messages to the console. It is available in the handler function. We encourage you to use it instead of console.log. It will automatically be tied to the trace id of the request.",
55
55
  "lines": [
56
- "33"
56
+ "32"
57
57
  ]
58
58
  },
59
59
  {
@@ -61,7 +61,7 @@
61
61
  "title": "HTTP Response",
62
62
  "description": "The handler can return a response to the client. This is how we can return a response to the client. It must comply with the responseSchema defined in the step configuration.",
63
63
  "lines": [
64
- "49"
64
+ "48"
65
65
  ]
66
66
  }
67
67
  ]
@@ -1,7 +1,6 @@
1
1
  import { ApiRouteConfig, Handlers } from 'motia'
2
2
  import { z } from 'zod'
3
- import { petStoreService } from '../services/pet-store'
4
- import { petSchema } from '../services/types'
3
+ import { petStoreService, petSchema } from '../../src/services/pet-store'
5
4
 
6
5
  export const config: ApiRouteConfig = {
7
6
  type: 'api',
@@ -1,6 +1,6 @@
1
1
  import { EventConfig, Handlers } from 'motia'
2
2
  import { z } from 'zod'
3
- import { petStoreService } from '../services/pet-store'
3
+ import { petStoreService } from '../../src/services/pet-store'
4
4
 
5
5
  export const config: EventConfig = {
6
6
  type: 'event',
@@ -0,0 +1,96 @@
1
+ ---
2
+ description: How to structure your Motia project
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Architecture Guide
8
+
9
+ ## Overview
10
+
11
+ This guide covers the architecture of a Motia project.
12
+
13
+ ## File Structure
14
+
15
+ All step files should be underneath the `steps/` folder.
16
+
17
+ Underneath the `steps/` folder, create subfolders for Flows. Flows are used to group steps together.
18
+
19
+ ## Step Naming Conventions
20
+
21
+ ### Typescript
22
+
23
+ - Use kebab-case for filenames: `resource-processing.step.ts`
24
+ - Include `.step` before language extension
25
+
26
+ ### Python
27
+
28
+ - Use snake_case for filenames: `data_processor_step.py`
29
+ - Include `_step` before language extension
30
+
31
+ ### Global
32
+
33
+ - Match handler names to config names
34
+ - Use descriptive, action-oriented names
35
+
36
+ ## Code Style Guidelines
37
+
38
+ - **JavaScript**: Use modern ES6+ features, async/await, proper error handling
39
+ - **TypeScript**: Make sure you use the correct Handlers type that is auto generated on the `types.d.ts` file.
40
+
41
+ ## Defining Middlewares
42
+
43
+ Middleware is a powerful feature in Motia to help adding common validation, error
44
+ handling and other common logic to your steps.
45
+
46
+ - Make sure to add all the middlewares in a single folder, called `middlewares/`.
47
+ - Create a comprehensive file name for the middleware, like `auth.middleware.ts`.
48
+ - Follow SOLID principles with separation of concerns in middlewares, create a middleware for each responsibility.
49
+ - Use core middleware to handle ZodError gracefully (see [Error Handling Guide](./error-handling.mdc))
50
+ - Rate limiting and CORS are not needed to be handled in middleware since they're an infrastructure concern.
51
+
52
+ ## Domain Driven Design
53
+
54
+ Make sure you follow Domain Driven Design principles in your project.
55
+
56
+ - Create `/src/services` folder to store your services, this is where it holds business logic.
57
+ - Create `/src/repositories` folder to store your repositories, this is where it holds data access logic.
58
+ - Create `/src/utils` folder to store your utility functions.
59
+ - Models and DTOs are not quite necessary, we can rely on zod to create the models and DTOs from the steps.
60
+ - Controller layer is the Steps, it should have mostly logic around validation and calling services.
61
+ - Avoid having Service methods with just a call to the Repository, it should have some logic around it, if it doesn't have, then Steps can have access to repositories directly.
62
+
63
+ ### Services
64
+
65
+ Defining services can be done in the following way:
66
+
67
+ - Create a folder underneath `/src/services/` folder, like `/src/services/auth/`.
68
+ - Create a file inside the folder called `index.ts`.
69
+ - Inside `index.ts`, export a constant with the name of the service, with the methods as properties.
70
+ - Methods should be defined as separate files, use export named functions.
71
+ - Use the service in the Steps.
72
+
73
+ #### Example
74
+
75
+ ```typescript
76
+ /**
77
+ * Business logic for authentication defined in a separate file in the same folder.
78
+ */
79
+ import { login } from './login'
80
+
81
+ /**
82
+ * Constant with the name of the service, with the methods as properties.
83
+ */
84
+ export const authService = {
85
+ login
86
+ }
87
+ ```
88
+
89
+ ## Logging and observability
90
+
91
+ - Make sure to use the Logger from Motia (from context object) to log messages.
92
+ - Make sure to have visibility of what is going on in a request
93
+ - Before throwing errors, make sure to log the issue, identify if issue is a validation blocker, then log with `logger.warn`, if it's something that is not supposed to happen, then log with `logger.error`.
94
+ - Make sure to add context to the logs to help identify any potential issues.
95
+
96
+
@@ -0,0 +1,122 @@
1
+ ---
2
+ description: How to handle errors in a Motia project
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Error Handling Guide
8
+
9
+ Errors happen, but we need to handle them gracefully. Make sure you create a custom error class for your project, underneath `/src/errors/` folder.
10
+
11
+ ## Good practices
12
+
13
+ - Use Custom error to return errors to the client.
14
+ - Anything that is not the error class, should be logged with `logger.error`. And root cause should be omitted to the client.
15
+
16
+ ## Create a custom Error class
17
+
18
+ Name: `/src/errors/base.error.ts`
19
+
20
+ ```typescript
21
+ export class BaseError extends Error {
22
+ public readonly status: number
23
+ public readonly code: string
24
+ public readonly metadata: Record<string, any>
25
+
26
+ constructor(
27
+ message: string,
28
+ status: number = 500,
29
+ code: string = 'INTERNAL_SERVER_ERROR',
30
+ metadata: Record<string, any> = {}
31
+ ) {
32
+ super(message)
33
+ this.name = this.constructor.name
34
+ this.status = status
35
+ this.code = code
36
+ this.metadata = metadata
37
+
38
+ // Maintains proper stack trace for where our error was thrown
39
+ Error.captureStackTrace(this, this.constructor)
40
+ }
41
+
42
+ toJSON() {
43
+ return {
44
+ error: {
45
+ name: this.name,
46
+ message: this.message,
47
+ code: this.code,
48
+ status: this.status,
49
+ ...(Object.keys(this.metadata).length > 0 && { metadata: this.metadata }),
50
+ },
51
+ }
52
+ }
53
+ }
54
+ ```
55
+
56
+ Then create sub class for specific errors that are commonly thrown in your project.
57
+
58
+ Name: `/src/errors/not-found.error.ts`
59
+
60
+ ```typescript
61
+ import { BaseError } from './base.error'
62
+
63
+ export class NotFoundError extends BaseError {
64
+ constructor(message: string = 'Not Found', metadata: Record<string, any> = {}) {
65
+ super(message, 404, 'NOT_FOUND', metadata)
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## Core Middleware
71
+
72
+ Make sure you create a core middleware that will be added to ALL API Steps.
73
+
74
+ File: `/src/middlewares/core.middleware.ts`
75
+
76
+ ```typescript
77
+ import { ApiMiddleware } from 'motia'
78
+ import { ZodError } from 'zod'
79
+ import { BaseError } from '../errors/base.error'
80
+
81
+ export const coreMiddleware: ApiMiddleware = async (req, ctx, next) => {
82
+ const logger = ctx.logger
83
+
84
+ try {
85
+ return await next()
86
+ } catch (error: any) {
87
+ if (error instanceof ZodError) {
88
+ logger.error('Validation error', {
89
+ error,
90
+ stack: error.stack,
91
+ errors: error.errors,
92
+ })
93
+
94
+ return {
95
+ status: 400,
96
+ body: {
97
+ error: 'Invalid request body',
98
+ data: error.errors,
99
+ },
100
+ }
101
+ } else if (error instanceof BaseError) {
102
+ logger.error('BaseError', {
103
+ status: error.status,
104
+ code: error.code,
105
+ metadata: error.metadata,
106
+ name: error.name,
107
+ message: error.message,
108
+ })
109
+
110
+ return { status: error.status, body: error.toJSON() }
111
+ }
112
+
113
+ logger.error('Error while performing request', {
114
+ error,
115
+ body: req.body,
116
+ stack: error.stack,
117
+ })
118
+
119
+ return { status: 500, body: { error: 'Internal Server Error' } }
120
+ }
121
+ }
122
+ ```
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Rules for the project
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ ## Adding migration
8
+
9
+ Make sure to use [migration guide](./architecture/database/database-migration.mdc) to create a new migration.
10
+
11
+ ## Database integration
12
+
13
+ Whenever database is used, please use [database guide](./architecture/database/database.mdc) to create a database connection and methods.
14
+
15
+ ## Real time events
16
+
17
+ Make sure to use [real time events guide](./rules/motia/realtime-streaming.mdc) to create a new real time event.
18
+
19
+ ## State/Cache management
20
+
21
+ Make sure to use [state management guide](./rules/motia/state-management.mdc) to create a new state management.
22
+
23
+ ## Authentication
24
+
25
+ If ever need to add authentication, make sure to use middleware to authenticate the request.
26
+ Make sure to use [middlewares](./rules/motia/middlewares.mdc) to validate the requests.