@easybuild/cli 0.0.1

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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/index.ts
27
+ var import_commander = require("commander");
28
+ var import_inquirer = __toESM(require("inquirer"));
29
+ var import_fs_extra2 = __toESM(require("fs-extra"));
30
+ var import_path2 = __toESM(require("path"));
31
+
32
+ // src/runtime.ts
33
+ var runtimes = {
34
+ "next-app": {
35
+ label: "Next.js (App Router)",
36
+ templateDir: "next-app",
37
+ fileName: "route",
38
+ output: (cwd, baseDir, lang) => `${cwd}/${baseDir}/app/api/p/[...path]/route.${lang}`
39
+ },
40
+ "next-pages": {
41
+ label: "Next.js (Pages Router)",
42
+ templateDir: "next-pages",
43
+ fileName: "route",
44
+ output: (cwd, baseDir, lang) => `${cwd}/${baseDir}/pages/api/p/[...path].${lang}`
45
+ }
46
+ // "express": {
47
+ // label: "Express (Node.js)",
48
+ // templateDir: "express",
49
+ // fileName: "index",
50
+ // output: (cwd: string, baseDir: string, lang: string) =>
51
+ // `${cwd}/easybuild-proxy.${lang}`,
52
+ // },
53
+ // "vercel": {
54
+ // label: "Vercel Serverless Function",
55
+ // templateDir: "vercel",
56
+ // fileName: "api",
57
+ // output: (cwd: string, baseDir: string, lang: string) =>
58
+ // `${cwd}/api/p/[...path].${lang}`,
59
+ // },
60
+ // "netlify": {
61
+ // label: "Netlify Function",
62
+ // templateDir: "netlify",
63
+ // fileName: "handler",
64
+ // output: (cwd: string, baseDir: string, lang: string) =>
65
+ // `${cwd}/netlify/functions/easybuild.${lang}`,
66
+ // },
67
+ // "cloudflare": {
68
+ // label: "Cloudflare Worker",
69
+ // templateDir: "cloudflare",
70
+ // fileName: "worker",
71
+ // output: (cwd: string, baseDir: string, lang: string) =>
72
+ // `${cwd}/src/worker.${lang}`,
73
+ // },
74
+ };
75
+
76
+ // src/installers/runtime.ts
77
+ var import_path = __toESM(require("path"));
78
+ var import_fs_extra = __toESM(require("fs-extra"));
79
+ async function installRuntime(cwd, runtimeKey, language) {
80
+ const runtime = runtimes[runtimeKey];
81
+ if (!runtime) {
82
+ console.error("Invalid runtime selected.");
83
+ return;
84
+ }
85
+ const hasSrc = await import_fs_extra.default.pathExists(import_path.default.join(cwd, "src"));
86
+ const baseDir = hasSrc ? "src" : "";
87
+ const outputPath = runtime.output(cwd, baseDir, language);
88
+ const templatePath = import_path.default.resolve(
89
+ __dirname,
90
+ "../templates",
91
+ runtime.templateDir,
92
+ language,
93
+ `${runtime.fileName}.${language}`
94
+ );
95
+ await import_fs_extra.default.ensureDir(import_path.default.dirname(outputPath));
96
+ if (await import_fs_extra.default.pathExists(outputPath)) {
97
+ console.log("\u26A0\uFE0F EasyBuild route already exists.");
98
+ return;
99
+ }
100
+ await import_fs_extra.default.copyFile(templatePath, outputPath);
101
+ console.log(`\u2705 EasyBuild ${runtimeKey} installed.`);
102
+ }
103
+
104
+ // src/index.ts
105
+ async function detectLanguage(cwd) {
106
+ const hasTsConfig = await import_fs_extra2.default.pathExists(
107
+ import_path2.default.join(cwd, "tsconfig.json")
108
+ );
109
+ return hasTsConfig ? "ts" : "js";
110
+ }
111
+ import_commander.program.action(async () => {
112
+ const cwd = process.cwd();
113
+ const { runtime } = await import_inquirer.default.prompt([
114
+ {
115
+ type: "list",
116
+ name: "runtime",
117
+ message: "Select your Server Environment:",
118
+ choices: Object.entries(runtimes).map(
119
+ ([key, value]) => ({
120
+ name: value.label,
121
+ value: key
122
+ })
123
+ )
124
+ }
125
+ ]);
126
+ const language = await detectLanguage(cwd);
127
+ await installRuntime(cwd, runtime, language);
128
+ });
129
+ import_commander.program.parse();
@@ -0,0 +1,35 @@
1
+ // EASYBUILD_RUNTIME: express
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import { Router } from "express";
5
+
6
+ const router = Router();
7
+
8
+ router.all("/api/p/*", async (req, res) => {
9
+ const forwardPath = req.params[0] || "";
10
+
11
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
12
+
13
+ try {
14
+ const response = await fetch(url, {
15
+ method: req.method,
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
19
+ },
20
+ body:
21
+ req.method !== "GET" && req.method !== "HEAD"
22
+ ? JSON.stringify(req.body)
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ res.status(response.status).send(data);
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ res.status(500).json({ error: "Proxy failed" });
32
+ }
33
+ });
34
+
35
+ export default router;
@@ -0,0 +1,35 @@
1
+ // EASYBUILD_RUNTIME: express
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import { Router } from "express";
5
+
6
+ const router = Router();
7
+
8
+ router.all("/api/p/*", async (req, res) => {
9
+ const forwardPath = req.params[0] || "";
10
+
11
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
12
+
13
+ try {
14
+ const response = await fetch(url, {
15
+ method: req.method,
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
19
+ },
20
+ body:
21
+ req.method !== "GET" && req.method !== "HEAD"
22
+ ? JSON.stringify(req.body)
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ res.status(response.status).send(data);
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ res.status(500).json({ error: "Proxy failed" });
32
+ }
33
+ });
34
+
35
+ export default router;
@@ -0,0 +1,39 @@
1
+ // EASYBUILD_RUNTIME: netlify
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export const handler = async (event) => {
5
+ const forwardPath = event.path.replace(
6
+ "/.netlify/functions/easybuild",
7
+ ""
8
+ );
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: event.httpMethod,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ event.httpMethod !== "GET" &&
21
+ event.httpMethod !== "HEAD"
22
+ ? event.body
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ return {
29
+ statusCode: response.status,
30
+ body: data,
31
+ };
32
+ } catch (error) {
33
+ console.error("Proxy error:", error);
34
+ return {
35
+ statusCode: 500,
36
+ body: JSON.stringify({ error: "Proxy failed" }),
37
+ };
38
+ }
39
+ };
@@ -0,0 +1,36 @@
1
+ // EASYBUILD_RUNTIME: netlify
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export const handler = async (event: any) => {
5
+ const pathParts = event.path.replace("/.netlify/functions/", "");
6
+ const forwardPath = pathParts.replace("proxy/", "");
7
+
8
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
9
+
10
+ try {
11
+ const response = await fetch(url, {
12
+ method: event.httpMethod,
13
+ headers: {
14
+ "Content-Type": "application/json",
15
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
16
+ },
17
+ body:
18
+ event.httpMethod !== "GET" && event.httpMethod !== "HEAD"
19
+ ? event.body
20
+ : undefined,
21
+ });
22
+
23
+ const data = await response.text();
24
+
25
+ return {
26
+ statusCode: response.status,
27
+ body: data,
28
+ };
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ return {
32
+ statusCode: 500,
33
+ body: JSON.stringify({ error: "Proxy failed" }),
34
+ };
35
+ }
36
+ };
@@ -0,0 +1,57 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ // EASYBUILD_RUNTIME: next-app
4
+ // EASYBUILD_VERSION: 0.1.0
5
+
6
+ async function handler(req, { params }) {
7
+ const { path } = params || {};
8
+ const forwardPath = Array.isArray(path) ? path.join("/") : path || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ let body;
13
+ const method = req.method;
14
+
15
+ if (method !== "GET" && method !== "HEAD") {
16
+ try {
17
+ body = await req.json();
18
+ } catch (e) {
19
+ console.error("Failed to parse body", e);
20
+ }
21
+ }
22
+
23
+ try {
24
+ const response = await fetch(url, {
25
+ method,
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
29
+ },
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ });
32
+
33
+ const data = await response.text();
34
+
35
+ return new NextResponse(data, {
36
+ status: response.status,
37
+ headers: {
38
+ "Content-Type":
39
+ response.headers.get("Content-Type") || "application/json",
40
+ },
41
+ });
42
+ } catch (error) {
43
+ console.error("Proxy error:", error);
44
+ return new NextResponse(
45
+ JSON.stringify({ error: "Proxy failed" }),
46
+ { status: 500 }
47
+ );
48
+ }
49
+ }
50
+
51
+ export {
52
+ handler as GET,
53
+ handler as POST,
54
+ handler as PUT,
55
+ handler as DELETE,
56
+ handler as PATCH,
57
+ };
@@ -0,0 +1,57 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ // EASYBUILD_RUNTIME: next-app
4
+ // EASYBUILD_VERSION: 0.1.0
5
+
6
+ async function handler(req, { params }) {
7
+ const { path } = params || {};
8
+ const forwardPath = Array.isArray(path) ? path.join("/") : path || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ let body;
13
+ const method = req.method;
14
+
15
+ if (method !== "GET" && method !== "HEAD") {
16
+ try {
17
+ body = await req.json();
18
+ } catch (e) {
19
+ console.error("Failed to parse body", e);
20
+ }
21
+ }
22
+
23
+ try {
24
+ const response = await fetch(url, {
25
+ method,
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
29
+ },
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ });
32
+
33
+ const data = await response.text();
34
+
35
+ return new NextResponse(data, {
36
+ status: response.status,
37
+ headers: {
38
+ "Content-Type":
39
+ response.headers.get("Content-Type") || "application/json",
40
+ },
41
+ });
42
+ } catch (error) {
43
+ console.error("Proxy error:", error);
44
+ return new NextResponse(
45
+ JSON.stringify({ error: "Proxy failed" }),
46
+ { status: 500 }
47
+ );
48
+ }
49
+ }
50
+
51
+ export {
52
+ handler as GET,
53
+ handler as POST,
54
+ handler as PUT,
55
+ handler as DELETE,
56
+ handler as PATCH,
57
+ };
@@ -0,0 +1,44 @@
1
+ import { NextResponse } from 'next/server';
2
+
3
+ async function handler(req, { params }) {
4
+ const { path } = await params;
5
+ const forwardPath = Array.isArray(path) ? path.join("/") : path;
6
+
7
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
8
+
9
+ let body = undefined;
10
+ const method = req.method;
11
+
12
+ if (method !== 'GET' && method !== 'HEAD') {
13
+ try {
14
+ body = await req.json();
15
+ } catch (e) {
16
+ console.error("Failed to parse body", e);
17
+ }
18
+ }
19
+
20
+ try {
21
+ const response = await fetch(url, {
22
+ method: method,
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ''}`,
26
+ },
27
+ body: body ? JSON.stringify(body) : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ return new NextResponse(data, {
33
+ status: response.status,
34
+ headers: {
35
+ 'Content-Type': response.headers.get('Content-Type') || 'application/json'
36
+ }
37
+ });
38
+ } catch (error) {
39
+ console.error("Proxy error:", error);
40
+ return new NextResponse(JSON.stringify({ error: "Proxy failed" }), { status: 500 });
41
+ }
42
+ }
43
+
44
+ export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };
@@ -0,0 +1,44 @@
1
+ import { NextResponse } from 'next/server';
2
+
3
+ async function handler(req, { params }) {
4
+ const { path } = await params;
5
+ const forwardPath = Array.isArray(path) ? path.join("/") : path;
6
+
7
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
8
+
9
+ let body = undefined;
10
+ const method = req.method;
11
+
12
+ if (method !== 'GET' && method !== 'HEAD') {
13
+ try {
14
+ body = await req.json();
15
+ } catch (e) {
16
+ console.error("Failed to parse body", e);
17
+ }
18
+ }
19
+
20
+ try {
21
+ const response = await fetch(url, {
22
+ method: method,
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ''}`,
26
+ },
27
+ body: body ? JSON.stringify(body) : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ return new NextResponse(data, {
33
+ status: response.status,
34
+ headers: {
35
+ 'Content-Type': response.headers.get('Content-Type') || 'application/json'
36
+ }
37
+ });
38
+ } catch (error) {
39
+ console.error("Proxy error:", error);
40
+ return new NextResponse(JSON.stringify({ error: "Proxy failed" }), { status: 500 });
41
+ }
42
+ }
43
+
44
+ export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };
@@ -0,0 +1,32 @@
1
+ // EASYBUILD_RUNTIME: next-pages
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export default async function handler(req, res) {
5
+ const pathParts = req.query.path;
6
+ const forwardPath = Array.isArray(pathParts)
7
+ ? pathParts.join("/")
8
+ : pathParts || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: req.method,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ req.method !== "GET" && req.method !== "HEAD"
21
+ ? JSON.stringify(req.body)
22
+ : undefined,
23
+ });
24
+
25
+ const data = await response.text();
26
+
27
+ res.status(response.status).send(data);
28
+ } catch (error) {
29
+ console.error("Proxy error:", error);
30
+ res.status(500).json({ error: "Proxy failed" });
31
+ }
32
+ }
@@ -0,0 +1,37 @@
1
+ // EASYBUILD_RUNTIME: next-pages
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import type { NextApiRequest, NextApiResponse } from "next";
5
+
6
+ export default async function handler(
7
+ req: NextApiRequest,
8
+ res: NextApiResponse
9
+ ) {
10
+ const pathParts = req.query.path;
11
+ const forwardPath = Array.isArray(pathParts)
12
+ ? pathParts.join("/")
13
+ : pathParts || "";
14
+
15
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
16
+
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: req.method,
20
+ headers: {
21
+ "Content-Type": "application/json",
22
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
23
+ },
24
+ body:
25
+ req.method !== "GET" && req.method !== "HEAD"
26
+ ? JSON.stringify(req.body)
27
+ : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ res.status(response.status).send(data);
33
+ } catch (error) {
34
+ console.error("Proxy error:", error);
35
+ res.status(500).json({ error: "Proxy failed" });
36
+ }
37
+ }
@@ -0,0 +1,32 @@
1
+ // EASYBUILD_RUNTIME: vercel
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export default async function handler(req, res) {
5
+ const pathParts = req.query.path;
6
+ const forwardPath = Array.isArray(pathParts)
7
+ ? pathParts.join("/")
8
+ : pathParts || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: req.method,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ req.method !== "GET" && req.method !== "HEAD"
21
+ ? JSON.stringify(req.body)
22
+ : undefined,
23
+ });
24
+
25
+ const data = await response.text();
26
+
27
+ res.status(response.status).send(data);
28
+ } catch (error) {
29
+ console.error("Proxy error:", error);
30
+ res.status(500).json({ error: "Proxy failed" });
31
+ }
32
+ }
@@ -0,0 +1,37 @@
1
+ // EASYBUILD_RUNTIME: vercel
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import type { VercelRequest, VercelResponse } from "@vercel/node";
5
+
6
+ export default async function handler(
7
+ req: VercelRequest,
8
+ res: VercelResponse
9
+ ) {
10
+ const pathParts = req.query.path;
11
+ const forwardPath = Array.isArray(pathParts)
12
+ ? pathParts.join("/")
13
+ : pathParts || "";
14
+
15
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
16
+
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: req.method,
20
+ headers: {
21
+ "Content-Type": "application/json",
22
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
23
+ },
24
+ body:
25
+ req.method !== "GET" && req.method !== "HEAD"
26
+ ? JSON.stringify(req.body)
27
+ : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ res.status(response.status).send(data);
33
+ } catch (error) {
34
+ console.error("Proxy error:", error);
35
+ res.status(500).json({ error: "Proxy failed" });
36
+ }
37
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@easybuild/cli",
3
+ "version": "0.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "bin": {
8
+ "easybuild": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup src/index.ts --format cjs --target node16 && cpy \"templates/**/*\" dist/templates",
12
+ "dev": "ts-node src/index.ts"
13
+ },
14
+ "keywords": ["easybuild", "cli", "proxy", "serverless"],
15
+ "author": "easybuild-cli",
16
+ "license": "MIT",
17
+ "description": "",
18
+ "dependencies": {
19
+ "chalk": "^5.6.2",
20
+ "commander": "^14.0.3",
21
+ "fs-extra": "^11.3.3",
22
+ "inquirer": "^12.11.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/commander": "^2.12.0",
26
+ "@types/inquirer": "^9.0.9",
27
+ "@types/node": "^25.1.0",
28
+ "tsup": "^8.5.1",
29
+ "typescript": "^5.9.3"
30
+ }
31
+ }
package/src/index.ts ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from "commander";
4
+ import inquirer from "inquirer";
5
+ import fs from "fs-extra";
6
+ import path from "path";
7
+ import { runtimes } from "./runtime";
8
+ import { installRuntime } from "./installers/runtime";
9
+
10
+ async function detectLanguage(cwd: string): Promise<"ts" | "js"> {
11
+ const hasTsConfig = await fs.pathExists(
12
+ path.join(cwd, "tsconfig.json")
13
+ );
14
+
15
+ return hasTsConfig ? "ts" : "js";
16
+ }
17
+
18
+ program.action(async () => {
19
+ const cwd = process.cwd();
20
+
21
+ const { runtime } = await inquirer.prompt([
22
+ {
23
+ type: "list",
24
+ name: "runtime",
25
+ message: "Select your Server Environment:",
26
+ choices: Object.entries(runtimes).map(
27
+ ([key, value]) => ({
28
+ name: value.label,
29
+ value: key,
30
+ })
31
+ ),
32
+ },
33
+ ]);
34
+
35
+ const language = await detectLanguage(cwd);
36
+
37
+ await installRuntime(cwd, runtime, language);
38
+ });
39
+
40
+ program.parse();
@@ -0,0 +1,40 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { runtimes } from "../runtime";
4
+
5
+ export async function installRuntime(
6
+ cwd: string,
7
+ runtimeKey: string,
8
+ language: "ts" | "js"
9
+ ) {
10
+ const runtime = runtimes[runtimeKey];
11
+
12
+ if (!runtime) {
13
+ console.error("Invalid runtime selected.");
14
+ return;
15
+ }
16
+
17
+ const hasSrc = await fs.pathExists(path.join(cwd, "src"));
18
+ const baseDir = hasSrc ? "src" : "";
19
+
20
+ const outputPath = runtime.output(cwd, baseDir, language);
21
+
22
+ const templatePath = path.resolve(
23
+ __dirname,
24
+ "../templates",
25
+ runtime.templateDir,
26
+ language,
27
+ `${runtime.fileName}.${language}`
28
+ );
29
+
30
+ await fs.ensureDir(path.dirname(outputPath));
31
+
32
+ if (await fs.pathExists(outputPath)) {
33
+ console.log("⚠️ EasyBuild route already exists.");
34
+ return;
35
+ }
36
+
37
+ await fs.copyFile(templatePath, outputPath);
38
+
39
+ console.log(`✅ EasyBuild ${runtimeKey} installed.`);
40
+ }
package/src/runtime.ts ADDED
@@ -0,0 +1,49 @@
1
+ export const runtimes = {
2
+ "next-app": {
3
+ label: "Next.js (App Router)",
4
+ templateDir: "next-app",
5
+ fileName: "route",
6
+ output: (cwd: string, baseDir: string, lang: string) =>
7
+ `${cwd}/${baseDir}/app/api/p/[...path]/route.${lang}`,
8
+ },
9
+
10
+ "next-pages": {
11
+ label: "Next.js (Pages Router)",
12
+ templateDir: "next-pages",
13
+ fileName: "route",
14
+ output: (cwd: string, baseDir: string, lang: string) =>
15
+ `${cwd}/${baseDir}/pages/api/p/[...path].${lang}`,
16
+ },
17
+
18
+ // "express": {
19
+ // label: "Express (Node.js)",
20
+ // templateDir: "express",
21
+ // fileName: "index",
22
+ // output: (cwd: string, baseDir: string, lang: string) =>
23
+ // `${cwd}/easybuild-proxy.${lang}`,
24
+ // },
25
+
26
+ // "vercel": {
27
+ // label: "Vercel Serverless Function",
28
+ // templateDir: "vercel",
29
+ // fileName: "api",
30
+ // output: (cwd: string, baseDir: string, lang: string) =>
31
+ // `${cwd}/api/p/[...path].${lang}`,
32
+ // },
33
+
34
+ // "netlify": {
35
+ // label: "Netlify Function",
36
+ // templateDir: "netlify",
37
+ // fileName: "handler",
38
+ // output: (cwd: string, baseDir: string, lang: string) =>
39
+ // `${cwd}/netlify/functions/easybuild.${lang}`,
40
+ // },
41
+
42
+ // "cloudflare": {
43
+ // label: "Cloudflare Worker",
44
+ // templateDir: "cloudflare",
45
+ // fileName: "worker",
46
+ // output: (cwd: string, baseDir: string, lang: string) =>
47
+ // `${cwd}/src/worker.${lang}`,
48
+ // },
49
+ };
@@ -0,0 +1,35 @@
1
+ // EASYBUILD_RUNTIME: express
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import { Router } from "express";
5
+
6
+ const router = Router();
7
+
8
+ router.all("/api/p/*", async (req, res) => {
9
+ const forwardPath = req.params[0] || "";
10
+
11
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
12
+
13
+ try {
14
+ const response = await fetch(url, {
15
+ method: req.method,
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
19
+ },
20
+ body:
21
+ req.method !== "GET" && req.method !== "HEAD"
22
+ ? JSON.stringify(req.body)
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ res.status(response.status).send(data);
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ res.status(500).json({ error: "Proxy failed" });
32
+ }
33
+ });
34
+
35
+ export default router;
@@ -0,0 +1,35 @@
1
+ // EASYBUILD_RUNTIME: express
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import { Router } from "express";
5
+
6
+ const router = Router();
7
+
8
+ router.all("/api/p/*", async (req, res) => {
9
+ const forwardPath = req.params[0] || "";
10
+
11
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
12
+
13
+ try {
14
+ const response = await fetch(url, {
15
+ method: req.method,
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
19
+ },
20
+ body:
21
+ req.method !== "GET" && req.method !== "HEAD"
22
+ ? JSON.stringify(req.body)
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ res.status(response.status).send(data);
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ res.status(500).json({ error: "Proxy failed" });
32
+ }
33
+ });
34
+
35
+ export default router;
@@ -0,0 +1,39 @@
1
+ // EASYBUILD_RUNTIME: netlify
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export const handler = async (event) => {
5
+ const forwardPath = event.path.replace(
6
+ "/.netlify/functions/easybuild",
7
+ ""
8
+ );
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: event.httpMethod,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ event.httpMethod !== "GET" &&
21
+ event.httpMethod !== "HEAD"
22
+ ? event.body
23
+ : undefined,
24
+ });
25
+
26
+ const data = await response.text();
27
+
28
+ return {
29
+ statusCode: response.status,
30
+ body: data,
31
+ };
32
+ } catch (error) {
33
+ console.error("Proxy error:", error);
34
+ return {
35
+ statusCode: 500,
36
+ body: JSON.stringify({ error: "Proxy failed" }),
37
+ };
38
+ }
39
+ };
@@ -0,0 +1,36 @@
1
+ // EASYBUILD_RUNTIME: netlify
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export const handler = async (event: any) => {
5
+ const pathParts = event.path.replace("/.netlify/functions/", "");
6
+ const forwardPath = pathParts.replace("proxy/", "");
7
+
8
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
9
+
10
+ try {
11
+ const response = await fetch(url, {
12
+ method: event.httpMethod,
13
+ headers: {
14
+ "Content-Type": "application/json",
15
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
16
+ },
17
+ body:
18
+ event.httpMethod !== "GET" && event.httpMethod !== "HEAD"
19
+ ? event.body
20
+ : undefined,
21
+ });
22
+
23
+ const data = await response.text();
24
+
25
+ return {
26
+ statusCode: response.status,
27
+ body: data,
28
+ };
29
+ } catch (error) {
30
+ console.error("Proxy error:", error);
31
+ return {
32
+ statusCode: 500,
33
+ body: JSON.stringify({ error: "Proxy failed" }),
34
+ };
35
+ }
36
+ };
@@ -0,0 +1,57 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ // EASYBUILD_RUNTIME: next-app
4
+ // EASYBUILD_VERSION: 0.1.0
5
+
6
+ async function handler(req, { params }) {
7
+ const { path } = params || {};
8
+ const forwardPath = Array.isArray(path) ? path.join("/") : path || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ let body;
13
+ const method = req.method;
14
+
15
+ if (method !== "GET" && method !== "HEAD") {
16
+ try {
17
+ body = await req.json();
18
+ } catch (e) {
19
+ console.error("Failed to parse body", e);
20
+ }
21
+ }
22
+
23
+ try {
24
+ const response = await fetch(url, {
25
+ method,
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
29
+ },
30
+ body: body ? JSON.stringify(body) : undefined,
31
+ });
32
+
33
+ const data = await response.text();
34
+
35
+ return new NextResponse(data, {
36
+ status: response.status,
37
+ headers: {
38
+ "Content-Type":
39
+ response.headers.get("Content-Type") || "application/json",
40
+ },
41
+ });
42
+ } catch (error) {
43
+ console.error("Proxy error:", error);
44
+ return new NextResponse(
45
+ JSON.stringify({ error: "Proxy failed" }),
46
+ { status: 500 }
47
+ );
48
+ }
49
+ }
50
+
51
+ export {
52
+ handler as GET,
53
+ handler as POST,
54
+ handler as PUT,
55
+ handler as DELETE,
56
+ handler as PATCH,
57
+ };
@@ -0,0 +1,44 @@
1
+ import { NextResponse } from 'next/server';
2
+
3
+ async function handler(req, { params }) {
4
+ const { path } = await params;
5
+ const forwardPath = Array.isArray(path) ? path.join("/") : path;
6
+
7
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
8
+
9
+ let body = undefined;
10
+ const method = req.method;
11
+
12
+ if (method !== 'GET' && method !== 'HEAD') {
13
+ try {
14
+ body = await req.json();
15
+ } catch (e) {
16
+ console.error("Failed to parse body", e);
17
+ }
18
+ }
19
+
20
+ try {
21
+ const response = await fetch(url, {
22
+ method: method,
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ''}`,
26
+ },
27
+ body: body ? JSON.stringify(body) : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ return new NextResponse(data, {
33
+ status: response.status,
34
+ headers: {
35
+ 'Content-Type': response.headers.get('Content-Type') || 'application/json'
36
+ }
37
+ });
38
+ } catch (error) {
39
+ console.error("Proxy error:", error);
40
+ return new NextResponse(JSON.stringify({ error: "Proxy failed" }), { status: 500 });
41
+ }
42
+ }
43
+
44
+ export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };
@@ -0,0 +1,32 @@
1
+ // EASYBUILD_RUNTIME: next-pages
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export default async function handler(req, res) {
5
+ const pathParts = req.query.path;
6
+ const forwardPath = Array.isArray(pathParts)
7
+ ? pathParts.join("/")
8
+ : pathParts || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: req.method,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ req.method !== "GET" && req.method !== "HEAD"
21
+ ? JSON.stringify(req.body)
22
+ : undefined,
23
+ });
24
+
25
+ const data = await response.text();
26
+
27
+ res.status(response.status).send(data);
28
+ } catch (error) {
29
+ console.error("Proxy error:", error);
30
+ res.status(500).json({ error: "Proxy failed" });
31
+ }
32
+ }
@@ -0,0 +1,37 @@
1
+ // EASYBUILD_RUNTIME: next-pages
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import type { NextApiRequest, NextApiResponse } from "next";
5
+
6
+ export default async function handler(
7
+ req: NextApiRequest,
8
+ res: NextApiResponse
9
+ ) {
10
+ const pathParts = req.query.path;
11
+ const forwardPath = Array.isArray(pathParts)
12
+ ? pathParts.join("/")
13
+ : pathParts || "";
14
+
15
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
16
+
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: req.method,
20
+ headers: {
21
+ "Content-Type": "application/json",
22
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
23
+ },
24
+ body:
25
+ req.method !== "GET" && req.method !== "HEAD"
26
+ ? JSON.stringify(req.body)
27
+ : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ res.status(response.status).send(data);
33
+ } catch (error) {
34
+ console.error("Proxy error:", error);
35
+ res.status(500).json({ error: "Proxy failed" });
36
+ }
37
+ }
@@ -0,0 +1,32 @@
1
+ // EASYBUILD_RUNTIME: vercel
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ export default async function handler(req, res) {
5
+ const pathParts = req.query.path;
6
+ const forwardPath = Array.isArray(pathParts)
7
+ ? pathParts.join("/")
8
+ : pathParts || "";
9
+
10
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
11
+
12
+ try {
13
+ const response = await fetch(url, {
14
+ method: req.method,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
18
+ },
19
+ body:
20
+ req.method !== "GET" && req.method !== "HEAD"
21
+ ? JSON.stringify(req.body)
22
+ : undefined,
23
+ });
24
+
25
+ const data = await response.text();
26
+
27
+ res.status(response.status).send(data);
28
+ } catch (error) {
29
+ console.error("Proxy error:", error);
30
+ res.status(500).json({ error: "Proxy failed" });
31
+ }
32
+ }
@@ -0,0 +1,37 @@
1
+ // EASYBUILD_RUNTIME: vercel
2
+ // EASYBUILD_VERSION: 0.1.0
3
+
4
+ import type { VercelRequest, VercelResponse } from "@vercel/node";
5
+
6
+ export default async function handler(
7
+ req: VercelRequest,
8
+ res: VercelResponse
9
+ ) {
10
+ const pathParts = req.query.path;
11
+ const forwardPath = Array.isArray(pathParts)
12
+ ? pathParts.join("/")
13
+ : pathParts || "";
14
+
15
+ const url = `https://api.tryezbuild.tech/api/p/${forwardPath}`;
16
+
17
+ try {
18
+ const response = await fetch(url, {
19
+ method: req.method,
20
+ headers: {
21
+ "Content-Type": "application/json",
22
+ "Authorization": `Bearer ${process.env.EASYBUILD_SECRET_KEY || ""}`,
23
+ },
24
+ body:
25
+ req.method !== "GET" && req.method !== "HEAD"
26
+ ? JSON.stringify(req.body)
27
+ : undefined,
28
+ });
29
+
30
+ const data = await response.text();
31
+
32
+ res.status(response.status).send(data);
33
+ } catch (error) {
34
+ console.error("Proxy error:", error);
35
+ res.status(500).json({ error: "Proxy failed" });
36
+ }
37
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "Node",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "resolveJsonModule": true,
12
+ "declaration": true
13
+ },
14
+ "include": ["src"]
15
+ }