@sveltejs/kit 1.0.0-next.522 → 1.0.0-next.524

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.522",
3
+ "version": "1.0.0-next.524",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -5,7 +5,7 @@ import { pipeline } from 'stream';
5
5
  import { promisify } from 'util';
6
6
  import { copy, rimraf, mkdirp } from '../../utils/filesystem.js';
7
7
  import { generate_manifest } from '../generate_manifest/index.js';
8
- import { affects_path } from '../../utils/routing.js';
8
+ import { get_route_segments } from '../../utils/routing.js';
9
9
 
10
10
  const pipe = promisify(pipeline);
11
11
 
@@ -48,14 +48,11 @@ export function create_builder({ config, build_data, routes, prerendered, log })
48
48
 
49
49
  return {
50
50
  id: route.id,
51
- segments: route.id
52
- .split('/')
53
- .filter(affects_path)
54
- .map((segment) => ({
55
- dynamic: segment.includes('['),
56
- rest: segment.includes('[...'),
57
- content: segment
58
- })),
51
+ segments: get_route_segments(route.id).map((segment) => ({
52
+ dynamic: segment.includes('['),
53
+ rest: segment.includes('[...'),
54
+ content: segment
55
+ })),
59
56
  pattern: route.pattern,
60
57
  methods: Array.from(methods)
61
58
  };
@@ -9,7 +9,7 @@ import { crawl } from './crawl.js';
9
9
  import { escape_html_attr } from '../../utils/escape.js';
10
10
  import { logger } from '../utils.js';
11
11
  import { load_config } from '../config/index.js';
12
- import { affects_path } from '../../utils/routing.js';
12
+ import { get_route_segments } from '../../utils/routing.js';
13
13
  import { get_option } from '../../runtime/server/utils.js';
14
14
 
15
15
  /**
@@ -370,7 +370,7 @@ export async function prerender() {
370
370
  for (const [id, prerender] of prerender_map) {
371
371
  if (prerender) {
372
372
  if (id.includes('[')) continue;
373
- const path = `${id.split('/').filter(affects_path).join('/')}`;
373
+ const path = `/${get_route_segments(id).join('/')}`;
374
374
  enqueue(null, config.paths.base + path);
375
375
  }
376
376
  }
@@ -1,4 +1,4 @@
1
- import { affects_path } from '../../../utils/routing.js';
1
+ import { get_route_segments } from '../../../utils/routing.js';
2
2
 
3
3
  /**
4
4
  * @typedef {{
@@ -133,13 +133,11 @@ export function sort_routes(routes) {
133
133
 
134
134
  /** @param {string} id */
135
135
  function split_route_id(id) {
136
- return (
136
+ return get_route_segments(
137
137
  id
138
138
  // remove all [[optional]] parts unless they're at the very end
139
139
  .replace(/\[\[[^\]]+\]\](?!$)/g, '')
140
- .split('/')
141
- .filter((segment) => segment !== '' && affects_path(segment))
142
- );
140
+ ).filter(Boolean);
143
141
  }
144
142
 
145
143
  /**
@@ -147,7 +147,7 @@ export async function write_types(config, manifest_data, file) {
147
147
  return;
148
148
  }
149
149
 
150
- const id = posixify(path.relative(config.kit.files.routes, path.dirname(file)));
150
+ const id = '/' + posixify(path.relative(config.kit.files.routes, path.dirname(file)));
151
151
 
152
152
  const route = manifest_data.routes.find((route) => route.id === id);
153
153
  if (!route) return; // this shouldn't ever happen
@@ -18,7 +18,7 @@ export function parse(nodes, server_loads, dictionary, matchers) {
18
18
  /** @param {string} path */
19
19
  exec: (path) => {
20
20
  const match = pattern.exec(path);
21
- if (match) return exec(match, names, types, matchers);
21
+ if (match) return exec(match, id, names, types, matchers);
22
22
  },
23
23
  errors: [1, ...(errors || [])].map((n) => nodes[n]),
24
24
  layouts: [0, ...(layouts || [])].map(create_layout_loader),
@@ -67,7 +67,7 @@ export async function respond(request, options, state) {
67
67
  const match = candidate.pattern.exec(decoded);
68
68
  if (!match) continue;
69
69
 
70
- const matched = exec(match, candidate.names, candidate.types, matchers);
70
+ const matched = exec(match, candidate.id, candidate.names, candidate.types, matchers);
71
71
  if (matched) {
72
72
  route = candidate;
73
73
  params = decode_params(matched);
@@ -16,10 +16,7 @@ export function parse_route_id(id) {
16
16
  id === '/'
17
17
  ? /^\/$/
18
18
  : new RegExp(
19
- `^${id
20
- .split(/(?:\/|$)/)
21
- .slice(1)
22
- .filter(affects_path)
19
+ `^${get_route_segments(id)
23
20
  .map((segment, i, segments) => {
24
21
  const decoded_segment = decodeURIComponent(segment);
25
22
  // special case — /[...rest]/ could contain zero segments
@@ -98,19 +95,32 @@ export function parse_route_id(id) {
98
95
  * Returns `false` for `(group)` segments
99
96
  * @param {string} segment
100
97
  */
101
- export function affects_path(segment) {
98
+ function affects_path(segment) {
102
99
  return !/^\([^)]+\)$/.test(segment);
103
100
  }
104
101
 
102
+ /**
103
+ * Splits a route id into its segments, removing segments that
104
+ * don't affect the path (i.e. groups). The root route is represented by `/`
105
+ * and will be returned as `['']`.
106
+ * @param {string} route
107
+ * @returns string[]
108
+ */
109
+ export function get_route_segments(route) {
110
+ return route.slice(1).split('/').filter(affects_path);
111
+ }
112
+
105
113
  /**
106
114
  * @param {RegExpMatchArray} match
115
+ * @param {string} routeId
107
116
  * @param {string[]} names
108
117
  * @param {string[]} types
109
118
  * @param {Record<string, import('types').ParamMatcher>} matchers
110
119
  */
111
- export function exec(match, names, types, matchers) {
120
+ export function exec(match, routeId, names, types, matchers) {
112
121
  /** @type {Record<string, string>} */
113
122
  const params = {};
123
+ let last_type_idx = -1;
114
124
 
115
125
  for (let i = 0; i < names.length; i += 1) {
116
126
  const name = names[i];
@@ -121,7 +131,12 @@ export function exec(match, names, types, matchers) {
121
131
  const matcher = matchers[type];
122
132
  if (!matcher) throw new Error(`Missing "${type}" param matcher`); // TODO do this ahead of time?
123
133
 
124
- if (!matcher(value)) return;
134
+ last_type_idx = routeId.indexOf(`=${type}`, last_type_idx + 1);
135
+ const is_empty_optional_param =
136
+ !value &&
137
+ // a param without a value can only be an optional or rest param
138
+ routeId.lastIndexOf('[[', last_type_idx) > routeId.lastIndexOf('[...', last_type_idx);
139
+ if (!is_empty_optional_param && !matcher(value)) return;
125
140
  }
126
141
 
127
142
  params[name] = value;