@mastra/deployer-netlify 0.0.1-alpha.31 → 0.0.1-alpha.4

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/index.js CHANGED
@@ -1,148 +1,8 @@
1
- import { Deployer } from '@mastra/deployer';
2
- import { getBundler } from '@mastra/deployer/build';
3
- import virtual from '@rollup/plugin-virtual';
4
- import { execa } from 'execa';
5
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
6
- import { join } from 'path';
7
1
 
8
- // src/index.ts
2
+ 'use strict'
9
3
 
10
- // src/helpers.ts
11
- async function createNetlifySite({ token, name, scope }) {
12
- console.log(token, name, scope);
13
- const response = await fetch("https://api.netlify.com/api/v1/sites", {
14
- method: "POST",
15
- headers: {
16
- Authorization: `Bearer ${token}`,
17
- "Content-Type": "application/json"
18
- },
19
- body: JSON.stringify({
20
- name,
21
- account_slug: scope,
22
- // Optional - if not provided, creates in user's default account
23
- force_ssl: true
24
- // Enable HTTPS
25
- })
26
- });
27
- const data = await response.json();
28
- if (!response.ok) {
29
- console.error(JSON.stringify(data));
30
- throw new Error(`Failed to create site: ${data.message || "Unknown error"}`);
31
- }
32
- return {
33
- id: data.id,
34
- name: data.name,
35
- url: data.ssl_url || data.url,
36
- adminUrl: data.admin_url
37
- };
4
+ if (process.env.NODE_ENV === 'production') {
5
+ module.exports = require('./deployer-netlify.cjs.production.min.js')
6
+ } else {
7
+ module.exports = require('./deployer-netlify.cjs.development.js')
38
8
  }
39
- async function findNetlifySite({ token, name, scope }) {
40
- const response = await fetch(`https://api.netlify.com/api/v1/${scope}/sites?filter=all&name=${name}`, {
41
- headers: {
42
- Authorization: `Bearer ${token}`,
43
- "Content-Type": "application/json"
44
- }
45
- });
46
- const data = await response.json();
47
- if (!response.ok) {
48
- throw new Error(`Failed to search sites: ${data.message || "Unknown error"}`);
49
- }
50
- return data.find((site) => site.name === name);
51
- }
52
- async function getOrCreateSite({ token, name, scope }) {
53
- let existingSite;
54
- try {
55
- existingSite = await findNetlifySite({ token, name, scope });
56
- } catch (e) {
57
- }
58
- if (existingSite) {
59
- return existingSite;
60
- }
61
- return createNetlifySite({ token, name, scope });
62
- }
63
-
64
- // src/index.ts
65
- var NetlifyDeployer = class extends Deployer {
66
- scope;
67
- projectName;
68
- token;
69
- constructor({ scope, projectName, token }) {
70
- super({ name: "NETLIFY" });
71
- this.scope = scope;
72
- this.projectName = projectName;
73
- this.token = token;
74
- }
75
- writeFiles({ dir }) {
76
- if (!existsSync(join(dir, "netlify/functions/api"))) {
77
- mkdirSync(join(dir, "netlify/functions/api"), { recursive: true });
78
- }
79
- writeFileSync(
80
- join(dir, "netlify.toml"),
81
- `[functions]
82
- node_bundler = "esbuild"
83
- directory = "netlify/functions"
84
-
85
- [[redirects]]
86
- force = true
87
- from = "/*"
88
- status = 200
89
- to = "/.netlify/functions/api/:splat"
90
- `
91
- );
92
- }
93
- async deploy(outputDirectory) {
94
- const site = await getOrCreateSite({ token: this.token, name: this.projectName || `mastra`, scope: this.scope });
95
- const p2 = execa(
96
- "npx",
97
- [
98
- "netlify-cli",
99
- "deploy",
100
- "--site",
101
- site.id,
102
- "--auth",
103
- this.token,
104
- "--dir",
105
- ".",
106
- "--functions",
107
- "./netlify/functions"
108
- ],
109
- {
110
- cwd: outputDirectory
111
- }
112
- );
113
- p2.stdout.pipe(process.stdout);
114
- await p2;
115
- }
116
- async prepare(outputDirectory) {
117
- await super.prepare(outputDirectory);
118
- if (!existsSync(join(outputDirectory, "netlify/functions/api"))) {
119
- mkdirSync(join(outputDirectory, "netlify/functions/api"), { recursive: true });
120
- }
121
- this.writeFiles({ dir: outputDirectory });
122
- }
123
- async bundle(mastraDir, outputDirectory) {
124
- const bundler = await getBundler({
125
- input: "#entry",
126
- external: [/^@opentelemetry\//],
127
- plugins: [virtual({ "#entry": this.getEntry() })]
128
- });
129
- bundler.write({
130
- inlineDynamicImports: true,
131
- file: join(outputDirectory, "netlify", "functions", "api", "index.mjs"),
132
- format: "es"
133
- });
134
- }
135
- getEntry() {
136
- return `
137
- import { handle } from 'hono/netlify'
138
- import { mastra } from '#mastra';
139
- import { createHonoServer } from '#server';
140
-
141
- const app = await createHonoServer(mastra);
142
-
143
- export default handle(app)
144
- `;
145
- }
146
- };
147
-
148
- export { NetlifyDeployer };
package/package.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
2
  "name": "@mastra/deployer-netlify",
3
- "version": "0.0.1-alpha.31",
3
+ "version": "0.0.1-alpha.4",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
+ "module": "dist/deployer-netlify.esm.js",
7
8
  "types": "dist/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "types": "./dist/index.d.ts",
11
- "default": "./dist/index.js"
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/deployer-netlify.esm.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ }
12
19
  },
