@sveltejs/kit 1.0.0-next.375 → 1.0.0-next.378

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/README.md CHANGED
@@ -5,7 +5,7 @@ This is the [SvelteKit](https://kit.svelte.dev) framework and CLI.
5
5
  The quickest way to get started is via the [create-svelte](https://github.com/sveltejs/kit/tree/master/packages/create-svelte) package:
6
6
 
7
7
  ```bash
8
- npm init svelte my-app
8
+ npm create svelte@latest my-app
9
9
  cd my-app
10
10
  npm install
11
11
  npm run dev
@@ -145,12 +145,6 @@ function is_pojo(body) {
145
145
  return true;
146
146
  }
147
147
 
148
- /** @param {import('types').RequestEvent} event */
149
- function normalize_request_method(event) {
150
- const method = event.request.method.toLowerCase();
151
- return method === 'delete' ? 'del' : method; // 'delete' is a reserved word
152
- }
153
-
154
148
  /**
155
149
  * Serialize an error into a JSON string, by copying its `name`, `message`
156
150
  * and (in dev) `stack`, plus any custom properties, plus recursively
@@ -192,6 +186,19 @@ function clone_error(error, get_stack) {
192
186
  return object;
193
187
  }
194
188
 
189
+ // TODO: Remove for 1.0
190
+ /** @param {Record<string, any>} mod */
191
+ function check_method_names(mod) {
192
+ ['get', 'post', 'put', 'patch', 'del'].forEach((m) => {
193
+ if (m in mod) {
194
+ const replacement = m === 'del' ? 'DELETE' : m.toUpperCase();
195
+ throw Error(
196
+ `Endpoint method "${m}" has changed to "${replacement}". See https://github.com/sveltejs/kit/discussions/5359 for more information.`
197
+ );
198
+ }
199
+ });
200
+ }
201
+
195
202
  /** @type {import('types').SSRErrorPage} */
