@sveltejs/kit 1.0.0-next.291 → 1.0.0-next.292

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.
@@ -0,0 +1,56 @@
1
+ const absolute = /^([a-z]+:)?\/?\//;
2
+ const scheme = /^[a-z]+:/;
3
+
4
+ /**
5
+ * @param {string} base
6
+ * @param {string} path
7
+ */
8
+ function resolve(base, path) {
9
+ if (scheme.test(path)) return path;
10
+
11
+ const base_match = absolute.exec(base);
12
+ const path_match = absolute.exec(path);
13
+
14
+ if (!base_match) {
15
+ throw new Error(`bad base path: "${base}"`);
16
+ }
17
+
18
+ const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
19
+ const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
20
+
21
+ baseparts.pop();
22
+
23
+ for (let i = 0; i < pathparts.length; i += 1) {
24
+ const part = pathparts[i];
25
+ if (part === '.') continue;
26
+ else if (part === '..') baseparts.pop();
27
+ else baseparts.push(part);
28
+ }
29
+
30
+ const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
31
+
32
+ return `${prefix}${baseparts.join('/')}`;
33
+ }
34
+
35
+ /** @param {string} path */
36
+ function is_root_relative(path) {
37
+ return path[0] === '/' && path[1] !== '/';
38
+ }
39
+
40
+ /**
41
+ * @param {string} path
42
+ * @param {import('types').TrailingSlash} trailing_slash
43
+ */
44
+ function normalize_path(path, trailing_slash) {
45
+ if (path === '/' || trailing_slash === 'ignore') return path;
46
+
47
+ if (trailing_slash === 'never') {
48
+ return path.endsWith('/') ? path.slice(0, -1) : path;
49
+ } else if (trailing_slash === 'always' && /\/[^./]+$/.test(path)) {
50
+ return path + '/';
51
+ }
52
+
53
+ return path;
54
+ }
55
+
56
+ export { is_root_relative as i, normalize_path as n, resolve as r };
package/dist/cli.js CHANGED
@@ -4,7 +4,6 @@ import { exec as exec$1 } from 'child_process';
4
4
  import { createConnection, createServer } from 'net';
5
5
  import fs__default from 'fs';
6
6
  import * as url from 'url';
7
- import { fileURLToPath } from 'url';
8
7
  import { networkInterfaces, release } from 'os';
9
8
 
10
9
  let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
@@ -214,115 +213,6 @@ function check_weird(port) {
214
213
  });
215
214
  }
216
215
 
