-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
681 additions
and
66 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env node | ||
|
||
require('./dist/bin.js') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "middleflare", | ||
"version": "0.0.0", | ||
"description": "Deploy Next.js middleware to Cloudflare Workers", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"repository": "https://github.com/remorses/middleflare", | ||
"bin": { | ||
"middleflare": "bin.js" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"cli": "tsx src/bin.ts", | ||
"watch": "tsc -w" | ||
}, | ||
"files": [ | ||
"dist", | ||
"src", | ||
"bin.js", | ||
"esm" | ||
], | ||
"keywords": [], | ||
"author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>", | ||
"license": "", | ||
"devDependencies": { | ||
"next": "^13.4.12" | ||
}, | ||
"dependencies": { | ||
"@cac/required-option": "^1.0.0", | ||
"@cloudflare/workers-types": "^3.8.0", | ||
"@types/node": "^20.4.5", | ||
"cac": "^6.7.14", | ||
"esbuild": "^0.18.17", | ||
"esbuild-plugin-polyfill-node": "^0.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { cac } from 'cac' | ||
import { buildMiddleware } from './build' | ||
const { name, version } = require('../package.json') | ||
|
||
const cli = cac(name) | ||
|
||
cli.command('') | ||
.option('--url <url>', 'Your deployed Next.js url, like xxx.fly.dev', {}) | ||
.option('--middleware <middlewarePath>', 'Your Next.js middleware path', {}) | ||
.action(async (opts) => { | ||
console.log(opts) | ||
const { middleware, url } = opts | ||
await buildMiddleware({ | ||
middleware, | ||
url, | ||
}) | ||
}) | ||
|
||
cli.help() | ||
cli.version(version) | ||
|
||
async function main() { | ||
try { | ||
// Parse CLI args without running the command | ||
cli.parse(process.argv, { run: false }) | ||
// Run the command yourself | ||
// You only need `await` when your command action returns a Promise | ||
await cli.runMatchedCommand() | ||
} catch (error: any) { | ||
// Handle error here.. | ||
// e.g. | ||
console.error(error.stack) | ||
process.exit(1) | ||
} | ||
} | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import { build, context, PluginBuild } from 'esbuild' | ||
|
||
import { polyfillNode } from 'esbuild-plugin-polyfill-node' | ||
|
||
import fs from 'fs' | ||
|
||
import path from 'path' | ||
|
||
// console.log(process.env.DIRECT_URL) | ||
|
||
export async function buildMiddleware({ middleware, url }) { | ||
if (!middleware) { | ||
throw new Error(`--middleware is required`) | ||
} | ||
if (!url) { | ||
throw new Error(`--url is required`) | ||
} | ||
middleware = path.resolve(middleware) | ||
const u = safeUrl(url) | ||
if (!u) { | ||
throw new Error(`invalid url ${url}`) | ||
} | ||
// to make docker generate native prisma addons | ||
const define = Object.fromEntries( | ||
Object.keys(process.env).map((k) => { | ||
return [`process.env.${k}`, JSON.stringify(process.env[k])] | ||
}), | ||
) | ||
fs.promises.unlink('dist').catch((e) => null) | ||
const index = path.resolve( | ||
path.dirname(require.resolve('../package.json')), | ||
'src/index.ts', | ||
) | ||
const { metafile } = await build({ | ||
// entryPoints: ['src/worker.ts'], | ||
stdin: { | ||
contents: ` | ||
import { middlewareAdapter } from '${index}'; | ||
export default middlewareAdapter({ | ||
middlewareModule: await import('${middleware}'), | ||
finalUrl: '${url}', | ||
}) | ||
`, | ||
resolveDir: process.cwd(), | ||
loader: 'ts', | ||
}, | ||
bundle: true, | ||
platform: 'browser', | ||
sourcemap: false, | ||
// sourcemap: 'inline', | ||
metafile: true, | ||
format: 'esm', | ||
minify: false, | ||
// format: 'esm', | ||
// mainFields: ['module', 'main'], | ||
plugins: [ | ||
LooselyIgnoreDeps(), | ||
polyfillNode(), // | ||
StripWasmModulesQuery(), | ||
// UseNextEsm(), | ||
], | ||
external: [], | ||
// target: 'node18', | ||
logOverride: { | ||
'import-is-undefined': 'silent', | ||
}, | ||
define, | ||
// splitting: false, | ||
// splitting: true, | ||
// outdir: 'dist', | ||
outfile: 'dist/worker.js', | ||
}) | ||
|
||
fs.writeFileSync('dist/metafile.json', JSON.stringify(metafile, null, 2)) | ||
} | ||
|
||
const ignore = ['@vercel/og'] | ||
function LooselyIgnoreDeps() { | ||
return { | ||
name: 'Skip binaries', | ||
setup(build: PluginBuild) { | ||
const ignorePath = '/__ignore__' | ||
build.onLoad({ filter: /__ignore__/ }, (args) => { | ||
return { | ||
contents: '', | ||
loader: 'js', | ||
} | ||
}) | ||
build.onResolve( | ||
{ | ||
filter: /.*/, | ||
}, | ||
(args) => { | ||
if ( | ||
ignore.some( | ||
(x) => args.path === x || args.path.includes(x), | ||
) | ||
) { | ||
return { path: ignorePath } | ||
} | ||
return | ||
}, | ||
) | ||
}, | ||
} | ||
} | ||
|
||
function UseNextEsm() { | ||
return { | ||
name: 'Use next esm', | ||
setup(build: PluginBuild) { | ||
build.onResolve( | ||
{ | ||
filter: /\/next\/dist.*/, | ||
}, | ||
(args) => { | ||
if (!args.path.includes('node_modules')) { | ||
return | ||
} | ||
if (!args.path.startsWith('next/')) { | ||
return | ||
} | ||
const newPath = args.path.replace( | ||
'/next/dist/', | ||
'/next/dist/esm/', | ||
) | ||
|
||
return { | ||
path: newPath, | ||
} | ||
}, | ||
) | ||
}, | ||
} | ||
} | ||
|
||
function StripWasmModulesQuery() { | ||
return { | ||
name: 'wasm modules', | ||
setup(build: PluginBuild) { | ||
build.onResolve( | ||
{ | ||
filter: /\.wasm(?:\?.*)?/, | ||
}, | ||
(args) => { | ||
return { | ||
path: removeQuery( | ||
path.isAbsolute(args.path) | ||
? args.path | ||
: path.join(args.resolveDir, args.path), | ||
), | ||
sideEffects: false, | ||
} | ||
}, | ||
) | ||
build.onLoad( | ||
{ | ||
filter: /\.wasm(?:\?.*)?/, | ||
}, | ||
(args) => { | ||
return { | ||
resolveDir: path.dirname(args.path), | ||
contents: fs.readFileSync(args.path), | ||
loader: 'copy', | ||
} | ||
}, | ||
) | ||
}, | ||
} | ||
} | ||
|
||
function removeQuery(url: string) { | ||
const i = url.indexOf('?') | ||
if (i === -1) return url | ||
return url.slice(0, i) | ||
} | ||
|
||
function safeUrl(url: string) { | ||
try { | ||
return new URL(url) | ||
} catch (e) { | ||
return null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { middlewareAdapter } from './utils' |
Oops, something went wrong.