motia 0.5.11-beta.119 → 0.5.12-beta.121

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 (70) hide show
  1. package/dist/cjs/cli.js +0 -21
  2. package/dist/cjs/create/index.d.ts +0 -1
  3. package/dist/cjs/create/index.js +27 -21
  4. package/dist/cjs/create/templates/generate.d.ts +1 -1
  5. package/dist/cjs/create/templates/generate.js +5 -23
  6. package/dist/cjs/create/templates/generate.ts +6 -31
  7. package/dist/cjs/create/templates/index.js +0 -1
  8. package/dist/cjs/create/templates/index.ts +0 -1
  9. package/dist/cjs/docker/utils/print-intro.js +1 -0
  10. package/dist/esm/cli.js +0 -18
  11. package/dist/esm/create/index.d.ts +0 -1
  12. package/dist/esm/create/index.js +17 -11
  13. package/dist/esm/create/templates/generate.d.ts +1 -1
  14. package/dist/esm/create/templates/generate.js +6 -24
  15. package/dist/esm/create/templates/generate.ts +6 -31
  16. package/dist/esm/create/templates/index.js +0 -1
  17. package/dist/esm/create/templates/index.ts +0 -1
  18. package/dist/esm/docker/utils/print-intro.js +1 -0
  19. package/dist/types/create/index.d.ts +0 -1
  20. package/dist/types/create/templates/generate.d.ts +1 -1
  21. package/package.json +4 -4
  22. package/dist/cjs/create/setup-template.d.ts +0 -2
  23. package/dist/cjs/create/setup-template.js +0 -13
  24. package/dist/cjs/create/setup-tutorial-flow.d.ts +0 -6
  25. package/dist/cjs/create/setup-tutorial-flow.js +0 -30
  26. package/dist/cjs/create/templates/basic-tutorial/00-noop.step.ts.txt +0 -30
  27. package/dist/cjs/create/templates/basic-tutorial/01-api.step.ts.txt +0 -90
  28. package/dist/cjs/create/templates/basic-tutorial/02-process-food-order.step.ts.txt +0 -54
  29. package/dist/cjs/create/templates/basic-tutorial/03-state-audit-cron.step.ts.txt +0 -42
  30. package/dist/cjs/create/templates/basic-tutorial/04_new_order_notifications.step.py.txt +0 -22
  31. package/dist/cjs/create/templates/basic-tutorial/motia-workbench.json +0 -27
  32. package/dist/cjs/create/templates/basic-tutorial/services/pet-store.ts.txt +0 -32
  33. package/dist/cjs/create/utils.d.ts +0 -2
  34. package/dist/cjs/create/utils.js +0 -21
  35. package/dist/esm/create/setup-template.d.ts +0 -2
  36. package/dist/esm/create/setup-template.js +0 -9
  37. package/dist/esm/create/setup-tutorial-flow.d.ts +0 -6
  38. package/dist/esm/create/setup-tutorial-flow.js +0 -23
  39. package/dist/esm/create/templates/basic-tutorial/00-noop.step.ts.txt +0 -30
  40. package/dist/esm/create/templates/basic-tutorial/01-api.step.ts.txt +0 -90
  41. package/dist/esm/create/templates/basic-tutorial/02-process-food-order.step.ts.txt +0 -54
  42. package/dist/esm/create/templates/basic-tutorial/03-state-audit-cron.step.ts.txt +0 -42
  43. package/dist/esm/create/templates/basic-tutorial/04_new_order_notifications.step.py.txt +0 -22
  44. package/dist/esm/create/templates/basic-tutorial/motia-workbench.json +0 -27
  45. package/dist/esm/create/templates/basic-tutorial/services/pet-store.ts.txt +0 -32
  46. package/dist/esm/create/utils.d.ts +0 -2
  47. package/dist/esm/create/utils.js +0 -13
  48. package/dist/types/create/setup-template.d.ts +0 -2
  49. package/dist/types/create/setup-tutorial-flow.d.ts +0 -6
  50. package/dist/types/create/utils.d.ts +0 -2
  51. /package/dist/cjs/create/templates/default/{00-noop.step.ts.txt → steps/00-noop.step.ts.txt} +0 -0
  52. /package/dist/cjs/create/templates/default/{00-noop.step.tsx.txt → steps/00-noop.step.tsx.txt} +0 -0
  53. /package/dist/cjs/create/templates/default/{01-api.step.ts.txt → steps/01-api.step.ts.txt} +0 -0
  54. /package/dist/cjs/create/templates/default/{02-test-state.step.ts.txt → steps/02-test-state.step.ts.txt} +0 -0
  55. /package/dist/cjs/create/templates/default/{03-check-state-change.step.ts.txt → steps/03-check-state-change.step.ts.txt} +0 -0
  56. /package/dist/cjs/create/templates/python/{00_noop_step.py.txt → steps/00_noop_step.py.txt} +0 -0
  57. /package/dist/cjs/create/templates/python/{00_noop_step.tsx.txt → steps/00_noop_step.tsx.txt} +0 -0
  58. /package/dist/cjs/create/templates/python/{01_api_step.py.txt → steps/01_api_step.py.txt} +0 -0
  59. /package/dist/cjs/create/templates/python/{02_test_state_step.py.txt → steps/02_test_state_step.py.txt} +0 -0
  60. /package/dist/cjs/create/templates/python/{03_check_state_change_step.py.txt → steps/03_check_state_change_step.py.txt} +0 -0
  61. /package/dist/esm/create/templates/default/{00-noop.step.ts.txt → steps/00-noop.step.ts.txt} +0 -0
  62. /package/dist/esm/create/templates/default/{00-noop.step.tsx.txt → steps/00-noop.step.tsx.txt} +0 -0
  63. /package/dist/esm/create/templates/default/{01-api.step.ts.txt → steps/01-api.step.ts.txt} +0 -0
  64. /package/dist/esm/create/templates/default/{02-test-state.step.ts.txt → steps/02-test-state.step.ts.txt} +0 -0
  65. /package/dist/esm/create/templates/default/{03-check-state-change.step.ts.txt → steps/03-check-state-change.step.ts.txt} +0 -0
  66. /package/dist/esm/create/templates/python/{00_noop_step.py.txt → steps/00_noop_step.py.txt} +0 -0
  67. /package/dist/esm/create/templates/python/{00_noop_step.tsx.txt → steps/00_noop_step.tsx.txt} +0 -0
  68. /package/dist/esm/create/templates/python/{01_api_step.py.txt → steps/01_api_step.py.txt} +0 -0
  69. /package/dist/esm/create/templates/python/{02_test_state_step.py.txt → steps/02_test_state_step.py.txt} +0 -0
  70. /package/dist/esm/create/templates/python/{03_check_state_change_step.py.txt → steps/03_check_state_change_step.py.txt} +0 -0