217
- /** @param {string} dir */
218
- function mkdirp(dir) {
219
- try {
220
- fs__default.mkdirSync(dir, { recursive: true });
221
- } catch (/** @type {any} */ e) {
222
- if (e.code === 'EEXIST') return;
223
- throw e;
224
- }
225
- }
226
-
227
- /** @param {string} path */
228
- function rimraf(path) {
229
- (fs__default.rmSync || fs__default.rmdirSync)(path, { recursive: true, force: true });
230
- }
231
-
232
- /**
233
- * @param {string} source
234
- * @param {string} target
235
- * @param {{
236
- * filter?: (basename: string) => boolean;
237
- * replace?: Record<string, string>;
238
- * }} opts
239
- */
240
- function copy(source, target, opts = {}) {
241
- if (!fs__default.existsSync(source)) return [];
242
-
243
- /** @type {string[]} */
244
- const files = [];
245
-
246
- const prefix = posixify(target) + '/';
247
-
248
- const regex = opts.replace
249
- ? new RegExp(`\\b(${Object.keys(opts.replace).join('|')})\\b`, 'g')
250
- : null;
251
-
252
- /**
253
- * @param {string} from
254
- * @param {string} to
255
- */
256
- function go(from, to) {
257
- if (opts.filter && !opts.filter(path__default.basename(from))) return;
258
-
259
- const stats = fs__default.statSync(from);
260
-
261
- if (stats.isDirectory()) {
262
- fs__default.readdirSync(from).forEach((file) => {
263
- go(path__default.join(from, file), path__default.join(to, file));
264
- });
265
- } else {
266
- mkdirp(path__default.dirname(to));
267
-
268
- if (opts.replace) {
269
- const data = fs__default.readFileSync(from, 'utf-8');
270
- fs__default.writeFileSync(
271
- to,
272
- data.replace(
273
- /** @type {RegExp} */ (regex),
274
- (match, key) => /** @type {Record<string, string>} */ (opts.replace)[key]
275
- )
276
- );
277
- } else {
278
- fs__default.copyFileSync(from, to);
279
- }
280
-
281
- files.push(to === target ? posixify(path__default.basename(to)) : posixify(to).replace(prefix, ''));
282
- }
283
- }
284
-
285
- go(source, target);
286
-
287
- return files;
288
- }
289
-
290
- /**
291
- * Get a list of all files in a directory
292
- * @param {string} cwd - the directory to walk
293
- * @param {boolean} [dirs] - whether to include directories in the result
294
- */
295
- function walk(cwd, dirs = false) {
296
- /** @type {string[]} */
297
- const all_files = [];
298
-
299
- /** @param {string} dir */
300
- function walk_dir(dir) {
301
- const files = fs__default.readdirSync(path__default.join(cwd, dir));
302
-
303
- for (const file of files) {
304
- const joined = path__default.join(dir, file);
305
- const stats = fs__default.statSync(path__default.join(cwd, joined));
306
- if (stats.isDirectory()) {
307
- if (dirs) all_files.push(joined);
308
- walk_dir(joined);
309
- } else {
310
- all_files.push(joined);
311
- }
312
- }
313
- }
314
-
315
- return walk_dir(''), all_files;
316
- }
317
-
318
- /** @param {string} str */
319
- function posixify(str) {
320
- return str.replace(/\\/g, '/');
321
- }
322
-
323
- const __filename = fileURLToPath(import.meta.url);
324
- const __dirname = path__default.dirname(__filename);
325
-
326
216
  const get_runtime_path = /** @param {import('types').ValidatedConfig} config */ (config) =>
327
217
  posixify_path(path__default.join(config.kit.outDir, 'runtime'))
328
218
  ;
@@ -333,25 +223,6 @@ function posixify_path(str) {
333
223
  return `/${parsed.dir.slice(parsed.root.length).split(path__default.sep).join('/')}/${parsed.base}`;
334
224
  }
335
225
 
336
- /** @param {string} dest */
337
- function copy_assets(dest) {
338
- {
339
- let prefix = '..';
340
- do {
341
- // we jump through these hoops so that this function
342
- // works whether or not it's been bundled
343
- const resolved = path__default.resolve(__dirname, `${prefix}/assets`);
344
-
345
- if (fs__default.existsSync(resolved)) {
346
- copy(resolved, dest);
347
- return;
348
- }
349
-
350
- prefix = `../${prefix}`;
351
- } while (true); // eslint-disable-line
352
- }
353
- }
354
-
355
226
  function noop() {}
356
227
 
357
228
  /** @param {{ verbose: boolean }} opts */
@@ -401,7 +272,7 @@ function resolve_entry(entry) {
401
272
  return null;
402
273
  }
403
274
 
404
- /** @param {import('./create_app/index.js').ManifestData} manifest_data */
275
+ /** @param {import('types').ManifestData} manifest_data */
405
276
  function get_mime_lookup(manifest_data) {
406
277
  /** @type {Record<string, string>} */
407
278
  const mime = {};
@@ -526,6 +397,8 @@ const options = object(
526
397
  })
527
398
  }),
528
399
 
