motia 0.15.4-beta.170-980856 → 0.15.4-beta.170-590272

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.
@@ -1,4 +1,5 @@
1
1
  import { BuildError, BuildErrorType } from "../../utils/errors/build.error.mjs";
2
+ import { validatePythonEnvironment } from "../../utils/validate-python-environment.mjs";
2
3
  import { collectFlows, getStepFiles, getStreamFiles } from "../../generate-locked-data.mjs";
3
4
  import { Builder } from "../build/builder.mjs";
4
5
  import { distDir, projectDir, stepsConfigPath } from "./constants.mjs";
@@ -23,7 +24,12 @@ const build = async (listener) => {
23
24
  });
24
25
  fs.mkdirSync(distDir, { recursive: true });
25
26
  const lockedData = new LockedData(projectDir, new MemoryStreamAdapterManager(), new NoPrinter());
26
- if (hasPythonSteps([...stepFiles, ...streamFiles])) builder.registerBuilder("python", new PythonBuilder(builder, listener));
27
+ const hasPython = hasPythonSteps([...stepFiles, ...streamFiles]);
28
+ if (!(await validatePythonEnvironment({
29
+ baseDir: projectDir,
30
+ hasPythonFiles: hasPython
31
+ })).success) throw new BuildError(BuildErrorType.COMPILATION, void 0, "Python environment validation failed. Please run the install command to set up your Python environment.");
32
+ if (hasPython) builder.registerBuilder("python", new PythonBuilder(builder, listener));
27
33
  if ((await collectFlows(projectDir, lockedData).catch((err) => {
28
34
  const finalMessage = `${err.filePath ? `Build error in ${err.filePath}` : "Build error"}\nPlease check the logs above for details`;
29
35
  throw new BuildError(BuildErrorType.COMPILATION, err.filePath, finalMessage, err);
@@ -1 +1 @@
1
- {"version":3,"file":"build.mjs","names":["stepsFile: StepsConfigFile"],"sources":["../../../src/cloud/new-deployment/build.ts"],"sourcesContent":["import { isApiStep, LockedData, MemoryStreamAdapterManager, NoPrinter } from '@motiadev/core'\nimport fs from 'fs'\nimport { collectFlows, getStepFiles, getStreamFiles } from '../../generate-locked-data'\nimport { BuildError, BuildErrorType } from '../../utils/errors/build.error'\nimport { Builder, type StepsConfigFile } from '../build/builder'\nimport { NodeBuilder } from '../build/builders/node/index'\nimport { PythonBuilder } from '../build/builders/python/index'\nimport { distDir, projectDir, stepsConfigPath } from './constants'\nimport type { BuildListener } from './listeners/listener.types'\n\nconst hasPythonSteps = (stepFiles: string[]) => {\n return stepFiles.some((file) => file.endsWith('.py'))\n}\n\nexport const build = async (listener: BuildListener): Promise<Builder> => {\n const builder = new Builder(projectDir, listener)\n const stepFiles = getStepFiles(projectDir)\n const streamFiles = getStreamFiles(projectDir)\n\n if (stepFiles.length === 0) {\n throw new Error('Project contains no steps, please add some steps before building')\n }\n\n // Register language-specific builders\n builder.registerBuilder('node', new NodeBuilder(builder, listener))\n\n fs.rmSync(distDir, { recursive: true, force: true })\n fs.mkdirSync(distDir, { recursive: true })\n\n const lockedData = new LockedData(projectDir, new MemoryStreamAdapterManager(), new NoPrinter())\n\n if (hasPythonSteps([...stepFiles, ...streamFiles])) {\n builder.registerBuilder('python', new PythonBuilder(builder, listener))\n }\n\n const invalidSteps = await collectFlows(projectDir, lockedData).catch((err) => {\n const errorMessage = err.filePath ? `Build error in ${err.filePath}` : 'Build error'\n\n const finalMessage = `${errorMessage}\\nPlease check the logs above for details`\n\n throw new BuildError(BuildErrorType.COMPILATION, err.filePath, finalMessage, err)\n })\n\n if (invalidSteps.length > 0) {\n throw new Error('Project contains invalid steps, please fix them before building')\n }\n\n await Promise.all(lockedData.activeSteps.map((step) => builder.buildStep(step)))\n await builder.buildApiSteps(lockedData.activeSteps.filter(isApiStep))\n\n const streams = lockedData.listStreams()\n\n for (const stream of streams) {\n if (stream.config.baseConfig.storageType === 'default') {\n builder.registerStateStream(stream)\n } else {\n listener.onWarning(stream.filePath, 'Custom streams are not supported yet in the cloud')\n }\n }\n\n const stepsFile: StepsConfigFile = {\n steps: builder.stepsConfig,\n streams: builder.streamsConfig,\n routers: builder.routersConfig,\n }\n fs.writeFileSync(stepsConfigPath, JSON.stringify(stepsFile, null, 2))\n\n return builder\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAM,kBAAkB,cAAwB;AAC9C,QAAO,UAAU,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC;;AAGvD,MAAa,QAAQ,OAAO,aAA8C;CACxE,MAAM,UAAU,IAAI,QAAQ,YAAY,SAAS;CACjD,MAAM,YAAY,aAAa,WAAW;CAC1C,MAAM,cAAc,eAAe,WAAW;AAE9C,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,MAAM,mEAAmE;AAIrF,SAAQ,gBAAgB,QAAQ,IAAI,YAAY,SAAS,SAAS,CAAC;AAEnE,IAAG,OAAO,SAAS;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AACpD,IAAG,UAAU,SAAS,EAAE,WAAW,MAAM,CAAC;CAE1C,MAAM,aAAa,IAAI,WAAW,YAAY,IAAI,4BAA4B,EAAE,IAAI,WAAW,CAAC;AAEhG,KAAI,eAAe,CAAC,GAAG,WAAW,GAAG,YAAY,CAAC,CAChD,SAAQ,gBAAgB,UAAU,IAAI,cAAc,SAAS,SAAS,CAAC;AAWzE,MARqB,MAAM,aAAa,YAAY,WAAW,CAAC,OAAO,QAAQ;EAG7E,MAAM,eAAe,GAFA,IAAI,WAAW,kBAAkB,IAAI,aAAa,cAElC;AAErC,QAAM,IAAI,WAAW,eAAe,aAAa,IAAI,UAAU,cAAc,IAAI;GACjF,EAEe,SAAS,EACxB,OAAM,IAAI,MAAM,kEAAkE;AAGpF,OAAM,QAAQ,IAAI,WAAW,YAAY,KAAK,SAAS,QAAQ,UAAU,KAAK,CAAC,CAAC;AAChF,OAAM,QAAQ,cAAc,WAAW,YAAY,OAAO,UAAU,CAAC;CAErE,MAAM,UAAU,WAAW,aAAa;AAExC,MAAK,MAAM,UAAU,QACnB,KAAI,OAAO,OAAO,WAAW,gBAAgB,UAC3C,SAAQ,oBAAoB,OAAO;KAEnC,UAAS,UAAU,OAAO,UAAU,oDAAoD;CAI5F,MAAMA,YAA6B;EACjC,OAAO,QAAQ;EACf,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB;AACD,IAAG,cAAc,iBAAiB,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC;AAErE,QAAO"}
1
+ {"version":3,"file":"build.mjs","names":["stepsFile: StepsConfigFile"],"sources":["../../../src/cloud/new-deployment/build.ts"],"sourcesContent":["import { isApiStep, LockedData, MemoryStreamAdapterManager, NoPrinter } from '@motiadev/core'\nimport fs from 'fs'\nimport { collectFlows, getStepFiles, getStreamFiles } from '../../generate-locked-data'\nimport { BuildError, BuildErrorType } from '../../utils/errors/build.error'\nimport { validatePythonEnvironment } from '../../utils/validate-python-environment'\nimport { Builder, type StepsConfigFile } from '../build/builder'\nimport { NodeBuilder } from '../build/builders/node/index'\nimport { PythonBuilder } from '../build/builders/python/index'\nimport { distDir, projectDir, stepsConfigPath } from './constants'\nimport type { BuildListener } from './listeners/listener.types'\n\nconst hasPythonSteps = (stepFiles: string[]) => {\n return stepFiles.some((file) => file.endsWith('.py'))\n}\n\nexport const build = async (listener: BuildListener): Promise<Builder> => {\n const builder = new Builder(projectDir, listener)\n const stepFiles = getStepFiles(projectDir)\n const streamFiles = getStreamFiles(projectDir)\n\n if (stepFiles.length === 0) {\n throw new Error('Project contains no steps, please add some steps before building')\n }\n\n // Register language-specific builders\n builder.registerBuilder('node', new NodeBuilder(builder, listener))\n\n fs.rmSync(distDir, { recursive: true, force: true })\n fs.mkdirSync(distDir, { recursive: true })\n\n const lockedData = new LockedData(projectDir, new MemoryStreamAdapterManager(), new NoPrinter())\n\n const hasPython = hasPythonSteps([...stepFiles, ...streamFiles])\n const pythonValidation = await validatePythonEnvironment({ baseDir: projectDir, hasPythonFiles: hasPython })\n if (!pythonValidation.success) {\n throw new BuildError(\n BuildErrorType.COMPILATION,\n undefined,\n 'Python environment validation failed. Please run the install command to set up your Python environment.',\n )\n }\n\n if (hasPython) {\n builder.registerBuilder('python', new PythonBuilder(builder, listener))\n }\n\n const invalidSteps = await collectFlows(projectDir, lockedData).catch((err) => {\n const errorMessage = err.filePath ? `Build error in ${err.filePath}` : 'Build error'\n\n const finalMessage = `${errorMessage}\\nPlease check the logs above for details`\n\n throw new BuildError(BuildErrorType.COMPILATION, err.filePath, finalMessage, err)\n })\n\n if (invalidSteps.length > 0) {\n throw new Error('Project contains invalid steps, please fix them before building')\n }\n\n await Promise.all(lockedData.activeSteps.map((step) => builder.buildStep(step)))\n await builder.buildApiSteps(lockedData.activeSteps.filter(isApiStep))\n\n const streams = lockedData.listStreams()\n\n for (const stream of streams) {\n if (stream.config.baseConfig.storageType === 'default') {\n builder.registerStateStream(stream)\n } else {\n listener.onWarning(stream.filePath, 'Custom streams are not supported yet in the cloud')\n }\n }\n\n const stepsFile: StepsConfigFile = {\n steps: builder.stepsConfig,\n streams: builder.streamsConfig,\n routers: builder.routersConfig,\n }\n fs.writeFileSync(stepsConfigPath, JSON.stringify(stepsFile, null, 2))\n\n return builder\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,kBAAkB,cAAwB;AAC9C,QAAO,UAAU,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC;;AAGvD,MAAa,QAAQ,OAAO,aAA8C;CACxE,MAAM,UAAU,IAAI,QAAQ,YAAY,SAAS;CACjD,MAAM,YAAY,aAAa,WAAW;CAC1C,MAAM,cAAc,eAAe,WAAW;AAE9C,KAAI,UAAU,WAAW,EACvB,OAAM,IAAI,MAAM,mEAAmE;AAIrF,SAAQ,gBAAgB,QAAQ,IAAI,YAAY,SAAS,SAAS,CAAC;AAEnE,IAAG,OAAO,SAAS;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AACpD,IAAG,UAAU,SAAS,EAAE,WAAW,MAAM,CAAC;CAE1C,MAAM,aAAa,IAAI,WAAW,YAAY,IAAI,4BAA4B,EAAE,IAAI,WAAW,CAAC;CAEhG,MAAM,YAAY,eAAe,CAAC,GAAG,WAAW,GAAG,YAAY,CAAC;AAEhE,KAAI,EADqB,MAAM,0BAA0B;EAAE,SAAS;EAAY,gBAAgB;EAAW,CAAC,EACtF,QACpB,OAAM,IAAI,WACR,eAAe,aACf,QACA,0GACD;AAGH,KAAI,UACF,SAAQ,gBAAgB,UAAU,IAAI,cAAc,SAAS,SAAS,CAAC;AAWzE,MARqB,MAAM,aAAa,YAAY,WAAW,CAAC,OAAO,QAAQ;EAG7E,MAAM,eAAe,GAFA,IAAI,WAAW,kBAAkB,IAAI,aAAa,cAElC;AAErC,QAAM,IAAI,WAAW,eAAe,aAAa,IAAI,UAAU,cAAc,IAAI;GACjF,EAEe,SAAS,EACxB,OAAM,IAAI,MAAM,kEAAkE;AAGpF,OAAM,QAAQ,IAAI,WAAW,YAAY,KAAK,SAAS,QAAQ,UAAU,KAAK,CAAC,CAAC;AAChF,OAAM,QAAQ,cAAc,WAAW,YAAY,OAAO,UAAU,CAAC;CAErE,MAAM,UAAU,WAAW,aAAa;AAExC,MAAK,MAAM,UAAU,QACnB,KAAI,OAAO,OAAO,WAAW,gBAAgB,UAC3C,SAAQ,oBAAoB,OAAO;KAEnC,UAAS,UAAU,OAAO,UAAU,oDAAoD;CAI5F,MAAMA,YAA6B;EACjC,OAAO,QAAQ;EACf,SAAS,QAAQ;EACjB,SAAS,QAAQ;EAClB;AACD,IAAG,cAAc,iBAAiB,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC;AAErE,QAAO"}
@@ -1,6 +1,5 @@
1
1
  import { internalLogger } from "./internal-logger.mjs";
2
2
  import { findPythonSitePackagesDir } from "./python-version-utils.mjs";
3
- import fs from "fs";
4
3
  import path from "path";
5
4
 
6
5
  //#region src/utils/activate-python-env.ts
@@ -17,20 +16,15 @@ const activatePythonVenv = ({ baseDir, isVerbose = false, pythonVersion = "3.13"
17
16
  baseDir,
18
17
  pythonVersion
19
18
  });
20
- if (fs.existsSync(venvPath)) {
21
- process.env.PATH = `${venvBinPath}${path.delimiter}${process.env.PATH}`;
22
- process.env.VIRTUAL_ENV = venvPath;
23
- process.env.PYTHON_SITE_PACKAGES = sitePackagesPath;
24
- delete process.env.PYTHONHOME;
25
- if (isVerbose) {
26
- const pythonPath = process.platform === "win32" ? path.join(venvBinPath, "python.exe") : path.join(venvBinPath, "python");
27
- const relativePath = (path$1) => path$1.replace(baseDir, "<projectDir>");
28
- internalLogger.info("Using Python", relativePath(pythonPath));
29
- internalLogger.info("Site-packages path", relativePath(sitePackagesPath));
30
- }
31
- } else {
32
- internalLogger.error("Python virtual environment not found in python_modules/");
33
- internalLogger.error("Please run `motia install` to create a new virtual environment");
19
+ process.env.PATH = `${venvBinPath}${path.delimiter}${process.env.PATH}`;
20
+ process.env.VIRTUAL_ENV = venvPath;
21
+ process.env.PYTHON_SITE_PACKAGES = sitePackagesPath;
22
+ delete process.env.PYTHONHOME;
23
+ if (isVerbose) {
24
+ const pythonPath = process.platform === "win32" ? path.join(venvBinPath, "python.exe") : path.join(venvBinPath, "python");
25
+ const relativePath = (path$1) => path$1.replace(baseDir, "<projectDir>");
26
+ internalLogger.info("Using Python", relativePath(pythonPath));
27
+ internalLogger.info("Site-packages path", relativePath(sitePackagesPath));
34
28
  }
35
29
  };
36
30
 
@@ -1 +1 @@
1
- {"version":3,"file":"activate-python-env.mjs","names":["path"],"sources":["../../src/utils/activate-python-env.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { internalLogger } from './internal-logger'\nimport { findPythonSitePackagesDir } from './python-version-utils'\n\ninterface VenvConfig {\n baseDir: string\n isVerbose?: boolean\n pythonVersion?: string\n}\n\nexport const getSitePackagesPath = ({ baseDir, pythonVersion = '3.13' }: VenvConfig): string => {\n const venvPath = path.join(baseDir, 'python_modules')\n const libPath = path.join(venvPath, 'lib')\n const actualPythonVersionPath = findPythonSitePackagesDir(libPath, pythonVersion)\n return path.join(venvPath, 'lib', actualPythonVersionPath, 'site-packages')\n}\n\nexport const activatePythonVenv = ({ baseDir, isVerbose = false, pythonVersion = '3.13' }: VenvConfig): void => {\n internalLogger.info('Activating Python environment')\n\n // Set the virtual environment path\n const venvPath = path.join(baseDir, 'python_modules')\n const venvBinPath = path.join(venvPath, process.platform === 'win32' ? 'Scripts' : 'bin')\n\n // Find the Python version directory using the utility function\n const sitePackagesPath = getSitePackagesPath({ baseDir, pythonVersion })\n\n // Verify that the virtual environment exists\n if (fs.existsSync(venvPath)) {\n // Add virtual environment to PATH\n process.env.PATH = `${venvBinPath}${path.delimiter}${process.env.PATH}`\n // Set VIRTUAL_ENV environment variable\n process.env.VIRTUAL_ENV = venvPath\n // Set PYTHON_SITE_PACKAGES with the site-packages path\n process.env.PYTHON_SITE_PACKAGES = sitePackagesPath\n // Remove PYTHONHOME if it exists as it can interfere with venv\n delete process.env.PYTHONHOME\n\n // Log Python environment information if verbose mode is enabled\n if (isVerbose) {\n const pythonPath =\n process.platform === 'win32' ? path.join(venvBinPath, 'python.exe') : path.join(venvBinPath, 'python')\n\n const relativePath = (path: string) => path.replace(baseDir, '<projectDir>')\n\n internalLogger.info('Using Python', relativePath(pythonPath))\n internalLogger.info('Site-packages path', relativePath(sitePackagesPath))\n }\n } else {\n internalLogger.error('Python virtual environment not found in python_modules/')\n internalLogger.error('Please run `motia install` to create a new virtual environment')\n }\n}\n"],"mappings":";;;;;;AAWA,MAAa,uBAAuB,EAAE,SAAS,gBAAgB,aAAiC;CAC9F,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;CAErD,MAAM,0BAA0B,0BADhB,KAAK,KAAK,UAAU,MAAM,EACyB,cAAc;AACjF,QAAO,KAAK,KAAK,UAAU,OAAO,yBAAyB,gBAAgB;;AAG7E,MAAa,sBAAsB,EAAE,SAAS,YAAY,OAAO,gBAAgB,aAA+B;AAC9G,gBAAe,KAAK,gCAAgC;CAGpD,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;CACrD,MAAM,cAAc,KAAK,KAAK,UAAU,QAAQ,aAAa,UAAU,YAAY,MAAM;CAGzF,MAAM,mBAAmB,oBAAoB;EAAE;EAAS;EAAe,CAAC;AAGxE,KAAI,GAAG,WAAW,SAAS,EAAE;AAE3B,UAAQ,IAAI,OAAO,GAAG,cAAc,KAAK,YAAY,QAAQ,IAAI;AAEjE,UAAQ,IAAI,cAAc;AAE1B,UAAQ,IAAI,uBAAuB;AAEnC,SAAO,QAAQ,IAAI;AAGnB,MAAI,WAAW;GACb,MAAM,aACJ,QAAQ,aAAa,UAAU,KAAK,KAAK,aAAa,aAAa,GAAG,KAAK,KAAK,aAAa,SAAS;GAExG,MAAM,gBAAgB,WAAiBA,OAAK,QAAQ,SAAS,eAAe;AAE5E,kBAAe,KAAK,gBAAgB,aAAa,WAAW,CAAC;AAC7D,kBAAe,KAAK,sBAAsB,aAAa,iBAAiB,CAAC;;QAEtE;AACL,iBAAe,MAAM,0DAA0D;AAC/E,iBAAe,MAAM,iEAAiE"}
1
+ {"version":3,"file":"activate-python-env.mjs","names":["path"],"sources":["../../src/utils/activate-python-env.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { internalLogger } from './internal-logger'\nimport { findPythonSitePackagesDir } from './python-version-utils'\n\ninterface VenvConfig {\n baseDir: string\n isVerbose?: boolean\n pythonVersion?: string\n}\n\nexport const getSitePackagesPath = ({ baseDir, pythonVersion = '3.13' }: VenvConfig): string => {\n const venvPath = path.join(baseDir, 'python_modules')\n const libPath = path.join(venvPath, 'lib')\n const actualPythonVersionPath = findPythonSitePackagesDir(libPath, pythonVersion)\n return path.join(venvPath, 'lib', actualPythonVersionPath, 'site-packages')\n}\n\nexport const activatePythonVenv = ({ baseDir, isVerbose = false, pythonVersion = '3.13' }: VenvConfig): void => {\n internalLogger.info('Activating Python environment')\n\n // Set the virtual environment path\n const venvPath = path.join(baseDir, 'python_modules')\n const venvBinPath = path.join(venvPath, process.platform === 'win32' ? 'Scripts' : 'bin')\n\n // Find the Python version directory using the utility function\n const sitePackagesPath = getSitePackagesPath({ baseDir, pythonVersion })\n\n // Add virtual environment to PATH\n process.env.PATH = `${venvBinPath}${path.delimiter}${process.env.PATH}`\n // Set VIRTUAL_ENV environment variable\n process.env.VIRTUAL_ENV = venvPath\n // Set PYTHON_SITE_PACKAGES with the site-packages path\n process.env.PYTHON_SITE_PACKAGES = sitePackagesPath\n // Remove PYTHONHOME if it exists as it can interfere with venv\n delete process.env.PYTHONHOME\n\n // Log Python environment information if verbose mode is enabled\n if (isVerbose) {\n const pythonPath =\n process.platform === 'win32' ? path.join(venvBinPath, 'python.exe') : path.join(venvBinPath, 'python')\n\n const relativePath = (path: string) => path.replace(baseDir, '<projectDir>')\n\n internalLogger.info('Using Python', relativePath(pythonPath))\n internalLogger.info('Site-packages path', relativePath(sitePackagesPath))\n }\n}\n"],"mappings":";;;;;AAWA,MAAa,uBAAuB,EAAE,SAAS,gBAAgB,aAAiC;CAC9F,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;CAErD,MAAM,0BAA0B,0BADhB,KAAK,KAAK,UAAU,MAAM,EACyB,cAAc;AACjF,QAAO,KAAK,KAAK,UAAU,OAAO,yBAAyB,gBAAgB;;AAG7E,MAAa,sBAAsB,EAAE,SAAS,YAAY,OAAO,gBAAgB,aAA+B;AAC9G,gBAAe,KAAK,gCAAgC;CAGpD,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;CACrD,MAAM,cAAc,KAAK,KAAK,UAAU,QAAQ,aAAa,UAAU,YAAY,MAAM;CAGzF,MAAM,mBAAmB,oBAAoB;EAAE;EAAS;EAAe,CAAC;AAGxE,SAAQ,IAAI,OAAO,GAAG,cAAc,KAAK,YAAY,QAAQ,IAAI;AAEjE,SAAQ,IAAI,cAAc;AAE1B,SAAQ,IAAI,uBAAuB;AAEnC,QAAO,QAAQ,IAAI;AAGnB,KAAI,WAAW;EACb,MAAM,aACJ,QAAQ,aAAa,UAAU,KAAK,KAAK,aAAa,aAAa,GAAG,KAAK,KAAK,aAAa,SAAS;EAExG,MAAM,gBAAgB,WAAiBA,OAAK,QAAQ,SAAS,eAAe;AAE5E,iBAAe,KAAK,gBAAgB,aAAa,WAAW,CAAC;AAC7D,iBAAe,KAAK,sBAAsB,aAAa,iBAAiB,CAAC"}
@@ -52,6 +52,27 @@ async function validatePythonEnvironment({ baseDir, hasPythonFiles, pythonVersio
52
52
  hasPythonFiles: true
53
53
  };
54
54
  }
55
+ try {
56
+ if (fs.readdirSync(libPath).filter((item) => item.startsWith("python3")).length === 0) {
57
+ const installCmd = getInstallCommand(baseDir);
58
+ internalLogger.error("Python environment is incomplete");
59
+ internalLogger.info("The python_modules/lib directory exists but contains no Python version directories");
60
+ internalLogger.info(`Run '${installCmd}' to recreate your Python environment`);
61
+ return {
62
+ success: false,
63
+ hasPythonFiles: true
64
+ };
65
+ }
66
+ } catch (error) {
67
+ const installCmd = getInstallCommand(baseDir);
68
+ internalLogger.error("Python environment is incomplete");
69
+ internalLogger.info("The python_modules/lib directory cannot be read");
70
+ internalLogger.info(`Run '${installCmd}' to recreate your Python environment`);
71
+ return {
72
+ success: false,
73
+ hasPythonFiles: true
74
+ };
75
+ }
55
76
  return {
56
77
  success: true,
57
78
  hasPythonFiles: true
@@ -1 +1 @@
1
- {"version":3,"file":"validate-python-environment.mjs","names":[],"sources":["../../src/utils/validate-python-environment.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { getPackageManager } from './get-package-manager'\nimport { internalLogger } from './internal-logger'\nimport { getPythonCommand } from './python-version-utils'\n\nexport interface ValidationResult {\n success: boolean\n hasPythonFiles: boolean\n}\n\ninterface ValidateConfig {\n baseDir: string\n hasPythonFiles: boolean\n pythonVersion?: string\n}\n\nfunction getInstallCommand(baseDir: string): string {\n const pm = getPackageManager(baseDir)\n switch (pm) {\n case 'yarn':\n return 'yarn install'\n case 'pnpm':\n return 'pnpm install'\n case 'bun':\n return 'bun install'\n case 'npm':\n default:\n return 'npm install'\n }\n}\n\nexport async function validatePythonEnvironment({\n baseDir,\n hasPythonFiles,\n pythonVersion = '3.13',\n}: ValidateConfig): Promise<ValidationResult> {\n if (!hasPythonFiles) {\n return { success: true, hasPythonFiles: false }\n }\n\n try {\n await getPythonCommand(pythonVersion, baseDir)\n } catch {\n internalLogger.error('Python is not installed')\n internalLogger.info('Python files were detected in your project but Python 3 is not available')\n internalLogger.info('Please install Python 3.10 or higher: https://www.python.org/downloads/')\n return { success: false, hasPythonFiles: true }\n }\n\n const venvPath = path.join(baseDir, 'python_modules')\n if (!fs.existsSync(venvPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment not configured')\n internalLogger.info('The python_modules directory was not found')\n internalLogger.info(`Run '${installCmd}' to set up your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n const libPath = path.join(venvPath, 'lib')\n if (!fs.existsSync(libPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules directory exists but appears to be corrupted')\n internalLogger.info(`Run '${installCmd}' to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n return { success: true, hasPythonFiles: true }\n}\n"],"mappings":";;;;;;;AAiBA,SAAS,kBAAkB,SAAyB;AAElD,SADW,kBAAkB,QAAQ,EACrC;EACE,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,eAAsB,0BAA0B,EAC9C,SACA,gBACA,gBAAgB,UAC4B;AAC5C,KAAI,CAAC,eACH,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAO;AAGjD,KAAI;AACF,QAAM,iBAAiB,eAAe,QAAQ;SACxC;AACN,iBAAe,MAAM,0BAA0B;AAC/C,iBAAe,KAAK,2EAA2E;AAC/F,iBAAe,KAAK,0EAA0E;AAC9F,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;AACrD,KAAI,CAAC,GAAG,WAAW,SAAS,EAAE;EAC5B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,oCAAoC;AACzD,iBAAe,KAAK,6CAA6C;AACjE,iBAAe,KAAK,QAAQ,WAAW,qCAAqC;AAC5E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,UAAU,KAAK,KAAK,UAAU,MAAM;AAC1C,KAAI,CAAC,GAAG,WAAW,QAAQ,EAAE;EAC3B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kEAAkE;AACtF,iBAAe,KAAK,QAAQ,WAAW,uCAAuC;AAC9E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;AAGjD,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAM"}
1
+ {"version":3,"file":"validate-python-environment.mjs","names":["error: any"],"sources":["../../src/utils/validate-python-environment.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { getPackageManager } from './get-package-manager'\nimport { internalLogger } from './internal-logger'\nimport { getPythonCommand } from './python-version-utils'\n\nexport interface ValidationResult {\n success: boolean\n hasPythonFiles: boolean\n}\n\ninterface ValidateConfig {\n baseDir: string\n hasPythonFiles: boolean\n pythonVersion?: string\n}\n\nfunction getInstallCommand(baseDir: string): string {\n const pm = getPackageManager(baseDir)\n switch (pm) {\n case 'yarn':\n return 'yarn install'\n case 'pnpm':\n return 'pnpm install'\n case 'bun':\n return 'bun install'\n case 'npm':\n default:\n return 'npm install'\n }\n}\n\nexport async function validatePythonEnvironment({\n baseDir,\n hasPythonFiles,\n pythonVersion = '3.13',\n}: ValidateConfig): Promise<ValidationResult> {\n if (!hasPythonFiles) {\n return { success: true, hasPythonFiles: false }\n }\n\n try {\n await getPythonCommand(pythonVersion, baseDir)\n } catch {\n internalLogger.error('Python is not installed')\n internalLogger.info('Python files were detected in your project but Python 3 is not available')\n internalLogger.info('Please install Python 3.10 or higher: https://www.python.org/downloads/')\n return { success: false, hasPythonFiles: true }\n }\n\n const venvPath = path.join(baseDir, 'python_modules')\n if (!fs.existsSync(venvPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment not configured')\n internalLogger.info('The python_modules directory was not found')\n internalLogger.info(`Run '${installCmd}' to set up your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n const libPath = path.join(venvPath, 'lib')\n if (!fs.existsSync(libPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules directory exists but appears to be corrupted')\n internalLogger.info(`Run '${installCmd}' to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n try {\n const libContents = fs.readdirSync(libPath)\n const pythonDirs = libContents.filter((item) => item.startsWith('python3'))\n\n if (pythonDirs.length === 0) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules/lib directory exists but contains no Python version directories')\n internalLogger.info(`Run '${installCmd}' to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n } catch (error: any) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules/lib directory cannot be read')\n internalLogger.info(`Run '${installCmd}' to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n return { success: true, hasPythonFiles: true }\n}\n"],"mappings":";;;;;;;AAiBA,SAAS,kBAAkB,SAAyB;AAElD,SADW,kBAAkB,QAAQ,EACrC;EACE,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,eAAsB,0BAA0B,EAC9C,SACA,gBACA,gBAAgB,UAC4B;AAC5C,KAAI,CAAC,eACH,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAO;AAGjD,KAAI;AACF,QAAM,iBAAiB,eAAe,QAAQ;SACxC;AACN,iBAAe,MAAM,0BAA0B;AAC/C,iBAAe,KAAK,2EAA2E;AAC/F,iBAAe,KAAK,0EAA0E;AAC9F,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;AACrD,KAAI,CAAC,GAAG,WAAW,SAAS,EAAE;EAC5B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,oCAAoC;AACzD,iBAAe,KAAK,6CAA6C;AACjE,iBAAe,KAAK,QAAQ,WAAW,qCAAqC;AAC5E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,UAAU,KAAK,KAAK,UAAU,MAAM;AAC1C,KAAI,CAAC,GAAG,WAAW,QAAQ,EAAE;EAC3B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kEAAkE;AACtF,iBAAe,KAAK,QAAQ,WAAW,uCAAuC;AAC9E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;AAGjD,KAAI;AAIF,MAHoB,GAAG,YAAY,QAAQ,CACZ,QAAQ,SAAS,KAAK,WAAW,UAAU,CAAC,CAE5D,WAAW,GAAG;GAC3B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,kBAAe,MAAM,mCAAmC;AACxD,kBAAe,KAAK,qFAAqF;AACzG,kBAAe,KAAK,QAAQ,WAAW,uCAAuC;AAC9E,UAAO;IAAE,SAAS;IAAO,gBAAgB;IAAM;;UAE1CA,OAAY;EACnB,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kDAAkD;AACtE,iBAAe,KAAK,QAAQ,WAAW,uCAAuC;AAC9E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;AAGjD,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAM"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "motia",
3
3
  "description": "Build production-grade backends with a single primitive. APIs, background jobs, Queues, Workflows, and AI agents - unified in one system with built-in State management, Streaming, and Observability.",
4
- "version": "0.15.4-beta.170-980856",
4
+ "version": "0.15.4-beta.170-590272",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
7
7
  "repository": {
@@ -46,13 +46,13 @@
46
46
  "table": "^6.9.0",
47
47
  "ts-node": "^10.9.2",
48
48
  "zod": "^4.1.12",
49
- "@motiadev/adapter-bullmq-events": "0.15.4-beta.170-980856",
50
- "@motiadev/adapter-redis-cron": "0.15.4-beta.170-980856",
51
- "@motiadev/adapter-redis-state": "0.15.4-beta.170-980856",
52
- "@motiadev/adapter-redis-streams": "0.15.4-beta.170-980856",
53
- "@motiadev/core": "0.15.4-beta.170-980856",
54
- "@motiadev/stream-client-node": "0.15.4-beta.170-980856",
55
- "@motiadev/workbench": "0.15.4-beta.170-980856"
49
+ "@motiadev/adapter-redis-cron": "0.15.4-beta.170-590272",
50
+ "@motiadev/adapter-bullmq-events": "0.15.4-beta.170-590272",
51
+ "@motiadev/adapter-redis-state": "0.15.4-beta.170-590272",
52
+ "@motiadev/adapter-redis-streams": "0.15.4-beta.170-590272",
53
+ "@motiadev/workbench": "0.15.4-beta.170-590272",
54
+ "@motiadev/stream-client-node": "0.15.4-beta.170-590272",
55
+ "@motiadev/core": "0.15.4-beta.170-590272"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@amplitude/analytics-types": "^2.9.2",