motia 0.5.11-beta.120-357906 → 0.5.11-beta.120-207545

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 (80) hide show
  1. package/dist/cjs/cloud/build/builders/node/index.js +4 -1
  2. package/dist/cjs/cloud/build/builders/python/index.d.ts +1 -2
  3. package/dist/cjs/cloud/build/builders/python/index.js +37 -37
  4. package/dist/cjs/cloud/build/builders/python/uv-packager.d.ts +1 -2
  5. package/dist/cjs/cloud/build/builders/python/uv-packager.js +38 -37
  6. package/dist/cjs/cloud/cli/deploy.js +8 -4
  7. package/dist/cjs/cloud/endpoints.d.ts +2 -0
  8. package/dist/cjs/cloud/endpoints.js +102 -0
  9. package/dist/cjs/cloud/new-deployment/cloud-api/create-deployment.d.ts +3 -1
  10. package/dist/cjs/cloud/new-deployment/cloud-api/index.d.ts +3 -1
  11. package/dist/cjs/cloud/new-deployment/listeners/streaming-deployment-listener.d.ts +44 -0
  12. package/dist/cjs/cloud/new-deployment/listeners/streaming-deployment-listener.js +278 -0
  13. package/dist/cjs/cloud/new-deployment/streams/deployment-stream.d.ts +46 -0
  14. package/dist/cjs/cloud/new-deployment/streams/deployment-stream.js +108 -0
  15. package/dist/cjs/create/templates/python/steps/state_audit_cron_step.py.txt +1 -1
  16. package/dist/cjs/create/templates/typescript/steps/state-audit-cron.step.ts.txt +1 -1
  17. package/dist/cjs/cursor-rules/index.js +32 -3
  18. package/dist/cjs/dev.js +3 -1
  19. package/dist/cjs/install.js +5 -0
  20. package/dist/cjs/utils/ensure-uv.d.ts +1 -0
  21. package/dist/cjs/utils/ensure-uv.js +81 -0
  22. package/dist/esm/cloud/build/builders/node/index.js +4 -1
  23. package/dist/esm/cloud/build/builders/python/index.d.ts +1 -2
  24. package/dist/esm/cloud/build/builders/python/index.js +38 -38
  25. package/dist/esm/cloud/build/builders/python/uv-packager.d.ts +1 -2
  26. package/dist/esm/cloud/build/builders/python/uv-packager.js +38 -37
  27. package/dist/esm/cloud/cli/deploy.js +8 -4
  28. package/dist/esm/cloud/endpoints.d.ts +2 -0
  29. package/dist/esm/cloud/endpoints.js +98 -0
  30. package/dist/esm/cloud/new-deployment/cloud-api/create-deployment.d.ts +3 -1
  31. package/dist/esm/cloud/new-deployment/cloud-api/index.d.ts +3 -1
  32. package/dist/esm/cloud/new-deployment/listeners/streaming-deployment-listener.d.ts +44 -0
  33. package/dist/esm/cloud/new-deployment/listeners/streaming-deployment-listener.js +274 -0
  34. package/dist/esm/cloud/new-deployment/streams/deployment-stream.d.ts +46 -0
  35. package/dist/esm/cloud/new-deployment/streams/deployment-stream.js +103 -0
  36. package/dist/esm/create/templates/python/steps/state_audit_cron_step.py.txt +1 -1
  37. package/dist/esm/create/templates/typescript/steps/state-audit-cron.step.ts.txt +1 -1
  38. package/dist/esm/cursor-rules/index.js +32 -3
  39. package/dist/esm/dev.js +3 -1
  40. package/dist/esm/install.js +5 -0
  41. package/dist/esm/utils/ensure-uv.d.ts +1 -0
  42. package/dist/esm/utils/ensure-uv.js +77 -0
  43. package/dist/types/cloud/build/builders/python/index.d.ts +1 -2
  44. package/dist/types/cloud/build/builders/python/uv-packager.d.ts +1 -2
  45. package/dist/types/cloud/endpoints.d.ts +2 -0
  46. package/dist/types/cloud/new-deployment/cloud-api/create-deployment.d.ts +3 -1
  47. package/dist/types/cloud/new-deployment/cloud-api/index.d.ts +3 -1
  48. package/dist/types/cloud/new-deployment/listeners/streaming-deployment-listener.d.ts +44 -0
  49. package/dist/types/cloud/new-deployment/streams/deployment-stream.d.ts +46 -0
  50. package/dist/types/utils/ensure-uv.d.ts +1 -0
  51. package/package.json +4 -4
  52. package/dist/cjs/utils/uv-install.d.ts +0 -6
  53. package/dist/cjs/utils/uv-install.js +0 -129
  54. package/dist/dot-files/.cursor/rules/ai-agent-patterns.mdc +0 -725
  55. package/dist/dot-files/.cursor/rules/api-design-patterns.mdc +0 -740
  56. package/dist/dot-files/.cursor/rules/api-steps.mdc +0 -230
  57. package/dist/dot-files/.cursor/rules/architecture.mdc +0 -189
  58. package/dist/dot-files/.cursor/rules/authentication-patterns.mdc +0 -620
  59. package/dist/dot-files/.cursor/rules/background-job-patterns.mdc +0 -628
  60. package/dist/dot-files/.cursor/rules/complete-application-patterns.mdc +0 -433
  61. package/dist/dot-files/.cursor/rules/complete-backend-generator.mdc +0 -415
  62. package/dist/dot-files/.cursor/rules/cron-steps.mdc +0 -257
  63. package/dist/dot-files/.cursor/rules/event-steps.mdc +0 -504
  64. package/dist/dot-files/.cursor/rules/instructions.mdc +0 -15
  65. package/dist/dot-files/.cursor/rules/multi-language-workflows.mdc +0 -1059
  66. package/dist/dot-files/.cursor/rules/noop-steps.mdc +0 -57
  67. package/dist/dot-files/.cursor/rules/production-deployment.mdc +0 -668
  68. package/dist/dot-files/.cursor/rules/realtime-streaming.mdc +0 -656
  69. package/dist/dot-files/.cursor/rules/state-management.mdc +0 -371
  70. package/dist/dot-files/.cursor/rules/steps.mdc +0 -373
  71. package/dist/dot-files/.cursor/rules/testing.mdc +0 -329
  72. package/dist/dot-files/.cursor/rules/typescript.mdc +0 -409
  73. package/dist/dot-files/.cursor/rules/ui-steps.mdc +0 -90
  74. package/dist/dot-files/.cursor/rules/workflow-patterns.mdc +0 -938
  75. package/dist/dot-files/AGENTS.md +0 -397
  76. package/dist/dot-files/CLAUDE.md +0 -1032
  77. package/dist/dot-files/README.md +0 -58
  78. package/dist/esm/utils/uv-install.d.ts +0 -6
  79. package/dist/esm/utils/uv-install.js +0 -122
  80. package/dist/types/utils/uv-install.d.ts +0 -6