400
+ endpointExtensions: string_array(['.js', '.ts']),
401
+
529
402
  files: object({
530
403
  assets: string('static'),
531
404
  hooks: string(join('src', 'hooks')),
@@ -619,6 +492,7 @@ const options = object(
619
492
  (keypath) =>
620
493
  `${keypath} has been removed — it is now controlled by the trailingSlash option. See https://kit.svelte.dev/docs/configuration#trailingslash`
621
494
  ),
495
+ default: boolean(false),
622
496
  enabled: boolean(true),
623
497
  entries: validate(['*'], (input, keypath) => {
624
498
  if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
@@ -996,7 +870,7 @@ async function launch(port, https) {
996
870
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
997
871
  }
998
872
 
999
- const prog = sade('svelte-kit').version('1.0.0-next.291');
873
+ const prog = sade('svelte-kit').version('1.0.0-next.292');
1000
874
 
1001
875
  prog
1002
876
  .command('dev')
@@ -1048,8 +922,10 @@ prog
1048
922
  process.env.NODE_ENV = process.env.NODE_ENV || 'production';
1049
923
  const config = await load_config();
1050
924
 
925
+ const log = logger({ verbose });
926
+
1051
927
  const { build } = await import('./chunks/index2.js');
1052
- const build_data = await build(config);
928
+ const { build_data, prerendered } = await build(config, { log });
1053
929
 
1054
930
  console.log(
1055
931
  `\nRun ${$.bold().cyan('npm run preview')} to preview your production build locally.`
@@ -1057,7 +933,7 @@ prog
1057
933
 
1058
934
  if (config.kit.adapter) {
1059
935
  const { adapt } = await import('./chunks/index4.js');
1060
- await adapt(config, build_data, { verbose });
936
+ await adapt(config, build_data, prerendered, { log });
1061
937
 
1062
938
  // this is necessary to close any open db connections, etc
1063
939
  process.exit(0);
@@ -1117,6 +993,19 @@ prog
1117
993
  }
1118
994
  });
1119
995
 
996
+ prog
997
+ .command('sync')
998
+ .describe('Synchronise generated files')
999
+ .action(async () => {
1000
+ try {
1001
+ const config = await load_config();
1002
+ const sync = await import('./chunks/sync.js');
1003
+ sync.all(config);
1004
+ } catch (error) {
1005
+ handle_error(error);
1006
+ }
1007
+ });
1008
+
1120
1009
  prog.parse(process.argv, { unknown: (arg) => `Unknown option: ${arg}` });
1121
1010
 
1122
1011
  /** @param {number} port */
@@ -1154,7 +1043,7 @@ async function check_port(port) {
1154
1043
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1155
1044
  if (open) launch(port, https);
1156
1045
 
1157
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.291'}\n`));
1046
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.292'}\n`));
1158
1047
 
1159
1048
  const protocol = https ? 'https:' : 'http:';
1160
1049
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
@@ -1191,4 +1080,4 @@ function welcome({ port, host, https, open, loose, allow, cwd }) {
1191
1080
  console.log('\n');
1192
1081
  }
1193
1082
 
1194
- export { $, get_mime_lookup as a, copy_assets as b, coalesce_to_error as c, get_aliases as d, print_config_conflicts as e, rimraf as f, get_runtime_path as g, copy as h, logger as i, load_template as l, mkdirp as m, posixify as p, resolve_entry as r, walk as w };
1083
+ export { $, get_mime_lookup as a, get_aliases as b, coalesce_to_error as c, get_runtime_path as g, load_template as l, print_config_conflicts as p, resolve_entry as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.291",
3
+ "version": "1.0.0-next.292",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -79,29 +79,15 @@
79
79
  "build": "rollup -c && node scripts/cp.js src/runtime/components assets/components && npm run types",
80
80
  "dev": "rollup -cw",
81
81
  "lint": "eslint --ignore-path .gitignore --ignore-pattern \"src/packaging/test/**\" \"{src,test}/**/*.{ts,mjs,js,svelte}\" && npm run check-format",
82
- "check": "tsc && npm run check:integration && npm run check:prerendering",
83
- "check:integration": "npm run check:integration:amp && npm run check:integration:basics && npm run check:integration:options && npm run check:integration:options-2",
84
- "check:integration:amp": "cd test/apps/amp && pnpm check",
85
- "check:integration:basics": "cd test/apps/basics && pnpm check",
86
- "check:integration:options": "cd test/apps/options && pnpm check",
87
- "check:integration:options-2": "cd test/apps/options-2 && pnpm check",
88
- "check:prerendering": "npm run check:prerendering:basics && npm run check:prerendering:options",
89
- "check:prerendering:basics": "cd test/prerendering/basics && pnpm check",
90
- "check:prerendering:options": "cd test/prerendering/options && pnpm check",
82
+ "check": "tsc",
83
+ "check:all": "tsc && pnpm run -r check --filter ./",
91
84
  "format": "npm run check-format -- --write",
92
85
  "check-format": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore",
93
- "test": "npm run test:unit && npm run test:typings && npm run test:packaging && npm run test:prerendering && npm run test:integration",
86
+ "test": "npm run test:unit && npm run test:typings && npm run test:packaging",
87
+ "test:all": "pnpm run -r test --workspace-concurrency 1 --filter ./",
94
88
  "test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
95
89
  "test:typings": "tsc --project test/typings",
96
- "test:prerendering": "pnpm test:prerendering:basics && pnpm test:prerendering:options",
97
- "test:prerendering:basics": "cd test/prerendering/basics && pnpm test",
98
- "test:prerendering:options": "cd test/prerendering/options && pnpm test",
99
90
  "test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
100
- "test:integration": "pnpm test:integration:amp && pnpm test:integration:basics && pnpm test:integration:options && pnpm test:integration:options-2",
101
- "test:integration:amp": "cd test/apps/amp && pnpm test",
102
- "test:integration:basics": "cd test/apps/basics && pnpm test",
103
- "test:integration:options": "cd test/apps/options && pnpm test",
104
- "test:integration:options-2": "cd test/apps/options-2 && pnpm test",
105
91
  "types": "node scripts/extract-types.js"
106
92
  }
107
93
  }
@@ -228,6 +228,10 @@ declare module '$service-worker' {
228
228
  * An array of URL strings representing the files in your static directory, or whatever directory is specified by `config.kit.files.assets`. You can customize which files are included from `static` directory using [`config.kit.serviceWorker.files`](/docs/configuration)
229
229
  */
230
230
  export const files: string[];
231
+ /**
232
+ * An array of pathnames corresponding to prerendered pages and endpoints.
233
+ */
234
+ export const prerendered: string[];
231
235
  /**
232
236
  * The result of calling `Date.now()` at build time. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches.
233
237
  */
package/types/index.d.ts CHANGED
@@ -41,6 +41,7 @@ export interface Config {
41
41
  mode?: 'hash' | 'nonce' | 'auto';
42
42
  directives?: CspDirectives;
43
43
  };
44
+ endpointExtensions?: string[];
44
45
  files?: {
45
46
  assets?: string;
46
47
  hooks?: string;
@@ -69,6 +70,7 @@ export interface Config {
69
70
  prerender?: {
70
71
  concurrency?: number;
71
72
  crawl?: boolean;
73
+ default?: boolean;
72
74
  enabled?: boolean;
73
75
  entries?: string[];
74
76
  onError?: PrerenderOnErrorValue;
@@ -145,7 +147,7 @@ export interface Page<Params extends Record<string, string> = Record<string, str
145
147
  * that method. Note that since 'delete' is a reserved word in
146
148
  * JavaScript, delete handles are called `del` instead.
147
149
  *
148
- * Note that you can use [generated types](/docs/types#generated)
150
+ * Note that you can use [generated types](/docs/types#generated-types)
149
151
  * instead of manually specifying the `Params` generic argument.
150
152
  */
151
153
  export interface RequestHandler<Params = Record<string, string>, Output extends Body = Body> {
@@ -14,6 +14,7 @@ import {
14
14
  HttpMethod,
15
15
  JSONObject,
16
16
  MaybePromise,
17
+ Prerendered,
17
18
  RequestEvent,
18
19
  RequestOptions,
19
20
  ResolveOptions,
@@ -63,15 +64,13 @@ export interface BuildData {
63
64
  methods: Record<string, HttpMethod[]>;
64
65
  vite_manifest: import('vite').Manifest;
65
66
  };
66
- static: string[];
67
- entries: string[];
68
67
  }
69
68
 
70
69
  export type CSRComponent = any; // TODO
71
70
 
72
71
  export type CSRComponentLoader = () => Promise<CSRComponent>;
73
72
 
74
- export type CSRRoute = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?, HasShadow?];
73
+ export type CSRRoute = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?, ShadowKey?];
75
74
 
76
75
  export interface EndpointData {
77
76
  type: 'endpoint';
@@ -84,8 +83,6 @@ export interface EndpointData {
84
83
 
85
84
  export type GetParams = (match: RegExpExecArray) => Record<string, string>;
86
85
 
87
- type HasShadow = 1;
88
-
89
86
  export interface Hooks {
90
87
  externalFetch: ExternalFetch;
91
88
  getSession: GetSession;
@@ -149,8 +146,8 @@ export interface PrerenderDependency {
149
146
  }
150
147
 
151
148
  export interface PrerenderOptions {
152
- fallback?: string;
153
- all: boolean;
149
+ fallback?: boolean;
150
+ default: boolean;
154
151
  dependencies: Map<string, PrerenderDependency>;
155
152
  }
156
153
 
@@ -179,6 +176,13 @@ export interface ShadowEndpointOutput<Output extends JSONObject = JSONObject> {
179
176
  body?: Output;
180
177
  }
181
178
 
179
+ /**
180
+ * The route key of a page with a matching endpoint — used to ensure the
181
+ * client loads data from the right endpoint during client-side navigation
182
+ * rather than a different route that happens to match the path
183
+ */
184
+ type ShadowKey = string;
185
+
182
186
  export interface ShadowRequestHandler<Output extends JSONObject = JSONObject> {
183
187
  (event: RequestEvent): MaybePromise<Either<ShadowEndpointOutput<Output>, Fallthrough>>;
184
188
  }
@@ -272,6 +276,7 @@ export interface SSROptions {
272
276
 
273
277
  export interface SSRPage {
274
278
  type: 'page';
279
+ key: string;
275
280
  pattern: RegExp;
276
281
  params: GetParams;
277
282
  shadow:
@@ -2,7 +2,7 @@
2
2
  // but which cannot be imported from `@sveltejs/kit`. Care should
3
3
  // be taken to avoid breaking changes when editing this file
4
4
 
5
- import { SSRNodeLoader, SSRRoute } from './internal';
5
+ import { SSRNodeLoader, SSRRoute, ValidatedConfig } from './internal';
6
6
 
7
7
  export interface AdapterEntry {
8
8
  /**
@@ -35,8 +35,8 @@ export interface Builder {
35
35
  rimraf(dir: string): void;
36
36
  mkdirp(dir: string): void;
37
37
 
38
- appDir: string;
39
- trailingSlash: TrailingSlash;
38
+ config: ValidatedConfig;
39
+ prerendered: Prerendered;
40
40
 
41
41
  /**
42
42
  * Create entry points that map to individual functions
@@ -56,6 +56,16 @@ export interface Builder {
56
56
  * @returns an array of paths corresponding to the files that have been created by the copy
57
57
  */
58
58
  writeClient(dest: string): string[];
59
+ /**
60
+ *
61
+ * @param dest
62
+ */
63
+ writePrerendered(
64
+ dest: string,
65
+ opts?: {
66
+ fallback?: string;
67
+ }
68
+ ): string[];
59
69
  /**
60
70
  * @param dest the destination folder to which files should be copied
61
71
  * @returns an array of paths corresponding to the files that have been created by the copy
@@ -81,8 +91,6 @@ export interface Builder {
81
91
  replace?: Record<string, string>;
82
92
  }
83
93
  ): string[];
84
-
85
- prerender(options: { all?: boolean; dest: string; fallback?: string }): Promise<Prerendered>;
86
94
  }
87
95
 
88
96
  // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts