Skip to content

Commit c6c46b4

Browse files
taty2010orinokai
andcommitted
file cleanup + simplify functions
Co-authored-by: Rob Stanford <orinokai@users.noreply.github.com>
1 parent 2669bf6 commit c6c46b4

File tree

8 files changed

+129
-190
lines changed

8 files changed

+129
-190
lines changed

src/handlers/server.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
/* eslint-disable n/prefer-global/buffer */
2-
/* eslint-disable max-statements */
32
import { toComputeResponse, toReqRes } from '@fastly/http-compute-js'
4-
import { HandlerEvent, type Handler, HandlerContext } from "@netlify/functions"
53
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
64
import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js'
75

8-
import { netliBlob } from '../helpers/blobs/blobs.cjs'
96
import { RUN_DIR } from '../helpers/constants.js'
107
import { setCacheControlHeaders, setVaryHeaders } from '../helpers/headers.js'
118

@@ -48,12 +45,3 @@ export default async (request: Request) => {
4845

4946
return toComputeResponse(res)
5047
}
51-
// Commenting out for now
52-
// export const handler: Handler = (event: HandlerEvent, context: HandlerContext): any => {
53-
// if (context?.clientContext?.custom?.blobs) {
54-
// const rawData = Buffer.from(context.clientContext.custom.blobs, 'base64')
55-
// const data = JSON.parse(rawData.toString('ascii'))
56-
57-
// netliBlob(data.token, `deploy:${event.headers['x-nf-deploy-id']}`, `${event.headers['x-nf-site-id']}`, data.url)
58-
// }
59-
// }

src/helpers/blobs.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { getStore } from '@netlify/blobs'
2+
3+
export const netliBlob = (token: string, deployID: string, siteID: string, apiURL?: string) => {
4+
const storeAuth = { deployID, siteID, token, apiURL }
5+
// apiURL uses default on build so we only preserve context if apiURL is set within handler function
6+
if (apiURL) {
7+
process.env.NETLIFY_BLOBS_CONTEXT = btoa(JSON.stringify(storeAuth))
8+
}
9+
return getStore(storeAuth)
10+
}

src/helpers/blobs/blobs.cts

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/helpers/blobs/cacheFormat.ts

Lines changed: 0 additions & 87 deletions
This file was deleted.

src/helpers/cache.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { readFile } from 'node:fs/promises'
2+
3+
import { BUILD_DIR } from './constants.js'
4+
import type { MetaFile } from './types.js'
5+
6+
export const buildCacheValue = (path: string, ext: string) => {
7+
const isRoute = ext === '.body'
8+
const isPage = path.startsWith('server/pages') && ext === '.html'
9+
const isApp = path.startsWith('server/app') && ext === '.html'
10+
const isFetchCache = path.startsWith('cache/fetch-cache')
11+
12+
switch (true) {
13+
case isRoute:
14+
return buileRouteCacheValue(path)
15+
case isPage:
16+
return buildPageCacheValue(path, false)
17+
case isApp:
18+
return buildPageCacheValue(path, true)
19+
case isFetchCache:
20+
return buildFetchCacheValue(path)
21+
default:
22+
return {}
23+
}
24+
}
25+
26+
const buildPageCacheValue = async (path: string, appDir: boolean) => {
27+
const pageData = appDir
28+
? await readFile(`${BUILD_DIR}/.next/${path}.rsc`, 'utf8')
29+
: JSON.parse(await readFile(`${BUILD_DIR}/.next/${path}.json`, 'utf8'))
30+
let meta: MetaFile = {}
31+
32+
if (appDir) {
33+
try {
34+
meta = await JSON.parse(await readFile(`${BUILD_DIR}/.next/${path}.meta`, 'utf8'))
35+
} catch {}
36+
}
37+
38+
return {
39+
lastModified: Date.now(),
40+
value: {
41+
kind: 'PAGE',
42+
html: await readFile(`${BUILD_DIR}/.next/${path}.html`, 'utf8'),
43+
pageData,
44+
headers: meta.headers,
45+
status: meta.status,
46+
},
47+
}
48+
}
49+
50+
const buildFetchCacheValue = async (path: string) => {
51+
const parsedData = JSON.parse(await readFile(`${BUILD_DIR}/.next/${path}`, 'utf8'))
52+
return {
53+
lastModified: Date.now(),
54+
value: parsedData,
55+
}
56+
}
57+
58+
const buileRouteCacheValue = async (path: string) => {
59+
try {
60+
const data = await readFile(`${BUILD_DIR}/.next/${path}.body`, 'utf8')
61+
const meta = await JSON.parse(await readFile(`${BUILD_DIR}/.next/${path}.meta`, 'utf8'))
62+
return {
63+
lastModified: Date.now(),
64+
value: {
65+
kind: 'ROUTE',
66+
body: data,
67+
headers: meta.headers,
68+
status: meta.status,
69+
},
70+
}
71+
} catch {}
72+
}