package/dist/cjs/cli.js CHANGED
@@ -1,15 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
4
  /* eslint-disable @typescript-eslint/no-require-imports */
8
5
  const commander_1 = require("commander");
9
6
  require("./cloud");
10
7
  const version_1 = require("./version");
11
8
  const config_utils_1 = require("./cloud/config-utils");
12
- const inquirer_1 = __importDefault(require("inquirer"));
13
9
  const defaultPort = 3000;
14
10
  const defaultHost = '0.0.0.0';
15
11
  require('dotenv/config');
@@ -32,23 +28,14 @@ commander_1.program
32
28
  .option('-c, --cursor', 'Copy .cursor folder from template')
33
29
  .option('-i, --interactive', 'Use interactive prompts to create project')
34
30
  .option('-y, --skip-confirmation', 'Skip confirmation prompt')
35
- .option('-d, --skip-tutorial', 'Skip the motia tutorial', false)
36
31
  .action((0, config_utils_1.handler)(async (arg, context) => {
37
32
  if (arg.name || arg.template || arg.cursor) {
38
33
  const { create } = require('./create');
39
- const disableTutorial = await inquirer_1.default.prompt({
40
- type: 'confirm',
41
- name: 'disableTutorial',
42
- message: 'Do you wish to disable the motia tutorial?',
43
- default: arg.skipTutorial,
44
- when: () => arg.skipTutorial === false,
45
- });
46
34
  await create({
47
35
  projectName: arg.name ?? '.',
48
36
  template: arg.template ?? 'default',
49
37
  cursorEnabled: arg.cursor,
50
38
  context,
51
- skipTutorialTemplates: disableTutorial.disableTutorial,
52
39
  });
53
40
  }
54
41
  else {
@@ -156,14 +143,6 @@ generate
156
143
  stepFilePath: arg.dir,
157
144
  });
158
145
  });
159
- generate
160
- .command('tutorial-flow')
161
- .description('Download the tutorial flow into an existing motia project')
162
- .action((0, config_utils_1.handler)(async (_, context) => {
163
- const { createTutorialFlow } = require('./create/setup-tutorial-flow');
164
- await createTutorialFlow({ context });
165
- process.exit(0);
166
- }));
167
146
  const docker = commander_1.program.command('docker').description('Motia docker commands');
168
147
  docker
169
148
  .command('setup')
@@ -4,7 +4,6 @@ type Args = {
4
4
  template?: string;
5
5
  cursorEnabled?: boolean;
6
6
  context: CliContext;
7
- skipTutorialTemplates?: boolean;
8
7
  };
