@sveltejs/adapter-vercel 2.0.1 → 2.0.3

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.
@@ -11,11 +11,25 @@ await server.init({
11
11
  env: /** @type {Record<string, string>} */ (process.env)
12
12
  });
13
13
 
14
+ const DATA_SUFFIX = '/__data.json';
15
+
14
16
  /**
15
17
  * @param {import('http').IncomingMessage} req
16
18
  * @param {import('http').ServerResponse} res
17
19
  */
18
20
  export default async (req, res) => {
21
+ if (req.url) {
22
+ const [path, search] = req.url.split('?');
23
+
24
+ const params = new URLSearchParams(search);
25
+ const pathname = params.get('__pathname');
26
+
27
+ if (pathname) {
28
+ params.delete('__pathname');
29
+ req.url = `${pathname}${path.endsWith(DATA_SUFFIX) ? DATA_SUFFIX : ''}?${params}`;
30
+ }
31
+ }
32
+
19
33
  /** @type {Request} */
20
34
  let request;
21
35
 
package/index.d.ts CHANGED
@@ -35,11 +35,7 @@ export interface ServerlessConfig {
35
35
  /**
36
36
  * Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to `false` means it will never expire.
37
37
  */
38
- expiration?: number | false;
39
- /**
40
- * Option group number of the asset. Assets with the same group number will all be re-validated at the same time.
41
- */
42
- group?: number;
38
+ expiration: number | false;
43
39
  /**
44
40
  * Random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset
45
41
  * with a __prerender_bypass=<token> cookie.
package/index.js CHANGED
@@ -76,22 +76,6 @@ const plugin = function (defaults = {}) {
76
76
  `${dirs.functions}/${name}.func`,
77
77
  config
78
78
  );
79
-
80
- if (config.isr) {
81
- write(
82
- `${dirs.functions}/${name}.prerender-config.json`,
83
- JSON.stringify(
84
- {
85
- expiration: config.isr.expiration,
86
- group: config.isr.group,
87
- bypassToken: config.isr.bypassToken,
88
- allowQuery: config.isr.allowQuery
89
- },
90
- null,
91
- '\t'
92
- )
93
- );
94
- }
95
79
  }
96
80
 
97
81
  /**
@@ -158,6 +142,9 @@ const plugin = function (defaults = {}) {
158
142
  /** @type {Map<string, string>} */
159
143
  const functions = new Map();
160
144
 
145
+ /** @type {Map<import('@sveltejs/kit').RouteDefinition<import('.').Config>, { expiration: number | false, bypassToken: string | undefined, allowQuery: string[], group: number, passQuery: true }>} */
146
+ const isr_config = new Map();
147
+
161
148
  // group routes by config
162
149
  for (const route of builder.routes) {
163
150
  if (route.prerender === true) continue;
@@ -175,6 +162,20 @@ const plugin = function (defaults = {}) {
175
162
 
176
163
  const config = { runtime, ...defaults, ...route.config };
177
164
 
165
+ if (config.isr) {
166
+ if (config.isr.allowQuery?.includes('__pathname')) {
167
+ throw new Error('__pathname is a reserved query parameter for isr.allowQuery');
168
+ }
169
+
170
+ isr_config.set(route, {
171
+ expiration: config.isr.expiration,
172
+ bypassToken: config.isr.bypassToken,
173
+ allowQuery: ['__pathname', ...(config.isr.allowQuery ?? [])],
174
+ group: isr_config.size + 1,
175
+ passQuery: true
176
+ });
177
+ }
178
+
178
179
  const hash = hash_config(config);
179
180
 
180
181
  // first, check there are no routes with incompatible configs that will be merged
@@ -200,25 +201,28 @@ const plugin = function (defaults = {}) {
200
201
  group.routes.push(route);
201
202
  }
202
203
 
204
+ const singular = groups.size === 1;
205
+
203
206
  for (const group of groups.values()) {
204
207
  const generate_function =
205
208
  group.config.runtime === 'edge' ? generate_edge_function : generate_serverless_function;
206
209
 
207
210
  // generate one function for the group
208
- const name = `fn-${group.i}`;
211
+ const name = singular ? 'fn' : `fn-${group.i}`;
212
+
209
213
  await generate_function(
210
214
  name,
211
215
  /** @type {any} */ (group.config),
212
216
  /** @type {import('@sveltejs/kit').RouteDefinition<any>[]} */ (group.routes)
213
217
  );
214
218
 
215
- if (groups.size === 1) {
219
+ if (singular) {
216
220
  // Special case: One function for all routes
217
221
  static_config.routes.push({ src: '/.*', dest: `/${name}` });
218
- } else {
219
- for (const route of group.routes) {
220
- functions.set(route.pattern.toString(), name);
221
- }
222
+ }
223
+
224
+ for (const route of group.routes) {
225
+ functions.set(route.pattern.toString(), name);
222
226
  }
223
227
  }
224
228
 
@@ -238,12 +242,47 @@ const plugin = function (defaults = {}) {
238
242
  src = '^/?';
239
243
  }
240
244
 
241
- src += '(?:/__data.json)?$';
245
+ const name = functions.get(pattern) ?? 'fn-0';
246
+
247
+ const isr = isr_config.get(route);
248
+ if (isr) {
249
+ const isr_name = route.id.slice(1) || '__root__'; // should we check that __root__ isn't a route?
250
+ const base = `${dirs.functions}/${isr_name}`;
251
+ builder.mkdirp(base);
252
+
253
+ const target = `${dirs.functions}/${name}.func`;
254
+ const relative = path.relative(path.dirname(base), target);
255
+
256
+ // create a symlink to the actual function, but use the
257
+ // route name so that we can derive the correct URL
258
+ fs.symlinkSync(relative, `${base}.func`);
259
+ fs.symlinkSync(`../${relative}`, `${base}/__data.json.func`);
260
+
261
+ let i = 1;
262
+ const pathname = route.segments
263
+ .map((segment) => {
264
+ return segment.dynamic ? `$${i++}` : segment.content;
265
+ })
266
+ .join('/');
267
+
268
+ const json = JSON.stringify(isr, null, '\t');
269
+
270
+ write(`${base}.prerender-config.json`, json);
271
+ write(`${base}/__data.json.prerender-config.json`, json);
272
+
273
+ const q = `?__pathname=/${pathname}`;
242
274
 
243
- const name = functions.get(pattern);
244
- if (name) {
245
- static_config.routes.push({ src, dest: `/${name}` });
246
- functions.delete(pattern);
275
+ static_config.routes.push({
276
+ src: src + '$',
277
+ dest: `${isr_name}${q}`
278
+ });
279
+
280
+ static_config.routes.push({
281
+ src: src + '/__data.json$',
282
+ dest: `${isr_name}/__data.json${q}`
283
+ });
284
+ } else if (!singular) {
285
+ static_config.routes.push({ src: src + '(?:/__data.json)?$', dest: `/${name}` });
247
286
  }
248
287
  }
249
288
 
@@ -266,11 +305,7 @@ function hash_config(config) {
266
305
  config.external ?? '',
267
306
  config.regions ?? '',
268
307
  config.memory ?? '',
269
- config.maxDuration ?? '',
270
- config.isr?.expiration ?? '',
271
- config.isr?.group ?? '',
272
- config.isr?.bypassToken ?? '',
273
- config.isr?.allowQuery ?? ''
308
+ config.maxDuration ?? ''
274
309
  ].join('/');
275
310
  }
276
311
 
@@ -400,22 +435,21 @@ async function create_function_bundle(builder, entry, dir, config) {
400
435
  }
401
436
  }
402
437
 
438
+ const files = Array.from(traced.fileList);
439
+
403
440
  // find common ancestor directory
404
441
  /** @type {string[]} */
405
- let common_parts = [];
442
+ let common_parts = files[0]?.split(path.sep) ?? [];
406
443
 
407
- for (const file of traced.fileList) {
408
- if (common_parts) {
409
- const parts = file.split(path.sep);
444
+ for (let i = 1; i < files.length; i += 1) {
445
+ const file = files[i];
446
+ const parts = file.split(path.sep);
410
447
 
411
- for (let i = 0; i < common_parts.length; i += 1) {
412
- if (parts[i] !== common_parts[i]) {
413
- common_parts = common_parts.slice(0, i);
414
- break;
415
- }
448
+ for (let j = 0; j < common_parts.length; j += 1) {
449
+ if (parts[j] !== common_parts[j]) {
450
+ common_parts = common_parts.slice(0, j);
451
+ break;
416
452
  }
417
- } else {
418
- common_parts = path.dirname(file).split(path.sep);
419
453
  }
420
454
  }
421
455
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/adapter-vercel",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -29,7 +29,7 @@
29
29
  "devDependencies": {
30
30
  "@types/node": "^16.18.6",
31
31
  "typescript": "^4.9.4",
32
- "@sveltejs/kit": "^1.5.0"
32
+ "@sveltejs/kit": "^1.7.1"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@sveltejs/kit": "^1.5.0"