src/helpers/constants.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ export const WORKING_DIR = process.cwd()
77

88
export const BUILD_DIR = `${WORKING_DIR}/.netlify`
99
export const RUN_DIR = WORKING_DIR
10-
export const NEXT_DIR = `${BUILD_DIR}/.next`
11-
export const SERVER_DIR = `${NEXT_DIR}/server`
12-
export const STANDALONE_BUILD_DIR = `${NEXT_DIR}/standalone`
13-
export const FETCH_CACHE_DIR = `${NEXT_DIR}/cache/fetch-cache`
1410

1511
export const SERVER_FUNCTIONS_DIR = `${WORKING_DIR}/.netlify/functions-internal`
1612
export const SERVER_HANDLER_NAME = '___netlify-server-handler'

src/helpers/files.ts

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,70 @@
1-
/* eslint-disable import/no-extraneous-dependencies */
21
import { cpus } from 'os'
32
import path from 'path'
43

54
import { NetlifyPluginConstants } from '@netlify/build'
65
import { copy, move, remove } from 'fs-extra/esm'
76
import { globby } from 'globby'
8-
import { outdent } from 'outdent'
97
import pLimit from 'p-limit'
108

11-
import { getNormalizedBlobKey, netliBlob } from './blobs/blobs.cjs'
12-
import { removeFileDir, formatBlobContent } from './blobs/cacheFormat.js'
13-
import { NEXT_DIR, STANDALONE_BUILD_DIR } from './constants.js'
9+
import { netliBlob } from './blobs.js'
10+
import { buildCacheValue } from './cache.js'
11+
import { BUILD_DIR } from './constants.js'
1412

1513
/**
1614
* Move the Next.js build output from the publish dir to a temp dir
1715
*/
1816
export const stashBuildOutput = async ({ PUBLISH_DIR }: NetlifyPluginConstants) => {
19-
await move(PUBLISH_DIR, `${NEXT_DIR}`, { overwrite: true })
17+
await move(PUBLISH_DIR, `${BUILD_DIR}/.next`, { overwrite: true })
2018

2119
// remove prerendered content from the standalone build (it's also in the main build dir)
22-
const prerenderedContent = await getPrerenderedContent(STANDALONE_BUILD_DIR)
20+
const prerenderedContent = await getPrerenderedContent(`${BUILD_DIR}/.next/standalone`, false)
2321
await Promise.all(
24-
prerenderedContent.map((file: string) => remove(`${STANDALONE_BUILD_DIR}/${file}`))).catch((error) => console.error(error))
25-
22+
prerenderedContent.map((file: string) => remove(`${BUILD_DIR}/.next/standalone/${file}`)),
23+
).catch((error) => console.error(error))
2624
}
2725