9
8
  export declare const create: ({ projectName, template, cursorEnabled, context }: Args) => Promise<void>;
10
9
  export {};
@@ -6,25 +6,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.create = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
+ const templates_1 = require("./templates");
9
10
  const execute_command_1 = require("../utils/execute-command");
10
11
  const install_1 = require("../install");
11
12
  const generate_types_1 = require("../generate-types");
12
13
  const version_1 = require("../version");
13
- const setup_template_1 = require("./setup-template");
14
- const utils_1 = require("./utils");
15
14
  // eslint-disable-next-line @typescript-eslint/no-require-imports
16
15
  require('ts-node').register({
17
16
  transpileOnly: true,
18
17
  compilerOptions: { module: 'commonjs' },
19
18
  });
19
+ const checkIfFileExists = (dir, fileName) => {
20
+ return fs_1.default.existsSync(path_1.default.join(dir, fileName));
21
+ };
22
+ const checkIfDirectoryExists = (dir) => {
23
+ try {
24
+ return fs_1.default.statSync(dir).isDirectory();
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ };
20
30
  const getPackageManager = (dir) => {
21
- if ((0, utils_1.checkIfFileExists)(dir, 'yarn.lock')) {
31
+ if (checkIfFileExists(dir, 'yarn.lock')) {
22
32
  return 'yarn';
23
33
  }
24
- else if ((0, utils_1.checkIfFileExists)(dir, 'pnpm-lock.yaml')) {
34
+ else if (checkIfFileExists(dir, 'pnpm-lock.yaml')) {
25
35
  return 'pnpm';
26
36
  }
27
- else if ((0, utils_1.checkIfFileExists)(dir, 'package-lock.json')) {
37
+ else if (checkIfFileExists(dir, 'package-lock.json')) {
28
38
  return 'npm';
29
39
  }
30
40
  else {
@@ -87,14 +97,14 @@ const create = async ({ projectName, template, cursorEnabled, context }) => {
87
97
  '\n\n');
88
98
  const isCurrentDir = projectName === '.' || projectName === './' || projectName === '.\\';
89
99
  const rootDir = isCurrentDir ? process.cwd() : path_1.default.join(process.cwd(), projectName);
90
- if (!isCurrentDir && !(0, utils_1.checkIfDirectoryExists)(rootDir)) {
100
+ if (!isCurrentDir && !checkIfDirectoryExists(rootDir)) {
91
101
  fs_1.default.mkdirSync(path_1.default.join(rootDir));
92
102
  context.log('directory-created', (message) => message.tag('success').append('Directory created ').append(projectName, 'gray'));
93
103
  }
94
104
  else {
95
105
  context.log('directory-using', (message) => message.tag('info').append('Using current directory'));
96
106
  }
97
- if (!(0, utils_1.checkIfFileExists)(rootDir, 'package.json')) {
107
+ if (!checkIfFileExists(rootDir, 'package.json')) {
98
108
  const packageJsonContent = {
99
109
  name: projectName,
100
110
  description: '',
@@ -134,7 +144,7 @@ const create = async ({ projectName, template, cursorEnabled, context }) => {
134
144
  .append('command to')
135
145
  .append('package.json', 'gray'));
136
146
  }
137
- if (!(0, utils_1.checkIfFileExists)(rootDir, 'tsconfig.json')) {
147
+ if (!checkIfFileExists(rootDir, 'tsconfig.json')) {
138
148
  const tsconfigContent = {
139
149
  compilerOptions: {
140
150
  target: 'ES2020',
@@ -157,7 +167,7 @@ const create = async ({ projectName, template, cursorEnabled, context }) => {
157
167
  fs_1.default.writeFileSync(path_1.default.join(rootDir, 'tsconfig.json'), JSON.stringify(tsconfigContent, null, 2));
158
168
  context.log('tsconfig-json-created', (message) => message.tag('success').append('File').append('tsconfig.json', 'cyan').append('has been created.'));
159
169
  }
160
- if (!(0, utils_1.checkIfFileExists)(rootDir, '.gitignore')) {
170
+ if (!checkIfFileExists(rootDir, '.gitignore')) {
161
171
  const gitignoreContent = [
162
172
  'node_modules',
163
173
  'python_modules',
@@ -173,28 +183,24 @@ const create = async ({ projectName, template, cursorEnabled, context }) => {
173
183
  }
174
184
  const cursorTemplateDir = path_1.default.join(__dirname, '../../dot-files/.cursor');
175
185
  const cursorTargetDir = path_1.default.join(rootDir, '.cursor');
176
- if (cursorEnabled && !(0, utils_1.checkIfDirectoryExists)(cursorTargetDir)) {
186
+ if (cursorEnabled && !checkIfDirectoryExists(cursorTargetDir)) {
177
187
  fs_1.default.cpSync(cursorTemplateDir, cursorTargetDir, { recursive: true });
178
188
  context.log('cursor-folder-created', (message) => message.tag('success').append('Folder').append('.cursor', 'cyan').append('has been created.'));
179
189
  }
180
190
  const stepsDir = path_1.default.join(rootDir, 'steps');
181
- if (!(0, utils_1.checkIfDirectoryExists)(stepsDir)) {
191
+ if (!checkIfDirectoryExists(stepsDir)) {
182
192
  fs_1.default.mkdirSync(stepsDir);
183
193
  context.log('steps-directory-created', (message) => message.tag('success').append('Folder').append('steps', 'cyan').append('has been created.'));
184
194
  }
185
- if (!(0, utils_1.checkIfDirectoryExists)(path_1.default.join(stepsDir, 'basic-tutorial'))) {
186
- fs_1.default.mkdirSync(path_1.default.join(stepsDir, 'basic-tutorial'));
187
- }
188
- await (0, setup_template_1.setupTemplate)('basic-tutorial', stepsDir, context);
189
- if (template) {
190
- if (!(0, utils_1.checkIfDirectoryExists)(path_1.default.join(stepsDir, template))) {
191
- fs_1.default.mkdirSync(path_1.default.join(stepsDir, template));
192
- }
193
- await (0, setup_template_1.setupTemplate)(template, stepsDir, context);
195
+ if (!template || !(template in templates_1.templates)) {
196
+ context.log('template-not-found', (message) => message.tag('failed').append(`Template ${template} not found, please use one of the following:`));
197
+ context.log('available-templates', (message) => message.tag('info').append(`Available templates: \n\n ${Object.keys(templates_1.templates).join('\n')}`));
198
+ return;
194
199
  }
200
+ await templates_1.templates[template](rootDir, context);
195
201
  const packageManager = await installNodeDependencies(rootDir, context);
196
202
  if (template === 'python') {
197
- if (!(0, utils_1.checkIfFileExists)(rootDir, 'requirements.txt')) {
203
+ if (!checkIfFileExists(rootDir, 'requirements.txt')) {
198
204
  const requirementsContent = [
199
205
  // TODO: motia PyPi package
200
206
  // Add other Python dependencies as needed
@@ -1,3 +1,3 @@
1
1
  import { CliContext } from '../../cloud/config-utils';
2
2
  export type Generator = (rootDir: string, context: CliContext) => Promise<void>;
3
- export declare const generateTemplateSteps: (templateFolder: string) => Generator;
3
+ export declare const generateTemplateSteps: (templateDir: string) => Generator;
@@ -37,38 +37,20 @@ exports.generateTemplateSteps = void 0;
37
37
  const fs_1 = require("fs");
38
38
  const path = __importStar(require("path"));
39
39
  const glob_1 = require("glob");
40
- const generateTemplateSteps = (templateFolder) => {
40
+ const generateTemplateSteps = (templateDir) => {
41
41
  return async (rootDir, context) => {
42
- const templatePath = path.join(__dirname, templateFolder);
42
+ const templatePath = path.join(__dirname, templateDir);
43
43
  const files = (0, glob_1.globSync)('**/*', { absolute: false, cwd: templatePath });
44
44
  try {
45
45
  for (const fileName of files) {
46
46
  const filePath = path.join(templatePath, fileName);
47
- if ((0, fs_1.statSync)(filePath).isDirectory() && !filePath.match(/services|utils|lib/)) {
48
- // ignore folders
49
- continue;
50
- }
51
47
  if ((0, fs_1.statSync)(filePath).isDirectory()) {
52
- const folderPath = path.basename(filePath);
53
- (0, fs_1.mkdirSync)(path.join(rootDir, templateFolder, folderPath));
48
+ // ignore folders
54
49
  continue;
55
50
  }
56
51
  const sanitizedFileName = fileName.replace('.txt', '');
57
- const isWorkbenchConfig = fileName.match('motia-workbench.json');
58
- const generateFilePath = path.join(...(isWorkbenchConfig ? [rootDir, sanitizedFileName] : [rootDir, templateFolder, sanitizedFileName]));
59
- let content = await fs_1.promises.readFile(filePath, 'utf8');
60
- // Make sure statSync doesn't break the execution if the file doesn't exist
61
- try {
62
- if (isWorkbenchConfig && (0, fs_1.statSync)(generateFilePath).isFile()) {
63
- const existingWorkbenchConfig = await fs_1.promises.readFile(generateFilePath, 'utf8');
64
- const workbenchContent = JSON.parse(content);
65
- content = JSON.stringify([...JSON.parse(existingWorkbenchConfig), ...workbenchContent], null, 2);
66
- context.log('workbench-config-updated', (message) => message.tag('success').append('Workbench config').append('has been updated.'));
67
- }
68
- }
69
- catch {
70
- void 0;
71
- }
52
+ const generateFilePath = path.join(rootDir, sanitizedFileName);
53
+ const content = await fs_1.promises.readFile(filePath, 'utf8');
72
54
  await fs_1.promises.writeFile(generateFilePath, content, 'utf8');
73
55
  context.log(sanitizedFileName, (message) => {
74
56
  message.tag('success').append('File').append(sanitizedFileName, 'cyan').append('has been created.');
@@ -1,52 +1,27 @@
1
- import { promises as fs, statSync, mkdirSync } from 'fs'
1
+ import { promises as fs, statSync } from 'fs'
2
2
  import * as path from 'path'
3
3
  import { globSync } from 'glob'
4
4
  import { CliContext } from '../../cloud/config-utils'
5
5
 
6
6
  export type Generator = (rootDir: string, context: CliContext) => Promise<void>
7
7
 
8
- export const generateTemplateSteps = (templateFolder: string): Generator => {
8
+ export const generateTemplateSteps = (templateDir: string): Generator => {
9
9
  return async (rootDir: string, context: CliContext): Promise<void> => {
10
- const templatePath = path.join(__dirname, templateFolder)
10
+ const templatePath = path.join(__dirname, templateDir)
11
11
  const files = globSync('**/*', { absolute: false, cwd: templatePath })
12
12
 
13
13
  try {
14
14
  for (const fileName of files) {
15
15
  const filePath = path.join(templatePath, fileName)
16
16
 
17
- if (statSync(filePath).isDirectory() && !filePath.match(/services|utils|lib/)) {
18
- // ignore folders
19
- continue
20
- }
21
-
22
17
  if (statSync(filePath).isDirectory()) {
23
- const folderPath = path.basename(filePath)
24
- mkdirSync(path.join(rootDir, templateFolder, folderPath))
18
+ // ignore folders
25
19
  continue
26
20
  }
27
21
 
28
22
  const sanitizedFileName = fileName.replace('.txt', '')
29
- const isWorkbenchConfig = fileName.match('motia-workbench.json')
30
- const generateFilePath = path.join(
31
- ...(isWorkbenchConfig ? [rootDir, sanitizedFileName] : [rootDir, templateFolder, sanitizedFileName]),
32
- )
33
- let content = await fs.readFile(filePath, 'utf8')
34
-
35
- // Make sure statSync doesn't break the execution if the file doesn't exist
36
- try {
37
- if (isWorkbenchConfig && statSync(generateFilePath).isFile()) {
38
- const existingWorkbenchConfig = await fs.readFile(generateFilePath, 'utf8')
39
- const workbenchContent = JSON.parse(content)
40
-
41
- content = JSON.stringify([...JSON.parse(existingWorkbenchConfig), ...workbenchContent], null, 2)
42
-
43
- context.log('workbench-config-updated', (message) =>
44
- message.tag('success').append('Workbench config').append('has been updated.'),
45
- )
46
- }
47
- } catch {
48
- void 0
49
- }
23
+ const generateFilePath = path.join(rootDir, sanitizedFileName)
24
+ const content = await fs.readFile(filePath, 'utf8')
50
25
 
51
26
  await fs.writeFile(generateFilePath, content, 'utf8')
52
27
  context.log(sanitizedFileName, (message) => {
@@ -5,5 +5,4 @@ const generate_1 = require("./generate");
5
5
  exports.templates = {
6
6
  default: (0, generate_1.generateTemplateSteps)('default'),
7
7
  python: (0, generate_1.generateTemplateSteps)('python'),
8
- 'basic-tutorial': (0, generate_1.generateTemplateSteps)('basic-tutorial'),
9
8
  };
@@ -3,5 +3,4 @@ import { generateTemplateSteps, Generator } from './generate'
3
3
  export const templates: Record<string, Generator> = {
4
4
  default: generateTemplateSteps('default'),
5
5
  python: generateTemplateSteps('python'),
6
- 'basic-tutorial': generateTemplateSteps('basic-tutorial'),
7
6
  }
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable no-useless-escape */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.printMotiaDockerIntro = void 0;
4
5
  const printMotiaDockerIntro = () => {
package/dist/esm/cli.js CHANGED
@@ -4,7 +4,6 @@ import { program } from 'commander';
4
4
  import './cloud';
5
5
  import { version } from './version';
6
6
  import { handler } from './cloud/config-utils';
7
- import inquirer from 'inquirer';
8
7
  const defaultPort = 3000;
9
8
  const defaultHost = '0.0.0.0';
10
9
  require('dotenv/config');
@@ -27,23 +26,14 @@ program
27
26
  .option('-c, --cursor', 'Copy .cursor folder from template')
28
27
  .option('-i, --interactive', 'Use interactive prompts to create project')
29
28
  .option('-y, --skip-confirmation', 'Skip confirmation prompt')
30
- .option('-d, --skip-tutorial', 'Skip the motia tutorial', false)
31
29
  .action(handler(async (arg, context) => {
32
30
  if (arg.name || arg.template || arg.cursor) {
33
31
  const { create } = require('./create');
34
- const disableTutorial = await inquirer.prompt({
35
- type: 'confirm',
36
- name: 'disableTutorial',
37
- message: 'Do you wish to disable the motia tutorial?',
38
- default: arg.skipTutorial,
39
- when: () => arg.skipTutorial === false,
40
- });
41
32
  await create({
42
33
  projectName: arg.name ?? '.',
43
34
  template: arg.template ?? 'default',
44
35
  cursorEnabled: arg.cursor,
45
36
  context,
46
- skipTutorialTemplates: disableTutorial.disableTutorial,
47
37
  });
48
38
  }
49
39
  else {
@@ -151,14 +141,6 @@ generate
151
141
  stepFilePath: arg.dir,
152
142
  });
153
143
  });
154
- generate
155
- .command('tutorial-flow')
156
- .description('Download the tutorial flow into an existing motia project')
157
- .action(handler(async (_, context) => {
158
- const { createTutorialFlow } = require('./create/setup-tutorial-flow');
159
- await createTutorialFlow({ context });
160
- process.exit(0);
161
- }));
162
144
  const docker = program.command('docker').description('Motia docker commands');
163
145
  docker
164
146
  .command('setup')
@@ -4,7 +4,6 @@ type Args = {
4
4
  template?: string;
5
5
  cursorEnabled?: boolean;
6
6
  context: CliContext;
7
- skipTutorialTemplates?: boolean;
8
7
  };
9
8
  export declare const create: ({ projectName, template, cursorEnabled, context }: Args) => Promise<void>;
10
9
  export {};
@@ -1,16 +1,26 @@
1
1
  import path from 'path';
2
2
  import fs from 'fs';
3
+ import { templates } from './templates';
3
4
  import { executeCommand } from '../utils/execute-command';
4
5
  import { pythonInstall } from '../install';
5
6
  import { generateTypes } from '../generate-types';
6
7
  import { version } from '../version';
7
- import { setupTemplate } from './setup-template';
8
- import { checkIfFileExists, checkIfDirectoryExists } from './utils';
9
8
  // eslint-disable-next-line @typescript-eslint/no-require-imports
10
9
  require('ts-node').register({
11
10
  transpileOnly: true,
12
11
  compilerOptions: { module: 'commonjs' },
13
12
  });
13
+ const checkIfFileExists = (dir, fileName) => {
14
+ return fs.existsSync(path.join(dir, fileName));
15
+ };
16
+ const checkIfDirectoryExists = (dir) => {
17
+ try {
18
+ return fs.statSync(dir).isDirectory();
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ };
14
24
  const getPackageManager = (dir) => {
15
25
  if (checkIfFileExists(dir, 'yarn.lock')) {
16
26
  return 'yarn';
@@ -176,16 +186,12 @@ export const create = async ({ projectName, template, cursorEnabled, context })
176
186
  fs.mkdirSync(stepsDir);
177
187
  context.log('steps-directory-created', (message) => message.tag('success').append('Folder').append('steps', 'cyan').append('has been created.'));
178
188
  }
179
- if (!checkIfDirectoryExists(path.join(stepsDir, 'basic-tutorial'))) {
180
- fs.mkdirSync(path.join(stepsDir, 'basic-tutorial'));
181
- }
182
- await setupTemplate('basic-tutorial', stepsDir, context);
183
- if (template) {
184
- if (!checkIfDirectoryExists(path.join(stepsDir, template))) {
185
- fs.mkdirSync(path.join(stepsDir, template));
186
- }
187
- await setupTemplate(template, stepsDir, context);
189
+ if (!template || !(template in templates)) {
190
+ context.log('template-not-found', (message) => message.tag('failed').append(`Template ${template} not found, please use one of the following:`));
191
+ context.log('available-templates', (message) => message.tag('info').append(`Available templates: \n\n ${Object.keys(templates).join('\n')}`));
192
+ return;
188
193
  }
194
+ await templates[template](rootDir, context);
189
195
  const packageManager = await installNodeDependencies(rootDir, context);
190
196
  if (template === 'python') {
191
197
  if (!checkIfFileExists(rootDir, 'requirements.txt')) {
@@ -1,3 +1,3 @@
1
1
  import { CliContext } from '../../cloud/config-utils';
2
2
  export type Generator = (rootDir: string, context: CliContext) => Promise<void>;
3
- export declare const generateTemplateSteps: (templateFolder: string) => Generator;
3
+ export declare const generateTemplateSteps: (templateDir: string) => Generator;
@@ -1,38 +1,20 @@
1
- import { promises as fs, statSync, mkdirSync } from 'fs';
1
+ import { promises as fs, statSync } from 'fs';
2
2
  import * as path from 'path';
3
3
  import { globSync } from 'glob';
4
- export const generateTemplateSteps = (templateFolder) => {
4
+ export const generateTemplateSteps = (templateDir) => {
5
5
  return async (rootDir, context) => {
6
- const templatePath = path.join(__dirname, templateFolder);
6
+ const templatePath = path.join(__dirname, templateDir);
7
7
  const files = globSync('**/*', { absolute: false, cwd: templatePath });
8
8
  try {
9
9
  for (const fileName of files) {
10
10
  const filePath = path.join(templatePath, fileName);
11
- if (statSync(filePath).isDirectory() && !filePath.match(/services|utils|lib/)) {
12
- // ignore folders
13
- continue;
14
- }
15
11
  if (statSync(filePath).isDirectory()) {
16
- const folderPath = path.basename(filePath);
17
- mkdirSync(path.join(rootDir, templateFolder, folderPath));
12
+ // ignore folders
18
13
  continue;
19
14
  }
20
15
  const sanitizedFileName = fileName.replace('.txt', '');
21
- const isWorkbenchConfig = fileName.match('motia-workbench.json');
22
- const generateFilePath = path.join(...(isWorkbenchConfig ? [rootDir, sanitizedFileName] : [rootDir, templateFolder, sanitizedFileName]));
23
- let content = await fs.readFile(filePath, 'utf8');
24
- // Make sure statSync doesn't break the execution if the file doesn't exist
25
- try {
26
- if (isWorkbenchConfig && statSync(generateFilePath).isFile()) {
27
- const existingWorkbenchConfig = await fs.readFile(generateFilePath, 'utf8');
28
- const workbenchContent = JSON.parse(content);
29
- content = JSON.stringify([...JSON.parse(existingWorkbenchConfig), ...workbenchContent], null, 2);
30
- context.log('workbench-config-updated', (message) => message.tag('success').append('Workbench config').append('has been updated.'));
31
- }
32
- }
33
- catch {
34
- void 0;
35
- }
16
+ const generateFilePath = path.join(rootDir, sanitizedFileName);
17
+ const content = await fs.readFile(filePath, 'utf8');
36
18
  await fs.writeFile(generateFilePath, content, 'utf8');
37
19
  context.log(sanitizedFileName, (message) => {
38
20
  message.tag('success').append('File').append(sanitizedFileName, 'cyan').append('has been created.');
@@ -1,52 +1,27 @@
1
- import { promises as fs, statSync, mkdirSync } from 'fs'
1
+ import { promises as fs, statSync } from 'fs'
2
2
  import * as path from 'path'
3
3
  import { globSync } from 'glob'
4
4
  import { CliContext } from '../../cloud/config-utils'
5
5
 
6
6
  export type Generator = (rootDir: string, context: CliContext) => Promise<void>
7
7
 
8
- export const generateTemplateSteps = (templateFolder: string): Generator => {
8
+ export const generateTemplateSteps = (templateDir: string): Generator => {
9
9
  return async (rootDir: string, context: CliContext): Promise<void> => {
10
- const templatePath = path.join(__dirname, templateFolder)
10
+ const templatePath = path.join(__dirname, templateDir)
11
11
  const files = globSync('**/*', { absolute: false, cwd: templatePath })
12
12
 
13
13
  try {
14
14
  for (const fileName of files) {
15
15
  const filePath = path.join(templatePath, fileName)
16
16
 
17
- if (statSync(filePath).isDirectory() && !filePath.match(/services|utils|lib/)) {
18
- // ignore folders
19
- continue
20
- }
21
-
22
17
  if (statSync(filePath).isDirectory()) {
23
- const folderPath = path.basename(filePath)
24
- mkdirSync(path.join(rootDir, templateFolder, folderPath))
18
+ // ignore folders
25
19
  continue
26
20
  }
27
21
 
28
22
  const sanitizedFileName = fileName.replace('.txt', '')
29
- const isWorkbenchConfig = fileName.match('motia-workbench.json')
30
- const generateFilePath = path.join(
31
- ...(isWorkbenchConfig ? [rootDir, sanitizedFileName] : [rootDir, templateFolder, sanitizedFileName]),
32
- )
33
- let content = await fs.readFile(filePath, 'utf8')
34
-
35
- // Make sure statSync doesn't break the execution if the file doesn't exist
36
- try {
37
- if (isWorkbenchConfig && statSync(generateFilePath).isFile()) {
38
- const existingWorkbenchConfig = await fs.readFile(generateFilePath, 'utf8')
39
- const workbenchContent = JSON.parse(content)
40
-
41
- content = JSON.stringify([...JSON.parse(existingWorkbenchConfig), ...workbenchContent], null, 2)
42
-
43
- context.log('workbench-config-updated', (message) =>
44
- message.tag('success').append('Workbench config').append('has been updated.'),
45
- )
46
- }
47
- } catch {
48
- void 0
49
- }
23
+ const generateFilePath = path.join(rootDir, sanitizedFileName)
24
+ const content = await fs.readFile(filePath, 'utf8')
50
25
 
51
26
  await fs.writeFile(generateFilePath, content, 'utf8')
52
27
  context.log(sanitizedFileName, (message) => {
@@ -2,5 +2,4 @@ import { generateTemplateSteps } from './generate';
2
2
  export const templates = {
3
3
  default: generateTemplateSteps('default'),
4
4
  python: generateTemplateSteps('python'),
5
- 'basic-tutorial': generateTemplateSteps('basic-tutorial'),
6
5
  };
@@ -3,5 +3,4 @@ import { generateTemplateSteps, Generator } from './generate'
3
3
  export const templates: Record<string, Generator> = {
4
4
  default: generateTemplateSteps('default'),
5
5
  python: generateTemplateSteps('python'),
6
- 'basic-tutorial': generateTemplateSteps('basic-tutorial'),
7
6
  }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-useless-escape */
1
2
  export const printMotiaDockerIntro = () => {
2
3
  console.log('\n\n' +
3
4
  `
@@ -4,7 +4,6 @@ type Args = {
4
4
  template?: string;
5
5
  cursorEnabled?: boolean;
6
6
  context: CliContext;
7
- skipTutorialTemplates?: boolean;
8
7
  };
9
8
  export declare const create: ({ projectName, template, cursorEnabled, context }: Args) => Promise<void>;
10
9
  export {};
@@ -1,3 +1,3 @@
1
1
  import { CliContext } from '../../cloud/config-utils';
2
2
  export type Generator = (rootDir: string, context: CliContext) => Promise<void>;
3
- export declare const generateTemplateSteps: (templateFolder: string) => Generator;
3
+ export declare const generateTemplateSteps: (templateDir: string) => Generator;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "motia",
3
3
  "description": "A Modern Unified Backend Framework for APIs, Events and Agents",
4
- "version": "0.5.11-beta.119",
4
+ "version": "0.5.12-beta.121",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -43,9 +43,9 @@
43
43
  "inquirer": "^8.2.5",
44
44
  "table": "^6.9.0",
45
45
  "ts-node": "^10.9.2",
46
- "@motiadev/core": "0.5.11-beta.119",
47
- "@motiadev/stream-client-node": "0.5.11-beta.119",
48
- "@motiadev/workbench": "0.5.11-beta.119"
46
+ "@motiadev/core": "0.5.12-beta.121",
47
+ "@motiadev/stream-client-node": "0.5.12-beta.121",
48
+ "@motiadev/workbench": "0.5.12-beta.121"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@amplitude/analytics-types": "^2.9.2",
@@ -1,2 +0,0 @@
1
- import { CliContext } from '@/cloud/config-utils';
2
- export declare const setupTemplate: (template: string, rootDir: string, context: CliContext) => Promise<void>;
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setupTemplate = void 0;
4
- const templates_1 = require("./templates");
5
- const setupTemplate = async (template, rootDir, context) => {
6
- if (!template || !(template in templates_1.templates)) {
7
- context.log('template-not-found', (message) => message.tag('failed').append(`Template ${template} not found, please use one of the following:`));
8
- context.log('available-templates', (message) => message.tag('info').append(`Available templates: \n\n ${Object.keys(templates_1.templates).join('\n')}`));
9
- return;
10
- }
11
- await templates_1.templates[template](rootDir, context);
12
- };
13
- exports.setupTemplate = setupTemplate;
@@ -1,6 +0,0 @@
1
- import { CliContext } from '@/cloud/config-utils';
2
- type Args = {
3
- context: CliContext;
4
- };
5
- export declare const createTutorialFlow: ({ context }: Args) => Promise<void>;
6
- export {};