-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathfunctions.ts
103 lines (91 loc) · 3.75 KB
/
functions.ts
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
import { NetlifyConfig, NetlifyPluginConstants } from '@netlify/build'
import bridgeFile from '@vercel/node-bridge'
import { copyFile, ensureDir, writeFile, writeJSON } from 'fs-extra'
import type { ImageConfigComplete } from 'next/dist/server/image-config'
import { join, relative } from 'pathe'
import { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME, IMAGE_FUNCTION_NAME, DEFAULT_FUNCTIONS_SRC } from '../constants'
import { getHandler } from '../templates/getHandler'
import { getPageResolver } from '../templates/getPageResolver'
export const generateFunctions = async (
{ FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, PUBLISH_DIR }: NetlifyPluginConstants,
appDir: string,
): Promise<void> => {
const functionsDir = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC
const functionDir = join(process.cwd(), functionsDir, HANDLER_FUNCTION_NAME)
const publishDir = relative(functionDir, join(process.cwd(), PUBLISH_DIR))
const writeHandler = async (func: string, isODB: boolean) => {
const handlerSource = await getHandler({ isODB, publishDir, appDir: relative(functionDir, appDir) })
await ensureDir(join(functionsDir, func))
await writeFile(join(functionsDir, func, `${func}.js`), handlerSource)
await copyFile(bridgeFile, join(functionsDir, func, 'bridge.js'))
await copyFile(
join(__dirname, '..', '..', 'lib', 'templates', 'handlerUtils.js'),
join(functionsDir, func, 'handlerUtils.js'),
)
}
await writeHandler(HANDLER_FUNCTION_NAME, false)
await writeHandler(ODB_FUNCTION_NAME, true)
}
/**
* Writes a file in each function directory that contains references to every page entrypoint.
* This is just so that the nft bundler knows about them. We'll eventually do this better.
*/
export const generatePagesResolver = async ({
constants: { INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC, PUBLISH_DIR },
target,
}: {
constants: NetlifyPluginConstants
target: string
}): Promise<void> => {
const functionsPath = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC
const jsSource = await getPageResolver({
publish: PUBLISH_DIR,
target,
})
await writeFile(join(functionsPath, ODB_FUNCTION_NAME, 'pages.js'), jsSource)
await writeFile(join(functionsPath, HANDLER_FUNCTION_NAME, 'pages.js'), jsSource)
}
// Move our next/image function into the correct functions directory
export const setupImageFunction = async ({
constants: { INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC },
imageconfig = {},
netlifyConfig,
basePath,
}: {
constants: NetlifyPluginConstants
netlifyConfig: NetlifyConfig
basePath: string
imageconfig: Partial<ImageConfigComplete>
}): Promise<void> => {
const functionsPath = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC
const functionName = `${IMAGE_FUNCTION_NAME}.js`
const functionDirectory = join(functionsPath, IMAGE_FUNCTION_NAME)
await ensureDir(functionDirectory)
await writeJSON(join(functionDirectory, 'imageconfig.json'), {
...imageconfig,
basePath: [basePath, IMAGE_FUNCTION_NAME].join('/'),
})
await copyFile(join(__dirname, '..', '..', 'lib', 'templates', 'ipx.js'), join(functionDirectory, functionName))
const imagePath = imageconfig.path || '/_next/image'
netlifyConfig.redirects.push(
{
from: `${imagePath}*`,
query: { url: ':url', w: ':width', q: ':quality' },
to: `${basePath}/${IMAGE_FUNCTION_NAME}/w_:width,q_:quality/:url`,
status: 301,
},
{
from: `${basePath}/${IMAGE_FUNCTION_NAME}/*`,
to: `/.netlify/builders/${IMAGE_FUNCTION_NAME}`,
status: 200,
},
)
if (basePath) {
// next/image generates image static URLs that still point at the site root
netlifyConfig.redirects.push({
from: '/_next/static/image/*',
to: '/static/image/:splat',
status: 200,
})
}
}