@sveltejs/kit 1.0.0-next.296 → 1.0.0-next.299
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/assets/client/start.js +203 -111
- package/assets/server/index.js +196 -146
- package/dist/chunks/index.js +94 -83
- package/dist/chunks/index2.js +17 -4
- package/dist/chunks/index3.js +31 -30
- package/dist/chunks/index4.js +1 -0
- package/dist/chunks/index5.js +10 -1
- package/dist/chunks/routing.js +39 -0
- package/dist/chunks/sync.js +127 -71
- package/dist/cli.js +7 -8
- package/package.json +1 -1
- package/types/index.d.ts +25 -19
- package/types/internal.d.ts +29 -25
- package/types/private.d.ts +17 -17
package/dist/chunks/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { update, init } from './sync.js';
|
|
|
11
11
|
import { getRequest, setResponse } from '../node.js';
|
|
12
12
|
import { sequence } from '../hooks.js';
|
|
13
13
|
import { p as posixify } from './filesystem.js';
|
|
14
|
+
import { p as parse_route_id } from './routing.js';
|
|
14
15
|
import 'sade';
|
|
15
16
|
import 'child_process';
|
|
16
17
|
import 'net';
|
|
@@ -116,12 +117,15 @@ async function create_plugin(config, cwd) {
|
|
|
116
117
|
};
|
|
117
118
|
}),
|
|
118
119
|
routes: manifest_data.routes.map((route) => {
|
|
120
|
+
const { pattern, names, types } = parse_route_id(route.id);
|
|
121
|
+
|
|
119
122
|
if (route.type === 'page') {
|
|
120
123
|
return {
|
|
121
124
|
type: 'page',
|
|
122
|
-
|
|
123
|
-
pattern
|
|
124
|
-
|
|
125
|
+
id: route.id,
|
|
126
|
+
pattern,
|
|
127
|
+
names,
|
|
128
|
+
types,
|
|
125
129
|
shadow: route.shadow
|
|
126
130
|
? async () => {
|
|
127
131
|
const url = path__default.resolve(cwd, /** @type {string} */ (route.shadow));
|
|
@@ -135,14 +139,34 @@ async function create_plugin(config, cwd) {
|
|
|
135
139
|
|
|
136
140
|
return {
|
|
137
141
|
type: 'endpoint',
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
id: route.id,
|
|
143
|
+
pattern,
|
|
144
|
+
names,
|
|
145
|
+
types,
|
|
140
146
|
load: async () => {
|
|
141
147
|
const url = path__default.resolve(cwd, route.file);
|
|
142
148
|
return await vite.ssrLoadModule(url);
|
|
143
149
|
}
|
|
144
150
|
};
|
|
145
|
-
})
|
|
151
|
+
}),
|
|
152
|
+
validators: async () => {
|
|
153
|
+
/** @type {Record<string, import('types').ParamValidator>} */
|
|
154
|
+
const validators = {};
|
|
155
|
+
|
|
156
|
+
for (const key in manifest_data.validators) {
|
|
157
|
+
const file = manifest_data.validators[key];
|
|
158
|
+
const url = path__default.resolve(cwd, file);
|
|
159
|
+
const module = await vite.ssrLoadModule(url);
|
|
160
|
+
|
|
161
|
+
if (module.validate) {
|
|
162
|
+
validators[key] = module.validate;
|
|
163
|
+
} else {
|
|
164
|
+
throw new Error(`${file} does not export a \`validate\` function`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return validators;
|
|
169
|
+
}
|
|
146
170
|
}
|
|
147
171
|
};
|
|
148
172
|
}
|
|
@@ -168,7 +192,7 @@ async function create_plugin(config, cwd) {
|
|
|
168
192
|
update_manifest();
|
|
169
193
|
|
|
170
194
|
vite.watcher.on('add', update_manifest);
|
|
171
|
-
vite.watcher.on('
|
|
195
|
+
vite.watcher.on('unlink', update_manifest);
|
|
172
196
|
|
|
173
197
|
const assets = config.kit.paths.assets ? SVELTE_KIT_ASSETS : config.kit.paths.base;
|
|
174
198
|
const asset_server = sirv(config.kit.files.assets, {
|
|
@@ -271,62 +295,72 @@ async function create_plugin(config, cwd) {
|
|
|
271
295
|
|
|
272
296
|
const template = load_template(cwd, config);
|
|
273
297
|
|
|
274
|
-
const rendered = await respond(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
298
|
+
const rendered = await respond(
|
|
299
|
+
request,
|
|
300
|
+
{
|
|
301
|
+
amp: config.kit.amp,
|
|
302
|
+
csp: config.kit.csp,
|
|
303
|
+
dev: true,
|
|
304
|
+
floc: config.kit.floc,
|
|
305
|
+
get_stack: (error) => {
|
|
306
|
+
return fix_stack_trace(error);
|
|
307
|
+
},
|
|
308
|
+
handle_error: (error, event) => {
|
|
309
|
+
hooks.handleError({
|
|
310
|
+
error: new Proxy(error, {
|
|
311
|
+
get: (target, property) => {
|
|
312
|
+
if (property === 'stack') {
|
|
313
|
+
return fix_stack_trace(error);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return Reflect.get(target, property, target);
|
|
288
317
|
}
|
|
289
|
-
|
|
290
|
-
|
|
318
|
+
}),
|
|
319
|
+
event,
|
|
320
|
+
|
|
321
|
+
// TODO remove for 1.0
|
|
322
|
+
// @ts-expect-error
|
|
323
|
+
get request() {
|
|
324
|
+
throw new Error(
|
|
325
|
+
'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
|
|
326
|
+
);
|
|
291
327
|
}
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
hooks,
|
|
331
|
+
hydrate: config.kit.browser.hydrate,
|
|
332
|
+
manifest,
|
|
333
|
+
method_override: config.kit.methodOverride,
|
|
334
|
+
paths: {
|
|
335
|
+
base: config.kit.paths.base,
|
|
336
|
+
assets
|
|
337
|
+
},
|
|
338
|
+
prefix: '',
|
|
339
|
+
prerender: config.kit.prerender.enabled,
|
|
340
|
+
read: (file) => fs__default.readFileSync(path__default.join(config.kit.files.assets, file)),
|
|
341
|
+
root,
|
|
342
|
+
router: config.kit.browser.router,
|
|
343
|
+
template: ({ head, body, assets, nonce }) => {
|
|
344
|
+
return (
|
|
345
|
+
template
|
|
346
|
+
.replace(/%svelte\.assets%/g, assets)
|
|
347
|
+
.replace(/%svelte\.nonce%/g, nonce)
|
|
348
|
+
// head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
|
|
349
|
+
.replace('%svelte.head%', () => head)
|
|
350
|
+
.replace('%svelte.body%', () => body)
|
|
351
|
+
);
|
|
352
|
+
},
|
|
353
|
+
template_contains_nonce: template.includes('%svelte.nonce%'),
|
|
354
|
+
trailing_slash: config.kit.trailingSlash
|
|
303
355
|
},
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
prefix: '',
|
|
313
|
-
prerender: config.kit.prerender.enabled,
|
|
314
|
-
read: (file) => fs__default.readFileSync(path__default.join(config.kit.files.assets, file)),
|
|
315
|
-
root,
|
|
316
|
-
router: config.kit.browser.router,
|
|
317
|
-
template: ({ head, body, assets, nonce }) => {
|
|
318
|
-
return (
|
|
319
|
-
template
|
|
320
|
-
.replace(/%svelte\.assets%/g, assets)
|
|
321
|
-
.replace(/%svelte\.nonce%/g, nonce)
|
|
322
|
-
// head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
|
|
323
|
-
.replace('%svelte.head%', () => head)
|
|
324
|
-
.replace('%svelte.body%', () => body)
|
|
325
|
-
);
|
|
326
|
-
},
|
|
327
|
-
template_contains_nonce: template.includes('%svelte.nonce%'),
|
|
328
|
-
trailing_slash: config.kit.trailingSlash
|
|
329
|
-
});
|
|
356
|
+
{
|
|
357
|
+
getClientAddress: () => {
|
|
358
|
+
const { remoteAddress } = req.socket;
|
|
359
|
+
if (remoteAddress) return remoteAddress;
|
|
360
|
+
throw new Error('Could not determine clientAddress');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
);
|
|
330
364
|
|
|
331
365
|
if (rendered) {
|
|
332
366
|
setResponse(res, rendered);
|
|
@@ -345,29 +379,6 @@ async function create_plugin(config, cwd) {
|
|
|
345
379
|
};
|
|
346
380
|
}
|
|
347
381
|
|
|
348
|
-
/** @param {string[]} array */
|
|
349
|
-
function get_params(array) {
|
|
350
|
-
// given an array of params like `['x', 'y', 'z']` for
|
|
351
|
-
// src/routes/[x]/[y]/[z]/svelte, create a function
|
|
352
|
-
// that turns a RegExpExecArray into ({ x, y, z })
|
|
353
|
-
|
|
354
|
-
/** @param {RegExpExecArray} match */
|
|
355
|
-
const fn = (match) => {
|
|
356
|
-
/** @type {Record<string, string>} */
|
|
357
|
-
const params = {};
|
|
358
|
-
array.forEach((key, i) => {
|
|
359
|
-
if (key.startsWith('...')) {
|
|
360
|
-
params[key.slice(3)] = match[i + 1] || '';
|
|
361
|
-
} else {
|
|
362
|
-
params[key] = match[i + 1];
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
return params;
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
return fn;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
382
|
/** @param {import('http').ServerResponse} res */
|
|
372
383
|
function not_found(res) {
|
|
373
384
|
res.statusCode = 404;
|
package/dist/chunks/index2.js
CHANGED
|
@@ -15,6 +15,7 @@ import 'sade';
|
|
|
15
15
|
import 'child_process';
|
|
16
16
|
import 'net';
|
|
17
17
|
import 'os';
|
|
18
|
+
import './routing.js';
|
|
18
19
|
import 'node:http';
|
|
19
20
|
import 'node:https';
|
|
20
21
|
import 'node:zlib';
|
|
@@ -145,7 +146,6 @@ async function create_build(config) {
|
|
|
145
146
|
* @param {import('vite').Manifest} manifest
|
|
146
147
|
* @param {Set<string>} css
|
|
147
148
|
* @param {Set<string>} js
|
|
148
|
-
* @returns
|
|
149
149
|
*/
|
|
150
150
|
function find_deps(file, manifest, js, css) {
|
|
151
151
|
const chunk = manifest[file];
|
|
@@ -287,7 +287,6 @@ async function build_client({
|
|
|
287
287
|
* runtime: string;
|
|
288
288
|
* template: string;
|
|
289
289
|
* }} opts
|
|
290
|
-
* @returns
|
|
291
290
|
*/
|
|
292
291
|
const server_template = ({ config, hooks, has_service_worker, runtime, template }) => `
|
|
293
292
|
import root from '__GENERATED__/root.svelte';
|
|
@@ -424,7 +423,7 @@ async function build_server(
|
|
|
424
423
|
}
|
|
425
424
|
});
|
|
426
425
|
|
|
427
|
-
// ...and every component used by pages
|
|
426
|
+
// ...and every component used by pages...
|
|
428
427
|
manifest_data.components.forEach((file) => {
|
|
429
428
|
const resolved = path__default.resolve(cwd, file);
|
|
430
429
|
const relative = path__default.relative(config.kit.files.routes, resolved);
|
|
@@ -435,6 +434,12 @@ async function build_server(
|
|
|
435
434
|
input[name] = resolved;
|
|
436
435
|
});
|
|
437
436
|
|
|
437
|
+
// ...and every validator
|
|
438
|
+
Object.entries(manifest_data.validators).forEach(([key, file]) => {
|
|
439
|
+
const name = posixify(path__default.join('entries/validators', key));
|
|
440
|
+
input[name] = path__default.resolve(cwd, file);
|
|
441
|
+
});
|
|
442
|
+
|
|
438
443
|
/** @type {(file: string) => string} */
|
|
439
444
|
const app_relative = (file) => {
|
|
440
445
|
const relative_file = path__default.relative(build_dir, path__default.resolve(cwd, file));
|
|
@@ -500,6 +505,8 @@ async function build_server(
|
|
|
500
505
|
|
|
501
506
|
print_config_conflicts(conflicts, 'kit.vite.', 'build_server');
|
|
502
507
|
|
|
508
|
+
process.env.VITE_SVELTEKIT_ADAPTER_NAME = config.kit.adapter?.name;
|
|
509
|
+
|
|
503
510
|
const { chunks } = await create_build(merged_config);
|
|
504
511
|
|
|
505
512
|
/** @type {import('vite').Manifest} */
|
|
@@ -575,7 +582,6 @@ const method_names = {
|
|
|
575
582
|
};
|
|
576
583
|
|
|
577
584
|
/**
|
|
578
|
-
*
|
|
579
585
|
* @param {string} cwd
|
|
580
586
|
* @param {import('rollup').OutputChunk[]} output
|
|
581
587
|
* @param {import('types').ManifestData} manifest_data
|
|
@@ -1073,6 +1079,7 @@ async function prerender({ config, entries, files, log }) {
|
|
|
1073
1079
|
const dependencies = new Map();
|
|
1074
1080
|
|
|
1075
1081
|
const response = await server.respond(new Request(`http://sveltekit-prerender${encoded}`), {
|
|
1082
|
+
getClientAddress,
|
|
1076
1083
|
prerender: {
|
|
1077
1084
|
default: config.kit.prerender.default,
|
|
1078
1085
|
dependencies
|
|
@@ -1209,6 +1216,7 @@ async function prerender({ config, entries, files, log }) {
|
|
|
1209
1216
|
}
|
|
1210
1217
|
|
|
1211
1218
|
const rendered = await server.respond(new Request('http://sveltekit-prerender/[fallback]'), {
|
|
1219
|
+
getClientAddress,
|
|
1212
1220
|
prerender: {
|
|
1213
1221
|
fallback: true,
|
|
1214
1222
|
default: false,
|
|
@@ -1223,6 +1231,11 @@ async function prerender({ config, entries, files, log }) {
|
|
|
1223
1231
|
return prerendered;
|
|
1224
1232
|
}
|
|
1225
1233
|
|
|
1234
|
+
/** @return {string} */
|
|
1235
|
+
function getClientAddress() {
|
|
1236
|
+
throw new Error('Cannot read clientAddress during prerendering');
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1226
1239
|
/**
|
|
1227
1240
|
* @param {import('types').ValidatedConfig} config
|
|
1228
1241
|
* @param {{ log: import('types').Logger }} opts
|
package/dist/chunks/index3.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { s } from './misc.js';
|
|
2
|
+
import { p as parse_route_id } from './routing.js';
|
|
2
3
|
import { a as get_mime_lookup } from '../cli.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -41,10 +42,13 @@ function generate_manifest({ build_data, relative_path, routes, format = 'esm' }
|
|
|
41
42
|
});
|
|
42
43
|
|
|
43
44
|
/** @type {(path: string) => string} */
|
|
44
|
-
const
|
|
45
|
+
const load =
|
|
45
46
|
format === 'esm'
|
|
46
|
-
? (path) => `
|
|
47
|
-
: (path) => `
|
|
47
|
+
? (path) => `import('${path}')`
|
|
48
|
+
: (path) => `Promise.resolve().then(() => require('${path}'))`;
|
|
49
|
+
|
|
50
|
+
/** @type {(path: string) => string} */
|
|
51
|
+
const loader = (path) => `() => ${load(path)}`;
|
|
48
52
|
|
|
49
53
|
const assets = build_data.manifest_data.assets.map((asset) => asset.file);
|
|
50
54
|
if (build_data.service_worker) {
|
|
@@ -54,6 +58,8 @@ function generate_manifest({ build_data, relative_path, routes, format = 'esm' }
|
|
|
54
58
|
/** @param {string} id */
|
|
55
59
|
const get_index = (id) => id && /** @type {LookupEntry} */ (bundled_nodes.get(id)).index;
|
|
56
60
|
|
|
61
|
+
const validators = new Set();
|
|
62
|
+
|
|
57
63
|
// prettier-ignore
|
|
58
64
|
return `{
|
|
59
65
|
appDir: ${s(build_data.app_dir)},
|
|
@@ -62,18 +68,25 @@ function generate_manifest({ build_data, relative_path, routes, format = 'esm' }
|
|
|
62
68
|
_: {
|
|
63
69
|
entry: ${s(build_data.client.entry)},
|
|
64
70
|
nodes: [
|
|
65
|
-
${Array.from(bundled_nodes.values()).map(node =>
|
|
71
|
+
${Array.from(bundled_nodes.values()).map(node => loader(node.path)).join(',\n\t\t\t\t')}
|
|
66
72
|
],
|
|
67
73
|
routes: [
|
|
68
74
|
${routes.map(route => {
|
|
75
|
+
const { pattern, names, types } = parse_route_id(route.id);
|
|
76
|
+
|
|
77
|
+
types.forEach(type => {
|
|
78
|
+
if (type) validators.add(type);
|
|
79
|
+
});
|
|
80
|
+
|
|
69
81
|
if (route.type === 'page') {
|
|
70
82
|
return `{
|
|
71
83
|
type: 'page',
|
|
72
|
-
|
|
73
|
-
pattern: ${
|
|
74
|
-
|
|
84
|
+
id: ${s(route.id)},
|
|
85
|
+
pattern: ${pattern},
|
|
86
|
+
names: ${s(names)},
|
|
87
|
+
types: ${s(types)},
|
|
75
88
|
path: ${route.path ? s(route.path) : null},
|
|
76
|
-
shadow: ${route.shadow ?
|
|
89
|
+
shadow: ${route.shadow ? loader(`${relative_path}/${build_data.server.vite_manifest[route.shadow].file}`) : null},
|
|
77
90
|
a: ${s(route.a.map(get_index))},
|
|
78
91
|
b: ${s(route.b.map(get_index))}
|
|
79
92
|
}`.replace(/^\t\t/gm, '');
|
|
@@ -86,33 +99,21 @@ function generate_manifest({ build_data, relative_path, routes, format = 'esm' }
|
|
|
86
99
|
|
|
87
100
|
return `{
|
|
88
101
|
type: 'endpoint',
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
id: ${s(route.id)},
|
|
103
|
+
pattern: ${pattern},
|
|
104
|
+
names: ${s(names)},
|
|
105
|
+
types: ${s(types)},
|
|
106
|
+
load: ${loader(`${relative_path}/${build_data.server.vite_manifest[route.file].file}`)}
|
|
92
107
|
}`.replace(/^\t\t/gm, '');
|
|
93
108
|
}
|
|
94
109
|
}).filter(Boolean).join(',\n\t\t\t\t')}
|
|
95
|
-
]
|
|
110
|
+
],
|
|
111
|
+
validators: async () => {
|
|
112
|
+
${Array.from(validators).map(type => `const { validate: ${type} } = await ${load(`${relative_path}/entries/validators/${type}.js`)}`).join('\n\t\t\t\t')}
|
|
113
|
+
return { ${Array.from(validators).join(', ')} };
|
|
114
|
+
}
|
|
96
115
|
}
|
|
97
116
|
}`.replace(/^\t/gm, '');
|
|
98
117
|
}
|
|
99
118
|
|
|
100
|
-
/** @param {string[]} array */
|
|
101
|
-
function get_params(array) {
|
|
102
|
-
// given an array of params like `['x', 'y', 'z']` for
|
|
103
|
-
// src/routes/[x]/[y]/[z]/svelte, create a function
|
|
104
|
-
// that turns a RexExpMatchArray into ({ x, y, z })
|
|
105
|
-
return array.length
|
|
106
|
-
? '(m) => ({ ' +
|
|
107
|
-
array
|
|
108
|
-
.map((param, i) => {
|
|
109
|
-
return param.startsWith('...')
|
|
110
|
-
? `${param.slice(3)}: m[${i + 1}] || ''`
|
|
111
|
-
: `${param}: m[${i + 1}]`;
|
|
112
|
-
})
|
|
113
|
-
.join(', ') +
|
|
114
|
-
'})'
|
|
115
|
-
: 'null';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
119
|
export { generate_manifest as g };
|
package/dist/chunks/index4.js
CHANGED
package/dist/chunks/index5.js
CHANGED
|
@@ -145,7 +145,16 @@ async function preview({ port, host, config, https: use_https = false }) {
|
|
|
145
145
|
return res.end(err.reason || 'Invalid request body');
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
setResponse(
|
|
148
|
+
setResponse(
|
|
149
|
+
res,
|
|
150
|
+
await server.respond(request, {
|
|
151
|
+
getClientAddress: () => {
|
|
152
|
+
const { remoteAddress } = req.socket;
|
|
153
|
+
if (remoteAddress) return remoteAddress;
|
|
154
|
+
throw new Error('Could not determine clientAddress');
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
);
|
|
149
158
|
}
|
|
150
159
|
]);
|
|
151
160
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** @param {string} key */
|
|
2
|
+
function parse_route_id(key) {
|
|
3
|
+
/** @type {string[]} */
|
|
4
|
+
const names = [];
|
|
5
|
+
|
|
6
|
+
/** @type {string[]} */
|
|
7
|
+
const types = [];
|
|
8
|
+
|
|
9
|
+
const pattern =
|
|
10
|
+
key === ''
|
|
11
|
+
? /^\/$/
|
|
12
|
+
: new RegExp(
|
|
13
|
+
`^${decodeURIComponent(key)
|
|
14
|
+
.split('/')
|
|
15
|
+
.map((segment) => {
|
|
16
|
+
// special case — /[...rest]/ could contain zero segments
|
|
17
|
+
const match = /^\[\.\.\.(\w+)(?:=\w+)?\]$/.exec(segment);
|
|
18
|
+
if (match) {
|
|
19
|
+
names.push(match[1]);
|
|
20
|
+
types.push(match[2]);
|
|
21
|
+
return '(?:/(.*))?';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
'/' +
|
|
26
|
+
segment.replace(/\[(\.\.\.)?(\w+)(?:=(\w+))?\]/g, (m, rest, name, type) => {
|
|
27
|
+
names.push(name);
|
|
28
|
+
types.push(type);
|
|
29
|
+
return rest ? '(.*?)' : '([^/]+?)';
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
|
+
})
|
|
33
|
+
.join('')}/?$`
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return { pattern, names, types };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { parse_route_id as p };
|