2826
/**
2927
* Glob for prerendered content in the build output
3028
*/
31-
const getPrerenderedContent = async (cwd: string): Promise<string[]> => {
29+
const getPrerenderedContent = async (cwd: string, get = true): Promise<string[]> => {
3230
// TODO: test this
33-
return await globby([
34-
`cache/fetch-cache/*`,
35-
`server/+(app|pages)/**/*.+(html|json|rsc|body|meta)`,
36-
`!server/**/*.js.nft.{html,json}`,
37-
], { cwd, extglob: true })
31+
return await globby(
32+
get
33+
? [`cache/fetch-cache/*`, `server/+(app|pages)/**/*.+(html|body)`]
34+
: [
35+
`cache/fetch-cache/*`,
36+
`server/+(app|pages)/**/*.+(html|json|rsc|body|meta)`,
37+
`!server/**/*.js.nft.{html,json}`,
38+
],
39+
{ cwd, extglob: true },
40+
)
3841
}
3942

4043
/**
4144
* Upload prerendered content from the main build dir to the blob store
4245
*/
43-
export const storePrerenderedContent = async ({ NETLIFY_API_TOKEN, SITE_ID }:
44-
{
45-
NETLIFY_API_TOKEN: string,
46-
SITE_ID: string
47-
}) => {
48-
const deployID = `${process.env.DEPLOY_ID}`
49-
const blob = netliBlob(NETLIFY_API_TOKEN, deployID, SITE_ID)
50-
// todo: Check out setFiles within Blobs.js to see how to upload files to blob storage
51-
const limit = pLimit(Math.max(2, cpus().length))
52-
console.log(
53-
outdent`
54-
Uploading Files to Blob Storage...
55-
`)
56-
57-
const uploadFilesToBlob = async (pathName: string, file: string) => {
58-
const key = path.basename(pathName, path.extname(pathName))
59-
const content = await formatBlobContent(pathName, key, file)
60-
try{
61-
await blob.setJSON(getNormalizedBlobKey(key), content)
62-
}catch(error){
63-
console.error(error)
64-
}
65-
}
66-
67-
// todo: test it on demo with pages dir
68-
// eslint-disable-next-line unicorn/no-await-expression-member
69-
(await getPrerenderedContent(NEXT_DIR)).map((rawPath: string) => {
70-
const cacheFile = rawPath.startsWith('cache')
71-
const pathKey = removeFileDir(rawPath, (cacheFile ? 2 : 1))
72-
const files = findCacheFiles(pathKey, rawPath)
73-
74-
if(files){
75-
return limit(uploadFilesToBlob, pathKey, rawPath)
76-
}
77-
})
78-
}
79-
80-
const findCacheFiles = (pathKey: string, rawPath: string) => {
81-
const errorPages = pathKey.includes('404') || pathKey.includes('500')
82-
const isFetchCache = rawPath.startsWith('cache/fetch-cache')
83-
const isRoute = rawPath.endsWith('.body')
84-
const hasHtml = rawPath.endsWith('.html')
46+
export const storePrerenderedContent = async ({
47+
NETLIFY_API_TOKEN,
48+
SITE_ID,
49+
}: {
50+
NETLIFY_API_TOKEN: string
51+
SITE_ID: string
52+
}) => {
53+
const deployID = `${process.env.DEPLOY_ID}`
54+
const blob = netliBlob(NETLIFY_API_TOKEN, deployID, SITE_ID)
55+
// todo: Check out setFiles within Blobs.js to see how to upload files to blob storage
56+
const limit = pLimit(Math.max(2, cpus().length))
8557

86-
if (hasHtml && !errorPages || isFetchCache || isRoute){
87-
return true
88-
}
58+
const prerenderedContent = await getPrerenderedContent(`${BUILD_DIR}/.next`)
59+
return Promise.all(
60+
prerenderedContent.map(async (rawPath: string) => {
61+
// TODO: test this with files that have a double extension
62+
const ext = path.extname(rawPath)
63+
const key = rawPath.replace(ext, '')
64+
const value = await buildCacheValue(key, ext)
65+
return limit(() => blob.setJSON(key, value))
66+
}),
67+
)
8968
}
9069

9170
/**
@@ -94,6 +73,6 @@ const findCacheFiles = (pathKey: string, rawPath: string) => {
9473
export const publishStaticAssets = ({ PUBLISH_DIR }: NetlifyPluginConstants) => {
9574
return Promise.all([
9675
copy('public', PUBLISH_DIR),
97-
copy(`${NEXT_DIR}/static/`, `${PUBLISH_DIR}/_next/static`),
76+
copy(`${BUILD_DIR}/.next/static/`, `${PUBLISH_DIR}/_next/static`),
9877
])
9978
}

src/helpers/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { OutgoingHttpHeaders } from 'http'
2+
13
import type { NetlifyPluginOptions, NetlifyPluginConstants } from '@netlify/build'
24
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
35

@@ -20,4 +22,9 @@ export interface RequiredServerFiles {
2022
appDir?: string
2123
files?: string[]
2224
ignore?: string[]
25+
}
26+
27+
export interface MetaFile {
28+
status?: number
29+
headers?: OutgoingHttpHeaders
2330
}

0 commit comments

Comments
 (0)