@sveltejs/adapter-netlify 6.0.4 → 7.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/files/edge.js +9 -20
- package/files/serverless.js +18 -23
- package/index.js +192 -191
- package/package.json +9 -14
- package/files/shims.js +0 -32
package/files/edge.js
CHANGED
|
@@ -1,39 +1,28 @@
|
|
|
1
|
-
import { Server } from
|
|
2
|
-
import { manifest } from
|
|
3
|
-
|
|
1
|
+
import { Server } from "0SERVER";
|
|
2
|
+
import { manifest } from "MANIFEST";
|
|
3
|
+
//#region src/edge.js
|
|
4
4
|
const server = new Server(manifest);
|
|
5
|
-
|
|
6
5
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
* We don't know the origin until we receive a request, but
|
|
7
|
+
* that's guaranteed to happen before we call `read`
|
|
8
|
+
* @type {string}
|
|
9
|
+
*/
|
|
11
10
|
let origin;
|
|
12
|
-
|
|
13
11
|
const initialized = server.init({
|
|
14
|
-
// @ts-ignore
|
|
15
12
|
env: Deno.env.toObject(),
|
|
16
13
|
read: async (file) => {
|
|
17
14
|
const url = `${origin}/${file}`;
|
|
18
15
|
const response = await fetch(url);
|
|
19
|
-
|
|
20
|
-
if (!response.ok) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
`read(...) failed: could not fetch ${url} (${response.status} ${response.statusText})`
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
16
|
+
if (!response.ok) throw new Error(`read(...) failed: could not fetch ${url} (${response.status} ${response.statusText})`);
|
|
26
17
|
return response.body;
|
|
27
18
|
}
|
|
28
19
|
});
|
|
29
|
-
|
|
30
20
|
/** @type {import('@netlify/edge-functions').EdgeFunction} */
|
|
31
21
|
async function handler(request, context) {
|
|
32
22
|
if (!origin) {
|
|
33
23
|
origin = new URL(request.url).origin;
|
|
34
24
|
await initialized;
|
|
35
25
|
}
|
|
36
|
-
|
|
37
26
|
return server.respond(request, {
|
|
38
27
|
platform: { context },
|
|
39
28
|
getClientAddress() {
|
|
@@ -41,5 +30,5 @@ async function handler(request, context) {
|
|
|
41
30
|
}
|
|
42
31
|
});
|
|
43
32
|
}
|
|
44
|
-
|
|
33
|
+
//#endregion
|
|
45
34
|
export { handler as default };
|
package/files/serverless.js
CHANGED
|
@@ -1,40 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import 'node:buffer';
|
|
7
|
-
import 'node:crypto';
|
|
8
|
-
|
|
1
|
+
import { Server } from "0SERVER";
|
|
2
|
+
import { createReadStream } from "node:fs";
|
|
3
|
+
import { Readable } from "node:stream";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
//#region ../kit/src/exports/node/index.js
|
|
9
6
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
* Converts a file on disk to a readable stream
|
|
8
|
+
* @param {string} file
|
|
9
|
+
* @returns {ReadableStream}
|
|
10
|
+
* @since 2.4.0
|
|
11
|
+
*/
|
|
15
12
|
function createReadableStream(file) {
|
|
16
|
-
return
|
|
13
|
+
return Readable.toWeb(createReadStream(file));
|
|
17
14
|
}
|
|
18
|
-
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/serverless.js
|
|
19
17
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
19
|
+
* @returns {(request: Request, context: import('@netlify/functions').Context) => Promise<Response>}
|
|
20
|
+
*/
|
|
23
21
|
function init(manifest) {
|
|
24
22
|
const server = new Server(manifest);
|
|
25
|
-
|
|
26
23
|
/** @type {Promise<void> | null} */
|
|
27
24
|
let init_promise = server.init({
|
|
28
|
-
env:
|
|
25
|
+
env: process.env,
|
|
29
26
|
read: (file) => createReadableStream(`.netlify/server/${file}`)
|
|
30
27
|
});
|
|
31
|
-
|
|
32
28
|
return async (request, context) => {
|
|
33
29
|
if (init_promise !== null) {
|
|
34
30
|
await init_promise;
|
|
35
31
|
init_promise = null;
|
|
36
32
|
}
|
|
37
|
-
|
|
38
33
|
return server.respond(request, {
|
|
39
34
|
platform: { context },
|
|
40
35
|
getClientAddress() {
|
|
@@ -43,5 +38,5 @@ function init(manifest) {
|
|
|
43
38
|
});
|
|
44
39
|
};
|
|
45
40
|
}
|
|
46
|
-
|
|
41
|
+
//#endregion
|
|
47
42
|
export { init };
|
package/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { join, resolve, posix } from 'node:path';
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join, posix } from 'node:path';
|
|
4
3
|
import { fileURLToPath } from 'node:url';
|
|
5
4
|
import { builtinModules } from 'node:module';
|
|
6
5
|
import process from 'node:process';
|
|
7
|
-
import esbuild from 'esbuild';
|
|
8
6
|
import toml from '@iarna/toml';
|
|
7
|
+
import { build } from 'rolldown';
|
|
8
|
+
import { matches, get_publish_directory, s } from './utils.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @typedef {{
|
|
@@ -14,6 +14,9 @@ import toml from '@iarna/toml';
|
|
|
14
14
|
* } & toml.JsonMap} NetlifyConfig
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf-8'));
|
|
18
|
+
const adapter_version = pkg.version;
|
|
19
|
+
|
|
17
20
|
const name = '@sveltejs/adapter-netlify';
|
|
18
21
|
const files = fileURLToPath(new URL('./files', import.meta.url).href);
|
|
19
22
|
|
|
@@ -21,13 +24,16 @@ const edge_set_in_env_var =
|
|
|
21
24
|
process.env.NETLIFY_SVELTEKIT_USE_EDGE === 'true' ||
|
|
22
25
|
process.env.NETLIFY_SVELTEKIT_USE_EDGE === '1';
|
|
23
26
|
|
|
27
|
+
const netlify_framework_config_path = '.netlify/v1/config.json';
|
|
28
|
+
const netlify_framework_serverless_path = '.netlify/v1/functions';
|
|
29
|
+
const netlify_framework_edge_path = '.netlify/v1/edge-functions';
|
|
30
|
+
|
|
24
31
|
const FUNCTION_PREFIX = 'sveltekit-';
|
|
25
32
|
|
|
26
33
|
/** @type {import('./index.js').default} */
|
|
27
34
|
export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
28
35
|
return {
|
|
29
36
|
name,
|
|
30
|
-
/** @param {import('@sveltejs/kit').Builder} builder */
|
|
31
37
|
async adapt(builder) {
|
|
32
38
|
if (!builder.routes) {
|
|
33
39
|
throw new Error(
|
|
@@ -55,11 +61,14 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
|
55
61
|
|
|
56
62
|
// empty out existing build directories
|
|
57
63
|
builder.rimraf(publish);
|
|
64
|
+
builder.rimraf('.netlify/v1');
|
|
65
|
+
|
|
66
|
+
// clean up legacy directories from older adapter versions to avoid
|
|
67
|
+
// gnarly edge cases when an existing project is upgraded to this version
|
|
58
68
|
builder.rimraf('.netlify/edge-functions');
|
|
59
69
|
builder.rimraf('.netlify/server');
|
|
60
70
|
builder.rimraf('.netlify/package.json');
|
|
61
71
|
builder.rimraf('.netlify/serverless.js');
|
|
62
|
-
|
|
63
72
|
if (existsSync('.netlify/functions-internal')) {
|
|
64
73
|
for (const file of readdirSync('.netlify/functions-internal')) {
|
|
65
74
|
if (file.startsWith(FUNCTION_PREFIX)) {
|
|
@@ -75,13 +84,13 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
|
75
84
|
builder.writeClient(publish_dir);
|
|
76
85
|
builder.writePrerendered(publish_dir);
|
|
77
86
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
);
|
|
87
|
+
// Copy user's custom _headers file if it exists
|
|
88
|
+
if (existsSync('_headers')) {
|
|
89
|
+
builder.copy('_headers', join(publish, '_headers'));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
builder.log.minor('Writing Netlify config...');
|
|
93
|
+
write_frameworks_config({ builder });
|
|
85
94
|
|
|
86
95
|
if (edge) {
|
|
87
96
|
if (split) {
|
|
@@ -90,7 +99,7 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
|
90
99
|
|
|
91
100
|
await generate_edge_functions({ builder });
|
|
92
101
|
} else {
|
|
93
|
-
|
|
102
|
+
generate_serverless_functions({ builder, split, publish });
|
|
94
103
|
}
|
|
95
104
|
},
|
|
96
105
|
|
|
@@ -100,131 +109,24 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
|
100
109
|
}
|
|
101
110
|
};
|
|
102
111
|
}
|
|
103
|
-
/**
|
|
104
|
-
* @param { object } params
|
|
105
|
-
* @param {import('@sveltejs/kit').Builder} params.builder
|
|
106
|
-
*/
|
|
107
|
-
async function generate_edge_functions({ builder }) {
|
|
108
|
-
const tmp = builder.getBuildDirectory('netlify-tmp');
|
|
109
|
-
builder.rimraf(tmp);
|
|
110
|
-
builder.mkdirp(tmp);
|
|
111
|
-
|
|
112
|
-
builder.mkdirp('.netlify/edge-functions');
|
|
113
|
-
|
|
114
|
-
builder.log.minor('Generating Edge Function...');
|
|
115
|
-
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
116
|
-
|
|
117
|
-
builder.copy(`${files}/edge.js`, `${tmp}/entry.js`, {
|
|
118
|
-
replace: {
|
|
119
|
-
'0SERVER': `${relativePath}/index.js`,
|
|
120
|
-
MANIFEST: './manifest.js'
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const manifest = builder.generateManifest({
|
|
125
|
-
relativePath
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
writeFileSync(`${tmp}/manifest.js`, `export const manifest = ${manifest};\n`);
|
|
129
|
-
|
|
130
|
-
/** @type {{ assets: Set<string> }} */
|
|
131
|
-
// we have to prepend the file:// protocol because Windows doesn't support absolute path imports
|
|
132
|
-
const { assets } = (await import(`file://${tmp}/manifest.js`)).manifest;
|
|
133
|
-
|
|
134
|
-
const path = '/*';
|
|
135
|
-
// We only need to specify paths without the trailing slash because
|
|
136
|
-
// Netlify will handle the optional trailing slash for us
|
|
137
|
-
const excluded = [
|
|
138
|
-
// Contains static files
|
|
139
|
-
`/${builder.getAppPath()}/immutable/*`,
|
|
140
|
-
`/${builder.getAppPath()}/version.json`,
|
|
141
|
-
...builder.prerendered.paths,
|
|
142
|
-
...Array.from(assets).flatMap((asset) => {
|
|
143
|
-
if (asset.endsWith('/index.html')) {
|
|
144
|
-
const dir = asset.replace(/\/index\.html$/, '');
|
|
145
|
-
return [
|
|
146
|
-
`${builder.config.kit.paths.base}/${asset}`,
|
|
147
|
-
`${builder.config.kit.paths.base}/${dir}`
|
|
148
|
-
];
|
|
149
|
-
}
|
|
150
|
-
return `${builder.config.kit.paths.base}/${asset}`;
|
|
151
|
-
}),
|
|
152
|
-
// Should not be served by SvelteKit at all
|
|
153
|
-
'/.netlify/*'
|
|
154
|
-
];
|
|
155
112
|
|
|
156
|
-
/** @type {import('@netlify/edge-functions').Manifest} */
|
|
157
|
-
const edge_manifest = {
|
|
158
|
-
functions: [
|
|
159
|
-
{
|
|
160
|
-
function: 'render',
|
|
161
|
-
path,
|
|
162
|
-
excludedPath: /** @type {`/${string}`[]} */ (excluded)
|
|
163
|
-
}
|
|
164
|
-
],
|
|
165
|
-
version: 1
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
/** @type {BuildOptions} */
|
|
169
|
-
const esbuild_config = {
|
|
170
|
-
bundle: true,
|
|
171
|
-
format: 'esm',
|
|
172
|
-
platform: 'browser',
|
|
173
|
-
sourcemap: 'linked',
|
|
174
|
-
target: 'es2020',
|
|
175
|
-
loader: {
|
|
176
|
-
'.wasm': 'copy',
|
|
177
|
-
'.woff': 'copy',
|
|
178
|
-
'.woff2': 'copy',
|
|
179
|
-
'.ttf': 'copy',
|
|
180
|
-
'.eot': 'copy',
|
|
181
|
-
'.otf': 'copy'
|
|
182
|
-
},
|
|
183
|
-
// Node built-ins are allowed, but must be prefixed with `node:`
|
|
184
|
-
// https://docs.netlify.com/edge-functions/api/#runtime-environment
|
|
185
|
-
external: builtinModules.map((id) => `node:${id}`),
|
|
186
|
-
alias: Object.fromEntries(builtinModules.map((id) => [id, `node:${id}`]))
|
|
187
|
-
};
|
|
188
|
-
await Promise.all([
|
|
189
|
-
esbuild.build({
|
|
190
|
-
entryPoints: [`${tmp}/entry.js`],
|
|
191
|
-
outfile: '.netlify/edge-functions/render.js',
|
|
192
|
-
...esbuild_config
|
|
193
|
-
}),
|
|
194
|
-
builder.hasServerInstrumentationFile() &&
|
|
195
|
-
esbuild.build({
|
|
196
|
-
entryPoints: [`${builder.getServerDirectory()}/instrumentation.server.js`],
|
|
197
|
-
outfile: '.netlify/edge/instrumentation.server.js',
|
|
198
|
-
...esbuild_config
|
|
199
|
-
})
|
|
200
|
-
]);
|
|
201
|
-
|
|
202
|
-
if (builder.hasServerInstrumentationFile()) {
|
|
203
|
-
builder.instrument({
|
|
204
|
-
entrypoint: '.netlify/edge-functions/render.js',
|
|
205
|
-
instrumentation: '.netlify/edge/instrumentation.server.js',
|
|
206
|
-
start: '.netlify/edge/start.js'
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
writeFileSync('.netlify/edge-functions/manifest.json', JSON.stringify(edge_manifest));
|
|
211
|
-
}
|
|
212
113
|
/**
|
|
213
114
|
* @param { object } params
|
|
214
115
|
* @param {import('@sveltejs/kit').Builder} params.builder
|
|
215
116
|
* @param { string } params.publish
|
|
216
117
|
* @param { boolean } params.split
|
|
217
118
|
*/
|
|
218
|
-
function
|
|
219
|
-
|
|
119
|
+
function generate_serverless_functions({ builder, publish, split }) {
|
|
120
|
+
// https://docs.netlify.com/build/frameworks/frameworks-api/#netlifyv1functions
|
|
121
|
+
builder.mkdirp(netlify_framework_serverless_path);
|
|
220
122
|
|
|
221
|
-
builder.writeServer('.netlify/server');
|
|
123
|
+
builder.writeServer('.netlify/v1/server');
|
|
222
124
|
|
|
223
125
|
const replace = {
|
|
224
126
|
'0SERVER': './server/index.js' // digit prefix prevents CJS build from using this as a variable name, which would also get replaced
|
|
225
127
|
};
|
|
226
128
|
|
|
227
|
-
builder.copy(files, '.netlify', { replace, filter: (
|
|
129
|
+
builder.copy(files, '.netlify/v1', { replace, filter: (file) => !file.endsWith('edge.js') });
|
|
228
130
|
|
|
229
131
|
builder.log.minor('Generating serverless functions...');
|
|
230
132
|
|
|
@@ -306,75 +208,43 @@ function generate_lambda_functions({ builder, publish, split }) {
|
|
|
306
208
|
}
|
|
307
209
|
}
|
|
308
210
|
|
|
211
|
+
/**
|
|
212
|
+
* @returns {NetlifyConfig | null}
|
|
213
|
+
*/
|
|
309
214
|
function get_netlify_config() {
|
|
310
215
|
if (!existsSync('netlify.toml')) return null;
|
|
311
216
|
|
|
312
217
|
try {
|
|
313
|
-
return
|
|
218
|
+
return toml.parse(readFileSync('netlify.toml', 'utf-8'));
|
|
314
219
|
} catch (err) {
|
|
315
|
-
err
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* @param {NetlifyConfig | null} netlify_config
|
|
322
|
-
* @param {import('@sveltejs/kit').Builder} builder
|
|
323
|
-
**/
|
|
324
|
-
function get_publish_directory(netlify_config, builder) {
|
|
325
|
-
if (netlify_config) {
|
|
326
|
-
if (!netlify_config.build?.publish) {
|
|
327
|
-
builder.log.minor('No publish directory specified in netlify.toml, using default');
|
|
328
|
-
return;
|
|
220
|
+
if (err instanceof Error) {
|
|
221
|
+
throw new Error(`Failed to parse netlify.toml: ${err.message}`, { cause: err });
|
|
329
222
|
}
|
|
330
|
-
|
|
331
|
-
if (resolve(netlify_config.build.publish) === process.cwd()) {
|
|
332
|
-
throw new Error(
|
|
333
|
-
'The publish directory cannot be set to the site root. Please change it to another value such as "build" in netlify.toml.'
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
return netlify_config.build.publish;
|
|
223
|
+
throw err;
|
|
337
224
|
}
|
|
338
|
-
|
|
339
|
-
builder.log.warn(
|
|
340
|
-
'No netlify.toml found. Using default publish directory. Consult https://svelte.dev/docs/kit/adapter-netlify#usage for more details'
|
|
341
|
-
);
|
|
342
225
|
}
|
|
343
226
|
|
|
344
227
|
/**
|
|
345
|
-
*
|
|
228
|
+
* Writes the Netlify Frameworks API config file
|
|
229
|
+
* https://docs.netlify.com/build/frameworks/frameworks-api/
|
|
230
|
+
* @param {{ builder: import('@sveltejs/kit').Builder }} params
|
|
346
231
|
*/
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const next_b = b.slice(1);
|
|
359
|
-
|
|
360
|
-
for (let i = 0; i < a.length; i += 1) {
|
|
361
|
-
if (matches(a.slice(i), next_b)) return true;
|
|
232
|
+
function write_frameworks_config({ builder }) {
|
|
233
|
+
// https://docs.netlify.com/build/frameworks/frameworks-api/#headers
|
|
234
|
+
/** @type {{ headers: Array<{ for: string, values: Record<string, string> }> }} */
|
|
235
|
+
const config = {
|
|
236
|
+
headers: [
|
|
237
|
+
{
|
|
238
|
+
for: `/${builder.getAppPath()}/immutable/*`,
|
|
239
|
+
values: {
|
|
240
|
+
'cache-control': 'public, immutable, max-age=31536000'
|
|
241
|
+
}
|
|
362
242
|
}
|
|
243
|
+
]
|
|
244
|
+
};
|
|
363
245
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
if (!b[0].dynamic) {
|
|
368
|
-
if (!a[0].dynamic && a[0].content !== b[0].content) return false;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
if (a.length === 1 && b.length === 1) return true;
|
|
372
|
-
return matches(a.slice(1), b.slice(1));
|
|
373
|
-
} else if (a[0]) {
|
|
374
|
-
return a.length === 1 && a[0].rest;
|
|
375
|
-
} else {
|
|
376
|
-
return b.length === 1 && b[0].rest;
|
|
377
|
-
}
|
|
246
|
+
builder.mkdirp('.netlify/v1');
|
|
247
|
+
writeFileSync(netlify_framework_config_path, s(config));
|
|
378
248
|
}
|
|
379
249
|
|
|
380
250
|
/**
|
|
@@ -397,17 +267,17 @@ function generate_serverless_function({ builder, routes, patterns, name, exclude
|
|
|
397
267
|
const config = generate_config_export(patterns, exclude);
|
|
398
268
|
|
|
399
269
|
if (builder.hasServerInstrumentationFile()) {
|
|
400
|
-
writeFileSync(
|
|
270
|
+
writeFileSync(`${netlify_framework_serverless_path}/${name}.mjs`, fn);
|
|
401
271
|
builder.instrument({
|
|
402
|
-
entrypoint:
|
|
403
|
-
instrumentation: '.netlify/server/instrumentation.server.js',
|
|
404
|
-
start: `.netlify/
|
|
272
|
+
entrypoint: `${netlify_framework_serverless_path}/${name}.mjs`,
|
|
273
|
+
instrumentation: '.netlify/v1/server/instrumentation.server.js',
|
|
274
|
+
start: `.netlify/v1/server/${name}.start.mjs`,
|
|
405
275
|
module: {
|
|
406
276
|
generateText: generate_traced_module(config)
|
|
407
277
|
}
|
|
408
278
|
});
|
|
409
279
|
} else {
|
|
410
|
-
writeFileSync(
|
|
280
|
+
writeFileSync(`${netlify_framework_serverless_path}/${name}.mjs`, `${fn}\n${config}`);
|
|
411
281
|
}
|
|
412
282
|
}
|
|
413
283
|
|
|
@@ -423,6 +293,8 @@ export default init(${manifest});
|
|
|
423
293
|
`;
|
|
424
294
|
}
|
|
425
295
|
|
|
296
|
+
const generator_string = `@sveltejs/adapter-netlify@${adapter_version}`;
|
|
297
|
+
|
|
426
298
|
/**
|
|
427
299
|
* @param {string[]} patterns
|
|
428
300
|
* @param {string[]} [exclude]
|
|
@@ -430,10 +302,14 @@ export default init(${manifest});
|
|
|
430
302
|
*/
|
|
431
303
|
function generate_config_export(patterns, exclude = []) {
|
|
432
304
|
// TODO: add a human friendly name for the function https://docs.netlify.com/build/frameworks/frameworks-api/#configuration-options-2
|
|
305
|
+
|
|
306
|
+
// https://docs.netlify.com/build/frameworks/frameworks-api/#configuration-options-2
|
|
433
307
|
return `\
|
|
434
308
|
export const config = {
|
|
435
|
-
|
|
436
|
-
|
|
309
|
+
name: 'SvelteKit server',
|
|
310
|
+
generator: '${generator_string}',
|
|
311
|
+
path: [${patterns.map(s).join(', ')}],
|
|
312
|
+
excludedPath: [${['/.netlify/*', ...exclude].map(s).join(', ')}],
|
|
437
313
|
preferStatic: true
|
|
438
314
|
};
|
|
439
315
|
`;
|
|
@@ -446,10 +322,135 @@ export const config = {
|
|
|
446
322
|
function generate_traced_module(config) {
|
|
447
323
|
return ({ instrumentation, start }) => {
|
|
448
324
|
return `\
|
|
449
|
-
import '
|
|
450
|
-
const { default: _0 } = await import('
|
|
325
|
+
import '../server/${instrumentation}';
|
|
326
|
+
const { default: _0 } = await import('../server/${start}');
|
|
451
327
|
export { _0 as default };
|
|
452
328
|
|
|
453
329
|
${config}`;
|
|
454
330
|
};
|
|
455
331
|
}
|
|
332
|
+
|
|
333
|
+
/** @satisfies {import('rolldown').BuildOptions} */
|
|
334
|
+
const rolldown_config = {
|
|
335
|
+
platform: 'browser',
|
|
336
|
+
output: {
|
|
337
|
+
sourcemap: true,
|
|
338
|
+
codeSplitting: false
|
|
339
|
+
},
|
|
340
|
+
transform: {
|
|
341
|
+
target: 'es2022'
|
|
342
|
+
},
|
|
343
|
+
// Node built-ins are allowed, but must be prefixed with `node:`
|
|
344
|
+
// https://docs.netlify.com/edge-functions/api/#runtime-environment
|
|
345
|
+
external: builtinModules.map((id) => `node:${id}`),
|
|
346
|
+
resolve: {
|
|
347
|
+
alias: Object.fromEntries(builtinModules.map((id) => [id, `node:${id}`]))
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @param { object } params
|
|
353
|
+
* @param {import('@sveltejs/kit').Builder} params.builder
|
|
354
|
+
*/
|
|
355
|
+
async function generate_edge_functions({ builder }) {
|
|
356
|
+
const tmp = builder.getBuildDirectory('netlify-tmp');
|
|
357
|
+
builder.rimraf(tmp);
|
|
358
|
+
builder.mkdirp(tmp);
|
|
359
|
+
|
|
360
|
+
// https://docs.netlify.com/build/frameworks/frameworks-api/#edge-functions
|
|
361
|
+
builder.mkdirp('.netlify/v1/edge-functions');
|
|
362
|
+
|
|
363
|
+
builder.log.minor('Generating Edge Function...');
|
|
364
|
+
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
365
|
+
|
|
366
|
+
builder.copy(`${files}/edge.js`, `${tmp}/entry.js`, {
|
|
367
|
+
replace: {
|
|
368
|
+
'0SERVER': `${relativePath}/index.js`,
|
|
369
|
+
MANIFEST: './manifest.js'
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const manifest = builder.generateManifest({
|
|
374
|
+
relativePath
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
writeFileSync(`${tmp}/manifest.js`, `export const manifest = ${manifest};\n`);
|
|
378
|
+
|
|
379
|
+
/** @type {{ assets: Set<string> }} */
|
|
380
|
+
// we have to prepend the file:// protocol because Windows doesn't support absolute path imports
|
|
381
|
+
const { assets } = (await import(`file://${tmp}/manifest.js`)).manifest;
|
|
382
|
+
|
|
383
|
+
const path = '/*';
|
|
384
|
+
// We only need to specify paths without the trailing slash because
|
|
385
|
+
// Netlify will handle the optional trailing slash for us
|
|
386
|
+
const excluded_paths = [
|
|
387
|
+
// Contains static files
|
|
388
|
+
`/${builder.getAppPath()}/immutable/*`,
|
|
389
|
+
`/${builder.getAppPath()}/version.json`,
|
|
390
|
+
...builder.prerendered.paths,
|
|
391
|
+
...Array.from(assets).flatMap((asset) => {
|
|
392
|
+
if (asset.endsWith('/index.html')) {
|
|
393
|
+
const dir = asset.replace(/\/index\.html$/, '');
|
|
394
|
+
return [
|
|
395
|
+
`${builder.config.kit.paths.base}/${asset}`,
|
|
396
|
+
`${builder.config.kit.paths.base}/${dir}`
|
|
397
|
+
];
|
|
398
|
+
}
|
|
399
|
+
return `${builder.config.kit.paths.base}/${asset}`;
|
|
400
|
+
}),
|
|
401
|
+
// Should not be served by SvelteKit at all
|
|
402
|
+
'/.netlify/*'
|
|
403
|
+
];
|
|
404
|
+
|
|
405
|
+
await Promise.all([
|
|
406
|
+
build({
|
|
407
|
+
...rolldown_config,
|
|
408
|
+
input: `${tmp}/entry.js`,
|
|
409
|
+
output: {
|
|
410
|
+
...rolldown_config.output,
|
|
411
|
+
file: `${netlify_framework_edge_path}/${FUNCTION_PREFIX}render.js`
|
|
412
|
+
}
|
|
413
|
+
}),
|
|
414
|
+
builder.hasServerInstrumentationFile() &&
|
|
415
|
+
build({
|
|
416
|
+
...rolldown_config,
|
|
417
|
+
input: `${builder.getServerDirectory()}/instrumentation.server.js`,
|
|
418
|
+
output: {
|
|
419
|
+
...rolldown_config.output,
|
|
420
|
+
file: `${netlify_framework_edge_path}/${FUNCTION_PREFIX}instrumentation.server.js`
|
|
421
|
+
}
|
|
422
|
+
})
|
|
423
|
+
]);
|
|
424
|
+
|
|
425
|
+
if (builder.hasServerInstrumentationFile()) {
|
|
426
|
+
builder.instrument({
|
|
427
|
+
entrypoint: `${netlify_framework_edge_path}/${FUNCTION_PREFIX}render.js`,
|
|
428
|
+
instrumentation: `${netlify_framework_edge_path}/${FUNCTION_PREFIX}instrumentation.server.js`,
|
|
429
|
+
start: `${netlify_framework_edge_path}/${FUNCTION_PREFIX}start.js`
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
add_edge_function_config({ builder, path, excluded_paths });
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Adds edge function configuration to the Frameworks API config file `config.json`
|
|
438
|
+
* https://docs.netlify.com/build/frameworks/frameworks-api/#netlifyv1edge-functions
|
|
439
|
+
* @param {{ builder: import('@sveltejs/kit').Builder, path: string, excluded_paths: string[] }} params
|
|
440
|
+
*/
|
|
441
|
+
function add_edge_function_config({ path, excluded_paths }) {
|
|
442
|
+
const config = JSON.parse(readFileSync(netlify_framework_config_path, 'utf-8'));
|
|
443
|
+
|
|
444
|
+
// https://docs.netlify.com/build/frameworks/frameworks-api/#configuration-options-1
|
|
445
|
+
config.edge_functions = [
|
|
446
|
+
{
|
|
447
|
+
function: `${FUNCTION_PREFIX}render`,
|
|
448
|
+
name: 'SvelteKit server',
|
|
449
|
+
generator: generator_string,
|
|
450
|
+
path,
|
|
451
|
+
excludedPath: excluded_paths
|
|
452
|
+
}
|
|
453
|
+
];
|
|
454
|
+
|
|
455
|
+
writeFileSync(netlify_framework_config_path, s(config));
|
|
456
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/adapter-netlify",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0-next.0",
|
|
4
4
|
"description": "A SvelteKit adapter that creates a Netlify app",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adapter",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@iarna/toml": "^2.2.5",
|
|
37
|
-
"
|
|
37
|
+
"rolldown": "^1.0.0-rc.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@netlify/dev": "^4.11.2",
|
|
@@ -42,26 +42,21 @@
|
|
|
42
42
|
"@netlify/functions": "^5.0.0",
|
|
43
43
|
"@netlify/node-cookies": "^0.1.0",
|
|
44
44
|
"@netlify/types": "^2.1.0",
|
|
45
|
-
"@
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"@sveltejs/
|
|
49
|
-
"@types/node": "^18.19.119",
|
|
50
|
-
"rollup": "^4.14.2",
|
|
51
|
-
"typescript": "^5.3.3",
|
|
52
|
-
"vitest": "^4.0.0",
|
|
53
|
-
"@sveltejs/kit": "^2.53.1"
|
|
45
|
+
"@types/node": "^22.19.19",
|
|
46
|
+
"typescript": "^6.0.3",
|
|
47
|
+
"vitest": "^4.1.7",
|
|
48
|
+
"@sveltejs/kit": "^3.0.0-next.0"
|
|
54
49
|
},
|
|
55
50
|
"peerDependencies": {
|
|
56
51
|
"@sveltejs/kit": "^2.31.0"
|
|
57
52
|
},
|
|
58
53
|
"scripts": {
|
|
59
|
-
"dev": "
|
|
60
|
-
"build": "
|
|
54
|
+
"dev": "rolldown -cw",
|
|
55
|
+
"build": "rolldown -c",
|
|
61
56
|
"check": "tsc",
|
|
62
57
|
"lint": "prettier --check .",
|
|
63
58
|
"format": "pnpm lint --write",
|
|
64
|
-
"test": "pnpm test:integration",
|
|
59
|
+
"test": "pnpm test:unit && pnpm test:integration",
|
|
65
60
|
"test:unit": "vitest run",
|
|
66
61
|
"test:integration": "pnpm build && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test"
|
|
67
62
|
}
|
package/files/shims.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import buffer from 'node:buffer';
|
|
2
|
-
import { webcrypto } from 'node:crypto';
|
|
3
|
-
|
|
4
|
-
// `buffer.File` was added in Node 18.13.0 while the `File` global was added in Node 20.0.0
|
|
5
|
-
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File;
|
|
6
|
-
|
|
7
|
-
/** @type {Record<string, any>} */
|
|
8
|
-
const globals = {
|
|
9
|
-
crypto: webcrypto,
|
|
10
|
-
File
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// exported for dev/preview and node environments
|
|
14
|
-
/**
|
|
15
|
-
* Make various web APIs available as globals:
|
|
16
|
-
* - `crypto`
|
|
17
|
-
* - `File`
|
|
18
|
-
*/
|
|
19
|
-
function installPolyfills() {
|
|
20
|
-
for (const name in globals) {
|
|
21
|
-
if (name in globalThis) continue;
|
|
22
|
-
|
|
23
|
-
Object.defineProperty(globalThis, name, {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
writable: true,
|
|
27
|
-
value: globals[name]
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
installPolyfills();
|