1
1
import type { Context } from 'netlify:edge'
2
- import { HTMLRewriter } from 'https://deno.land/x/[email protected] /index.ts'
2
+ import { ElementHandlers , HTMLRewriter } from 'https://deno.land/x/[email protected] /index.ts'
3
3
4
4
export interface FetchEventResult {
5
5
response : Response
@@ -39,7 +39,8 @@ export const addMiddlewareHeaders = async (
39
39
40
40
interface NetlifyNextResponse extends Response {
41
41
originResponse : Response
42
- transforms : NextDataTransform [ ]
42
+ dataTransforms : NextDataTransform [ ]
43
+ elementHandlers : Array < [ selector : string , handlers : ElementHandlers ] >
43
44
}
44
45
45
46
export const buildResponse = async ( {
@@ -52,40 +53,48 @@ export const buildResponse = async ({
52
53
context : Context
53
54
} ) => {
54
55
// This means it's a Netlify Next response.
55
- if ( 'transforms ' in result . response ) {
56
+ if ( 'dataTransforms ' in result . response ) {
56
57
const response = result . response as NetlifyNextResponse
57
58
// If it's JSON we don't need to use the rewriter, we can just parse it
58
59
if ( response . originResponse . headers . get ( 'content-type' ) ?. includes ( 'application/json' ) ) {
59
60
const props = await response . originResponse . json ( )
60
- const transformed = response . transforms . reduce ( ( prev , transform ) => {
61
+ const transformed = response . dataTransforms . reduce ( ( prev , transform ) => {
61
62
return transform ( prev )
62
63
} , props )
63
64
return context . json ( transformed )
64
65
}
65
66
// This var will hold the contents of the script tag
66
67
let buffer = ''
67
68
// Create an HTMLRewriter that matches the Next data script tag
68
- const rewriter = new HTMLRewriter ( ) . on ( 'script[id="__NEXT_DATA__"]' , {
69
- text ( textChunk ) {
70
- // Grab all the chunks in the Next data script tag
71
- buffer += textChunk . text
72
- if ( textChunk . lastInTextNode ) {
73
- try {
74
- // When we have all the data, try to parse it as JSON
75
- const data = JSON . parse ( buffer . trim ( ) )
76
- // Apply all of the transforms to the props
77
- const props = response . transforms . reduce ( ( prev , transform ) => transform ( prev ) , data . props )
78
- // Replace the data with the transformed props
79
- textChunk . replace ( JSON . stringify ( { ...data , props } ) )
80
- } catch ( err ) {
81
- console . log ( 'Could not parse' , err )
69
+ const rewriter = new HTMLRewriter ( )
70
+
71
+ if ( response . dataTransforms . length > 0 ) {
72
+ rewriter . on ( 'script[id="__NEXT_DATA__"]' , {
73
+ text ( textChunk ) {
74
+ // Grab all the chunks in the Next data script tag
75
+ buffer += textChunk . text
76
+ if ( textChunk . lastInTextNode ) {
77
+ try {
78
+ // When we have all the data, try to parse it as JSON
79
+ const data = JSON . parse ( buffer . trim ( ) )
80
+ // Apply all of the transforms to the props
81
+ const props = response . dataTransforms . reduce ( ( prev , transform ) => transform ( prev ) , data . props )
82
+ // Replace the data with the transformed props
83
+ textChunk . replace ( JSON . stringify ( { ...data , props } ) )
84
+ } catch ( err ) {
85
+ console . log ( 'Could not parse' , err )
86
+ }
87
+ } else {
88
+ // Remove the chunk after we've appended it to the buffer
89
+ textChunk . remove ( )
82
90
}
83
- } else {
84
- // Remove the chunk after we've appended it to the buffer
85
- textChunk . remove ( )
86
- }
87
- } ,
88
- } )
91
+ } ,
92
+ } )
93
+ }
94
+
95
+ if ( response . elementHandlers . length > 0 ) {
96
+ response . elementHandlers . forEach ( ( [ selector , handlers ] ) => rewriter . on ( selector , handlers ) )
97
+ }
89
98
return rewriter . transform ( response . originResponse )
90
99
}
91
100
const res = new Response ( result . response . body , result . response )
0 commit comments