1
1
import type { NetlifyPluginOptions } from '@netlify/build'
2
2
import type { EdgeFunctionDefinition as NextDefinition } from 'next/dist/build/webpack/plugins/middleware-plugin.js'
3
3
import { cp , mkdir , readFile , rm , writeFile } from 'node:fs/promises'
4
- import { dirname , join , relative , resolve } from 'node:path'
4
+ import { dirname , join , resolve } from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
5
6
import { getMiddlewareManifest } from '../config.js'
6
7
import {
7
8
EDGE_FUNCTIONS_DIR ,
@@ -12,79 +13,60 @@ import {
12
13
} from '../constants.js'
13
14
14
15
interface NetlifyManifest {
15
- version : 1
16
+ version : number
16
17
functions : NetlifyDefinition [ ]
17
18
}
18
19
19
- type NetlifyDefinition =
20
- | {
21
- function : string
22
- name ?: string
23
- path : string
24
- cache ?: 'manual'
25
- generator : string
26
- }
27
- | {
28
- function : string
29
- name ?: string
30
- pattern : string
31
- cache ?: 'manual'
32
- generator : string
33
- }
34
-
35
- const getHandlerName = ( { name } : NextDefinition ) =>
36
- EDGE_HANDLER_NAME . replace ( '{{name}}' , name . replace ( / \W / g, '-' ) )
37
-
38
- const buildHandlerDefinitions = (
39
- { name : definitionName , matchers, page } : NextDefinition ,
40
- handlerName : string ,
41
- ) : NetlifyDefinition [ ] => {
42
- return definitionName === 'middleware'
43
- ? [
44
- {
45
- function : handlerName ,
46
- name : 'Next.js Middleware Handler' ,
47
- path : '/*' ,
48
- generator : `${ PLUGIN_NAME } @${ PLUGIN_VERSION } ` ,
49
- } as any ,
50
- ]
51
- : matchers . map ( ( matcher ) => ( {
52
- function : handlerName ,
53
- name : `Next.js Edge Handler: ${ page } ` ,
54
- pattern : matcher . regexp ,
55
- cache : 'manual' ,
56
- generator : `${ PLUGIN_NAME } @${ PLUGIN_VERSION } ` ,
57
- } ) )
20
+ interface NetlifyDefinition {
21
+ function : string
22
+ name : string
23
+ pattern : string
24
+ cache ?: 'manual'
25
+ generator : string
58
26
}
59
27
60
- const copyHandlerDependencies = async (
61
- { name : definitionName , files } : NextDefinition ,
62
- handlerName : string ,
63
- ) => {
28
+ const writeEdgeManifest = async ( manifest : NetlifyManifest ) => {
29
+ await mkdir ( resolve ( EDGE_FUNCTIONS_DIR ) , { recursive : true } )
30
+ await writeFile ( resolve ( EDGE_FUNCTIONS_DIR , 'manifest.json' ) , JSON . stringify ( manifest , null , 2 ) )
31
+ }
32
+
33
+ const writeHandlerFile = async ( { name } : NextDefinition ) => {
34
+ const handlerName = getHandlerName ( { name } )
35
+
36
+ await cp (
37
+ join ( PLUGIN_DIR , 'edge-runtime' ) ,
38
+ resolve ( EDGE_FUNCTIONS_DIR , handlerName , 'edge-runtime' ) ,
39
+ { recursive : true } ,
40
+ )
41
+ await writeFile (
42
+ resolve ( EDGE_FUNCTIONS_DIR , handlerName , `${ handlerName } .js` ) ,
43
+ `
44
+ import {handleMiddleware} from './edge-runtime/middleware.ts';
45
+ import handler from './server/${ name } .js';
46
+ export default (req, context) => handleMiddleware(req, context, handler);
47
+ ` ,
48
+ )
49
+ }
50
+
51
+ const copyHandlerDependencies = async ( { name, files } : NextDefinition ) => {
52
+ const edgeRuntimePath = join ( PLUGIN_DIR , 'edge-runtime' )
53
+ const srcDir = resolve ( '.next/standalone/.next' )
54
+ const shimPath = resolve ( edgeRuntimePath , 'shim/index.js' )
55
+ const shim = await readFile ( shimPath , 'utf8' )
56
+ const imports = `import './edge-runtime-webpack.js';`
57
+ const exports = `export default _ENTRIES["middleware_${ name } "].default;`
58
+
64
59
await Promise . all (
65
60
files . map ( async ( file ) => {
66
- const srcDir = join ( process . cwd ( ) , '.next/standalone/.next' )
67
- const destDir = join ( process . cwd ( ) , EDGE_FUNCTIONS_DIR , handlerName )
61
+ const destDir = resolve ( EDGE_FUNCTIONS_DIR , getHandlerName ( { name } ) )
68
62
69
- if ( file === `server/${ definitionName } .js` ) {
63
+ if ( file === `server/${ name } .js` ) {
70
64
const entrypoint = await readFile ( join ( srcDir , file ) , 'utf8' )
71
- // const exports = ``
72
- const exports = `
73
- export default _ENTRIES["middleware_${ definitionName } "].default;
74
- // export default () => {
75
-
76
- // console.log('here', _ENTRIES)
77
- // }
78
- `
79
- await mkdir ( dirname ( join ( destDir , file ) ) , { recursive : true } )
80
- await writeFile (
81
- join ( destDir , file ) ,
82
- `
83
- import './edge-runtime-webpack.js';
65
+ const parts = [ shim , imports , entrypoint , exports ]
84
66
67
+ await mkdir ( dirname ( join ( destDir , file ) ) , { recursive : true } )
68
+ await writeFile ( join ( destDir , file ) , parts . join ( '\n;' ) )
85
69
86
- var _ENTRIES = {};\n` . concat ( entrypoint , '\n' , exports ) ,
87
- )
88
70
return
89
71
}
90
72
@@ -93,29 +75,21 @@ const copyHandlerDependencies = async (
93
75
)
94
76
}
95
77
96
- const writeHandlerFile = async ( { name : definitionName } : NextDefinition , handlerName : string ) => {
97
- const handlerFile = resolve ( EDGE_FUNCTIONS_DIR , handlerName , `${ handlerName } .js` )
98
- const rel = relative ( handlerFile , join ( PLUGIN_DIR , 'dist/run/handlers/middleware.js' ) )
99
- await cp (
100
- join ( PLUGIN_DIR , 'edge-runtime' ) ,
101
- resolve ( EDGE_FUNCTIONS_DIR , handlerName , 'edge-runtime' ) ,
102
- {
103
- recursive : true ,
104
- } ,
105
- )
106
- await writeFile (
107
- resolve ( EDGE_FUNCTIONS_DIR , handlerName , `${ handlerName } .js` ) ,
108
- `import {handleMiddleware} from './edge-runtime/middleware.ts';
109
- import handler from './server/${ definitionName } .js';
110
- export default (req, context) => handleMiddleware(req, context, handler);
111
- export const config = {path: "/*"}` ,
112
- )
78
+ const createEdgeHandler = async ( definition : NextDefinition ) : Promise < void > => {
79
+ await copyHandlerDependencies ( definition )
80
+ await writeHandlerFile ( definition )
113
81
}
114
82
115
- const writeEdgeManifest = async ( manifest : NetlifyManifest ) => {
116
- await mkdir ( resolve ( EDGE_FUNCTIONS_DIR ) , { recursive : true } )
117
- await writeFile ( resolve ( EDGE_FUNCTIONS_DIR , 'manifest.json' ) , JSON . stringify ( manifest , null , 2 ) )
118
- }
83
+ const getHandlerName = ( { name } : Pick < NextDefinition , 'name' > ) : string =>
84
+ `${ EDGE_HANDLER_NAME } -${ name . replace ( / \W / g, '-' ) } `
85
+
86
+ const buildHandlerDefinition = ( { name, matchers, page } : NextDefinition ) : NetlifyDefinition => ( {
87
+ function : getHandlerName ( { name } ) ,
88
+ name : name === 'middleware' ? 'Next.js Middleware Handler' : `Next.js Edge Handler: ${ page } ` ,
89
+ pattern : matchers [ 0 ] . regexp ,
90
+ cache : name === 'middleware' ? undefined : 'manual' ,
91
+ generator : `${ PLUGIN_NAME } @${ PLUGIN_VERSION } ` ,
92
+ } )
119
93
120
94
export const createEdgeHandlers = async ( {
121
95
constants,
@@ -127,21 +101,12 @@ export const createEdgeHandlers = async ({
127
101
...Object . values ( nextManifest . middleware ) ,
128
102
// ...Object.values(nextManifest.functions)
129
103
]
130
- const netlifyManifest : NetlifyManifest = {
104
+ await Promise . all ( nextDefinitions . map ( createEdgeHandler ) )
105
+
106
+ const netlifyDefinitions = nextDefinitions . map ( buildHandlerDefinition )
107
+ const netlifyManifest = {
131
108
version : 1 ,
132
- functions : await nextDefinitions . reduce (
133
- async ( netlifyDefinitions : Promise < NetlifyDefinition [ ] > , nextDefinition : NextDefinition ) => {
134
- const handlerName = getHandlerName ( nextDefinition )
135
- await copyHandlerDependencies ( nextDefinition , handlerName )
136
- await writeHandlerFile ( nextDefinition , handlerName )
137
- return [
138
- ...( await netlifyDefinitions ) ,
139
- ...buildHandlerDefinitions ( nextDefinition , handlerName ) ,
140
- ]
141
- } ,
142
- Promise . resolve ( [ ] ) ,
143
- ) ,
109
+ functions : netlifyDefinitions ,
144
110
}
145
-
146
111
await writeEdgeManifest ( netlifyManifest )
147
112
}
0 commit comments