-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathbuild.mjs
More file actions
110 lines (93 loc) · 3.16 KB
/
build.mjs
File metadata and controls
110 lines (93 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { existsSync, mkdirSync, readFileSync } from "node:fs"
import { config } from "dotenv"
import * as esbuild from "esbuild"
// Load environment variables into a define object
config({ quiet: true })
const define = {}
const isDotSafeIdentifier = (str) => {
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str)
}
for (const k in process.env) {
/* Skip environment variables that should be evaluated at runtime */
// Keep these dynamic so code isn't tree-shaken based on CI build env
if (
[
"HOME",
"USER",
"XDG_CONFIG_HOME",
"SMITHERY_API_KEY",
"SMITHERY_BASE_URL",
"ANALYTICS_ENDPOINT",
].includes(k)
)
continue
// Skip variables whose names are not dot-safe identifiers (e.g., those containing hyphens, parentheses, etc.)
if (!isDotSafeIdentifier(k)) continue
define[`process.env.${k}`] = JSON.stringify(process.env[k])
}
// 1. Bundle bootstraps into string constants
console.log("Compiling bootstraps...")
const shttp = await esbuild.build({
entryPoints: ["src/runtime/shttp-bootstrap.ts"],
bundle: true,
format: "esm",
platform: "browser",
target: "es2022",
write: false,
minify: true,
external: ["virtual:user-module"],
})
const stdio = await esbuild.build({
entryPoints: ["src/runtime/stdio-bootstrap.ts"],
bundle: true,
format: "esm",
platform: "node",
target: "node20",
write: false,
minify: true,
external: ["virtual:user-module"],
})
define.__SHTTP_BOOTSTRAP__ = JSON.stringify(shttp.outputFiles[0].text)
define.__STDIO_BOOTSTRAP__ = JSON.stringify(stdio.outputFiles[0].text)
// Get package version
const packageJson = JSON.parse(readFileSync("package.json", "utf-8"))
// Inject version as global constant
define.__SMITHERY_VERSION__ = JSON.stringify(packageJson.version)
// Inject lazy dependency versions so they stay in sync with package.json
define.__LAZY_DEPS__ = JSON.stringify({
miniflare: packageJson.devDependencies.miniflare,
esbuild: packageJson.devDependencies.esbuild,
"@ngrok/ngrok": packageJson.devDependencies["@ngrok/ngrok"],
keytar: packageJson.devDependencies.keytar,
})
console.log("✓ Compiled bootstrap files")
// Packages with native binaries that cannot be bundled - they must be required at runtime.
// Only include packages that are DIRECTLY imported by CLI code and have native binaries.
// Transitive native deps (like workerd via miniflare) are handled by their parent package.
// - keytar: .node native addon for OS keychain
// - esbuild: platform-specific binaries for bundling
// - @ngrok/ngrok: native binary for tunneling
// - miniflare: has complex native deps (workerd) that must resolve at runtime
const nativePackages = ["@ngrok/ngrok", "esbuild", "keytar", "miniflare"]
// Build main CLI entry point
await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
platform: "node",
target: "node20",
format: "esm",
minify: true,
treeShaking: true,
outfile: "dist/index.js",
external: nativePackages,
banner: {
js: `import { createRequire } from 'module'; const require = createRequire(import.meta.url);`,
},
define,
})
// Copy runtime files to dist/runtime/
const runtimeDir = "dist/runtime"
if (!existsSync(runtimeDir)) {
mkdirSync(runtimeDir, { recursive: true })
}
console.log("✓ Build complete")