Skip to content

Commit e919f94

Browse files
committed
make things Bun-compatible
1 parent 3c7f1f0 commit e919f94

File tree

6 files changed

+60
-30
lines changed

6 files changed

+60
-30
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ Either use the [Mastro template for Node.js](https://github.com/mastrojs/templat
3838

3939
pnpm create @mastrojs/mastro@latest
4040

41+
#### Bun
42+
43+
Either use the [Mastro template for Bun](https://github.com/mastrojs/template-basic-bun) or run:
44+
bun create @mastrojs/mastro@latest
45+
4146

4247
## Deploy to production
4348

create-mastro/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ Create a new [Mastro](https://mastrojs.github.io/) project. Usage:
77
Node.js
88

99
pnpm create @mastrojs/mastro@latest
10+
11+
Bun
12+
13+
bun create @mastrojs/mastro@latest

create-mastro/index.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import { stdin, stdout } from "node:process";
1717
import { createInterface } from "node:readline/promises";
1818
import { Readable } from "node:stream";
1919

20+
const runtime = typeof Deno === "object"
21+
? "deno"
22+
// the usual ways to detect Bun don't appear to work in `bun create`
23+
: (process.env.npm_config_user_agent?.startsWith("bun") ? "bun" : "node");
24+
2025
/**
2126
* @param {string} path
2227
* @param {ReadableStream<Uint8Array<ArrayBuffer>>} data
@@ -50,8 +55,7 @@ const execCmd = (cmd) =>
5055
}))
5156
);
5257

53-
const isDeno = typeof Deno === "object";
54-
const repoName = `template-basic-${isDeno ? "deno" : "node"}`;
58+
const repoName = `template-basic-${runtime}`;
5559
const repoUrl = `https://github.com/mastrojs/${repoName}/archive/refs/heads/main.zip`;
5660
const zipFilePromise = fetch(repoUrl);
5761

@@ -80,13 +84,21 @@ if (dir) {
8084
if (unzipSuccess) {
8185
await fs.rename(outDir, dir);
8286

87+
const bunOrPnpm = runtime === "bun" ? "bun" : "pnpm";
88+
const installInstr = runtime === "deno"
89+
? ""
90+
: `\n\nThen install dependencies with: ${bunOrPnpm} install\n`;
91+
const startInstr = runtime === "deno"
92+
? "deno task start"
93+
: `${bunOrPnpm} run start`;
94+
8395
const codeStyle = "color: blue";
8496
console.log(
8597
`
8698
Success!
8799
88-
Enter the newly created folder with: %ccd ${dir}${isDeno ? "" : "\n\nThen install dependencies with: pnpm install\n"}
89-
%cThen start the dev server with: %c${isDeno ? "deno task" : "pnpm run"} start`,
100+
Enter the newly created folder with: %ccd ${dir}${installInstr}
101+
%cThen start the dev server with: %c${startInstr}`,
90102
codeStyle,
91103
"",
92104
codeStyle,

src/core/fs.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,21 @@ export const findFiles = async (pattern: string): Promise<string[]> => {
5858
if (fs) {
5959
const process = await import("node:process");
6060
const paths = [];
61-
for await (const entry of fs.glob(pattern, { withFileTypes: true })) {
62-
if (entry.isFile() && !entry.isSymbolicLink() && !entry.name.endsWith(sep + ".DS_Store")) {
63-
const path = entry.parentPath + sep + entry.name;
64-
const relativeToProjectRoot = path.slice(process.cwd().length);
65-
paths.push(relativeToProjectRoot);
61+
if (process.versions.bun) {
62+
// until https://github.com/oven-sh/bun/issues/22018 is fixed
63+
for await (const file of fs.glob(pattern)) {
64+
const entry = await fs.lstat(file);
65+
if (entry.isFile() && !entry.isSymbolicLink() && !file.endsWith(sep + ".DS_Store")) {
66+
paths.push(sep + file)
67+
}
68+
}
69+
} else {
70+
for await (const entry of fs.glob(pattern, { withFileTypes: true })) {
71+
if (entry.isFile() && !entry.isSymbolicLink() && !entry.name.endsWith(sep + ".DS_Store")) {
72+
const path = entry.parentPath + sep + entry.name;
73+
const relativeToProjectRoot = path.slice(process.cwd().length);
74+
paths.push(relativeToProjectRoot);
75+
}
6676
}
6777
}
6878
return paths;

src/core/router.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { findFiles, sep } from "./fs.ts";
22

3-
if (!globalThis.URLPattern) {
4-
// to be implemented by all browsers soon:
5-
// see https://wpt.fyi/results/urlpattern?q=label%3Ainterop-2025-urlpattern
6-
await import(`https://esm.sh/${'urlpattern-polyfill@10.1.3'}?bundle`);
3+
// @ts-ignore: Bun and URLPattern
4+
if (typeof Bun === "object" && !globalThis.URLPattern) {
5+
// until https://github.com/oven-sh/bun/issues/2286 is fixed
6+
await import("urlpattern" + "-polyfill");
77
}
88

99
export const paramRegex = /^\[([a-zA-Z0-9\.]+)\]/;

src/generator.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,6 @@ export const generate = async (config?: GenerateConfig): Promise<void> => {
3131
const { dirname } = await import("node:path");
3232
const { pathToFileURL } = await import("node:url");
3333

34-
const writeFile = async (path: string, data: ReadableStream<Uint8Array>) => {
35-
if (typeof Deno === "object") {
36-
return Deno.writeFile(path, data);
37-
} else {
38-
const { createWriteStream } = await import("node:fs");
39-
const { Readable } = await import("node:stream");
40-
return new Promise<void>((resolve, reject) =>
41-
// deno-lint-ignore no-explicit-any
42-
Readable.fromWeb(data as any)
43-
.pipe(createWriteStream(path))
44-
.on("finish", resolve)
45-
.on("error", reject)
46-
);
47-
}
48-
};
49-
5034
const { outFolder = "generated", pregenerateOnly = false } = config || {};
5135
const pregenerateAll = !pregenerateOnly;
5236

@@ -63,7 +47,22 @@ export const generate = async (config?: GenerateConfig): Promise<void> => {
6347
await fs.mkdir(dirname(outFilePath), { recursive: true });
6448
const { body } = file.response;
6549
if (body) {
66-
writeFile(outFilePath, body);
50+
if (typeof Deno === "object") {
51+
return Deno.writeFile(outFilePath, body);
52+
} else if (process.versions.bun) {
53+
// deno-lint-ignore no-explicit-any
54+
return (globalThis as any).Bun.write(outFilePath, file.response);
55+
} else {
56+
const { createWriteStream } = await import("node:fs");
57+
const { Readable } = await import("node:stream");
58+
return new Promise<void>((resolve, reject) =>
59+
// deno-lint-ignore no-explicit-any
60+
Readable.fromWeb(body as any)
61+
.pipe(createWriteStream(outFilePath))
62+
.on("finish", resolve)
63+
.on("error", reject)
64+
);
65+
}
6766
}
6867
}
6968
}

0 commit comments

Comments
 (0)