motia 0.17.9-beta.192-311932 → 0.17.9-beta.192-406008
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.
- package/dist/_virtual/rolldown_runtime.mjs +7 -0
- package/dist/create/index.mjs +4 -10
- package/dist/create/index.mjs.map +1 -1
- package/dist/plugins/install-plugin-dependencies.mjs +3 -5
- package/dist/plugins/install-plugin-dependencies.mjs.map +1 -1
- package/dist/redis/memory-manager.mjs +40 -8
- package/dist/redis/memory-manager.mjs.map +1 -1
- package/dist/utils/build-npm-command.mjs +51 -0
- package/dist/utils/build-npm-command.mjs.map +1 -0
- package/dist/utils/check-build-tools.mjs +97 -0
- package/dist/utils/check-build-tools.mjs.map +1 -0
- package/dist/utils/detect-wsl.mjs +39 -0
- package/dist/utils/detect-wsl.mjs.map +1 -0
- package/dist/utils/validate-python-environment.mjs +4 -6
- package/dist/utils/validate-python-environment.mjs.map +1 -1
- package/package.json +8 -8
package/dist/create/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { version } from "../version.mjs";
|
|
2
2
|
import { executeCommand } from "../utils/execute-command.mjs";
|
|
3
|
+
import { getInstallCommands, getInstallSaveCommands } from "../utils/build-npm-command.mjs";
|
|
3
4
|
import { checkIfDirectoryExists, checkIfFileExists } from "./utils.mjs";
|
|
4
5
|
import { getPackageManager, getPackageManagerFromEnv } from "../utils/get-package-manager.mjs";
|
|
5
6
|
import { generateTypes } from "../generate-types.mjs";
|
|
@@ -16,12 +17,7 @@ import { fileURLToPath } from "url";
|
|
|
16
17
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
18
|
const installRequiredDependencies = async (packageManager, rootDir, context) => {
|
|
18
19
|
context.log("installing-dependencies", (message) => message.tag("info").append("Installing dependencies..."));
|
|
19
|
-
const installCommand =
|
|
20
|
-
npm: "npm install --save",
|
|
21
|
-
yarn: "yarn add",
|
|
22
|
-
pnpm: "pnpm add",
|
|
23
|
-
bun: "bun add"
|
|
24
|
-
}[packageManager];
|
|
20
|
+
const installCommand = getInstallSaveCommands(rootDir)[packageManager];
|
|
25
21
|
const dependencies = [
|
|
26
22
|
`motia@${version}`,
|
|
27
23
|
"zod@4.1.12",
|
|
@@ -167,10 +163,8 @@ const create = async ({ projectName, template, cursorEnabled, context, skipRedis
|
|
|
167
163
|
packageManager = await preparePackageManager(rootDir, context, true);
|
|
168
164
|
context.log("installing-plugin-dependencies", (message) => message.tag("info").append("Installing plugin dependencies..."));
|
|
169
165
|
const installCommand = {
|
|
170
|
-
|
|
171
|
-
yarn: "yarn"
|
|
172
|
-
pnpm: "pnpm install",
|
|
173
|
-
bun: "bun install"
|
|
166
|
+
...getInstallCommands(rootDir),
|
|
167
|
+
yarn: "yarn"
|
|
174
168
|
}[packageManager];
|
|
175
169
|
try {
|
|
176
170
|
await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand}`, rootDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["packageManager: string"],"sources":["../../src/create/index.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport pc from 'picocolors'\nimport { fileURLToPath } from 'url'\nimport type { CliContext, Message } from '../cloud/config-utils'\nimport { generateTypes } from '../generate-types'\nimport { pythonInstall } from '../install'\nimport { pluginDependencies } from '../plugins/plugin-dependencies'\nimport { executeCommand } from '../utils/execute-command'\nimport { getPackageManager, getPackageManagerFromEnv } from '../utils/get-package-manager'\nimport { version } from '../version'\nimport { pullRules } from './pull-rules'\nimport { setupTemplate } from './setup-template'\nimport { checkIfDirectoryExists, checkIfFileExists } from './utils'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\n\nconst installRequiredDependencies = async (packageManager: string, rootDir: string, context: CliContext) => {\n context.log('installing-dependencies', (message: Message) => message.tag('info').append('Installing dependencies...'))\n\n const installCommand = {\n npm: 'npm install --save',\n yarn: 'yarn add',\n pnpm: 'pnpm add',\n bun: 'bun add',\n }[packageManager]\n\n const dependencies = [\n `motia@${version}`,\n 'zod@4.1.12',\n `@motiadev/adapter-bullmq-events@${version}`,\n ...pluginDependencies.map((dep: string) => `${dep}@${version}`),\n ].join(' ')\n\n const devDependencies = [\n 'ts-node@10.9.2',\n 'typescript@5.7.3',\n '@types/react@19.1.1',\n `@motiadev/workbench@${version}`,\n ].join(' ')\n\n try {\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand} ${dependencies}`, rootDir)\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand} -D ${devDependencies}`, rootDir)\n\n context.log('dependencies-installed', (message: Message) => message.tag('success').append('Dependencies installed'))\n } catch (error) {\n console.error('❌ Failed to install dependencies:', error)\n }\n}\n\nconst preparePackageManager = async (rootDir: string, context: CliContext, detectFromParent = false) => {\n const detectionDir = detectFromParent ? process.cwd() : rootDir\n const envPackageManager = getPackageManagerFromEnv()\n const packageManager = getPackageManager(detectionDir)\n\n const isFallback =\n !envPackageManager && packageManager === 'npm' && !checkIfFileExists(detectionDir, 'package-lock.json')\n\n if (isFallback) {\n context.log('package-manager-using-default', (message: Message) =>\n message.tag('info').append('Using default package manager').append(packageManager, 'gray'),\n )\n } else {\n context.log('package-manager-detected', (message: Message) =>\n message.tag('info').append('Detected package manager').append(packageManager, 'gray'),\n )\n }\n\n return packageManager\n}\n\nconst installNodeDependencies = async (rootDir: string, context: CliContext) => {\n const packageManager = await preparePackageManager(rootDir, context)\n\n await installRequiredDependencies(packageManager, rootDir, context).catch((error: unknown) => {\n context.log('failed-to-install-dependencies', (message: Message) =>\n message.tag('failed').append('Failed to install dependencies'),\n )\n console.error(error)\n })\n\n return packageManager\n}\n\ntype Args = {\n projectName: string\n template: string\n cursorEnabled: boolean\n context: CliContext\n skipTutorialTemplates?: boolean\n skipRedis?: boolean\n}\n\nexport const create = async ({\n projectName,\n template,\n cursorEnabled,\n context,\n skipRedis = false,\n}: Args): Promise<void> => {\n console.log(\n '\\n\\n' +\n `\n _____ ______ ______ ______\n /'\\\\_/\\`\\\\/\\\\ __\\`\\\\/\\\\__ _\\\\/\\\\__ _\\\\ /\\\\ _ \\\\\n /\\\\ \\\\ \\\\ \\\\/\\\\ \\\\/_/\\\\ \\\\/\\\\/_/\\\\ \\\\/ \\\\ \\\\ \\\\L\\\\ \\\\\n \\\\ \\\\ \\\\__\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ __ \\\\\n \\\\ \\\\ \\\\_/\\\\ \\\\ \\\\ \\\\_\\\\ \\\\ \\\\ \\\\ \\\\ \\\\_\\\\ \\\\__\\\\ \\\\ \\\\/\\\\ \\\\\n \\\\ \\\\_\\\\\\\\ \\\\_\\\\ \\\\_____\\\\ \\\\ \\\\_\\\\ /\\\\_____\\\\\\\\ \\\\_\\\\ \\\\_\\\\\n \\\\/_/ \\\\/_/\\\\/_____/ \\\\/_/ \\\\/_____/ \\\\/_/\\\\/_/\n ` +\n '\\n\\n',\n )\n\n const isCurrentDir = projectName === '.' || projectName === './' || projectName === '.\\\\'\n const rootDir = isCurrentDir ? process.cwd() : path.join(process.cwd(), projectName)\n const isPluginTemplate = template === 'plugin'\n\n process.env.REDISMS_DISABLE_POSTINSTALL = '1'\n if (!isCurrentDir && !checkIfDirectoryExists(rootDir)) {\n fs.mkdirSync(path.join(rootDir))\n context.log('directory-created', (message: Message) =>\n message.tag('success').append('Directory created ').append(projectName, 'gray'),\n )\n } else {\n context.log('directory-using', (message: Message) => message.tag('info').append('Using current directory'))\n }\n\n // Plugin template handles package.json differently (via template)\n if (!isPluginTemplate && !checkIfFileExists(rootDir, 'package.json')) {\n const finalProjectName =\n !projectName || projectName === '.' || projectName === './' || projectName === '.\\\\'\n ? path.basename(process.cwd())\n : projectName.trim()\n\n const packageJsonContent = {\n name: finalProjectName,\n description: '',\n type: 'module',\n scripts: {\n postinstall: 'motia install',\n dev: 'motia dev',\n start: 'motia start',\n 'generate-types': 'motia generate-types',\n build: 'motia build',\n clean: 'rm -rf dist node_modules python_modules .motia .mermaid',\n //'generate:config': 'motia get-config --output ./', TODO: doesnt work at the moment\n },\n keywords: ['motia'],\n }\n\n fs.writeFileSync(path.join(rootDir, 'package.json'), JSON.stringify(packageJsonContent, null, 2))\n\n context.log('package-json-created', (message: Message) =>\n message.tag('success').append('File').append('package.json', 'cyan').append('has been created.'),\n )\n } else if (!isPluginTemplate) {\n const packageJsonPath = path.join(rootDir, 'package.json')\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n if (!packageJson.scripts) {\n packageJson.scripts = {}\n }\n\n if (!packageJson.scripts.dev) {\n packageJson.scripts.dev = 'motia dev'\n } else {\n packageJson.scripts.olddev = packageJson.scripts.dev\n packageJson.scripts.dev = 'motia dev'\n context.log('dev-command-already-exists', (message: Message) =>\n message.tag('warning').append('dev command already exists in package.json'),\n )\n }\n\n fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))\n context.log('dev-command-updated', (message: Message) =>\n message\n .tag('success')\n .append('Updated')\n .append('dev', 'gray')\n .append('command to')\n .append('package.json', 'gray'),\n )\n }\n\n // Plugin template handles tsconfig.json via template\n if (!isPluginTemplate && !checkIfFileExists(rootDir, 'tsconfig.json')) {\n const tsconfigContent = {\n compilerOptions: {\n target: 'ES2020',\n module: 'ESNext',\n moduleResolution: 'bundler',\n allowImportingTsExtensions: true,\n noEmit: true,\n esModuleInterop: true,\n strict: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n allowJs: true,\n outDir: 'dist',\n rootDir: '.',\n baseUrl: '.',\n jsx: 'react-jsx',\n },\n include: ['**/*.ts', 'motia.config.ts', '**/*.tsx', 'types.d.ts', '**/*.jsx'],\n exclude: ['node_modules', 'dist', 'tests'],\n }\n\n fs.writeFileSync(path.join(rootDir, 'tsconfig.json'), JSON.stringify(tsconfigContent, null, 2))\n context.log('tsconfig-json-created', (message: Message) =>\n message.tag('success').append('File').append('tsconfig.json', 'cyan').append('has been created.'),\n )\n }\n\n // Plugin template handles .gitignore via template\n if (!isPluginTemplate && !checkIfFileExists(rootDir, '.gitignore')) {\n const gitignoreContent = [\n 'node_modules',\n 'python_modules',\n '.venv',\n 'venv',\n '.motia',\n '.mermaid',\n 'dist',\n '*.pyc',\n ].join('\\n')\n\n fs.writeFileSync(path.join(rootDir, '.gitignore'), gitignoreContent)\n context.log('gitignore-created', (message: Message) =>\n message.tag('success').append('File').append('.gitignore', 'cyan').append('has been created.'),\n )\n }\n\n // Skip cursor rules for plugin template\n if (!isPluginTemplate && cursorEnabled) {\n await pullRules({ force: true, rootDir }, context)\n }\n\n if (template) {\n await setupTemplate(template, rootDir, context)\n }\n\n if (!isPluginTemplate && skipRedis) {\n const motiaConfigPath = path.join(rootDir, 'motia.config.ts')\n\n const templatePath = path.join(__dirname, 'templates/motia.config.external-redis.ts.txt')\n const templateContent = fs.readFileSync(templatePath, 'utf-8')\n fs.writeFileSync(motiaConfigPath, templateContent)\n context.log('motia-config-created', (message: Message) =>\n message.tag('success').append('File').append('motia.config.ts', 'cyan').append('has been created.'),\n )\n }\n\n let packageManager: string\n if (!isPluginTemplate) {\n packageManager = await installNodeDependencies(rootDir, context)\n\n if (template.includes('python') || template.includes('multilang')) {\n await pythonInstall({ baseDir: rootDir })\n }\n\n await generateTypes(rootDir)\n } else {\n packageManager = await preparePackageManager(rootDir, context, true)\n\n context.log('installing-plugin-dependencies', (message: Message) =>\n message.tag('info').append('Installing plugin dependencies...'),\n )\n\n const installCommand = {\n npm: 'npm install',\n yarn: 'yarn',\n pnpm: 'pnpm install',\n bun: 'bun install',\n }[packageManager]\n\n try {\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand!}`, rootDir)\n context.log('plugin-dependencies-installed', (message: Message) =>\n message.tag('success').append('Plugin dependencies installed'),\n )\n } catch (error) {\n context.log('failed-to-install-plugin-dependencies', (message: Message) =>\n message.tag('failed').append('Failed to install plugin dependencies'),\n )\n console.error(error)\n }\n }\n\n const projectDirName = path.basename(rootDir)\n const devCommand = `${packageManager} run dev`\n const port = 3000\n const cdCommand = isCurrentDir ? '' : `${pc.cyan(`cd ${projectDirName}`)}\\n `\n\n context.log('success-blank', (message) => message.text(''))\n context.log('success-header', (message) =>\n message.text(`${pc.green('✨')} ${pc.bold('All set! Your project is ready to go.')}`),\n )\n context.log('success-blank-2', (message) => message.text(''))\n context.log('success-get-started', (message) => message.text('Get started:'))\n context.log('success-blank-3', (message) => message.text(''))\n context.log('success-commands', (message) => message.text(` ${cdCommand}${pc.cyan(devCommand)}`))\n context.log('success-blank-4', (message) => message.text(''))\n context.log('success-open', (message) => message.text(`Then open ${pc.cyan(`http://localhost:${port}`)}`))\n context.log('success-blank-5', (message: Message) => message.text(''))\n context.log('success-docs', (message) => message.text(`Docs: ${pc.cyan('https://www.motia.dev/docs')}`))\n context.log('success-blank-6', (message) => message.text(''))\n if (skipRedis) {\n context.log('redis-skip-warning', (message: Message) =>\n message\n .tag('warning')\n .append(\n '⚠️ You skipped Redis binary installation. Make sure to provide a Redis connection before running Motia.',\n ),\n )\n context.log('success-blank-7', (message) => message.text(''))\n }\n context.log('success-signoff', (message) => message.text('Happy coding! 🚀'))\n context.log('success-blank-8', (message) => message.text(''))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["packageManager: string"],"sources":["../../src/create/index.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport pc from 'picocolors'\nimport { fileURLToPath } from 'url'\nimport type { CliContext, Message } from '../cloud/config-utils'\nimport { generateTypes } from '../generate-types'\nimport { pythonInstall } from '../install'\nimport { pluginDependencies } from '../plugins/plugin-dependencies'\nimport { getInstallCommands, getInstallSaveCommands } from '../utils/build-npm-command'\nimport { executeCommand } from '../utils/execute-command'\nimport { getPackageManager, getPackageManagerFromEnv } from '../utils/get-package-manager'\nimport { version } from '../version'\nimport { pullRules } from './pull-rules'\nimport { setupTemplate } from './setup-template'\nimport { checkIfDirectoryExists, checkIfFileExists } from './utils'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\n\nconst installRequiredDependencies = async (packageManager: string, rootDir: string, context: CliContext) => {\n context.log('installing-dependencies', (message: Message) => message.tag('info').append('Installing dependencies...'))\n\n const installCommand = getInstallSaveCommands(rootDir)[packageManager]\n\n const dependencies = [\n `motia@${version}`,\n 'zod@4.1.12',\n `@motiadev/adapter-bullmq-events@${version}`,\n ...pluginDependencies.map((dep: string) => `${dep}@${version}`),\n ].join(' ')\n\n const devDependencies = [\n 'ts-node@10.9.2',\n 'typescript@5.7.3',\n '@types/react@19.1.1',\n `@motiadev/workbench@${version}`,\n ].join(' ')\n\n try {\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand} ${dependencies}`, rootDir)\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand} -D ${devDependencies}`, rootDir)\n\n context.log('dependencies-installed', (message: Message) => message.tag('success').append('Dependencies installed'))\n } catch (error) {\n console.error('❌ Failed to install dependencies:', error)\n }\n}\n\nconst preparePackageManager = async (rootDir: string, context: CliContext, detectFromParent = false) => {\n const detectionDir = detectFromParent ? process.cwd() : rootDir\n const envPackageManager = getPackageManagerFromEnv()\n const packageManager = getPackageManager(detectionDir)\n\n const isFallback =\n !envPackageManager && packageManager === 'npm' && !checkIfFileExists(detectionDir, 'package-lock.json')\n\n if (isFallback) {\n context.log('package-manager-using-default', (message: Message) =>\n message.tag('info').append('Using default package manager').append(packageManager, 'gray'),\n )\n } else {\n context.log('package-manager-detected', (message: Message) =>\n message.tag('info').append('Detected package manager').append(packageManager, 'gray'),\n )\n }\n\n return packageManager\n}\n\nconst installNodeDependencies = async (rootDir: string, context: CliContext) => {\n const packageManager = await preparePackageManager(rootDir, context)\n\n await installRequiredDependencies(packageManager, rootDir, context).catch((error: unknown) => {\n context.log('failed-to-install-dependencies', (message: Message) =>\n message.tag('failed').append('Failed to install dependencies'),\n )\n console.error(error)\n })\n\n return packageManager\n}\n\ntype Args = {\n projectName: string\n template: string\n cursorEnabled: boolean\n context: CliContext\n skipTutorialTemplates?: boolean\n skipRedis?: boolean\n}\n\nexport const create = async ({\n projectName,\n template,\n cursorEnabled,\n context,\n skipRedis = false,\n}: Args): Promise<void> => {\n console.log(\n '\\n\\n' +\n `\n _____ ______ ______ ______\n /'\\\\_/\\`\\\\/\\\\ __\\`\\\\/\\\\__ _\\\\/\\\\__ _\\\\ /\\\\ _ \\\\\n /\\\\ \\\\ \\\\ \\\\/\\\\ \\\\/_/\\\\ \\\\/\\\\/_/\\\\ \\\\/ \\\\ \\\\ \\\\L\\\\ \\\\\n \\\\ \\\\ \\\\__\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ __ \\\\\n \\\\ \\\\ \\\\_/\\\\ \\\\ \\\\ \\\\_\\\\ \\\\ \\\\ \\\\ \\\\ \\\\_\\\\ \\\\__\\\\ \\\\ \\\\/\\\\ \\\\\n \\\\ \\\\_\\\\\\\\ \\\\_\\\\ \\\\_____\\\\ \\\\ \\\\_\\\\ /\\\\_____\\\\\\\\ \\\\_\\\\ \\\\_\\\\\n \\\\/_/ \\\\/_/\\\\/_____/ \\\\/_/ \\\\/_____/ \\\\/_/\\\\/_/\n ` +\n '\\n\\n',\n )\n\n const isCurrentDir = projectName === '.' || projectName === './' || projectName === '.\\\\'\n const rootDir = isCurrentDir ? process.cwd() : path.join(process.cwd(), projectName)\n const isPluginTemplate = template === 'plugin'\n\n process.env.REDISMS_DISABLE_POSTINSTALL = '1'\n if (!isCurrentDir && !checkIfDirectoryExists(rootDir)) {\n fs.mkdirSync(path.join(rootDir))\n context.log('directory-created', (message: Message) =>\n message.tag('success').append('Directory created ').append(projectName, 'gray'),\n )\n } else {\n context.log('directory-using', (message: Message) => message.tag('info').append('Using current directory'))\n }\n\n // Plugin template handles package.json differently (via template)\n if (!isPluginTemplate && !checkIfFileExists(rootDir, 'package.json')) {\n const finalProjectName =\n !projectName || projectName === '.' || projectName === './' || projectName === '.\\\\'\n ? path.basename(process.cwd())\n : projectName.trim()\n\n const packageJsonContent = {\n name: finalProjectName,\n description: '',\n type: 'module',\n scripts: {\n postinstall: 'motia install',\n dev: 'motia dev',\n start: 'motia start',\n 'generate-types': 'motia generate-types',\n build: 'motia build',\n clean: 'rm -rf dist node_modules python_modules .motia .mermaid',\n //'generate:config': 'motia get-config --output ./', TODO: doesnt work at the moment\n },\n keywords: ['motia'],\n }\n\n fs.writeFileSync(path.join(rootDir, 'package.json'), JSON.stringify(packageJsonContent, null, 2))\n\n context.log('package-json-created', (message: Message) =>\n message.tag('success').append('File').append('package.json', 'cyan').append('has been created.'),\n )\n } else if (!isPluginTemplate) {\n const packageJsonPath = path.join(rootDir, 'package.json')\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n if (!packageJson.scripts) {\n packageJson.scripts = {}\n }\n\n if (!packageJson.scripts.dev) {\n packageJson.scripts.dev = 'motia dev'\n } else {\n packageJson.scripts.olddev = packageJson.scripts.dev\n packageJson.scripts.dev = 'motia dev'\n context.log('dev-command-already-exists', (message: Message) =>\n message.tag('warning').append('dev command already exists in package.json'),\n )\n }\n\n fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))\n context.log('dev-command-updated', (message: Message) =>\n message\n .tag('success')\n .append('Updated')\n .append('dev', 'gray')\n .append('command to')\n .append('package.json', 'gray'),\n )\n }\n\n // Plugin template handles tsconfig.json via template\n if (!isPluginTemplate && !checkIfFileExists(rootDir, 'tsconfig.json')) {\n const tsconfigContent = {\n compilerOptions: {\n target: 'ES2020',\n module: 'ESNext',\n moduleResolution: 'bundler',\n allowImportingTsExtensions: true,\n noEmit: true,\n esModuleInterop: true,\n strict: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n allowJs: true,\n outDir: 'dist',\n rootDir: '.',\n baseUrl: '.',\n jsx: 'react-jsx',\n },\n include: ['**/*.ts', 'motia.config.ts', '**/*.tsx', 'types.d.ts', '**/*.jsx'],\n exclude: ['node_modules', 'dist', 'tests'],\n }\n\n fs.writeFileSync(path.join(rootDir, 'tsconfig.json'), JSON.stringify(tsconfigContent, null, 2))\n context.log('tsconfig-json-created', (message: Message) =>\n message.tag('success').append('File').append('tsconfig.json', 'cyan').append('has been created.'),\n )\n }\n\n // Plugin template handles .gitignore via template\n if (!isPluginTemplate && !checkIfFileExists(rootDir, '.gitignore')) {\n const gitignoreContent = [\n 'node_modules',\n 'python_modules',\n '.venv',\n 'venv',\n '.motia',\n '.mermaid',\n 'dist',\n '*.pyc',\n ].join('\\n')\n\n fs.writeFileSync(path.join(rootDir, '.gitignore'), gitignoreContent)\n context.log('gitignore-created', (message: Message) =>\n message.tag('success').append('File').append('.gitignore', 'cyan').append('has been created.'),\n )\n }\n\n // Skip cursor rules for plugin template\n if (!isPluginTemplate && cursorEnabled) {\n await pullRules({ force: true, rootDir }, context)\n }\n\n if (template) {\n await setupTemplate(template, rootDir, context)\n }\n\n if (!isPluginTemplate && skipRedis) {\n const motiaConfigPath = path.join(rootDir, 'motia.config.ts')\n\n const templatePath = path.join(__dirname, 'templates/motia.config.external-redis.ts.txt')\n const templateContent = fs.readFileSync(templatePath, 'utf-8')\n fs.writeFileSync(motiaConfigPath, templateContent)\n context.log('motia-config-created', (message: Message) =>\n message.tag('success').append('File').append('motia.config.ts', 'cyan').append('has been created.'),\n )\n }\n\n let packageManager: string\n if (!isPluginTemplate) {\n packageManager = await installNodeDependencies(rootDir, context)\n\n if (template.includes('python') || template.includes('multilang')) {\n await pythonInstall({ baseDir: rootDir })\n }\n\n await generateTypes(rootDir)\n } else {\n packageManager = await preparePackageManager(rootDir, context, true)\n\n context.log('installing-plugin-dependencies', (message: Message) =>\n message.tag('info').append('Installing plugin dependencies...'),\n )\n\n const installCommands: Record<string, string> = {\n ...getInstallCommands(rootDir),\n yarn: 'yarn', // yarn uses plain 'yarn' for install\n }\n const installCommand = installCommands[packageManager]\n\n try {\n await executeCommand(`REDISMS_DISABLE_POSTINSTALL=1 ${installCommand!}`, rootDir)\n context.log('plugin-dependencies-installed', (message: Message) =>\n message.tag('success').append('Plugin dependencies installed'),\n )\n } catch (error) {\n context.log('failed-to-install-plugin-dependencies', (message: Message) =>\n message.tag('failed').append('Failed to install plugin dependencies'),\n )\n console.error(error)\n }\n }\n\n const projectDirName = path.basename(rootDir)\n const devCommand = `${packageManager} run dev`\n const port = 3000\n const cdCommand = isCurrentDir ? '' : `${pc.cyan(`cd ${projectDirName}`)}\\n `\n\n context.log('success-blank', (message) => message.text(''))\n context.log('success-header', (message) =>\n message.text(`${pc.green('✨')} ${pc.bold('All set! Your project is ready to go.')}`),\n )\n context.log('success-blank-2', (message) => message.text(''))\n context.log('success-get-started', (message) => message.text('Get started:'))\n context.log('success-blank-3', (message) => message.text(''))\n context.log('success-commands', (message) => message.text(` ${cdCommand}${pc.cyan(devCommand)}`))\n context.log('success-blank-4', (message) => message.text(''))\n context.log('success-open', (message) => message.text(`Then open ${pc.cyan(`http://localhost:${port}`)}`))\n context.log('success-blank-5', (message: Message) => message.text(''))\n context.log('success-docs', (message) => message.text(`Docs: ${pc.cyan('https://www.motia.dev/docs')}`))\n context.log('success-blank-6', (message) => message.text(''))\n if (skipRedis) {\n context.log('redis-skip-warning', (message: Message) =>\n message\n .tag('warning')\n .append(\n '⚠️ You skipped Redis binary installation. Make sure to provide a Redis connection before running Motia.',\n ),\n )\n context.log('success-blank-7', (message) => message.text(''))\n }\n context.log('success-signoff', (message) => message.text('Happy coding! 🚀'))\n context.log('success-blank-8', (message) => message.text(''))\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { version } from "../version.mjs";
|
|
2
2
|
import { executeCommand } from "../utils/execute-command.mjs";
|
|
3
|
+
import { getInstallCommands } from "../utils/build-npm-command.mjs";
|
|
3
4
|
import { getPackageManager } from "../utils/get-package-manager.mjs";
|
|
4
5
|
import { pluginDependencies } from "./plugin-dependencies.mjs";
|
|
5
6
|
import fs from "node:fs";
|
|
@@ -35,11 +36,8 @@ const installPluginDependencies = async (baseDir, printer) => {
|
|
|
35
36
|
packageManager = "npm";
|
|
36
37
|
}
|
|
37
38
|
printer.printPluginLog(`Installing dependencies using ${packageManager}...`);
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
yarn: "yarn install",
|
|
41
|
-
pnpm: "pnpm install"
|
|
42
|
-
}[packageManager] || "npm install";
|
|
39
|
+
const installCommands = getInstallCommands(baseDir);
|
|
40
|
+
const installCommand = installCommands[packageManager] || installCommands["npm"];
|
|
43
41
|
try {
|
|
44
42
|
await executeCommand(installCommand, baseDir, { silent: false });
|
|
45
43
|
printer.printPluginLog("Plugin dependencies installed successfully");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-plugin-dependencies.mjs","names":["missingDependencies: string[]"],"sources":["../../src/plugins/install-plugin-dependencies.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { Printer } from '@motiadev/core'\nimport { executeCommand } from '../utils/execute-command'\nimport { getPackageManager } from '../utils/get-package-manager'\nimport { version } from '../version'\nimport { pluginDependencies } from './plugin-dependencies'\n\nexport const installPluginDependencies = async (baseDir: string, printer: Printer): Promise<void> => {\n const packageJsonPath = path.join(baseDir, 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n printer.printPluginWarn('No package.json found, skipping plugin dependency installation')\n return\n }\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {}\n }\n\n const missingDependencies: string[] = []\n\n for (const dep of pluginDependencies) {\n if (packageJson.devDependencies?.[dep]) {\n delete packageJson.devDependencies[dep]\n }\n\n if (!packageJson.dependencies[dep]) {\n packageJson.dependencies[dep] = version\n missingDependencies.push(dep)\n }\n }\n\n if (missingDependencies.length === 0) {\n printer.printPluginLog('All plugin dependencies already installed')\n return\n }\n\n printer.printPluginLog(`Adding missing plugin dependencies: ${missingDependencies.join(', ')}`)\n\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`)\n printer.printPluginLog('Updated package.json with plugin dependencies')\n\n let packageManager = getPackageManager(baseDir)\n if (packageManager === 'unknown') {\n printer.printPluginError('No package manager found, using npm as default')\n packageManager = 'npm'\n }\n printer.printPluginLog(`Installing dependencies using ${packageManager}...`)\n\n const installCommands
|
|
1
|
+
{"version":3,"file":"install-plugin-dependencies.mjs","names":["missingDependencies: string[]"],"sources":["../../src/plugins/install-plugin-dependencies.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { Printer } from '@motiadev/core'\nimport { getInstallCommands } from '../utils/build-npm-command'\nimport { executeCommand } from '../utils/execute-command'\nimport { getPackageManager } from '../utils/get-package-manager'\nimport { version } from '../version'\nimport { pluginDependencies } from './plugin-dependencies'\n\nexport const installPluginDependencies = async (baseDir: string, printer: Printer): Promise<void> => {\n const packageJsonPath = path.join(baseDir, 'package.json')\n\n if (!fs.existsSync(packageJsonPath)) {\n printer.printPluginWarn('No package.json found, skipping plugin dependency installation')\n return\n }\n\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {}\n }\n\n const missingDependencies: string[] = []\n\n for (const dep of pluginDependencies) {\n if (packageJson.devDependencies?.[dep]) {\n delete packageJson.devDependencies[dep]\n }\n\n if (!packageJson.dependencies[dep]) {\n packageJson.dependencies[dep] = version\n missingDependencies.push(dep)\n }\n }\n\n if (missingDependencies.length === 0) {\n printer.printPluginLog('All plugin dependencies already installed')\n return\n }\n\n printer.printPluginLog(`Adding missing plugin dependencies: ${missingDependencies.join(', ')}`)\n\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`)\n printer.printPluginLog('Updated package.json with plugin dependencies')\n\n let packageManager = getPackageManager(baseDir)\n if (packageManager === 'unknown') {\n printer.printPluginError('No package manager found, using npm as default')\n packageManager = 'npm'\n }\n printer.printPluginLog(`Installing dependencies using ${packageManager}...`)\n\n const installCommands = getInstallCommands(baseDir)\n const installCommand = installCommands[packageManager] || installCommands['npm']\n\n try {\n await executeCommand(installCommand, baseDir, { silent: false })\n printer.printPluginLog('Plugin dependencies installed successfully')\n } catch (error) {\n printer.printPluginError('Failed to install plugin dependencies:', error)\n printer.printPluginWarn(`Please run '${installCommand}' manually to install the dependencies`)\n }\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,4BAA4B,OAAO,SAAiB,YAAoC;CACnG,MAAM,kBAAkB,KAAK,KAAK,SAAS,eAAe;AAE1D,KAAI,CAAC,GAAG,WAAW,gBAAgB,EAAE;AACnC,UAAQ,gBAAgB,iEAAiE;AACzF;;CAGF,MAAM,cAAc,KAAK,MAAM,GAAG,aAAa,iBAAiB,QAAQ,CAAC;AAEzE,KAAI,CAAC,YAAY,aACf,aAAY,eAAe,EAAE;CAG/B,MAAMA,sBAAgC,EAAE;AAExC,MAAK,MAAM,OAAO,oBAAoB;AACpC,MAAI,YAAY,kBAAkB,KAChC,QAAO,YAAY,gBAAgB;AAGrC,MAAI,CAAC,YAAY,aAAa,MAAM;AAClC,eAAY,aAAa,OAAO;AAChC,uBAAoB,KAAK,IAAI;;;AAIjC,KAAI,oBAAoB,WAAW,GAAG;AACpC,UAAQ,eAAe,4CAA4C;AACnE;;AAGF,SAAQ,eAAe,uCAAuC,oBAAoB,KAAK,KAAK,GAAG;AAE/F,IAAG,cAAc,iBAAiB,GAAG,KAAK,UAAU,aAAa,MAAM,EAAE,CAAC,IAAI;AAC9E,SAAQ,eAAe,gDAAgD;CAEvE,IAAI,iBAAiB,kBAAkB,QAAQ;AAC/C,KAAI,mBAAmB,WAAW;AAChC,UAAQ,iBAAiB,iDAAiD;AAC1E,mBAAiB;;AAEnB,SAAQ,eAAe,iCAAiC,eAAe,KAAK;CAE5E,MAAM,kBAAkB,mBAAmB,QAAQ;CACnD,MAAM,iBAAiB,gBAAgB,mBAAmB,gBAAgB;AAE1E,KAAI;AACF,QAAM,eAAe,gBAAgB,SAAS,EAAE,QAAQ,OAAO,CAAC;AAChE,UAAQ,eAAe,6CAA6C;UAC7D,OAAO;AACd,UAAQ,iBAAiB,0CAA0C,MAAM;AACzE,UAAQ,gBAAgB,eAAe,eAAe,wCAAwC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { internalLogger } from "../utils/internal-logger.mjs";
|
|
2
|
+
import { ensureBuildTools } from "../utils/check-build-tools.mjs";
|
|
1
3
|
import { mkdirSync } from "fs";
|
|
2
4
|
import { RedisMemoryServer } from "redis-memory-server";
|
|
3
5
|
|
|
@@ -21,6 +23,7 @@ var RedisMemoryManager = class {
|
|
|
21
23
|
}
|
|
22
24
|
async startServer(baseDir) {
|
|
23
25
|
if (!this.server) try {
|
|
26
|
+
await ensureBuildTools();
|
|
24
27
|
mkdirSync(baseDir, { recursive: true });
|
|
25
28
|
const instance = { args: [
|
|
26
29
|
"--appendonly",
|
|
@@ -34,23 +37,52 @@ var RedisMemoryManager = class {
|
|
|
34
37
|
] };
|
|
35
38
|
if (process.env.MOTIA_REDIS_PORT) instance.port = parseInt(process.env.MOTIA_REDIS_PORT || "6379");
|
|
36
39
|
this.server = new RedisMemoryServer({ instance });
|
|
37
|
-
console.log("Redis Memory Server started");
|
|
38
|
-
this.running = true;
|
|
39
40
|
this.registerCleanupHandlers();
|
|
40
41
|
} catch (error) {
|
|
41
|
-
|
|
42
|
+
internalLogger.error("Failed to initialize Redis Memory Server");
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
console.error(error.message);
|
|
45
|
+
if (process.env.LOG_LEVEL === "debug" && error.stack) {
|
|
46
|
+
console.error("\nStack trace:");
|
|
47
|
+
console.error(error.stack);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const host = await this.server.getHost();
|
|
54
|
+
const port = await this.server.getPort();
|
|
55
|
+
this.running = true;
|
|
56
|
+
internalLogger.info("Redis Memory Server started", `${host}:${port}`);
|
|
57
|
+
return {
|
|
58
|
+
host,
|
|
59
|
+
port
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
internalLogger.error("Failed to start Redis Memory Server");
|
|
63
|
+
if (error instanceof Error) {
|
|
64
|
+
console.error(error.message);
|
|
65
|
+
if (error.message.includes("make") || error.message.includes("compile")) {
|
|
66
|
+
console.error("\nThis error typically occurs when build tools are missing.");
|
|
67
|
+
console.error("Please ensure you have \"make\" and a C compiler installed.");
|
|
68
|
+
}
|
|
69
|
+
if (process.env.LOG_LEVEL === "debug" && error.stack) {
|
|
70
|
+
console.error("\nStack trace:");
|
|
71
|
+
console.error(error.stack);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
console.error("\nAlternative: Use an external Redis server");
|
|
75
|
+
console.error(" Set MOTIA_DISABLE_MEMORY_SERVER=true");
|
|
76
|
+
console.error(" Set MOTIA_REDIS_HOST=<your-redis-host>");
|
|
77
|
+
console.error(" Set MOTIA_REDIS_PORT=<your-redis-port> (default: 6379)");
|
|
42
78
|
throw error;
|
|
43
79
|
}
|
|
44
|
-
return {
|
|
45
|
-
host: await this.server.getHost(),
|
|
46
|
-
port: await this.server.getPort()
|
|
47
|
-
};
|
|
48
80
|
}
|
|
49
81
|
async stop() {
|
|
50
82
|
if (this.server && this.running) try {
|
|
51
83
|
await this.server.stop();
|
|
52
84
|
} catch (error) {
|
|
53
|
-
|
|
85
|
+
internalLogger.error("Error stopping Redis Memory Server", error?.message);
|
|
54
86
|
} finally {
|
|
55
87
|
this.running = false;
|
|
56
88
|
this.server = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-manager.mjs","names":["instance: RedisMemoryInstancePropT","error: unknown"],"sources":["../../src/redis/memory-manager.ts"],"sourcesContent":["import { mkdirSync } from 'fs'\nimport type { RedisClientType } from 'redis'\nimport { RedisMemoryServer } from 'redis-memory-server'\nimport type { RedisMemoryInstancePropT } from 'redis-memory-server/lib/types'\nimport type { RedisConnectionInfo } from './types'\n\nexport class RedisMemoryManager {\n private server: RedisMemoryServer | null = null\n private client: RedisClientType | null = null\n private running = false\n\n private registerCleanupHandlers(): void {\n process.on('exit', async () => {\n await this.stop()\n })\n process.on('SIGTERM', async () => {\n await this.stop()\n })\n\n process.on('SIGINT', async () => {\n await this.stop()\n })\n }\n\n async startServer(baseDir: string): Promise<RedisConnectionInfo> {\n if (!this.server) {\n try {\n mkdirSync(baseDir, { recursive: true })\n\n const instance: RedisMemoryInstancePropT = {\n args: ['--appendonly', 'yes', '--appendfsync', 'everysec', '--save', '\"\"', '--dir', baseDir],\n }\n\n if (process.env.MOTIA_REDIS_PORT) {\n instance.port = parseInt(process.env.MOTIA_REDIS_PORT || '6379')\n }\n\n this.server = new RedisMemoryServer({ instance })\n
|
|
1
|
+
{"version":3,"file":"memory-manager.mjs","names":["instance: RedisMemoryInstancePropT","error: unknown"],"sources":["../../src/redis/memory-manager.ts"],"sourcesContent":["import { mkdirSync } from 'fs'\nimport type { RedisClientType } from 'redis'\nimport { RedisMemoryServer } from 'redis-memory-server'\nimport type { RedisMemoryInstancePropT } from 'redis-memory-server/lib/types'\nimport { ensureBuildTools } from '../utils/check-build-tools'\nimport { internalLogger } from '../utils/internal-logger'\nimport type { RedisConnectionInfo } from './types'\n\nexport class RedisMemoryManager {\n private server: RedisMemoryServer | null = null\n private client: RedisClientType | null = null\n private running = false\n\n private registerCleanupHandlers(): void {\n process.on('exit', async () => {\n await this.stop()\n })\n process.on('SIGTERM', async () => {\n await this.stop()\n })\n\n process.on('SIGINT', async () => {\n await this.stop()\n })\n }\n\n async startServer(baseDir: string): Promise<RedisConnectionInfo> {\n if (!this.server) {\n try {\n // Check for required build tools before attempting to start\n await ensureBuildTools()\n\n mkdirSync(baseDir, { recursive: true })\n\n const instance: RedisMemoryInstancePropT = {\n args: ['--appendonly', 'yes', '--appendfsync', 'everysec', '--save', '\"\"', '--dir', baseDir],\n }\n\n if (process.env.MOTIA_REDIS_PORT) {\n instance.port = parseInt(process.env.MOTIA_REDIS_PORT || '6379')\n }\n\n this.server = new RedisMemoryServer({ instance })\n this.registerCleanupHandlers()\n } catch (error) {\n internalLogger.error('Failed to initialize Redis Memory Server')\n if (error instanceof Error) {\n console.error(error.message)\n if (process.env.LOG_LEVEL === 'debug' && error.stack) {\n console.error('\\nStack trace:')\n console.error(error.stack)\n }\n }\n throw error\n }\n }\n\n try {\n const host = await this.server.getHost()\n const port = await this.server.getPort()\n\n this.running = true\n internalLogger.info('Redis Memory Server started', `${host}:${port}`)\n\n return { host, port }\n } catch (error) {\n internalLogger.error('Failed to start Redis Memory Server')\n\n if (error instanceof Error) {\n console.error(error.message)\n\n // Provide helpful suggestions based on common error patterns\n if (error.message.includes('make') || error.message.includes('compile')) {\n console.error('\\nThis error typically occurs when build tools are missing.')\n console.error('Please ensure you have \"make\" and a C compiler installed.')\n }\n\n if (process.env.LOG_LEVEL === 'debug' && error.stack) {\n console.error('\\nStack trace:')\n console.error(error.stack)\n }\n }\n\n console.error('\\nAlternative: Use an external Redis server')\n console.error(' Set MOTIA_DISABLE_MEMORY_SERVER=true')\n console.error(' Set MOTIA_REDIS_HOST=<your-redis-host>')\n console.error(' Set MOTIA_REDIS_PORT=<your-redis-port> (default: 6379)')\n\n throw error\n }\n }\n\n async stop(): Promise<void> {\n if (this.server && this.running) {\n try {\n await this.server.stop()\n } catch (error: unknown) {\n internalLogger.error('Error stopping Redis Memory Server', (error as Error)?.message)\n } finally {\n this.running = false\n this.server = null\n }\n }\n }\n\n isRunning(): boolean {\n return this.running\n }\n\n getClient(): RedisClientType | null {\n return this.client\n }\n}\n"],"mappings":";;;;;;AAQA,IAAa,qBAAb,MAAgC;;gBACa;gBACF;iBACvB;;CAElB,AAAQ,0BAAgC;AACtC,UAAQ,GAAG,QAAQ,YAAY;AAC7B,SAAM,KAAK,MAAM;IACjB;AACF,UAAQ,GAAG,WAAW,YAAY;AAChC,SAAM,KAAK,MAAM;IACjB;AAEF,UAAQ,GAAG,UAAU,YAAY;AAC/B,SAAM,KAAK,MAAM;IACjB;;CAGJ,MAAM,YAAY,SAA+C;AAC/D,MAAI,CAAC,KAAK,OACR,KAAI;AAEF,SAAM,kBAAkB;AAExB,aAAU,SAAS,EAAE,WAAW,MAAM,CAAC;GAEvC,MAAMA,WAAqC,EACzC,MAAM;IAAC;IAAgB;IAAO;IAAiB;IAAY;IAAU;IAAM;IAAS;IAAQ,EAC7F;AAED,OAAI,QAAQ,IAAI,iBACd,UAAS,OAAO,SAAS,QAAQ,IAAI,oBAAoB,OAAO;AAGlE,QAAK,SAAS,IAAI,kBAAkB,EAAE,UAAU,CAAC;AACjD,QAAK,yBAAyB;WACvB,OAAO;AACd,kBAAe,MAAM,2CAA2C;AAChE,OAAI,iBAAiB,OAAO;AAC1B,YAAQ,MAAM,MAAM,QAAQ;AAC5B,QAAI,QAAQ,IAAI,cAAc,WAAW,MAAM,OAAO;AACpD,aAAQ,MAAM,iBAAiB;AAC/B,aAAQ,MAAM,MAAM,MAAM;;;AAG9B,SAAM;;AAIV,MAAI;GACF,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;GACxC,MAAM,OAAO,MAAM,KAAK,OAAO,SAAS;AAExC,QAAK,UAAU;AACf,kBAAe,KAAK,+BAA+B,GAAG,KAAK,GAAG,OAAO;AAErE,UAAO;IAAE;IAAM;IAAM;WACd,OAAO;AACd,kBAAe,MAAM,sCAAsC;AAE3D,OAAI,iBAAiB,OAAO;AAC1B,YAAQ,MAAM,MAAM,QAAQ;AAG5B,QAAI,MAAM,QAAQ,SAAS,OAAO,IAAI,MAAM,QAAQ,SAAS,UAAU,EAAE;AACvE,aAAQ,MAAM,8DAA8D;AAC5E,aAAQ,MAAM,8DAA4D;;AAG5E,QAAI,QAAQ,IAAI,cAAc,WAAW,MAAM,OAAO;AACpD,aAAQ,MAAM,iBAAiB;AAC/B,aAAQ,MAAM,MAAM,MAAM;;;AAI9B,WAAQ,MAAM,8CAA8C;AAC5D,WAAQ,MAAM,yCAAyC;AACvD,WAAQ,MAAM,2CAA2C;AACzD,WAAQ,MAAM,2DAA2D;AAEzE,SAAM;;;CAIV,MAAM,OAAsB;AAC1B,MAAI,KAAK,UAAU,KAAK,QACtB,KAAI;AACF,SAAM,KAAK,OAAO,MAAM;WACjBC,OAAgB;AACvB,kBAAe,MAAM,sCAAuC,OAAiB,QAAQ;YAC7E;AACR,QAAK,UAAU;AACf,QAAK,SAAS;;;CAKpB,YAAqB;AACnB,SAAO,KAAK;;CAGd,YAAoC;AAClC,SAAO,KAAK"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { shouldUseNoBinLinks } from "./detect-wsl.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/build-npm-command.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build an npm install command with appropriate flags for the environment.
|
|
6
|
+
* Adds --no-bin-links when running in WSL2 on Windows filesystem to prevent
|
|
7
|
+
* EPERM errors during npm install.
|
|
8
|
+
*
|
|
9
|
+
* @param baseCommand - The base npm command (e.g., 'npm install --save' or 'npm install')
|
|
10
|
+
* @param targetPath - The path where the command will be executed
|
|
11
|
+
* @returns The command with appropriate flags added
|
|
12
|
+
*/
|
|
13
|
+
function buildNpmCommand(baseCommand, targetPath) {
|
|
14
|
+
if (!baseCommand.startsWith("npm ")) return baseCommand;
|
|
15
|
+
if (shouldUseNoBinLinks(targetPath)) {
|
|
16
|
+
if (baseCommand.includes("npm install")) return baseCommand.replace("npm install", "npm install --no-bin-links");
|
|
17
|
+
}
|
|
18
|
+
return baseCommand;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get install commands for all package managers, with WSL2 compatibility for npm.
|
|
22
|
+
*
|
|
23
|
+
* @param targetPath - The path where the command will be executed
|
|
24
|
+
* @returns Record of package manager to install command
|
|
25
|
+
*/
|
|
26
|
+
function getInstallCommands(targetPath) {
|
|
27
|
+
return {
|
|
28
|
+
npm: buildNpmCommand("npm install", targetPath),
|
|
29
|
+
yarn: "yarn install",
|
|
30
|
+
pnpm: "pnpm install",
|
|
31
|
+
bun: "bun install"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get install commands with --save flag for all package managers, with WSL2 compatibility for npm.
|
|
36
|
+
*
|
|
37
|
+
* @param targetPath - The path where the command will be executed
|
|
38
|
+
* @returns Record of package manager to install command
|
|
39
|
+
*/
|
|
40
|
+
function getInstallSaveCommands(targetPath) {
|
|
41
|
+
return {
|
|
42
|
+
npm: buildNpmCommand("npm install --save", targetPath),
|
|
43
|
+
yarn: "yarn add",
|
|
44
|
+
pnpm: "pnpm add",
|
|
45
|
+
bun: "bun add"
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { getInstallCommands, getInstallSaveCommands };
|
|
51
|
+
//# sourceMappingURL=build-npm-command.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-npm-command.mjs","names":[],"sources":["../../src/utils/build-npm-command.ts"],"sourcesContent":["import { shouldUseNoBinLinks } from './detect-wsl'\n\n/**\n * Build an npm install command with appropriate flags for the environment.\n * Adds --no-bin-links when running in WSL2 on Windows filesystem to prevent\n * EPERM errors during npm install.\n *\n * @param baseCommand - The base npm command (e.g., 'npm install --save' or 'npm install')\n * @param targetPath - The path where the command will be executed\n * @returns The command with appropriate flags added\n */\nexport function buildNpmCommand(baseCommand: string, targetPath: string): string {\n // Only modify npm commands\n if (!baseCommand.startsWith('npm ')) {\n return baseCommand\n }\n\n // Add --no-bin-links if needed for WSL2 on Windows filesystem\n if (shouldUseNoBinLinks(targetPath)) {\n // Insert --no-bin-links after 'npm install' but before any other flags\n // Handle both 'npm install' and 'npm install --save' patterns\n if (baseCommand.includes('npm install')) {\n return baseCommand.replace('npm install', 'npm install --no-bin-links')\n }\n }\n\n return baseCommand\n}\n\n/**\n * Get install commands for all package managers, with WSL2 compatibility for npm.\n *\n * @param targetPath - The path where the command will be executed\n * @returns Record of package manager to install command\n */\nexport function getInstallCommands(targetPath: string): Record<string, string> {\n return {\n npm: buildNpmCommand('npm install', targetPath),\n yarn: 'yarn install',\n pnpm: 'pnpm install',\n bun: 'bun install',\n }\n}\n\n/**\n * Get install commands with --save flag for all package managers, with WSL2 compatibility for npm.\n *\n * @param targetPath - The path where the command will be executed\n * @returns Record of package manager to install command\n */\nexport function getInstallSaveCommands(targetPath: string): Record<string, string> {\n return {\n npm: buildNpmCommand('npm install --save', targetPath),\n yarn: 'yarn add',\n pnpm: 'pnpm add',\n bun: 'bun add',\n }\n}\n\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,gBAAgB,aAAqB,YAA4B;AAE/E,KAAI,CAAC,YAAY,WAAW,OAAO,CACjC,QAAO;AAIT,KAAI,oBAAoB,WAAW,EAGjC;MAAI,YAAY,SAAS,cAAc,CACrC,QAAO,YAAY,QAAQ,eAAe,6BAA6B;;AAI3E,QAAO;;;;;;;;AAST,SAAgB,mBAAmB,YAA4C;AAC7E,QAAO;EACL,KAAK,gBAAgB,eAAe,WAAW;EAC/C,MAAM;EACN,MAAM;EACN,KAAK;EACN;;;;;;;;AASH,SAAgB,uBAAuB,YAA4C;AACjF,QAAO;EACL,KAAK,gBAAgB,sBAAsB,WAAW;EACtD,MAAM;EACN,MAAM;EACN,KAAK;EACN"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import os from "os";
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/check-build-tools.ts
|
|
5
|
+
const checkCommand = async (command, args) => {
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
const child = spawn(command, args, {
|
|
8
|
+
stdio: "pipe",
|
|
9
|
+
shell: process.platform === "win32"
|
|
10
|
+
});
|
|
11
|
+
child.on("close", (code) => resolve(code === 0));
|
|
12
|
+
child.on("error", () => resolve(false));
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
const getPlatform = () => {
|
|
16
|
+
const platform = os.platform();
|
|
17
|
+
if (platform === "linux" || platform === "darwin" || platform === "win32") return platform;
|
|
18
|
+
return "unknown";
|
|
19
|
+
};
|
|
20
|
+
const getInstallInstructions = (missingTools, platform) => {
|
|
21
|
+
const toolsList = missingTools.join(", ");
|
|
22
|
+
switch (platform) {
|
|
23
|
+
case "linux": return `Missing build tools: ${toolsList}\n\nTo install on Ubuntu/Debian:
|
|
24
|
+
sudo apt-get update && sudo apt-get install build-essential
|
|
25
|
+
|
|
26
|
+
To install on Fedora/RHEL:
|
|
27
|
+
sudo dnf groupinstall "Development Tools"
|
|
28
|
+
|
|
29
|
+
To install on Arch Linux:
|
|
30
|
+
sudo pacman -S base-devel`;
|
|
31
|
+
case "darwin": return `Missing build tools: ${toolsList}\n\nTo install on macOS:
|
|
32
|
+
xcode-select --install
|
|
33
|
+
|
|
34
|
+
Or using Homebrew:
|
|
35
|
+
brew install make gcc`;
|
|
36
|
+
case "win32": return `Missing build tools: ${toolsList}\n\nThe Redis Memory Server requires build tools to compile Redis.
|
|
37
|
+
On Windows, we recommend using an external Redis instance instead.
|
|
38
|
+
|
|
39
|
+
Option 1: Use an external Redis server
|
|
40
|
+
Set MOTIA_DISABLE_MEMORY_SERVER=true and configure MOTIA_REDIS_HOST
|
|
41
|
+
|
|
42
|
+
Option 2: Install Visual Studio Build Tools
|
|
43
|
+
Download from: https://visualstudio.microsoft.com/visual-cpp-build-tools/
|
|
44
|
+
Select "Desktop development with C++" workload
|
|
45
|
+
|
|
46
|
+
Option 3: Use WSL (Windows Subsystem for Linux)
|
|
47
|
+
Run your project inside WSL with Linux build tools installed`;
|
|
48
|
+
default: return `Missing build tools: ${toolsList}\n\nPlease install make and a C compiler (gcc or clang) for your platform.
|
|
49
|
+
Alternatively, use an external Redis server by setting:
|
|
50
|
+
MOTIA_DISABLE_MEMORY_SERVER=true
|
|
51
|
+
MOTIA_REDIS_HOST=<your-redis-host>`;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Check if required build tools are available for compiling Redis.
|
|
56
|
+
* The redis-memory-server package needs to compile Redis from source,
|
|
57
|
+
* which requires make and a C compiler.
|
|
58
|
+
*/
|
|
59
|
+
const checkBuildTools = async () => {
|
|
60
|
+
const platform = getPlatform();
|
|
61
|
+
const missingTools = [];
|
|
62
|
+
if (platform === "win32") {
|
|
63
|
+
const hasNmake = await checkCommand("where", ["nmake"]);
|
|
64
|
+
const hasMake = await checkCommand("where", ["make"]);
|
|
65
|
+
if (!hasNmake && !hasMake) missingTools.push("make (or nmake)");
|
|
66
|
+
const hasCl = await checkCommand("where", ["cl"]);
|
|
67
|
+
const hasGcc = await checkCommand("where", ["gcc"]);
|
|
68
|
+
if (!hasCl && !hasGcc) missingTools.push("C compiler (cl.exe or gcc)");
|
|
69
|
+
} else {
|
|
70
|
+
if (!await checkCommand("make", ["--version"])) missingTools.push("make");
|
|
71
|
+
const hasGcc = await checkCommand("gcc", ["--version"]);
|
|
72
|
+
const hasCc = await checkCommand("cc", ["--version"]);
|
|
73
|
+
if (!hasGcc && !hasCc) missingTools.push("gcc (or cc)");
|
|
74
|
+
}
|
|
75
|
+
if (missingTools.length > 0) return {
|
|
76
|
+
success: false,
|
|
77
|
+
missingTools,
|
|
78
|
+
installInstructions: getInstallInstructions(missingTools, platform)
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
missingTools: [],
|
|
83
|
+
installInstructions: ""
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Throws an error if required build tools are missing.
|
|
88
|
+
* Use this before attempting to start the Redis Memory Server.
|
|
89
|
+
*/
|
|
90
|
+
const ensureBuildTools = async () => {
|
|
91
|
+
const result = await checkBuildTools();
|
|
92
|
+
if (!result.success) throw new Error("Redis Memory Server requires build tools to compile Redis.\n\n" + result.installInstructions);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
export { ensureBuildTools };
|
|
97
|
+
//# sourceMappingURL=check-build-tools.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-build-tools.mjs","names":["missingTools: string[]"],"sources":["../../src/utils/check-build-tools.ts"],"sourcesContent":["import { spawn } from 'child_process'\nimport os from 'os'\n\nexport interface BuildToolsCheckResult {\n success: boolean\n missingTools: string[]\n installInstructions: string\n}\n\nconst checkCommand = async (command: string, args: string[]): Promise<boolean> => {\n return new Promise((resolve) => {\n const child = spawn(command, args, { stdio: 'pipe', shell: process.platform === 'win32' })\n child.on('close', (code) => resolve(code === 0))\n child.on('error', () => resolve(false))\n })\n}\n\nconst getPlatform = (): 'linux' | 'darwin' | 'win32' | 'unknown' => {\n const platform = os.platform()\n if (platform === 'linux' || platform === 'darwin' || platform === 'win32') {\n return platform\n }\n return 'unknown'\n}\n\nconst getInstallInstructions = (missingTools: string[], platform: string): string => {\n const toolsList = missingTools.join(', ')\n\n switch (platform) {\n case 'linux':\n return (\n `Missing build tools: ${toolsList}\\n\\n` +\n 'To install on Ubuntu/Debian:\\n' +\n ' sudo apt-get update && sudo apt-get install build-essential\\n\\n' +\n 'To install on Fedora/RHEL:\\n' +\n ' sudo dnf groupinstall \"Development Tools\"\\n\\n' +\n 'To install on Arch Linux:\\n' +\n ' sudo pacman -S base-devel'\n )\n case 'darwin':\n return (\n `Missing build tools: ${toolsList}\\n\\n` +\n 'To install on macOS:\\n' +\n ' xcode-select --install\\n\\n' +\n 'Or using Homebrew:\\n' +\n ' brew install make gcc'\n )\n case 'win32':\n return (\n `Missing build tools: ${toolsList}\\n\\n` +\n 'The Redis Memory Server requires build tools to compile Redis.\\n' +\n 'On Windows, we recommend using an external Redis instance instead.\\n\\n' +\n 'Option 1: Use an external Redis server\\n' +\n ' Set MOTIA_DISABLE_MEMORY_SERVER=true and configure MOTIA_REDIS_HOST\\n\\n' +\n 'Option 2: Install Visual Studio Build Tools\\n' +\n ' Download from: https://visualstudio.microsoft.com/visual-cpp-build-tools/\\n' +\n ' Select \"Desktop development with C++\" workload\\n\\n' +\n 'Option 3: Use WSL (Windows Subsystem for Linux)\\n' +\n ' Run your project inside WSL with Linux build tools installed'\n )\n default:\n return (\n `Missing build tools: ${toolsList}\\n\\n` +\n 'Please install make and a C compiler (gcc or clang) for your platform.\\n' +\n 'Alternatively, use an external Redis server by setting:\\n' +\n ' MOTIA_DISABLE_MEMORY_SERVER=true\\n' +\n ' MOTIA_REDIS_HOST=<your-redis-host>'\n )\n }\n}\n\n/**\n * Check if required build tools are available for compiling Redis.\n * The redis-memory-server package needs to compile Redis from source,\n * which requires make and a C compiler.\n */\nexport const checkBuildTools = async (): Promise<BuildToolsCheckResult> => {\n const platform = getPlatform()\n const missingTools: string[] = []\n\n // On Windows, build tools work differently\n if (platform === 'win32') {\n // Check for nmake (Visual Studio) or make (MinGW/MSYS)\n const hasNmake = await checkCommand('where', ['nmake'])\n const hasMake = await checkCommand('where', ['make'])\n\n if (!hasNmake && !hasMake) {\n missingTools.push('make (or nmake)')\n }\n\n // Check for cl.exe (Visual Studio) or gcc (MinGW)\n const hasCl = await checkCommand('where', ['cl'])\n const hasGcc = await checkCommand('where', ['gcc'])\n\n if (!hasCl && !hasGcc) {\n missingTools.push('C compiler (cl.exe or gcc)')\n }\n } else {\n // Unix-like systems (Linux, macOS)\n const hasMake = await checkCommand('make', ['--version'])\n if (!hasMake) {\n missingTools.push('make')\n }\n\n // Check for gcc or cc (clang on macOS)\n const hasGcc = await checkCommand('gcc', ['--version'])\n const hasCc = await checkCommand('cc', ['--version'])\n\n if (!hasGcc && !hasCc) {\n missingTools.push('gcc (or cc)')\n }\n }\n\n if (missingTools.length > 0) {\n return {\n success: false,\n missingTools,\n installInstructions: getInstallInstructions(missingTools, platform),\n }\n }\n\n return {\n success: true,\n missingTools: [],\n installInstructions: '',\n }\n}\n\n/**\n * Throws an error if required build tools are missing.\n * Use this before attempting to start the Redis Memory Server.\n */\nexport const ensureBuildTools = async (): Promise<void> => {\n const result = await checkBuildTools()\n\n if (!result.success) {\n throw new Error(\n 'Redis Memory Server requires build tools to compile Redis.\\n\\n' + result.installInstructions,\n )\n }\n}\n\n"],"mappings":";;;;AASA,MAAM,eAAe,OAAO,SAAiB,SAAqC;AAChF,QAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,QAAQ,MAAM,SAAS,MAAM;GAAE,OAAO;GAAQ,OAAO,QAAQ,aAAa;GAAS,CAAC;AAC1F,QAAM,GAAG,UAAU,SAAS,QAAQ,SAAS,EAAE,CAAC;AAChD,QAAM,GAAG,eAAe,QAAQ,MAAM,CAAC;GACvC;;AAGJ,MAAM,oBAA8D;CAClE,MAAM,WAAW,GAAG,UAAU;AAC9B,KAAI,aAAa,WAAW,aAAa,YAAY,aAAa,QAChE,QAAO;AAET,QAAO;;AAGT,MAAM,0BAA0B,cAAwB,aAA6B;CACnF,MAAM,YAAY,aAAa,KAAK,KAAK;AAEzC,SAAQ,UAAR;EACE,KAAK,QACH,QACE,wBAAwB,UAAU;;;;;;;;EAQtC,KAAK,SACH,QACE,wBAAwB,UAAU;;;;;EAMtC,KAAK,QACH,QACE,wBAAwB,UAAU;;;;;;;;;;;;EAWtC,QACE,QACE,wBAAwB,UAAU;;;;;;;;;;;AAc1C,MAAa,kBAAkB,YAA4C;CACzE,MAAM,WAAW,aAAa;CAC9B,MAAMA,eAAyB,EAAE;AAGjC,KAAI,aAAa,SAAS;EAExB,MAAM,WAAW,MAAM,aAAa,SAAS,CAAC,QAAQ,CAAC;EACvD,MAAM,UAAU,MAAM,aAAa,SAAS,CAAC,OAAO,CAAC;AAErD,MAAI,CAAC,YAAY,CAAC,QAChB,cAAa,KAAK,kBAAkB;EAItC,MAAM,QAAQ,MAAM,aAAa,SAAS,CAAC,KAAK,CAAC;EACjD,MAAM,SAAS,MAAM,aAAa,SAAS,CAAC,MAAM,CAAC;AAEnD,MAAI,CAAC,SAAS,CAAC,OACb,cAAa,KAAK,6BAA6B;QAE5C;AAGL,MAAI,CADY,MAAM,aAAa,QAAQ,CAAC,YAAY,CAAC,CAEvD,cAAa,KAAK,OAAO;EAI3B,MAAM,SAAS,MAAM,aAAa,OAAO,CAAC,YAAY,CAAC;EACvD,MAAM,QAAQ,MAAM,aAAa,MAAM,CAAC,YAAY,CAAC;AAErD,MAAI,CAAC,UAAU,CAAC,MACd,cAAa,KAAK,cAAc;;AAIpC,KAAI,aAAa,SAAS,EACxB,QAAO;EACL,SAAS;EACT;EACA,qBAAqB,uBAAuB,cAAc,SAAS;EACpE;AAGH,QAAO;EACL,SAAS;EACT,cAAc,EAAE;EAChB,qBAAqB;EACtB;;;;;;AAOH,MAAa,mBAAmB,YAA2B;CACzD,MAAM,SAAS,MAAM,iBAAiB;AAEtC,KAAI,CAAC,OAAO,QACV,OAAM,IAAI,MACR,mEAAmE,OAAO,oBAC3E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { __require } from "../_virtual/rolldown_runtime.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/detect-wsl.ts
|
|
4
|
+
/**
|
|
5
|
+
* Detects if we're running in WSL2 with a Windows filesystem path.
|
|
6
|
+
* This is used to determine if we need to add --no-bin-links to npm commands
|
|
7
|
+
* to avoid EPERM errors when npm tries to chmod files on Windows filesystem.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if the current environment is WSL (Windows Subsystem for Linux)
|
|
11
|
+
*/
|
|
12
|
+
function isWsl() {
|
|
13
|
+
if (process.env.WSL_DISTRO_NAME || process.env.WSLENV) return true;
|
|
14
|
+
if (process.platform !== "linux") return false;
|
|
15
|
+
try {
|
|
16
|
+
const release = __require("os").release().toLowerCase();
|
|
17
|
+
return release.includes("microsoft") || release.includes("wsl");
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if a path is on the Windows filesystem (mounted via /mnt/)
|
|
24
|
+
*/
|
|
25
|
+
function isWindowsFilesystemPath(targetPath) {
|
|
26
|
+
return targetPath.startsWith("/mnt/");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Determines if --no-bin-links should be used for npm commands.
|
|
30
|
+
* This is needed when running in WSL2 on Windows filesystem to avoid
|
|
31
|
+
* EPERM errors during npm install.
|
|
32
|
+
*/
|
|
33
|
+
function shouldUseNoBinLinks(targetPath) {
|
|
34
|
+
return isWsl() && isWindowsFilesystemPath(targetPath);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { shouldUseNoBinLinks };
|
|
39
|
+
//# sourceMappingURL=detect-wsl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-wsl.mjs","names":[],"sources":["../../src/utils/detect-wsl.ts"],"sourcesContent":["/**\n * Detects if we're running in WSL2 with a Windows filesystem path.\n * This is used to determine if we need to add --no-bin-links to npm commands\n * to avoid EPERM errors when npm tries to chmod files on Windows filesystem.\n */\n\n/**\n * Check if the current environment is WSL (Windows Subsystem for Linux)\n */\nexport function isWsl(): boolean {\n // Check for WSL-specific environment variables\n if (process.env.WSL_DISTRO_NAME || process.env.WSLENV) {\n return true\n }\n\n // Check if running on Linux (WSL reports as Linux)\n if (process.platform !== 'linux') {\n return false\n }\n\n // Additional check: look for WSL in the kernel version\n try {\n const os = require('os')\n const release = os.release().toLowerCase()\n return release.includes('microsoft') || release.includes('wsl')\n } catch {\n return false\n }\n}\n\n/**\n * Check if a path is on the Windows filesystem (mounted via /mnt/)\n */\nexport function isWindowsFilesystemPath(targetPath: string): boolean {\n // Windows drives are mounted at /mnt/c/, /mnt/d/, etc. in WSL\n return targetPath.startsWith('/mnt/')\n}\n\n/**\n * Determines if --no-bin-links should be used for npm commands.\n * This is needed when running in WSL2 on Windows filesystem to avoid\n * EPERM errors during npm install.\n */\nexport function shouldUseNoBinLinks(targetPath: string): boolean {\n return isWsl() && isWindowsFilesystemPath(targetPath)\n}\n\n"],"mappings":";;;;;;;;;;;AASA,SAAgB,QAAiB;AAE/B,KAAI,QAAQ,IAAI,mBAAmB,QAAQ,IAAI,OAC7C,QAAO;AAIT,KAAI,QAAQ,aAAa,QACvB,QAAO;AAIT,KAAI;EAEF,MAAM,oBADa,KAAK,CACL,SAAS,CAAC,aAAa;AAC1C,SAAO,QAAQ,SAAS,YAAY,IAAI,QAAQ,SAAS,MAAM;SACzD;AACN,SAAO;;;;;;AAOX,SAAgB,wBAAwB,YAA6B;AAEnE,QAAO,WAAW,WAAW,QAAQ;;;;;;;AAQvC,SAAgB,oBAAoB,YAA6B;AAC/D,QAAO,OAAO,IAAI,wBAAwB,WAAW"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { internalLogger } from "./internal-logger.mjs";
|
|
2
2
|
import { getPythonCommand } from "./python-version-utils.mjs";
|
|
3
|
+
import { getInstallCommands } from "./build-npm-command.mjs";
|
|
3
4
|
import { getPackageManager } from "./get-package-manager.mjs";
|
|
4
5
|
import fs from "fs";
|
|
5
6
|
import path from "path";
|
|
@@ -7,12 +8,9 @@ import pc from "picocolors";
|
|
|
7
8
|
|
|
8
9
|
//#region src/utils/validate-python-environment.ts
|
|
9
10
|
function getInstallCommand(baseDir) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
case "npm":
|
|
14
|
-
default: return "npm install";
|
|
15
|
-
}
|
|
11
|
+
const pm = getPackageManager(baseDir);
|
|
12
|
+
const installCommands = getInstallCommands(baseDir);
|
|
13
|
+
return installCommands[pm] || installCommands["npm"];
|
|
16
14
|
}
|
|
17
15
|
async function validatePythonEnvironment({ baseDir, hasPythonFiles, pythonVersion = "3.13" }) {
|
|
18
16
|
if (!hasPythonFiles) return {
|
|
@@ -1 +1 @@
|
|
|
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 pc from 'picocolors'\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\nexport function getInstallCommand(baseDir: string): string {\n const pm = getPackageManager(baseDir)\n
|
|
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 pc from 'picocolors'\nimport { getInstallCommands } from './build-npm-command'\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\nexport function getInstallCommand(baseDir: string): string {\n const pm = getPackageManager(baseDir)\n const installCommands = getInstallCommands(baseDir)\n return installCommands[pm] || installCommands['npm']\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 const installCmd = getInstallCommand(baseDir)\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 internalLogger.error('Python environment not configured')\n internalLogger.info('The python_modules directory was not found')\n internalLogger.info(`Run ${pc.cyan(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 internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules directory exists but appears to be corrupted')\n internalLogger.info(`Run ${pc.cyan(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 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 ${pc.cyan(installCmd)} to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n } catch (error: any) {\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules/lib directory cannot be read')\n internalLogger.info(`Run ${pc.cyan(installCmd)} to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n return { success: true, hasPythonFiles: true }\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,kBAAkB,SAAyB;CACzD,MAAM,KAAK,kBAAkB,QAAQ;CACrC,MAAM,kBAAkB,mBAAmB,QAAQ;AACnD,QAAO,gBAAgB,OAAO,gBAAgB;;AAGhD,eAAsB,0BAA0B,EAC9C,SACA,gBACA,gBAAgB,UAC4B;AAC5C,KAAI,CAAC,eACH,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAO;CAGjD,MAAM,aAAa,kBAAkB,QAAQ;AAE7C,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;AAC5B,iBAAe,MAAM,oCAAoC;AACzD,iBAAe,KAAK,6CAA6C;AACjE,iBAAe,KAAK,OAAO,GAAG,KAAK,WAAW,CAAC,oCAAoC;AACnF,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,UAAU,KAAK,KAAK,UAAU,MAAM;AAC1C,KAAI,CAAC,GAAG,WAAW,QAAQ,EAAE;AAC3B,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kEAAkE;AACtF,iBAAe,KAAK,OAAO,GAAG,KAAK,WAAW,CAAC,sCAAsC;AACrF,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;AAGjD,KAAI;AAIF,MAHoB,GAAG,YAAY,QAAQ,CACZ,QAAQ,SAAS,KAAK,WAAW,UAAU,CAAC,CAE5D,WAAW,GAAG;AAC3B,kBAAe,MAAM,mCAAmC;AACxD,kBAAe,KAAK,qFAAqF;AACzG,kBAAe,KAAK,OAAO,GAAG,KAAK,WAAW,CAAC,sCAAsC;AACrF,UAAO;IAAE,SAAS;IAAO,gBAAgB;IAAM;;UAE1CA,OAAY;AACnB,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kDAAkD;AACtE,iBAAe,KAAK,OAAO,GAAG,KAAK,WAAW,CAAC,sCAAsC;AACrF,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.17.9-beta.192-
|
|
4
|
+
"version": "0.17.9-beta.192-406008",
|
|
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.13",
|
|
49
|
-
"@motiadev/adapter-bullmq-events": "0.17.9-beta.192-
|
|
50
|
-
"@motiadev/adapter-redis-cron": "0.17.9-beta.192-
|
|
51
|
-
"@motiadev/adapter-redis-
|
|
52
|
-
"@motiadev/
|
|
53
|
-
"@motiadev/
|
|
54
|
-
"@motiadev/
|
|
55
|
-
"@motiadev/
|
|
49
|
+
"@motiadev/adapter-bullmq-events": "0.17.9-beta.192-406008",
|
|
50
|
+
"@motiadev/adapter-redis-cron": "0.17.9-beta.192-406008",
|
|
51
|
+
"@motiadev/adapter-redis-streams": "0.17.9-beta.192-406008",
|
|
52
|
+
"@motiadev/core": "0.17.9-beta.192-406008",
|
|
53
|
+
"@motiadev/stream-client-node": "0.17.9-beta.192-406008",
|
|
54
|
+
"@motiadev/adapter-redis-state": "0.17.9-beta.192-406008",
|
|
55
|
+
"@motiadev/workbench": "0.17.9-beta.192-406008"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@amplitude/analytics-types": "^2.9.2",
|