@sveltejs/adapter-netlify 1.0.1 → 1.0.2
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/package.json +2 -3
- package/index.js +0 -304
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/adapter-netlify",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/sveltejs/kit",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
},
|
|
17
17
|
"./package.json": "./package.json"
|
|
18
18
|
},
|
|
19
|
-
"main": "index.js",
|
|
20
19
|
"types": "index.d.ts",
|
|
21
20
|
"files": [
|
|
22
21
|
"files",
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
"rollup": "^3.7.0",
|
|
39
38
|
"typescript": "^4.9.4",
|
|
40
39
|
"uvu": "^0.5.6",
|
|
41
|
-
"@sveltejs/kit": "^1.
|
|
40
|
+
"@sveltejs/kit": "^1.1.1"
|
|
42
41
|
},
|
|
43
42
|
"peerDependencies": {
|
|
44
43
|
"@sveltejs/kit": "^1.0.0"
|
package/index.js
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import { appendFileSync, existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
-
import { dirname, join, resolve, posix } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import esbuild from 'esbuild';
|
|
5
|
-
import toml from '@iarna/toml';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {{
|
|
9
|
-
* build?: { publish?: string }
|
|
10
|
-
* functions?: { node_bundler?: 'zisi' | 'esbuild' }
|
|
11
|
-
* } & toml.JsonMap} NetlifyConfig
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {{
|
|
16
|
-
* functions: Array<
|
|
17
|
-
* | {
|
|
18
|
-
* function: string;
|
|
19
|
-
* path: string;
|
|
20
|
-
* }
|
|
21
|
-
* | {
|
|
22
|
-
* function: string;
|
|
23
|
-
* pattern: string;
|
|
24
|
-
* }
|
|
25
|
-
* >;
|
|
26
|
-
* version: 1;
|
|
27
|
-
* }} HandlerManifest
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
const files = fileURLToPath(new URL('./files', import.meta.url).href);
|
|
31
|
-
|
|
32
|
-
const edge_set_in_env_var =
|
|
33
|
-
process.env.NETLIFY_SVELTEKIT_USE_EDGE === 'true' ||
|
|
34
|
-
process.env.NETLIFY_SVELTEKIT_USE_EDGE === '1';
|
|
35
|
-
|
|
36
|
-
/** @type {import('.').default} */
|
|
37
|
-
export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
|
|
38
|
-
return {
|
|
39
|
-
name: '@sveltejs/adapter-netlify',
|
|
40
|
-
|
|
41
|
-
async adapt(builder) {
|
|
42
|
-
const netlify_config = get_netlify_config();
|
|
43
|
-
|
|
44
|
-
// "build" is the default publish directory when Netlify detects SvelteKit
|
|
45
|
-
const publish = get_publish_directory(netlify_config, builder) || 'build';
|
|
46
|
-
|
|
47
|
-
// empty out existing build directories
|
|
48
|
-
builder.rimraf(publish);
|
|
49
|
-
builder.rimraf('.netlify/edge-functions');
|
|
50
|
-
builder.rimraf('.netlify/functions-internal');
|
|
51
|
-
builder.rimraf('.netlify/server');
|
|
52
|
-
builder.rimraf('.netlify/package.json');
|
|
53
|
-
builder.rimraf('.netlify/serverless.js');
|
|
54
|
-
|
|
55
|
-
builder.log.minor(`Publishing to "${publish}"`);
|
|
56
|
-
|
|
57
|
-
builder.log.minor('Copying assets...');
|
|
58
|
-
const publish_dir = `${publish}${builder.config.kit.paths.base}`;
|
|
59
|
-
builder.writeClient(publish_dir);
|
|
60
|
-
builder.writePrerendered(publish_dir);
|
|
61
|
-
|
|
62
|
-
builder.log.minor('Writing custom headers...');
|
|
63
|
-
const headers_file = join(publish, '_headers');
|
|
64
|
-
builder.copy('_headers', headers_file);
|
|
65
|
-
appendFileSync(
|
|
66
|
-
headers_file,
|
|
67
|
-
`\n\n/${builder.getAppPath()}/immutable/*\n cache-control: public\n cache-control: immutable\n cache-control: max-age=31536000\n`
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
if (edge) {
|
|
71
|
-
if (split) {
|
|
72
|
-
throw new Error('Cannot use `split: true` alongside `edge: true`');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
await generate_edge_functions({ builder });
|
|
76
|
-
} else {
|
|
77
|
-
await generate_lambda_functions({ builder, split, publish });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* @param { object } params
|
|
84
|
-
* @param {import('@sveltejs/kit').Builder} params.builder
|
|
85
|
-
*/
|
|
86
|
-
async function generate_edge_functions({ builder }) {
|
|
87
|
-
const tmp = builder.getBuildDirectory('netlify-tmp');
|
|
88
|
-
builder.rimraf(tmp);
|
|
89
|
-
builder.mkdirp(tmp);
|
|
90
|
-
|
|
91
|
-
builder.mkdirp('.netlify/edge-functions');
|
|
92
|
-
|
|
93
|
-
// Don't match the static directory
|
|
94
|
-
const pattern = '^/.*$';
|
|
95
|
-
|
|
96
|
-
// Go doesn't support lookarounds, so we can't do this
|
|
97
|
-
// const pattern = appDir ? `^/(?!${escapeStringRegexp(appDir)}).*$` : '^/.*$';
|
|
98
|
-
|
|
99
|
-
/** @type {HandlerManifest} */
|
|
100
|
-
const edge_manifest = {
|
|
101
|
-
functions: [
|
|
102
|
-
{
|
|
103
|
-
function: 'render',
|
|
104
|
-
pattern
|
|
105
|
-
}
|
|
106
|
-
],
|
|
107
|
-
version: 1
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
builder.log.minor('Generating Edge Function...');
|
|
111
|
-
const relativePath = posix.relative(tmp, builder.getServerDirectory());
|
|
112
|
-
|
|
113
|
-
builder.copy(`${files}/edge.js`, `${tmp}/entry.js`, {
|
|
114
|
-
replace: {
|
|
115
|
-
'0SERVER': `${relativePath}/index.js`,
|
|
116
|
-
MANIFEST: './manifest.js'
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const manifest = builder.generateManifest({
|
|
121
|
-
relativePath
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
writeFileSync(
|
|
125
|
-
`${tmp}/manifest.js`,
|
|
126
|
-
`export const manifest = ${manifest};\n\nexport const prerendered = new Set(${JSON.stringify(
|
|
127
|
-
builder.prerendered.paths
|
|
128
|
-
)});\n`
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
await esbuild.build({
|
|
132
|
-
entryPoints: [`${tmp}/entry.js`],
|
|
133
|
-
outfile: '.netlify/edge-functions/render.js',
|
|
134
|
-
bundle: true,
|
|
135
|
-
format: 'esm',
|
|
136
|
-
platform: 'browser',
|
|
137
|
-
sourcemap: 'linked',
|
|
138
|
-
target: 'es2020'
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
writeFileSync('.netlify/edge-functions/manifest.json', JSON.stringify(edge_manifest));
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* @param { object } params
|
|
145
|
-
* @param {import('@sveltejs/kit').Builder} params.builder
|
|
146
|
-
* @param { string } params.publish
|
|
147
|
-
* @param { boolean } params.split
|
|
148
|
-
*/
|
|
149
|
-
async function generate_lambda_functions({ builder, publish, split }) {
|
|
150
|
-
builder.mkdirp('.netlify/functions-internal');
|
|
151
|
-
|
|
152
|
-
/** @type {string[]} */
|
|
153
|
-
const redirects = [];
|
|
154
|
-
builder.writeServer('.netlify/server');
|
|
155
|
-
|
|
156
|
-
const replace = {
|
|
157
|
-
'0SERVER': './server/index.js' // digit prefix prevents CJS build from using this as a variable name, which would also get replaced
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
builder.copy(`${files}/esm`, '.netlify', { replace });
|
|
161
|
-
|
|
162
|
-
// Configuring the function to use ESM as the output format.
|
|
163
|
-
const fn_config = JSON.stringify({ config: { nodeModuleFormat: 'esm' }, version: 1 });
|
|
164
|
-
|
|
165
|
-
if (split) {
|
|
166
|
-
builder.log.minor('Generating serverless functions...');
|
|
167
|
-
|
|
168
|
-
await builder.createEntries((route) => {
|
|
169
|
-
const parts = [];
|
|
170
|
-
// Netlify's syntax uses '*' and ':param' as "splats" and "placeholders"
|
|
171
|
-
// https://docs.netlify.com/routing/redirects/redirect-options/#splats
|
|
172
|
-
for (const segment of route.segments) {
|
|
173
|
-
if (segment.rest) {
|
|
174
|
-
parts.push('*');
|
|
175
|
-
break; // Netlify redirects don't allow anything after a *
|
|
176
|
-
} else if (segment.dynamic) {
|
|
177
|
-
parts.push(`:${parts.length}`);
|
|
178
|
-
} else {
|
|
179
|
-
parts.push(segment.content);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const pattern = `/${parts.join('/')}`;
|
|
184
|
-
const name = parts.join('-').replace(/[:.]/g, '_').replace('*', '__rest') || 'index';
|
|
185
|
-
|
|
186
|
-
return {
|
|
187
|
-
id: pattern,
|
|
188
|
-
filter: (other) => matches(route.segments, other.segments),
|
|
189
|
-
complete: (entry) => {
|
|
190
|
-
const manifest = entry.generateManifest({
|
|
191
|
-
relativePath: '../server'
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
const fn = `import { init } from '../serverless.js';\n\nexport const handler = init(${manifest});\n`;
|
|
195
|
-
|
|
196
|
-
writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn);
|
|
197
|
-
writeFileSync(`.netlify/functions-internal/${name}.json`, fn_config);
|
|
198
|
-
|
|
199
|
-
redirects.push(`${pattern} /.netlify/functions/${name} 200`);
|
|
200
|
-
redirects.push(`${pattern}/__data.json /.netlify/functions/${name} 200`);
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
});
|
|
204
|
-
} else {
|
|
205
|
-
builder.log.minor('Generating serverless functions...');
|
|
206
|
-
|
|
207
|
-
const manifest = builder.generateManifest({
|
|
208
|
-
relativePath: '../server'
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
const fn = `import { init } from '../serverless.js';\n\nexport const handler = init(${manifest});\n`;
|
|
212
|
-
|
|
213
|
-
writeFileSync(`.netlify/functions-internal/render.json`, fn_config);
|
|
214
|
-
writeFileSync('.netlify/functions-internal/render.mjs', fn);
|
|
215
|
-
redirects.push('* /.netlify/functions/render 200');
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// this should happen at the end, after builder.writeClient(...),
|
|
219
|
-
// so that generated redirects are appended to custom redirects
|
|
220
|
-
// rather than replaced by them
|
|
221
|
-
builder.log.minor('Writing redirects...');
|
|
222
|
-
const redirect_file = join(publish, '_redirects');
|
|
223
|
-
if (existsSync('_redirects')) {
|
|
224
|
-
builder.copy('_redirects', redirect_file);
|
|
225
|
-
}
|
|
226
|
-
builder.mkdirp(dirname(redirect_file));
|
|
227
|
-
appendFileSync(redirect_file, `\n\n${redirects.join('\n')}`);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function get_netlify_config() {
|
|
231
|
-
if (!existsSync('netlify.toml')) return null;
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
return /** @type {NetlifyConfig} */ (toml.parse(readFileSync('netlify.toml', 'utf-8')));
|
|
235
|
-
} catch (err) {
|
|
236
|
-
err.message = `Error parsing netlify.toml: ${err.message}`;
|
|
237
|
-
throw err;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* @param {NetlifyConfig} netlify_config
|
|
243
|
-
* @param {import('@sveltejs/kit').Builder} builder
|
|
244
|
-
**/
|
|
245
|
-
function get_publish_directory(netlify_config, builder) {
|
|
246
|
-
if (netlify_config) {
|
|
247
|
-
if (!netlify_config.build?.publish) {
|
|
248
|
-
builder.log.minor('No publish directory specified in netlify.toml, using default');
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (netlify_config.redirects) {
|
|
253
|
-
throw new Error(
|
|
254
|
-
"Redirects are not supported in netlify.toml. Use _redirects instead. For more details consult the readme's troubleshooting section."
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
if (resolve(netlify_config.build.publish) === process.cwd()) {
|
|
258
|
-
throw new Error(
|
|
259
|
-
'The publish directory cannot be set to the site root. Please change it to another value such as "build" in netlify.toml.'
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
return netlify_config.build.publish;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
builder.log.warn(
|
|
266
|
-
'No netlify.toml found. Using default publish directory. Consult https://github.com/sveltejs/kit/tree/master/packages/adapter-netlify#configuration for more details '
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* @typedef {{ rest: boolean, dynamic: boolean, content: string }} RouteSegment
|
|
272
|
-
*/
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* @param {RouteSegment[]} a
|
|
276
|
-
* @param {RouteSegment[]} b
|
|
277
|
-
* @returns {boolean}
|
|
278
|
-
*/
|
|
279
|
-
function matches(a, b) {
|
|
280
|
-
if (a[0] && b[0]) {
|
|
281
|
-
if (b[0].rest) {
|
|
282
|
-
if (b.length === 1) return true;
|
|
283
|
-
|
|
284
|
-
const next_b = b.slice(1);
|
|
285
|
-
|
|
286
|
-
for (let i = 0; i < a.length; i += 1) {
|
|
287
|
-
if (matches(a.slice(i), next_b)) return true;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (!b[0].dynamic) {
|
|
294
|
-
if (!a[0].dynamic && a[0].content !== b[0].content) return false;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (a.length === 1 && b.length === 1) return true;
|
|
298
|
-
return matches(a.slice(1), b.slice(1));
|
|
299
|
-
} else if (a[0]) {
|
|
300
|
-
return a.length === 1 && a[0].rest;
|
|
301
|
-
} else {
|
|
302
|
-
return b.length === 1 && b[0].rest;
|
|
303
|
-
}
|
|
304
|
-
}
|