13
20
  "./package.json": "./package.json"
14
21
  },
@@ -16,26 +23,27 @@
16
23
  "author": "",
17
24
  "license": "ISC",
18
25
  "dependencies": {
19
- "@rollup/plugin-virtual": "^3.0.2",
20
26
  "date-fns": "^4.1.0",
21
27
  "dotenv": "^16.3.1",
22
28
  "execa": "^9.3.1",
23
29
  "netlify-cli": "^18.0.1",
24
30
  "zod": "^3.24.1",
25
- "@mastra/core": "0.2.0-alpha.84",
26
- "@mastra/deployer": "0.0.1-alpha.29"
31
+ "@mastra/core": "0.1.27-alpha.67",
32
+ "@mastra/deployer": "0.0.1-alpha.4"
27
33
  },
28
34
  "devDependencies": {
29
35
  "@babel/preset-env": "^7.26.0",
30
36
  "@babel/preset-typescript": "^7.26.0",
31
37
  "@tsconfig/recommended": "^1.0.7",
38
+ "@types/jsdom": "^21.1.7",
32
39
  "@types/node": "^22.9.0",
33
- "tsup": "^8.0.1",
34
- "vitest": "^3.0.4"
40
+ "@types/pg": "^8.11.10",
41
+ "dts-cli": "^2.0.5",
42
+ "vitest": "^2.1.8"
35
43
  },
36
44
  "scripts": {
37
- "build": "tsup-node src/index.ts --format esm --dts --clean --treeshake",
38
- "dev": "tsup-node src/index.ts --format esm --dts --clean --treeshake --watch",
45
+ "build": "dts build",
46
+ "build:dev": "dts watch",
39
47
  "test": "vitest run"
40
48
  }
41
49
  }
package/src/index.ts CHANGED
@@ -1,23 +1,13 @@
1
- import { Deployer } from '@mastra/deployer';
2
- import { getBundler } from '@mastra/deployer/build';
3
- import virtual from '@rollup/plugin-virtual';
1
+ import { MastraDeployer } from '@mastra/core';
4
2
  import { execa } from 'execa';
5
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
3
+ import { existsSync, mkdirSync, renameSync, writeFileSync } from 'fs';
6
4
  import { join } from 'path';