196
203
  const GENERIC_ERROR = {
197
204
  id: '__error'
@@ -238,24 +245,25 @@ function is_text(content_type) {
238
245
  * @returns {Promise<Response>}
239
246
  */
240
247
  async function render_endpoint(event, mod, options) {
241
- const method = normalize_request_method(event);
248
+ const { method } = event.request;
249
+
250
+ check_method_names(mod);
242
251
 
243
252
  /** @type {import('types').RequestHandler} */
244
253
  let handler = mod[method];
245
254
 
246
- if (!handler && method === 'head') {
247
- handler = mod.get;
255
+ if (!handler && method === 'HEAD') {
256
+ handler = mod.GET;
248
257
  }
249
258
 
250
259
  if (!handler) {
251
260
  const allowed = [];
252
261
 
253
- for (const method in ['get', 'post', 'put', 'patch']) {
254
- if (mod[method]) allowed.push(method.toUpperCase());
262
+ for (const method in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']) {
263
+ if (mod[method]) allowed.push(method);
255
264
  }
256
265
 
257
- if (mod.del) allowed.push('DELETE');
258
- if (mod.get || mod.head) allowed.push('HEAD');
266
+ if (mod.GET || mod.HEAD) allowed.push('HEAD');
259
267
 
260
268
  return event.request.headers.get('x-sveltekit-load')
261
269
  ? // TODO would be nice to avoid these requests altogether,
@@ -263,7 +271,7 @@ async function render_endpoint(event, mod, options) {
263
271
  new Response(undefined, {
264
272
  status: 204
265
273
  })
266
- : new Response(`${event.request.method} method not allowed`, {
274
+ : new Response(`${method} method not allowed`, {
267
275
  status: 405,
268
276
  headers: {
269
277
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
@@ -327,7 +335,7 @@ async function render_endpoint(event, mod, options) {
327
335
  }
328
336
 
329
337
  return new Response(
330
- method !== 'head' && !bodyless_status_codes.has(status) ? normalized_body : undefined,
338
+ method !== 'HEAD' && !bodyless_status_codes.has(status) ? normalized_body : undefined,
331
339
  {
332
340
  status,
333
341
  headers
@@ -2620,13 +2628,15 @@ async function load_shadow_data(route, event, options, prerender) {
2620
2628
  try {
2621
2629
  const mod = await route.shadow();
2622
2630
 
2623
- if (prerender && (mod.post || mod.put || mod.del || mod.patch)) {
2631
+ check_method_names(mod);
2632
+
2633
+ if (prerender && (mod.POST || mod.PUT || mod.DELETE || mod.PATCH)) {
2624
2634
  throw new Error('Cannot prerender pages that have endpoints with mutative methods');
2625
2635
  }
2626
2636
 
2627
- const method = normalize_request_method(event);
2628
- const is_get = method === 'head' || method === 'get';
2629
- const handler = method === 'head' ? mod.head || mod.get : mod[method];
2637
+ const { method } = event.request;
2638
+ const is_get = method === 'HEAD' || method === 'GET';
2639
+ const handler = method === 'HEAD' ? mod.HEAD || mod.GET : mod[method];
2630
2640
 
2631
2641
  if (!handler && !is_get) {
2632
2642
  return {
@@ -2673,7 +2683,7 @@ async function load_shadow_data(route, event, options, prerender) {
2673
2683
  data.body = body;
2674
2684
  }
2675
2685
 
2676
- const get = (method === 'head' && mod.head) || mod.get;
2686
+ const get = (method === 'HEAD' && mod.HEAD) || mod.GET;
2677
2687
  if (get) {
2678
2688
  const { status, headers, body } = validate_shadow_output(await get(event));
2679
2689
  add_cookies(/** @type {string[]} */ (data.cookies), headers);
@@ -83,7 +83,7 @@ function create_builder({ config, build_data, prerendered, log }) {
83
83
  content: segment
84
84
  })),
85
85
  pattern: route.pattern,
86
- methods: route.type === 'page' ? ['get'] : build_data.server.methods[route.file]
86
+ methods: route.type === 'page' ? ['GET'] : build_data.server.methods[route.file]
87
87
  }));
88
88
 
89
89
  const seen = new Set();
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ function handle_error(e) {
18
18
  process.exit(1);
19
19
  }
20
20
 
21
- const prog = sade('svelte-kit').version('1.0.0-next.375');
21
+ const prog = sade('svelte-kit').version('1.0.0-next.378');
22
22
 
23
23
  prog
24
24
  .command('package')
package/dist/node.js CHANGED
@@ -2,7 +2,7 @@ import http from 'node:http';
2
2
  import 'node:https';
3
3
  import 'node:zlib';
4
4
  import Stream, { PassThrough } from 'node:stream';
5
- import { Buffer as Buffer$1 } from 'node:buffer';
5
+ import { Buffer } from 'node:buffer';
6
6
  import { promisify, deprecate, types } from 'node:util';
7
7
  import { c as commonjsGlobal } from './chunks/_commonjsHelpers.js';
8
8
  import { format } from 'node:url';
@@ -4945,13 +4945,13 @@ class Body {
4945
4945
  body = null;
4946
4946
  } else if (isURLSearchParameters(body)) {
4947
4947
  // Body is a URLSearchParams
4948
- body = Buffer$1.from(body.toString());
4949
- } else if (isBlob(body)) ; else if (Buffer$1.isBuffer(body)) ; else if (types.isAnyArrayBuffer(body)) {
4948
+ body = Buffer.from(body.toString());
4949
+ } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (types.isAnyArrayBuffer(body)) {
4950
4950
  // Body is ArrayBuffer
4951
- body = Buffer$1.from(body);
4951
+ body = Buffer.from(body);
4952
4952
  } else if (ArrayBuffer.isView(body)) {
4953
4953
  // Body is ArrayBufferView
4954
- body = Buffer$1.from(body.buffer, body.byteOffset, body.byteLength);
4954
+ body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
4955
4955
  } else if (body instanceof Stream) ; else if (body instanceof FormData) {
4956
4956
  // Body is FormData
4957
4957
  body = formDataToBlob(body);
@@ -4959,12 +4959,12 @@ class Body {
4959
4959
  } else {
4960
4960
  // None of the above
4961
4961
  // coerce to string then buffer
4962
- body = Buffer$1.from(String(body));
4962
+ body = Buffer.from(String(body));
4963
4963
  }
4964
4964
 
4965
4965
  let stream = body;
4966
4966
 
4967
- if (Buffer$1.isBuffer(body)) {
4967
+ if (Buffer.isBuffer(body)) {
4968
4968
  stream = Stream.Readable.from(body);
4969
4969
  } else if (isBlob(body)) {
4970
4970
  stream = Stream.Readable.from(body.stream());
@@ -5106,12 +5106,12 @@ async function consumeBody(data) {
5106
5106
 
5107
5107
  // Body is null
5108
5108
  if (body === null) {
5109
- return Buffer$1.alloc(0);
5109
+ return Buffer.alloc(0);
5110
5110
  }
5111
5111
 
5112
5112
  /* c8 ignore next 3 */
5113
5113
  if (!(body instanceof Stream)) {
5114
- return Buffer$1.alloc(0);
5114
+ return Buffer.alloc(0);
5115
5115
  }
5116
5116
 
5117
5117
  // Body is stream
@@ -5138,10 +5138,10 @@ async function consumeBody(data) {
5138
5138
  if (body.readableEnded === true || body._readableState.ended === true) {
5139
5139
  try {
5140
5140
  if (accum.every(c => typeof c === 'string')) {
5141
- return Buffer$1.from(accum.join(''));
5141
+ return Buffer.from(accum.join(''));
5142
5142
  }
5143
5143
 
5144
- return Buffer$1.concat(accum, accumBytes);
5144
+ return Buffer.concat(accum, accumBytes);
5145
5145
  } catch (error) {
5146
5146
  throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error);
5147
5147
  }
@@ -5221,7 +5221,7 @@ const extractContentType = (body, request) => {
5221
5221
  }
5222
5222
 
5223
5223
  // Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView)
5224
- if (Buffer$1.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
5224
+ if (Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
5225
5225
  return null;
5226
5226
  }
5227
5227
 
@@ -5745,6 +5745,12 @@ function get_raw_body(req) {
5745
5745
  return null;
5746
5746
  }
5747
5747
 
5748
+ if (req.destroyed) {
5749
+ const readable = new ReadableStream();
5750
+ readable.cancel();
5751
+ return readable;
5752
+ }
5753
+
5748
5754
  let size = 0;
5749
5755
  let cancelled = false;
5750
5756
 
@@ -5755,31 +5761,34 @@ function get_raw_body(req) {
5755
5761
  });
5756
5762
 
5757
5763
  req.on('end', () => {
5758
- if (!cancelled) {
5759
- controller.close();
5760
- }
5764
+ if (cancelled) return;
5765
+ controller.close();
5761
5766
  });
5762
- },
5763
5767
 
5764
- pull(controller) {
5765
- return new Promise((fulfil) => {
5766
- req.once('data', (chunk) => {
5767
- if (!cancelled) {
5768
- size += chunk.length;
5769
- if (size > length) {
5770
- controller.error(new Error('content-length exceeded'));
5771
- }
5768
+ req.on('data', (chunk) => {
5769
+ if (cancelled) return;
5770
+
5771
+ size += chunk.length;
5772
+ if (size > length) {
5773
+ controller.error(new Error('content-length exceeded'));
5774
+ return;
5775
+ }
5772
5776
 
5773
- controller.enqueue(chunk);
5774
- }
5777
+ controller.enqueue(chunk);
5775
5778
 
5776
- fulfil();
5777
- });
5779
+ if (controller.desiredSize === null || controller.desiredSize <= 0) {
5780
+ req.pause();
5781
+ }
5778
5782
  });
5779
5783
  },
5780
5784
 
5781
- cancel() {
5785
+ pull() {
5786
+ req.resume();
5787
+ },
5788
+
5789
+ cancel(reason) {
5782
5790
  cancelled = true;
5791
+ req.destroy(reason);
5783
5792
  }
5784
5793
  });
5785
5794
  }
@@ -5831,16 +5840,26 @@ async function setResponse(res, response) {
5831
5840
  res.writeHead(response.status, headers);
5832
5841
 
5833
5842
  if (response.body) {
5834
- let cancelled = false;
5835
-
5836
5843
  const reader = response.body.getReader();
5837
5844
 
5845
+ if (res.destroyed) {
5846
+ reader.cancel();
5847
+ return;
5848
+ }
5849
+
5850
+ let cancelled = false;
5851
+
5838
5852
  res.on('close', () => {
5839
5853
  reader.cancel();
5840
5854
  cancelled = true;
5841
5855
  });
5842
5856
 
5843
- const next = async () => {
5857
+ res.on('error', (error) => {
5858
+ reader.cancel(error);
5859
+ cancelled = true;
5860
+ });
5861
+
5862
+ for (;;) {
5844
5863
  const { done, value } = await reader.read();
5845
5864
 
5846
5865
  if (cancelled) return;
@@ -5850,17 +5869,12 @@ async function setResponse(res, response) {
5850
5869
  return;
5851
5870
  }
5852
5871
 
5853
- res.write(Buffer.from(value), (error) => {
5854
- if (error) {
5855
- console.error('Error writing stream', error);
5856
- res.end();
5857
- } else {
5858
- next();
5859
- }
5860
- });
5861
- };
5872
+ const ok = res.write(value);
5862
5873
 
5863
- next();
5874
+ if (!ok) {
5875
+ await new Promise((fulfil) => res.once('drain', fulfil));
5876
+ }
5877
+ }
5864
5878
  } else {
5865
5879
  res.end();
5866
5880
  }
package/dist/vite.js CHANGED
@@ -4,7 +4,7 @@ import path__default, { join, dirname, resolve as resolve$1, normalize } from 'p
4
4
  import { a as load_template, $, c as coalesce_to_error, l as load_config } from './chunks/error.js';
5
5
  import { svelte } from '@sveltejs/vite-plugin-svelte';
6
6
  import * as vite from 'vite';
7
- import { loadConfigFromFile, searchForWorkspaceRoot } from 'vite';
7
+ import { loadConfigFromFile } from 'vite';
8
8
  import { p as posixify, m as mkdirp, r as rimraf } from './chunks/write_tsconfig.js';
9
9
  import { g as get_runtime_directory, s, i as init, a as get_runtime_prefix, u as update, b as get_mime_lookup, p as parse_route_id, c as all, l as logger } from './chunks/sync.js';
10
10
  import { pathToFileURL, URL as URL$1 } from 'url';
@@ -315,6 +315,17 @@ function remove_svelte_kit(config) {
315
315
  .filter((plugin) => plugin.name !== 'vite-plugin-svelte-kit');
316
316
  }
317
317
 
318
+ const method_names = new Set(['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']);
319
+
320
+ // If we'd written this in TypeScript, it could be easy...
321
+ /**
322
+ * @param {string} str
323
+ * @returns {str is import('types').HttpMethod}
324
+ */
325
+ function is_http_method(str) {
326
+ return method_names.has(str);
327
+ }
328
+
318
329
  /**
319
330
  * @param {{
320
331
  * hooks: string;
@@ -563,16 +574,6 @@ async function build_server(options, client) {
563
574
  };
564
575
  }
565
576
 
566
- /** @type {Record<string, string>} */
567
- const method_names = {
568
- get: 'get',
569
- head: 'head',
570
- post: 'post',
571
- put: 'put',
572
- del: 'delete',
573
- patch: 'patch'
574
- };
575
-
576
577
  /**
577
578
  * @param {string} cwd
578
579
  * @param {import('rollup').OutputChunk[]} output
@@ -593,9 +594,7 @@ function get_methods(cwd, output, manifest_data) {
593
594
  const file = route.type === 'endpoint' ? route.file : route.shadow;
594
595
 
595
596
  if (file && lookup[file]) {
596
- methods[file] = lookup[file]
597
- .map((x) => /** @type {import('types').HttpMethod} */ (method_names[x]))
598
- .filter(Boolean);
597
+ methods[file] = lookup[file].filter(is_http_method);
599
598
  }
600
599
  });
601
600
 
@@ -2987,7 +2986,7 @@ function kit() {
2987
2986
  svelte_config.kit.outDir,
2988
2987
  path__default.resolve(cwd, 'src'),
2989
2988
  path__default.resolve(cwd, 'node_modules'),
2990
- path__default.resolve(searchForWorkspaceRoot(cwd), 'node_modules')
2989
+ path__default.resolve(vite.searchForWorkspaceRoot(cwd), 'node_modules')
2991
2990
  ])
2992
2991
  ]
2993
2992
  },
@@ -3014,6 +3013,9 @@ function kit() {
3014
3013
  * Clears the output directories.
3015
3014
  */
3016
3015
  buildStart() {
3016
+ // Reset for new build. Goes here because `build --watch` calls buildStart but not config
3017
+ completed_build = false;
3018
+
3017
3019
  if (is_build) {
3018
3020
  rimraf(paths.build_dir);
3019
3021
  mkdirp(paths.build_dir);
@@ -3164,18 +3166,14 @@ function kit() {
3164
3166
  }
3165
3167
 
3166
3168
  function check_vite_version() {
3167
- let vite_major = 3;
3168
-
3169
- try {
3170
- const pkg = JSON.parse(fs__default.readFileSync('package.json', 'utf-8'));
3171
- vite_major = +pkg.devDependencies['vite'].replace(/^[~^]/, '')[0];
3172
- } catch {
3173
- // do nothing
3174
- }
3169
+ // TODO parse from kit peer deps and maybe do a full semver compare if we ever require feature releases a min
3170
+ const min_required_vite_major = 3;
3171
+ const vite_version = vite.version ?? '2.x'; // vite started exporting it's version in 3.0
3172
+ const current_vite_major = parseInt(vite_version.split('.')[0], 10);
3175
3173
 
3176
- if (vite_major < 3) {
3174
+ if (current_vite_major < min_required_vite_major) {
3177
3175
  throw new Error(
3178
- `Vite version ${vite_major} is no longer supported. Please upgrade to version 3`
3176
+ `Vite version ${current_vite_major} is no longer supported. Please upgrade to version ${min_required_vite_major}`
3179
3177
  );
3180
3178
  }
3181
3179
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.375",
3
+ "version": "1.0.0-next.378",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -15,7 +15,7 @@
15
15
  "sade": "^1.8.1"
16
16
  },
17
17
  "devDependencies": {
18
- "@playwright/test": "^1.23.3",
18
+ "@playwright/test": "^1.23.4",
19
19
  "@rollup/plugin-replace": "^4.0.0",
20
20
  "@types/connect": "^3.4.35",
21
21
  "@types/cookie": "^0.5.1",
package/types/index.d.ts CHANGED
@@ -244,7 +244,7 @@ export interface RequestEvent<Params extends Record<string, string> = Record<str
244
244
  }
245
245
 
246
246
  /**
247
- * A `(event: RequestEvent) => RequestHandlerOutput` function exported from an endpoint that corresponds to an HTTP verb (`get`, `put`, `patch`, etc) and handles requests with that method. Note that since 'delete' is a reserved word in JavaScript, delete handles are called `del` instead.
247
+ * A `(event: RequestEvent) => RequestHandlerOutput` function exported from an endpoint that corresponds to an HTTP verb (`GET`, `PUT`, `PATCH`, etc) and handles requests with that method.
248
248
  *
249
249
  * It receives `Params` as the first generic argument, which you can skip by using [generated types](/docs/types#generated-types) instead.
250
250
  *
@@ -142,7 +142,7 @@ export interface CspDirectives {
142
142
  >;
143
143
  }
144
144
 
145
- export type HttpMethod = 'get' | 'head' | 'post' | 'put' | 'delete' | 'patch';
145
+ export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
146
146
 
147
147
  export interface JSONObject {
148
148
  [key: string]: JSONValue;