@mastra/deployer 0.0.0-commonjs-20250227130920
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/.turbo/turbo-build.log +41 -0
- package/CHANGELOG.md +897 -0
- package/LICENSE +44 -0
- package/README.md +159 -0
- package/dist/_tsup-dts-rollup.d.cts +360 -0
- package/dist/_tsup-dts-rollup.d.ts +360 -0
- package/dist/build/analyze.cjs +367 -0
- package/dist/build/analyze.d.cts +1 -0
- package/dist/build/analyze.d.ts +1 -0
- package/dist/build/analyze.js +2 -0
- package/dist/build/bundler.cjs +353 -0
- package/dist/build/bundler.d.cts +2 -0
- package/dist/build/bundler.d.ts +2 -0
- package/dist/build/bundler.js +2 -0
- package/dist/build/index.cjs +1146 -0
- package/dist/build/index.d.cts +10 -0
- package/dist/build/index.d.ts +10 -0
- package/dist/build/index.js +5 -0
- package/dist/bundler/index.cjs +999 -0
- package/dist/bundler/index.d.cts +1 -0
- package/dist/bundler/index.d.ts +1 -0
- package/dist/bundler/index.js +5 -0
- package/dist/chunk-3ONBKVC4.js +113 -0
- package/dist/chunk-AXS5WSIK.js +290 -0
- package/dist/chunk-DTSFVNIF.js +260 -0
- package/dist/chunk-JMH7HCD6.js +274 -0
- package/dist/chunk-SGK37ZWD.js +254 -0
- package/dist/chunk-YNXJO2XU.js +69 -0
- package/dist/index.cjs +1229 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +131 -0
- package/dist/server/index.cjs +4930 -0
- package/dist/server/index.d.cts +2 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +4923 -0
- package/dist/templates/instrumentation-template.js +86 -0
- package/eslint.config.js +6 -0
- package/global.d.ts +0 -0
- package/package.json +112 -0
- package/public/templates/instrumentation-template.js +86 -0
- package/src/build/analyze.ts +279 -0
- package/src/build/babel/fix-libsql.ts +41 -0
- package/src/build/babel/get-deployer.ts +54 -0
- package/src/build/babel/get-telemetry-config.ts +62 -0
- package/src/build/babel/remove-deployer.ts +43 -0
- package/src/build/bundle.ts +139 -0
- package/src/build/bundler.ts +135 -0
- package/src/build/deployer.ts +67 -0
- package/src/build/deps.ts +149 -0
- package/src/build/env.ts +76 -0
- package/src/build/fs.ts +66 -0
- package/src/build/index.ts +7 -0
- package/src/build/isNodeBuiltin.ts +7 -0
- package/src/build/plugins/fix-libsql.ts +69 -0
- package/src/build/plugins/hono-alias.ts +17 -0
- package/src/build/plugins/pino.ts +93 -0
- package/src/build/plugins/remove-deployer.ts +37 -0
- package/src/build/plugins/telemetry-fix.ts +54 -0
- package/src/build/telemetry.ts +76 -0
- package/src/build/utils.ts +12 -0
- package/src/build/watcher.ts +43 -0
- package/src/bundler/index.ts +144 -0
- package/src/deploy/base.ts +30 -0
- package/src/deploy/index.ts +2 -0
- package/src/deploy/log.ts +61 -0
- package/src/index.ts +3 -0
- package/src/server/handlers/agents.ts +209 -0
- package/src/server/handlers/client.ts +36 -0
- package/src/server/handlers/error.ts +29 -0
- package/src/server/handlers/logs.ts +53 -0
- package/src/server/handlers/memory.ts +196 -0
- package/src/server/handlers/prompt.ts +128 -0
- package/src/server/handlers/root.ts +6 -0
- package/src/server/handlers/telemetry.ts +48 -0
- package/src/server/handlers/tools.ts +114 -0
- package/src/server/handlers/utils.ts +15 -0
- package/src/server/handlers/vector.ts +149 -0
- package/src/server/handlers/workflows.ts +119 -0
- package/src/server/index.ts +1355 -0
- package/src/server/openapi.json +434 -0
- package/src/server/openapi.script.js +22 -0
- package/src/server/types.ts +4 -0
- package/src/server/welcome.ts +105 -0
- package/tsconfig.json +5 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import babel from '@babel/core';
|
|
2
|
+
|
|
3
|
+
export function removeAllExceptTelemetryConfig(result: { hasCustomConfig: boolean }) {
|
|
4
|
+
let mastraClass: string | null = null;
|
|
5
|
+
|
|
6
|
+
const t = babel.types;
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
name: 'remove-all-except-telemetry-config',
|
|
10
|
+
visitor: {
|
|
11
|
+
ExportNamedDeclaration: {
|
|
12
|
+
// remove all exports
|
|
13
|
+
exit(path) {
|
|
14
|
+
path.remove();
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
ImportDeclaration(path) {
|
|
18
|
+
if (
|
|
19
|
+
(path.node.source.value === '@mastra/core' || path.node.source.value === '@mastra/core/mastra') &&
|
|
20
|
+
path.node.specifiers
|
|
21
|
+
) {
|
|
22
|
+
mastraClass =
|
|
23
|
+
path.node.specifiers.find(
|
|
24
|
+
// @ts-ignore - no need to type
|
|
25
|
+
p => p.imported?.name === 'Mastra',
|
|
26
|
+
)?.local?.name ?? null;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
NewExpression(path) {
|
|
30
|
+
if (mastraClass && (path.node.callee as babel.types.Identifier).name === mastraClass) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
let telemetry = path.node.arguments[0]?.properties?.find(
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
prop => prop.key.name === 'telemetry',
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const programPath = path.scope.getProgramParent().path;
|
|
38
|
+
if (!programPath) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (telemetry) {
|
|
43
|
+
result.hasCustomConfig = true;
|
|
44
|
+
} else {
|
|
45
|
+
telemetry = {
|
|
46
|
+
value: t.objectExpression([]),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// add the deployer export
|
|
51
|
+
const exportDeclaration = t.exportNamedDeclaration(
|
|
52
|
+
t.variableDeclaration('const', [t.variableDeclarator(t.identifier('telemetry'), telemetry.value)]),
|
|
53
|
+
[],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
programPath.node.body.push(exportDeclaration);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
} as babel.PluginObj;
|
|
62
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import babel from '@babel/core';
|
|
2
|
+
|
|
3
|
+
export function removeDeployer() {
|
|
4
|
+
const t = babel.types;
|
|
5
|
+
let mastraClass: string | null = null;
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
name: 'remove-deployer',
|
|
9
|
+
visitor: {
|
|
10
|
+
ImportDeclaration(path) {
|
|
11
|
+
if (
|
|
12
|
+
(path.node.source.value === '@mastra/core' || path.node.source.value === '@mastra/core/mastra') &&
|
|
13
|
+
path.node.specifiers
|
|
14
|
+
) {
|
|
15
|
+
const mastraObj = path.node.specifiers.find(
|
|
16
|
+
p => t.isImportSpecifier(p) && t.isIdentifier(p.imported) && p.imported.name === 'Mastra',
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (mastraObj?.local?.name) {
|
|
20
|
+
mastraClass = mastraObj.local.name;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
NewExpression(path, state) {
|
|
25
|
+
if (
|
|
26
|
+
mastraClass &&
|
|
27
|
+
t.isIdentifier(path.node.callee) &&
|
|
28
|
+
path.node.callee.name === mastraClass &&
|
|
29
|
+
!state.hasReplaced
|
|
30
|
+
) {
|
|
31
|
+
state.hasReplaced = true;
|
|
32
|
+
const newMastraObj = t.cloneNode(path.node);
|
|
33
|
+
if (t.isObjectExpression(newMastraObj.arguments[0]) && newMastraObj.arguments[0].properties?.[0]) {
|
|
34
|
+
newMastraObj.arguments[0].properties = newMastraObj.arguments[0].properties.filter(
|
|
35
|
+
prop => t.isObjectProperty(prop) && t.isIdentifier(prop.key) && prop.key.name !== 'deployer',
|
|
36
|
+
);
|
|
37
|
+
path.replaceWith(newMastraObj);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
} as babel.PluginObj;
|
|
43
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import alias from '@rollup/plugin-alias';
|
|
2
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
3
|
+
import json from '@rollup/plugin-json';
|
|
4
|
+
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
5
|
+
import { builtinModules } from 'node:module';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { rollup, watch, type InputOptions, type Plugin, type InputOption } from 'rollup';
|
|
8
|
+
import esbuild from 'rollup-plugin-esbuild';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
import { FileService } from './fs';
|
|
12
|
+
import { libSqlFix } from './plugins/fix-libsql';
|
|
13
|
+
import { removeDeployer } from './plugins/remove-deployer';
|
|
14
|
+
import { telemetryFix } from './plugins/telemetry-fix';
|
|
15
|
+
|
|
16
|
+
type NormalizedInputOptions = Omit<Partial<InputOptions>, 'plugins' | 'input' | 'external'> & {
|
|
17
|
+
plugins?: Plugin[];
|
|
18
|
+
input: InputOption;
|
|
19
|
+
external?: (string | RegExp)[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function getOptions(inputOptions: NormalizedInputOptions, platform: 'node' | 'browser', root: string): InputOptions {
|
|
23
|
+
const fileService = new FileService();
|
|
24
|
+
const entry = fileService.getFirstExistingFile([
|
|
25
|
+
join(root, 'src/mastra/index.ts'),
|
|
26
|
+
join(root, 'src/mastra/index.js'),
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
const nodeBuiltins = platform === 'node' ? builtinModules : [];
|
|
30
|
+
|
|
31
|
+
let nodeResolvePlugin =
|
|
32
|
+
platform === 'node'
|
|
33
|
+
? nodeResolve({
|
|
34
|
+
preferBuiltins: true,
|
|
35
|
+
exportConditions: ['node', 'import', 'require'],
|
|
36
|
+
mainFields: ['module', 'main'],
|
|
37
|
+
})
|
|
38
|
+
: nodeResolve({
|
|
39
|
+
preferBuiltins: false,
|
|
40
|
+
exportConditions: ['browser', 'import', 'require'],
|
|
41
|
+
mainFields: ['module', 'main'],
|
|
42
|
+
browser: true,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
logLevel: 'silent',
|
|
47
|
+
...inputOptions,
|
|
48
|
+
treeshake: false,
|
|
49
|
+
preserveSymlinks: true,
|
|
50
|
+
external: [
|
|
51
|
+
...nodeBuiltins,
|
|
52
|
+
...nodeBuiltins.map((builtin: string) => 'node:' + builtin),
|
|
53
|
+
...(inputOptions.external ?? []),
|
|
54
|
+
],
|
|
55
|
+
plugins: [
|
|
56
|
+
...(inputOptions.plugins ?? []),
|
|
57
|
+
telemetryFix(),
|
|
58
|
+
alias({
|
|
59
|
+
entries: [
|
|
60
|
+
{
|
|
61
|
+
find: /^\#server$/,
|
|
62
|
+
replacement: fileURLToPath(import.meta.resolve('@mastra/deployer/server')).replaceAll('\\', '/'),
|
|
63
|
+
},
|
|
64
|
+
{ find: /^\#mastra$/, replacement: entry.replaceAll('\\', '/') },
|
|
65
|
+
{
|
|
66
|
+
find: /^hono\//,
|
|
67
|
+
replacement: 'hono/',
|
|
68
|
+
customResolver: (id: string, importer: string | undefined) => {
|
|
69
|
+
if (!importer?.startsWith('\x00virtual')) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const path = import.meta.resolve(id);
|
|
74
|
+
return fileURLToPath(path);
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
}),
|
|
79
|
+
commonjs({
|
|
80
|
+
strictRequires: 'strict',
|
|
81
|
+
transformMixedEsModules: true,
|
|
82
|
+
// dynamicRequireTargets: ['node_modules/**/@libsql+win32-*/*'],
|
|
83
|
+
}),
|
|
84
|
+
libSqlFix(),
|
|
85
|
+
// for debugging
|
|
86
|
+
// {
|
|
87
|
+
// name: 'logger',
|
|
88
|
+
// // @ts-ignore
|
|
89
|
+
// resolveId(id, ...args) {
|
|
90
|
+
// console.log({ id, args });
|
|
91
|
+
// },
|
|
92
|
+
// },
|
|
93
|
+
nodeResolvePlugin,
|
|
94
|
+
json(),
|
|
95
|
+
esbuild({
|
|
96
|
+
include: /\.tsx?$/,
|
|
97
|
+
target: 'node20',
|
|
98
|
+
platform,
|
|
99
|
+
minify: false,
|
|
100
|
+
define: {
|
|
101
|
+
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
removeDeployer(entry),
|
|
105
|
+
esbuild({
|
|
106
|
+
include: entry,
|
|
107
|
+
target: 'node20',
|
|
108
|
+
platform,
|
|
109
|
+
minify: false,
|
|
110
|
+
}),
|
|
111
|
+
].filter(Boolean),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function getBundler(
|
|
116
|
+
inputOptions: NormalizedInputOptions,
|
|
117
|
+
args: {
|
|
118
|
+
platform?: 'node' | 'browser';
|
|
119
|
+
dir?: string;
|
|
120
|
+
} = {},
|
|
121
|
+
) {
|
|
122
|
+
const { platform = 'node', dir = process.cwd() } = args;
|
|
123
|
+
const bundle = await rollup(getOptions(inputOptions, platform, dir));
|
|
124
|
+
|
|
125
|
+
return bundle;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function getWatcher(
|
|
129
|
+
inputOptions: NormalizedInputOptions,
|
|
130
|
+
args: {
|
|
131
|
+
platform?: 'node' | 'browser';
|
|
132
|
+
dir?: string;
|
|
133
|
+
} = {},
|
|
134
|
+
) {
|
|
135
|
+
const { platform = 'node', dir = process.cwd() } = args;
|
|
136
|
+
const watcher = watch(getOptions(inputOptions, platform, dir));
|
|
137
|
+
|
|
138
|
+
return watcher;
|
|
139
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import alias from '@rollup/plugin-alias';
|
|
2
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
3
|
+
import json from '@rollup/plugin-json';
|
|
4
|
+
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { rollup, type InputOptions, type OutputOptions } from 'rollup';
|
|
7
|
+
import esbuild from 'rollup-plugin-esbuild';
|
|
8
|
+
|
|
9
|
+
import type { analyzeBundle } from './analyze';
|
|
10
|
+
import { libSqlFix } from './plugins/fix-libsql';
|
|
11
|
+
import { removeDeployer } from './plugins/remove-deployer';
|
|
12
|
+
import { telemetryFix } from './plugins/telemetry-fix';
|
|
13
|
+
|
|
14
|
+
export async function getInputOptions(
|
|
15
|
+
entryFile: string,
|
|
16
|
+
analyzedBundleInfo: Awaited<ReturnType<typeof analyzeBundle>>,
|
|
17
|
+
platform: 'node' | 'browser',
|
|
18
|
+
): Promise<InputOptions> {
|
|
19
|
+
let nodeResolvePlugin =
|
|
20
|
+
platform === 'node'
|
|
21
|
+
? nodeResolve({
|
|
22
|
+
preferBuiltins: true,
|
|
23
|
+
exportConditions: ['node', 'import', 'require'],
|
|
24
|
+
mainFields: ['module', 'main'],
|
|
25
|
+
})
|
|
26
|
+
: nodeResolve({
|
|
27
|
+
preferBuiltins: false,
|
|
28
|
+
exportConditions: ['browser', 'import', 'require'],
|
|
29
|
+
mainFields: ['module', 'main'],
|
|
30
|
+
browser: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const externals = Array.from(analyzedBundleInfo.externalDependencies).concat(['@mastra/core/hooks']);
|
|
34
|
+
return {
|
|
35
|
+
logLevel: process.env.MASTRA_BUNDLER_DEBUG === 'true' ? 'debug' : 'silent',
|
|
36
|
+
treeshake: true,
|
|
37
|
+
preserveSymlinks: true,
|
|
38
|
+
external: externals,
|
|
39
|
+
plugins: [
|
|
40
|
+
telemetryFix(),
|
|
41
|
+
libSqlFix(),
|
|
42
|
+
{
|
|
43
|
+
name: 'alias-optimized-deps',
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
resolveId(id) {
|
|
46
|
+
if (!analyzedBundleInfo.dependencies.has(id)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const isInvalidChunk = analyzedBundleInfo.invalidChunks.has(analyzedBundleInfo.dependencies.get(id)!);
|
|
51
|
+
if (isInvalidChunk) {
|
|
52
|
+
return {
|
|
53
|
+
id,
|
|
54
|
+
external: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
id: '.mastra/.build/' + analyzedBundleInfo.dependencies.get(id)!,
|
|
60
|
+
external: false,
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
alias({
|
|
65
|
+
entries: [
|
|
66
|
+
{
|
|
67
|
+
find: /^\#server$/,
|
|
68
|
+
replacement: fileURLToPath(import.meta.resolve('@mastra/deployer/server')).replaceAll('\\', '/'),
|
|
69
|
+
},
|
|
70
|
+
{ find: /^\#mastra$/, replacement: entryFile.replaceAll('\\', '/') },
|
|
71
|
+
],
|
|
72
|
+
}),
|
|
73
|
+
esbuild({
|
|
74
|
+
target: 'node20',
|
|
75
|
+
platform,
|
|
76
|
+
minify: false,
|
|
77
|
+
define: {
|
|
78
|
+
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
commonjs({
|
|
82
|
+
extensions: ['.js', '.ts'],
|
|
83
|
+
transformMixedEsModules: true,
|
|
84
|
+
esmExternals(id) {
|
|
85
|
+
return externals.includes(id);
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
nodeResolvePlugin,
|
|
89
|
+
// for debugging
|
|
90
|
+
// {
|
|
91
|
+
// name: 'logger',
|
|
92
|
+
// //@ts-ignore
|
|
93
|
+
// resolveId(id, ...args) {
|
|
94
|
+
// console.log({ id, args });
|
|
95
|
+
// },
|
|
96
|
+
// // @ts-ignore
|
|
97
|
+
// transform(code, id) {
|
|
98
|
+
// if (code.includes('class Duplexify ')) {
|
|
99
|
+
// console.log({ duplex: id });
|
|
100
|
+
// }
|
|
101
|
+
// },
|
|
102
|
+
// },
|
|
103
|
+
json(),
|
|
104
|
+
removeDeployer(entryFile),
|
|
105
|
+
// treeshake unused imports
|
|
106
|
+
esbuild({
|
|
107
|
+
include: entryFile,
|
|
108
|
+
target: 'node20',
|
|
109
|
+
platform,
|
|
110
|
+
minify: false,
|
|
111
|
+
}),
|
|
112
|
+
].filter(Boolean),
|
|
113
|
+
} satisfies InputOptions;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function createBundler(
|
|
117
|
+
inputOptions: InputOptions,
|
|
118
|
+
outputOptions: Partial<OutputOptions> & { dir: string },
|
|
119
|
+
) {
|
|
120
|
+
const bundler = await rollup(inputOptions);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
write: () => {
|
|
124
|
+
return bundler.write({
|
|
125
|
+
...outputOptions,
|
|
126
|
+
format: 'esm',
|
|
127
|
+
entryFileNames: '[name].mjs',
|
|
128
|
+
chunkFileNames: '[name].mjs',
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
close: () => {
|
|
132
|
+
return bundler.close();
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as babel from '@babel/core';
|
|
2
|
+
import type { MastraDeployer } from '@mastra/core';
|
|
3
|
+
import { rollup } from 'rollup';
|
|
4
|
+
import esbuild from 'rollup-plugin-esbuild';
|
|
5
|
+
|
|
6
|
+
import { removeAllExceptDeployer } from './babel/get-deployer';
|
|
7
|
+
|
|
8
|
+
export async function getDeployer(entryFile: string, outputDir: string) {
|
|
9
|
+
const bundle = await rollup({
|
|
10
|
+
input: {
|
|
11
|
+
deployer: entryFile,
|
|
12
|
+
},
|
|
13
|
+
treeshake: true,
|
|
14
|
+
plugins: [
|
|
15
|
+
// transpile typescript to something we understand
|
|
16
|
+
esbuild({
|
|
17
|
+
target: 'node20',
|
|
18
|
+
platform: 'node',
|
|
19
|
+
minify: false,
|
|
20
|
+
}),
|
|
21
|
+
{
|
|
22
|
+
name: 'get-deployer',
|
|
23
|
+
transform(code, id) {
|
|
24
|
+
if (!this.getModuleInfo(id)?.isEntry) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
babel.transform(
|
|
30
|
+
code,
|
|
31
|
+
{
|
|
32
|
+
babelrc: false,
|
|
33
|
+
configFile: false,
|
|
34
|
+
filename: id,
|
|
35
|
+
plugins: [removeAllExceptDeployer],
|
|
36
|
+
},
|
|
37
|
+
(err, result) => {
|
|
38
|
+
if (err) {
|
|
39
|
+
return reject(err);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
resolve({
|
|
43
|
+
code: result!.code!,
|
|
44
|
+
map: result!.map!,
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
// let esbuild remove all unused imports
|
|
52
|
+
esbuild({
|
|
53
|
+
target: 'node20',
|
|
54
|
+
platform: 'node',
|
|
55
|
+
minify: false,
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await bundle.write({
|
|
61
|
+
dir: outputDir,
|
|
62
|
+
format: 'es',
|
|
63
|
+
entryFileNames: '[name].mjs',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return (await import(`file:${outputDir}/deployer.mjs`)).deployer as unknown as MastraDeployer;
|
|
67
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { MastraBase } from '@mastra/core/base';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path, { dirname } from 'path';
|
|
4
|
+
import type { PackageJson } from 'type-fest';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
import fsExtra from 'fs-extra/esm';
|
|
8
|
+
import fsPromises from 'fs/promises';
|
|
9
|
+
|
|
10
|
+
import { createChildProcessLogger } from '../deploy/log.js';
|
|
11
|
+
|
|
12
|
+
export class Deps extends MastraBase {
|
|
13
|
+
private packageManager: string;
|
|
14
|
+
private rootDir: string;
|
|
15
|
+
|
|
16
|
+
constructor(rootDir = process.cwd()) {
|
|
17
|
+
super({ component: 'DEPLOYER', name: 'DEPS' });
|
|
18
|
+
|
|
19
|
+
this.rootDir = rootDir;
|
|
20
|
+
this.packageManager = this.getPackageManager();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private findLockFile(dir: string): string | null {
|
|
24
|
+
const lockFiles = ['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock', 'bun.lock'];
|
|
25
|
+
for (const file of lockFiles) {
|
|
26
|
+
if (fs.existsSync(path.join(dir, file))) {
|
|
27
|
+
return file;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const parentDir = path.resolve(dir, '..');
|
|
31
|
+
if (parentDir !== dir) {
|
|
32
|
+
return this.findLockFile(parentDir);
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private getPackageManager(): string {
|
|
38
|
+
const lockFile = this.findLockFile(this.rootDir);
|
|
39
|
+
switch (lockFile) {
|
|
40
|
+
case 'pnpm-lock.yaml':
|
|
41
|
+
return 'pnpm';
|
|
42
|
+
case 'package-lock.json':
|
|
43
|
+
return 'npm';
|
|
44
|
+
case 'yarn.lock':
|
|
45
|
+
return 'yarn';
|
|
46
|
+
case 'bun.lock':
|
|
47
|
+
return 'bun';
|
|
48
|
+
default:
|
|
49
|
+
return 'npm';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public async install({ dir = this.rootDir, packages = [] }: { dir?: string; packages?: string[] }) {
|
|
54
|
+
let runCommand = this.packageManager;
|
|
55
|
+
if (this.packageManager === 'npm') {
|
|
56
|
+
runCommand = `${this.packageManager} i`;
|
|
57
|
+
} else {
|
|
58
|
+
runCommand = `${this.packageManager} ${packages?.length > 0 ? `add` : `install`}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const cpLogger = createChildProcessLogger({
|
|
62
|
+
logger: this.logger,
|
|
63
|
+
root: dir,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return cpLogger({
|
|
67
|
+
cmd: runCommand,
|
|
68
|
+
args: packages,
|
|
69
|
+
env: {
|
|
70
|
+
PATH: process.env.PATH!,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public async installPackages(packages: string[]) {
|
|
76
|
+
let runCommand = this.packageManager;
|
|
77
|
+
if (this.packageManager === 'npm') {
|
|
78
|
+
runCommand = `${this.packageManager} i`;
|
|
79
|
+
} else {
|
|
80
|
+
runCommand = `${this.packageManager} add`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const cpLogger = createChildProcessLogger({
|
|
84
|
+
logger: this.logger,
|
|
85
|
+
root: '',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return cpLogger({
|
|
89
|
+
cmd: `${runCommand}`,
|
|
90
|
+
args: packages,
|
|
91
|
+
env: {
|
|
92
|
+
PATH: process.env.PATH!,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public async checkDependencies(dependencies: string[]): Promise<string> {
|
|
98
|
+
try {
|
|
99
|
+
const packageJsonPath = path.join(this.rootDir, 'package.json');
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
await fsPromises.access(packageJsonPath);
|
|
103
|
+
} catch {
|
|
104
|
+
return 'No package.json file found in the current directory';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const packageJson = JSON.parse(await fsPromises.readFile(packageJsonPath, 'utf-8'));
|
|
108
|
+
for (const dependency of dependencies) {
|
|
109
|
+
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
110
|
+
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return 'ok';
|
|
115
|
+
} catch (err) {
|
|
116
|
+
console.error(err);
|
|
117
|
+
return 'Could not check dependencies';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public async getProjectName() {
|
|
122
|
+
try {
|
|
123
|
+
const packageJsonPath = path.join(this.rootDir, 'package.json');
|
|
124
|
+
const packageJson = await fsPromises.readFile(packageJsonPath, 'utf-8');
|
|
125
|
+
const pkg = JSON.parse(packageJson);
|
|
126
|
+
return pkg.name;
|
|
127
|
+
} catch (err) {
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public async getPackageVersion() {
|
|
133
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
134
|
+
const __dirname = dirname(__filename);
|
|
135
|
+
const pkgJsonPath = path.join(__dirname, '..', '..', 'package.json');
|
|
136
|
+
|
|
137
|
+
const content = (await fsExtra.readJSON(pkgJsonPath)) as PackageJson;
|
|
138
|
+
return content.version;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public async addScriptsToPackageJson(scripts: Record<string, string>) {
|
|
142
|
+
const packageJson = JSON.parse(await fsPromises.readFile('package.json', 'utf-8'));
|
|
143
|
+
packageJson.scripts = {
|
|
144
|
+
...packageJson.scripts,
|
|
145
|
+
...scripts,
|
|
146
|
+
};
|
|
147
|
+
await fsPromises.writeFile('package.json', JSON.stringify(packageJson, null, 2));
|
|
148
|
+
}
|
|
149
|
+
}
|
package/src/build/env.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
|
|
3
|
+
export abstract class EnvService {
|
|
4
|
+
abstract getEnvValue(key: string): Promise<string | null>;
|
|
5
|
+
abstract setEnvValue(key: string, value: string): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class FileEnvService extends EnvService {
|
|
9
|
+
private filePath: string;
|
|
10
|
+
|
|
11
|
+
constructor(filePath: string) {
|
|
12
|
+
super();
|
|
13
|
+
this.filePath = filePath;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private readFile(filePath: string): Promise<string> {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
fs.readFile(filePath, 'utf8', (err: NodeJS.ErrnoException | null, data: string) => {
|
|
19
|
+
if (err) reject(err);
|
|
20
|
+
else resolve(data);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private writeFile({ filePath, data }: { filePath: string; data: string }): Promise<void> {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
fs.writeFile(filePath, data, 'utf8', (err: NodeJS.ErrnoException | null) => {
|
|
28
|
+
if (err) reject(err);
|
|
29
|
+
else resolve();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private async updateEnvData({
|
|
35
|
+
key,
|
|
36
|
+
value,
|
|
37
|
+
filePath = this.filePath,
|
|
38
|
+
data,
|
|
39
|
+
}: {
|
|
40
|
+
key: string;
|
|
41
|
+
value: string;
|
|
42
|
+
filePath?: string;
|
|
43
|
+
data: string;
|
|
44
|
+
}): Promise<string> {
|
|
45
|
+
const regex = new RegExp(`^${key}=.*$`, 'm');
|
|
46
|
+
if (data.match(regex)) {
|
|
47
|
+
data = data.replace(regex, `${key}=${value}`);
|
|
48
|
+
} else {
|
|
49
|
+
data += `\n${key}=${value}`;
|
|
50
|
+
}
|
|
51
|
+
await this.writeFile({ filePath, data });
|
|
52
|
+
console.log(`${key} set to ${value} in ENV file.`);
|
|
53
|
+
return data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getEnvValue(key: string): Promise<string | null> {
|
|
57
|
+
try {
|
|
58
|
+
const data = await this.readFile(this.filePath);
|
|
59
|
+
const regex = new RegExp(`^${key}=(.*)$`, 'm');
|
|
60
|
+
const match = data.match(regex);
|
|
61
|
+
return match?.[1] || null;
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(`Error reading ENV value: ${err}`);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async setEnvValue(key: string, value: string): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
const data = await this.readFile(this.filePath);
|
|
71
|
+
await this.updateEnvData({ key, value, data });
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.error(`Error writing ENV value: ${err}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|