@@ -68,7 +68,10 @@ class NodeBuilder {
68
68
  async buildApiSteps(steps) {
69
69
  const relativePath = path_1.default.relative(constants_1.distDir, this.builder.projectDir);
70
70
  const getStepPath = (step) => {
71
- return step.filePath.replace(this.builder.projectDir, relativePath).replace(/(.*)\.(ts|js)$/, '$1.js');
71
+ return step.filePath
72
+ .replace(this.builder.projectDir, relativePath)
73
+ .replace(/(.*)\.(ts|js)$/, '$1.js')
74
+ .replace(/\\/g, '/');
72
75
  };
73
76
  const file = fs_1.default
74
77
  .readFileSync(path_1.default.join(__dirname, 'router-template.ts'), 'utf-8')
@@ -5,9 +5,7 @@ export declare class PythonBuilder implements StepBuilder {
5
5
  private readonly builder;
6
6
  private readonly listener;
7
7
  private uvPackager;
8
- private uvConfig;
9
8
  constructor(builder: Builder, listener: BuildListener);
10
- private loadUvConfig;
11
9
  buildApiSteps(steps: Step<ApiRouteConfig>[]): Promise<RouterBuildResult>;
12
10
  build(step: Step): Promise<void>;
13
11
  private addStepToArchive;
@@ -18,4 +16,5 @@ export declare class PythonBuilder implements StepBuilder {
18
16
  private findInternalFiles;
19
17
  private resolveModulePaths;
20
18
  private getModuleName;
19
+ private waitForDirectoryReady;
21
20
  }
@@ -10,40 +10,22 @@ const archiver_1 = require("../archiver");
10
10
  const include_static_files_1 = require("../include-static-files");
11
11
  const constants_1 = require("../../../new-deployment/constants");
12
12
  const uv_packager_1 = require("./uv-packager");
13
+ const activate_python_env_1 = require("../../../../utils/activate-python-env");
13
14
  class PythonBuilder {
14
15
  constructor(builder, listener) {
15
16
  this.builder = builder;
16
17
  this.listener = listener;
17
- this.uvConfig = { ...uv_packager_1.defaultUvConfig, ...this.loadUvConfig() };
18
- this.uvPackager = new uv_packager_1.UvPackager(this.builder.projectDir, this.uvConfig);
19
- }
20
- loadUvConfig() {
21
- const configFiles = ['uv.config.json', '.uvrc.json'];
22
- for (const configFile of configFiles) {
23
- const configPath = path_1.default.join(this.builder.projectDir, configFile);
24
- if (fs_1.default.existsSync(configPath)) {
25
- try {
26
- const configContent = fs_1.default.readFileSync(configPath, 'utf-8');
27
- return JSON.parse(configContent);
28
- }
29
- catch (err) {
30
- console.warn(`Warning: Failed to load UV config from ${configFile}`);
31
- }
32
- }
33
- }
34
- return {};
18
+ (0, activate_python_env_1.activatePythonVenv)({ baseDir: this.builder.projectDir });
19
+ this.uvPackager = new uv_packager_1.UvPackager(this.builder.projectDir);
35
20
  }
36
21
  async buildApiSteps(steps) {
37
22
  const zipName = 'router-python.zip';
38
23
  const archive = new archiver_1.Archiver(path_1.default.join(constants_1.distDir, zipName));
39
- if (!await this.uvPackager.checkUvInstalled()) {
40
- throw new Error('UV is not installed. Please install UV: curl -LsSf https://astral.sh/uv/install.sh | sh');
41
- }
42
24
  const tempSitePackages = path_1.default.join(constants_1.distDir, `temp-python-packages-${Date.now()}`);
43
25
  try {
44
26
  await this.uvPackager.packageDependencies(tempSitePackages);
45
- // Pequena pausa para garantir que o filesystem sincronize
46
- await new Promise(resolve => setTimeout(resolve, 100));
27
+ // Wait for directory to be ready with proper access checks
28
+ await this.waitForDirectoryReady(tempSitePackages);
47
29
  await this.addPackagesToArchive(archive, tempSitePackages);
48
30
  for (const step of steps) {
49
31
  await this.addStepToArchive(step, archive);
@@ -70,15 +52,12 @@ class PythonBuilder {
70
52
  this.builder.registerStep({ entrypointPath, bundlePath, step, type: 'python' });
71
53
  this.listener.onBuildStart(step);
72
54
  try {
73
- if (!await this.uvPackager.checkUvInstalled()) {
74
- throw new Error('UV is not installed. Please install UV: curl -LsSf https://astral.sh/uv/install.sh | sh');
75
- }
76
55
  fs_1.default.mkdirSync(path_1.default.dirname(outfile), { recursive: true });
77
56
  const archive = new archiver_1.Archiver(outfile);
78
57
  const tempSitePackages = path_1.default.join(constants_1.distDir, `temp-python-packages-${Date.now()}`);
79
58
  try {
80
59
  await this.uvPackager.packageDependencies(tempSitePackages);
81
- await new Promise(resolve => setTimeout(resolve, 100));
60
+ await this.waitForDirectoryReady(tempSitePackages);
82
61
  await this.addStepToArchive(step, archive);
83
62
  await this.addPackagesToArchive(archive, tempSitePackages);
84
63
  (0, include_static_files_1.includeStaticFiles)([step], this.builder, archive);
@@ -113,7 +92,6 @@ class PythonBuilder {
113
92
  console.warn(`Warning: Site packages directory not found: ${sitePackagesDir}`);
114
93
  return;
115
94
  }
116
- // Verificar se o diretório está acessível
117
95
  try {
118
96
  fs_1.default.accessSync(sitePackagesDir, fs_1.default.constants.R_OK);
119
97
  }
@@ -208,13 +186,11 @@ class PythonBuilder {
208
186
  files.push(path_1.default.relative(this.builder.projectDir, filePath));
209
187
  try {
210
188
  const content = fs_1.default.readFileSync(filePath, 'utf-8');
211
- // Regex melhorada para capturar imports mais complexos
212
189
  const importRegex = /^(?:from\s+([a-zA-Z_][a-zA-Z0-9_.]*)\s+import|import\s+([a-zA-Z_][a-zA-Z0-9_.]*))/gm;
213
190
  let match;
214
191
  while ((match = importRegex.exec(content)) !== null) {
215
192
  const moduleName = match[1] || match[2]; // from X import Y ou import X
216
- // Verificar diferentes formas de import
217
- this.resolveModulePaths(moduleName, path_1.default.dirname(filePath)).forEach(possiblePath => {
193
+ this.resolveModulePaths(moduleName, path_1.default.dirname(filePath)).forEach((possiblePath) => {
218
194
  if (fs_1.default.existsSync(possiblePath)) {
219
195
  analyzeFile(possiblePath);
220
196
  }
@@ -233,23 +209,47 @@ class PythonBuilder {
233
209
  const baseName = parts[0];
234
210
  const subPath = parts.length > 1 ? path_1.default.join(...parts) : baseName;
235
211
  return [
236
- // Relativo ao arquivo atual
237
212
  path_1.default.join(currentDir, `${baseName}.py`),
238
213
  path_1.default.join(currentDir, baseName, '__init__.py'),
239
214
  path_1.default.join(currentDir, `${subPath}.py`),
240
- // Relativo ao diretório do projeto
241
215
  path_1.default.join(this.builder.projectDir, `${baseName}.py`),
242
216
  path_1.default.join(this.builder.projectDir, baseName, '__init__.py'),
243
217
  path_1.default.join(this.builder.projectDir, `${subPath}.py`),
244
- // Para utils.database -> utils/database.py
245
218
  path_1.default.join(this.builder.projectDir, subPath + '.py'),
246
219
  path_1.default.join(this.builder.projectDir, subPath, '__init__.py'),
247
220
  ];
248
221
  }
249
222
  getModuleName(step) {
250
- return this.normalizeStepPath(step, true)
251
- .replace(/\.py$/, '')
252
- .replace(/\//g, '.');
223
+ return this.normalizeStepPath(step, true).replace(/\.py$/, '').replace(/\//g, '.');
224
+ }
225
+ async waitForDirectoryReady(dirPath, maxRetries = 10, initialDelayMs = 10) {
226
+ let lastError = null;
227
+ for (let i = 0; i < maxRetries; i++) {
228
+ try {
229
+ const exists = await fs_1.default.promises
230
+ .access(dirPath, fs_1.default.constants.F_OK)
231
+ .then(() => true)
232
+ .catch(() => false);
233
+ if (!exists) {
234
+ // Directory doesn't exist yet, wait
235
+ lastError = new Error(`Directory ${dirPath} does not exist yet`);
236
+ }
237
+ else {
238
+ await fs_1.default.promises.access(dirPath, fs_1.default.constants.R_OK);
239
+ return;
240
+ }
241
+ }
242
+ catch (error) {
243
+ lastError = error;
244
+ }
245
+ if (i === maxRetries - 1) {
246
+ throw new Error(`Directory ${dirPath} is not accessible after ${maxRetries} attempts. ` +
247
+ `Last error: ${lastError?.message || 'Unknown error'}`);
248
+ }
249
+ // Exponential backoff: 10ms, 20ms, 40ms, 80ms, etc.
250
+ const delay = initialDelayMs * Math.pow(2, i);
251
+ await new Promise((resolve) => setTimeout(resolve, Math.min(delay, 1000))); // Cap at 1 second
252
+ }
253
253
  }
254
254
  }
255
255
  exports.PythonBuilder = PythonBuilder;
@@ -8,7 +8,6 @@ export declare class UvPackager {
8
8
  private readonly projectDir;
9
9
  private readonly config;
10
10
  constructor(projectDir: string, config?: UvPackageConfig);
11
- checkUvInstalled(): Promise<boolean>;
11
+ private runCommand;
12
12
  packageDependencies(targetDir: string): Promise<void>;
13
- private runUvCommand;
14
13
  }
@@ -8,53 +8,28 @@ const child_process_1 = require("child_process");
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  exports.defaultUvConfig = {
11
- pythonVersion: '3.13',
12
- platform: 'x86_64-manylinux2014',
13
- onlyBinary: true
11
+ pythonVersion: process.env.MOTIA_PYTHON_VERSION || '3.13',
12
+ platform: process.env.MOTIA_PLATFORM || 'x86_64-manylinux2014',
13
+ onlyBinary: process.env.MOTIA_ONLY_BINARY !== 'false',
14
14
  };
15
15
  class UvPackager {
16
16
  constructor(projectDir, config = exports.defaultUvConfig) {
17
17
  this.projectDir = projectDir;
18
18
  this.config = config;
19
19
  }
20
- async checkUvInstalled() {
21
- return new Promise((resolve) => {
22
- const child = (0, child_process_1.spawn)('uv', ['--version'], { stdio: 'pipe' });
23
- child.on('close', (code) => resolve(code === 0));
24
- child.on('error', () => resolve(false));
25
- });
26
- }
27
- async packageDependencies(targetDir) {
28
- if (!fs_1.default.existsSync(targetDir)) {
29
- fs_1.default.mkdirSync(targetDir, { recursive: true });
30
- }
31
- const requirementsFile = path_1.default.join(this.projectDir, 'requirements.txt');
32
- if (!fs_1.default.existsSync(requirementsFile)) {
33
- return;
34
- }
35
- const args = [
36
- 'pip', 'install',
37
- '--target', targetDir,
38
- '--requirement', requirementsFile,
39
- '--python-version', this.config.pythonVersion || '3.13',
40
- '--python-platform', this.config.platform || 'x86_64-manylinux2014',
41
- '--force-reinstall'
42
- ];
43
- if (this.config.onlyBinary) {
44
- args.push('--only-binary=:all:');
45
- }
46
- await this.runUvCommand(args);
47
- }
48
- async runUvCommand(args) {
20
+ async runCommand(command, args, options) {
49
21
  return new Promise((resolve, reject) => {
50
- const child = (0, child_process_1.spawn)('uv', args, {
51
- cwd: this.projectDir,
52
- stdio: ['pipe', 'pipe', 'pipe']
22
+ const child = (0, child_process_1.spawn)(command, args, {
23
+ cwd: options?.cwd,
24
+ stdio: ['pipe', 'pipe', 'pipe'],
53
25
  });
54
26
  let stdout = '';
55
27
  let stderr = '';
56
28
  child.stdout?.on('data', (data) => {
57
29
  stdout += data.toString();
30
+ if (options?.showOutput) {
31
+ process.stdout.write(data);
32
+ }
58
33
  });
59
34
  child.stderr?.on('data', (data) => {
60
35
  stderr += data.toString();
@@ -64,13 +39,39 @@ class UvPackager {
64
39
  resolve(stdout);
65
40
  }
66
41
  else {
67
- reject(new Error(`UV command failed: ${stderr || stdout}`));
42
+ const errorPrefix = `Command '${command}'`;
43
+ reject(new Error(`${errorPrefix} failed: ${stderr || stdout}`));
68
44
  }
69
45
  });
70
46
  child.on('error', (error) => {
71
- reject(new Error(`Failed to spawn UV: ${error.message}`));
47
+ reject(new Error(`Failed to spawn ${command}: ${error.message}`));
72
48
  });
73
49
  });
74
50
  }
51
+ async packageDependencies(targetDir) {
52
+ if (!fs_1.default.existsSync(targetDir)) {
53
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
54
+ }
55
+ const requirementsFile = path_1.default.join(this.projectDir, 'requirements.txt');
56
+ if (!fs_1.default.existsSync(requirementsFile)) {
57
+ return;
58
+ }
59
+ const args = [
60
+ 'pip',
61
+ 'install',
62
+ '--target',
63
+ targetDir,
64
+ '--requirement',
65
+ requirementsFile,
66
+ '--python-version',
67
+ this.config.pythonVersion || '3.13',
68
+ '--python-platform',
69
+ this.config.platform || 'x86_64-manylinux2014',
70
+ ];
71
+ if (this.config.onlyBinary) {
72
+ args.push('--only-binary=:all:');
73
+ }
74
+ await this.runCommand('uv', args, { cwd: this.projectDir });
75
+ }
75
76
  }
76
77
  exports.UvPackager = UvPackager;
@@ -13,11 +13,13 @@ cli_1.cloudCli
13
13
  .command('deploy')
14
14
  .description('Deploy a new version to Motia Cloud')
15
15
  .requiredOption('-k, --api-key <key>', 'The API key for authentication', process.env.MOTIA_API_KEY)
16
- .requiredOption('-v, --version-name <version>', 'The version to deploy')
17
16
  .option('-p, --project-id <id>', 'Project ID (Deprecated)')
17
+ .option('-n, --project-name <name>', 'Project name (used when creating a new project)')
18
18
  .option('-s, --environment-id <id>', 'Environment ID', process.env.MOTIA_ENVIRONMENT_ID)
19
+ .option('--environment-name <name>', 'Environment name')
19
20
  .option('-e, --env-file <path>', 'Path to environment file')
20
- .option('-n, --project-name <name>', 'Project name (used when creating a new project)', '')
21
+ .requiredOption('-v, --version-name <version>', 'The version to deploy')
22
+ .option('-d, --version-description <description>', 'The description of the version')
21
23
  .action((0, config_utils_1.handler)(async (arg, context) => {
22
24
  const listener = new cli_listener_1.CliListener(context);
23
25
  const builder = await (0, build_1.build)(listener);
@@ -30,9 +32,11 @@ cli_1.cloudCli
30
32
  const deployment = await cloud_api_1.cloudApi
31
33
  .createDeployment({
32
34
  apiKey: arg.apiKey,
33
- versionName: arg.versionName,
34
- environmentId: arg.environmentId,
35
35
  projectName: arg.projectName,
36
+ environmentId: arg.environmentId,
37
+ environmentName: arg.environmentName,
38
+ versionName: arg.versionName,
39
+ versionDescription: arg.versionDescription,
36
40
  })
37
41
  .catch((error) => {
38
42
  context.log('creating-deployment', (message) => message.tag('failed').append('Failed to create deployment'));
@@ -0,0 +1,2 @@
1
+ import { LockedData, MotiaServer } from '@motiadev/core';
2
+ export declare const deployEndpoints: (server: MotiaServer, lockedData: LockedData) => void;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deployEndpoints = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const build_validation_1 = require("./build/build-validation");
6
+ const streaming_deployment_listener_1 = require("./new-deployment/listeners/streaming-deployment-listener");
7
+ const build_1 = require("./new-deployment/build");
8
+ const upload_artifacts_1 = require("./new-deployment/upload-artifacts");
9
+ const deployment_stream_1 = require("./new-deployment/streams/deployment-stream");
10
+ const cloud_api_1 = require("./new-deployment/cloud-api");
11
+ const version_1 = require("../version");
12
+ const deployEndpoints = (server, lockedData) => {
13
+ const { app } = server;
14
+ // Criar stream de deployment se não existir
15
+ const deploymentStream = lockedData.createStream({
16
+ filePath: '__motia.deployment',
17
+ hidden: true,
18
+ config: {
19
+ name: '__motia.deployment',
20
+ baseConfig: { storageType: 'default' },
21
+ schema: null,
22
+ },
23
+ })();
24
+ const deploymentManager = new deployment_stream_1.DeploymentStreamManager(deploymentStream);
25
+ app.get('/__motia', (_, res) => {
26
+ res.status(200).json({ version: version_1.version });
27
+ });
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ app.post('/__motia/cloud/deploy/start', async (req, res) => {
30
+ try {
31
+ const { deploymentToken, deploymentId, envs } = req.body;
32
+ const sessionId = deploymentId || (0, crypto_1.randomUUID)();
33
+ if (!deploymentToken || !deploymentId) {
34
+ return res.status(400).json({
35
+ success: false,
36
+ error: 'deploymentToken and deploymentId are required',
37
+ });
38
+ }
39
+ await deploymentManager.startDeployment(sessionId);
40
+ const listener = new streaming_deployment_listener_1.StreamingDeploymentListener(sessionId, deploymentStream);
41
+ res.json({
42
+ success: true,
43
+ message: 'Deployment started',
44
+ deploymentId: sessionId,
45
+ streamName: 'deployment-status',
46
+ groupId: 'deployments',
47
+ itemId: sessionId,
48
+ });
49
+ setImmediate(async () => {
50
+ try {
51
+ await listener.startBuildPhase();
52
+ const builder = await (0, build_1.build)(listener).catch(() => {
53
+ throw new Error('Build failed, check the logs for more information');
54
+ });
55
+ const isValid = (0, build_validation_1.buildValidation)(builder, listener);
56
+ if (!isValid) {
57
+ await listener.onBuildErrors(listener.getErrors());
58
+ return;
59
+ }
60
+ await listener.startUploadPhase();
61
+ await (0, upload_artifacts_1.uploadArtifacts)(builder, deploymentToken, listener);
62
+ await listener.startDeployPhase();
63
+ await cloud_api_1.cloudApi.startDeployment({
64
+ deploymentToken,
65
+ envVars: envs,
66
+ steps: builder.stepsConfig,
67
+ streams: builder.streamsConfig,
68
+ routers: builder.routersConfig,
69
+ });
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ }
72
+ catch (error) {
73
+ console.error('Deployment failed:', error);
74
+ // Update stream with error
75
+ if (listener) {
76
+ await listener.onDeployError(error.message);
77
+ }
78
+ }
79
+ });
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ }
82
+ catch (error) {
83
+ console.error('Failed to start deployment:', error);
84
+ res.status(500).json({ success: false, error: error.message });
85
+ }
86
+ });
87
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
+ app.get('/__motia/cloud/deploy/status/:deploymentId', async (req, res) => {
89
+ try {
90
+ const { deploymentId } = req.params;
91
+ const deployment = await deploymentManager.getDeployment(deploymentId);
92
+ return deployment
93
+ ? res.status(200).json({ success: true, deployment })
94
+ : res.status(404).json({ success: false, error: 'Deployment not found' });
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ }
97
+ catch (error) {
98
+ res.status(500).json({ success: false, error: error.message });
99
+ }
100
+ });
101
+ };
102
+ exports.deployEndpoints = deployEndpoints;
@@ -1,8 +1,10 @@
1
1
  type CreateDeploymentRequest = {
2
2
  apiKey: string;
3
+ projectName?: string;
3
4
  environmentId?: string;
5
+ environmentName?: string;
4
6
  versionName: string;
5
- projectName?: string;
7
+ versionDescription?: string;
6
8
  };
7
9
  type CreateDeploymentResult = {
8
10
  deploymentId: string;
@@ -11,9 +11,11 @@ export declare const cloudApi: {
11
11
  }>;
12
12
  createDeployment: (request: {
13
13
  apiKey: string;
14
+ projectName?: string;
14
15
  environmentId?: string;
16
+ environmentName?: string;
15
17
  versionName: string;
16
- projectName?: string;
18
+ versionDescription?: string;
17
19
  }) => Promise<{
18
20
  deploymentId: string;
19
21
  deploymentToken: string;
@@ -0,0 +1,44 @@
1
+ import { Step, MotiaStream } from '@motiadev/core';
2
+ import { Stream } from '@motiadev/core/dist/src/types-stream';
3
+ import { BuildStepConfig } from '../../build/builder';
4
+ import { ValidationError } from '../../build/build-validation';
5
+ import { DeploymentListener, DeployData } from './listener.types';
6
+ import { DeploymentData } from '../streams/deployment-stream';
7
+ export declare class StreamingDeploymentListener implements DeploymentListener {
8
+ private deploymentId;
9
+ private errors;
10
+ private warnings;
11
+ private streamManager;
12
+ constructor(deploymentId: string, deploymentStream: MotiaStream<DeploymentData>);
13
+ private relativePath;
14
+ private getStepType;
15
+ private getLanguage;
16
+ private updateStream;
17
+ getErrors(): ValidationError[];
18
+ onBuildStart(step: Step): Promise<void>;
19
+ onBuildProgress(step: Step, message: string): Promise<void>;
20
+ onBuildEnd(step: Step, size: number): Promise<void>;
21
+ onBuildError(step: Step, error: Error): Promise<void>;
22
+ onBuildSkip(step: Step, reason: string): Promise<void>;
23
+ onStreamCreated(stream: Stream): Promise<void>;
24
+ onApiRouterBuilding(language: string): Promise<void>;
25
+ onApiRouterBuilt(language: string, size: number): Promise<void>;
26
+ onWarning(id: string, warning: string): Promise<void>;
27
+ onBuildWarning(warning: ValidationError): Promise<void>;
28
+ onBuildErrors(errors: ValidationError[]): Promise<void>;
29
+ stepUploadStart(stepPath: string, step: BuildStepConfig): Promise<void>;
30
+ stepUploadProgress(stepPath: string, step: BuildStepConfig, progress: number): Promise<void>;
31
+ stepUploadEnd(stepPath: string, step: BuildStepConfig): Promise<void>;
32
+ stepUploadError(stepPath: string, step: BuildStepConfig): Promise<void>;
33
+ routeUploadStart(path: string, language: string): Promise<void>;
34
+ routeUploadProgress(path: string, language: string, progress: number): Promise<void>;
35
+ routeUploadEnd(path: string, language: string): Promise<void>;
36
+ routeUploadError(path: string, language: string): Promise<void>;
37
+ onDeployStart(): Promise<void>;
38
+ onDeployProgress(data: DeployData): Promise<void>;
39
+ onDeployEnd(): Promise<void>;
40
+ onDeployError(errorMessage: string): Promise<void>;
41
+ startBuildPhase(): Promise<void>;
42
+ startUploadPhase(): Promise<void>;
43
+ startDeployPhase(): Promise<void>;
44
+ }