7
5
 
8
6
  import { getOrCreateSite } from './helpers.js';
9
7
 
10
- export class NetlifyDeployer extends Deployer {
11
- protected scope: string;
12
- protected projectName: string;
13
- protected token: string;
14
-
15
- constructor({ scope, projectName, token }: { scope: string; projectName: string; token: string }) {
16
- super({ name: 'NETLIFY' });
17
-
18
- this.scope = scope;
19
- this.projectName = projectName;
20
- this.token = token;
8
+ export class NetlifyDeployer extends MastraDeployer {
9
+ constructor({ scope, env, projectName }: { projectName: string; env?: Record<string, any>; scope: string }) {
10
+ super({ scope, env, projectName });
21
11
  }
22
12
 
23
13
  writeFiles({ dir }: { dir: string }): void {
@@ -28,38 +18,30 @@ export class NetlifyDeployer extends Deployer {
28
18
  // TODO ENV KEYS
29
19
  writeFileSync(
30
20
  join(dir, 'netlify.toml'),
31
- `[functions]
32
- node_bundler = "esbuild"
33
- directory = "netlify/functions"
34
-
35
- [[redirects]]
36
- force = true
37
- from = "/*"
38
- status = 200
39
- to = "/.netlify/functions/api/:splat"
40
- `,
21
+ `
22
+ [functions]
23
+ node_bundler = "esbuild"
24
+ directory = "/netlify/functions"
25
+
26
+ [[redirects]]
27
+ force = true
28
+ from = "/*"
29
+ status = 200
30
+ to = "/.netlify/functions/api/:splat"
31
+ `,
41
32
  );
33
+
34
+ this.writeIndex({ dir });
42
35
  }
43
36
 
44
- async deploy(outputDirectory: string): Promise<void> {
45
- const site = await getOrCreateSite({ token: this.token, name: this.projectName || `mastra`, scope: this.scope });
37
+ async deploy({ dir, token }: { dir: string; token: string }): Promise<void> {
38
+ const site = await getOrCreateSite({ token, name: this.projectName || `mastra`, scope: this.scope });
46
39
 
47
40
  const p2 = execa(
48
- 'npx',
49
- [
50
- 'netlify-cli',
51
- 'deploy',
52
- '--site',
53
- site.id,
54
- '--auth',
55
- this.token,
56
- '--dir',
57
- '.',
58
- '--functions',
59
- './netlify/functions',
60
- ],
41
+ 'netlify',
42
+ ['deploy', '--site', site.id, '--auth', token, '--dir', '.', '--functions', './netlify/functions'],
61
43
  {
62
- cwd: outputDirectory,
44
+ cwd: dir,
63
45
  },
64
46
  );
65
47
 
@@ -67,39 +49,23 @@ to = "/.netlify/functions/api/:splat"
67
49
  await p2;
68
50
  }
69
51
 
70
- async prepare(outputDirectory: string): Promise<void> {
71
- await super.prepare(outputDirectory);
72
-
73
- // Prepare the deployment directory
74
- if (!existsSync(join(outputDirectory, 'netlify/functions/api'))) {
75
- mkdirSync(join(outputDirectory, 'netlify/functions/api'), { recursive: true });
76
- }
77
- this.writeFiles({ dir: outputDirectory });
78
- }
79
-
80
- async bundle(mastraDir: string, outputDirectory: string): Promise<void> {
81
- const bundler = await getBundler({
82
- input: '#entry',
83
- external: [/^@opentelemetry\//],
84
- plugins: [virtual({ '#entry': this.getEntry() })],
52
+ writeIndex({ dir }: { dir: string }): void {
53
+ ['mastra.mjs', 'hono.mjs', 'server.mjs'].forEach(file => {
54
+ renameSync(join(dir, file), join(dir, `netlify/functions/api/${file}`));
85
55
  });
86
56
 
87
- bundler.write({
88
- inlineDynamicImports: true,
89
- file: join(outputDirectory, 'netlify', 'functions', 'api', 'index.mjs'),
90
- format: 'es',
91
- });
92
- }
93
-
94
- private getEntry(): string {
95
- return `
96
- import { handle } from 'hono/netlify'
97
- import { mastra } from '#mastra';
98
- import { createHonoServer } from '#server';
99
-
100
- const app = await createHonoServer(mastra);
101
-
102
- export default handle(app)
103
- `;
57
+ writeFileSync(
58
+ join(dir, 'netlify/functions/api/api.mts'),
59
+ `
60
+ export default async (req, context) => {
61
+ const { app } = await import('./hono.mjs');
62
+ // Pass the request directly to Hono
63
+ return app.fetch(req, {
64
+ // Optional context passing if needed
65
+ env: { context }
66
+ })
67
+ }
68
+ `,
69
+ );
104
70
  }
105
71
  }
package/tsconfig.json CHANGED
@@ -1,5 +1,10 @@
1
1
  {
2
- "extends": "../../tsconfig.node.json",
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "moduleResolution": "bundler",
5
+ "outDir": "./dist",
6
+ "rootDir": "./src"
7
+ },
3
8
  "include": ["src/**/*"],
4
9
  "exclude": ["node_modules", "**/*.test.ts"]
5
10
  }
package/vitest.config.ts CHANGED
@@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config';
2
2
 
3
3
  export default defineConfig({
4
4
  test: {
5
- environment: 'node',
5
+ globals: true,
6
6
  include: ['src/**/*.test.ts'],
7
7
  },
8
8
  });
package/README.md DELETED
@@ -1,86 +0,0 @@
1
- # @mastra/deployer-netlify
2
-
3
- A Netlify deployer for Mastra applications.
4
-
5
- ## Features
6
-
7
- - Deploy Mastra applications to Netlify Functions
8
- - Automatic site creation and configuration
9
- - Serverless function support with Edge Functions
10
- - Zero-configuration deployments
11
-
12
- ## Installation
13
-
14
- ```bash
15
- pnpm add @mastra/deployer-netlify
16
- ```
17
-
18
- ## Usage
19
-
20
- The Netlify deployer is used as part of the Mastra framework:
21
-
22
- ```typescript
23
- import { Mastra } from '@mastra/core';
24
- import { NetlifyDeployer } from '@mastra/deployer-netlify';
25
-
26
- const deployer = new NetlifyDeployer({
27
- scope: 'your-team-id',
28
- projectName: 'your-project-name',
29
- });
30
-
31
- const mastra = new Mastra({
32
- deployer,
33
- // ... other Mastra configuration options
34
- });
35
- ```
36
-
37
- ## Configuration
38
-
39
- ### Constructor Options
40
-
41
- - `scope` (required): Your Netlify team ID
42
- - `projectName`: Name of your Netlify site (will be created if it doesn't exist)
43
-
44
- ## Project Structure
45
-
46
- The deployer automatically creates the following structure:
47
-
48
- ```
49
- your-project/
50
- ├── netlify/
51
- │ └── functions/
52
- │ └── api/
53
- └── netlify.toml
54
- ```
55
-
56
- ### netlify.toml Configuration
57
-
58
- The deployer creates a `netlify.toml` with the following defaults:
59
-
60
- ```toml
61
- [functions]
62
- node_bundler = "esbuild"
63
- directory = "/netlify/functions"
64
-
65
- [[redirects]]
66
- force = true
67
- from = "/*"
68
- status = 200
69
- to = "/.netlify/functions/api/:splat"
70
- ```
71
-
72
- ## Environment Variables
73
-
74
- Environment variables are handled automatically through:
75
-
76
- - `.env` files in your project
77
- - Environment variables passed through the Mastra configuration
78
- - Netlify's environment variable UI
79
-
80
- ## Deployment Process
81
-
82
- The deployer will:
83
-
84
- 1. Create a new site if it doesn't exist
85
- 2. Configure the site with your environment variables
86
- 3. Deploy your application to Netlify Functions