@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.20

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.
Files changed (192) hide show
  1. package/package.json +58 -36
  2. package/src/cli.js +14 -11
  3. package/src/constants.js +6 -1
  4. package/src/core/adapt/builder.js +54 -60
  5. package/src/core/adapt/index.js +2 -5
  6. package/src/core/config/index.js +141 -76
  7. package/src/core/config/options.js +260 -260
  8. package/src/core/config/types.d.ts +1 -1
  9. package/src/core/env.js +143 -13
  10. package/src/core/generate_manifest/index.js +18 -15
  11. package/src/core/postbuild/analyse.js +7 -19
  12. package/src/core/postbuild/crawl.js +22 -6
  13. package/src/core/postbuild/entities.js +8 -2
  14. package/src/core/postbuild/fallback.js +4 -2
  15. package/src/core/postbuild/prerender.js +193 -69
  16. package/src/core/postbuild/queue.js +2 -1
  17. package/src/core/sync/create_manifest_data/conflict.js +1 -1
  18. package/src/core/sync/create_manifest_data/index.js +72 -52
  19. package/src/core/sync/sync.js +35 -26
  20. package/src/core/sync/ts.js +1 -1
  21. package/src/core/sync/utils.js +22 -2
  22. package/src/core/sync/{write_non_ambient.js → write_app_types.js} +105 -56
  23. package/src/core/sync/write_client_manifest.js +13 -28
  24. package/src/core/sync/write_env.js +7 -5
  25. package/src/core/sync/write_server.js +25 -33
  26. package/src/core/sync/write_tsconfig/index.js +274 -0
  27. package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
  28. package/src/core/sync/write_tsconfig/utils.js +77 -0
  29. package/src/core/sync/write_tsconfig/validate.js +128 -0
  30. package/src/core/sync/write_types/index.js +119 -116
  31. package/src/core/utils.js +30 -5
  32. package/src/exports/env/index.js +77 -0
  33. package/src/exports/env/public.d.ts +55 -0
  34. package/src/exports/hooks/index.js +3 -9
  35. package/src/exports/hooks/public.d.ts +194 -0
  36. package/src/exports/hooks/sequence.js +9 -6
  37. package/src/exports/index.js +53 -20
  38. package/src/exports/internal/client.js +5 -0
  39. package/src/exports/internal/env.js +8 -5
  40. package/src/exports/internal/index.js +1 -90
  41. package/src/exports/internal/{event.js → server/event.js} +1 -2
  42. package/src/exports/internal/server/index.js +37 -0
  43. package/src/exports/internal/server/telemetry.js +95 -0
  44. package/src/exports/internal/shared.js +90 -0
  45. package/src/exports/node/index.js +64 -22
  46. package/src/exports/params/index.js +70 -0
  47. package/src/exports/params/public.d.ts +63 -0
  48. package/src/exports/public.d.ts +219 -1118
  49. package/src/exports/url.js +86 -0
  50. package/src/exports/vite/build/build_server.js +53 -64
  51. package/src/exports/vite/build/remote.js +24 -19
  52. package/src/exports/vite/build/utils.js +0 -8
  53. package/src/exports/vite/dev/index.js +199 -125
  54. package/src/exports/vite/index.js +1514 -833
  55. package/src/exports/vite/module_ids.js +2 -2
  56. package/src/exports/vite/preview/index.js +32 -24
  57. package/src/exports/vite/utils.js +83 -45
  58. package/src/pathname.js +55 -0
  59. package/src/runner.js +15 -0
  60. package/src/runtime/app/env/internal.js +4 -4
  61. package/src/runtime/app/env/types.d.ts +1 -1
  62. package/src/runtime/app/environment/index.js +3 -3
  63. package/src/runtime/app/{forms.js → forms/index.js} +73 -42
  64. package/src/runtime/app/forms/public.d.ts +2 -0
  65. package/src/runtime/app/forms/types.d.ts +56 -0
  66. package/src/runtime/app/internal/transport.js +53 -0
  67. package/src/runtime/app/manifest/index.js +1 -0
  68. package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
  69. package/src/runtime/app/navigation/public.d.ts +237 -0
  70. package/src/runtime/app/paths/client.js +37 -37
  71. package/src/runtime/app/paths/index.js +1 -1
  72. package/src/runtime/app/paths/internal/client.js +34 -2
  73. package/src/runtime/app/paths/internal/server.js +6 -23
  74. package/src/runtime/app/paths/internal.d.ts +3 -0
  75. package/src/runtime/app/paths/public.d.ts +1 -29
  76. package/src/runtime/app/paths/server.js +36 -17
  77. package/src/runtime/app/paths/types.d.ts +11 -19
  78. package/src/runtime/app/server/index.js +2 -2
  79. package/src/runtime/app/server/public.d.ts +519 -0
  80. package/src/runtime/app/server/remote/command.js +13 -11
  81. package/src/runtime/app/server/remote/form.js +61 -39
  82. package/src/runtime/app/server/remote/prerender.js +45 -45
  83. package/src/runtime/app/server/remote/query.js +106 -108
  84. package/src/runtime/app/server/remote/requested.js +27 -19
  85. package/src/runtime/app/server/remote/shared.js +75 -75
  86. package/src/runtime/app/service-worker/index.js +24 -0
  87. package/src/runtime/app/state/client.js +4 -2
  88. package/src/runtime/app/state/index.js +7 -5
  89. package/src/runtime/app/state/public.d.ts +72 -0
  90. package/src/runtime/app/state/server.js +3 -0
  91. package/src/runtime/app/stores.js +15 -78
  92. package/src/runtime/client/bundle.js +1 -1
  93. package/src/runtime/client/client-entry.js +3 -0
  94. package/src/runtime/client/client.js +1336 -648
  95. package/src/runtime/client/constants.js +3 -6
  96. package/src/runtime/client/entry.js +24 -3
  97. package/src/runtime/client/fetcher.js +25 -25
  98. package/src/runtime/client/ndjson.js +1 -1
  99. package/src/runtime/client/parse.js +1 -1
  100. package/src/runtime/client/payload.js +17 -0
  101. package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
  102. package/src/runtime/client/remote-functions/command.svelte.js +37 -61
  103. package/src/runtime/client/remote-functions/form.svelte.js +267 -178
  104. package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
  105. package/src/runtime/client/remote-functions/query/index.js +10 -17
  106. package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
  107. package/src/runtime/client/remote-functions/query/proxy.js +5 -5
  108. package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
  109. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  110. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
  111. package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
  112. package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
  113. package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
  114. package/src/runtime/client/snapshots.js +147 -0
  115. package/src/runtime/client/state.svelte.js +94 -55
  116. package/src/runtime/client/stream.js +3 -2
  117. package/src/runtime/client/types.d.ts +13 -9
  118. package/src/runtime/client/utils.js +22 -110
  119. package/src/runtime/components/root.svelte +56 -0
  120. package/src/runtime/env/dynamic/private.js +7 -0
  121. package/src/runtime/env/dynamic/public.js +7 -0
  122. package/src/runtime/env/static/private.js +6 -0
  123. package/src/runtime/env/static/public.js +6 -0
  124. package/src/runtime/form-utils.js +172 -61
  125. package/src/runtime/pathname.js +20 -32
  126. package/src/runtime/props.svelte.js +72 -0
  127. package/src/runtime/server/constants.js +0 -3
  128. package/src/runtime/server/cookie.js +70 -53
  129. package/src/runtime/server/csrf.js +65 -0
  130. package/src/runtime/server/data/index.js +48 -52
  131. package/src/runtime/server/dev.js +22 -0
  132. package/src/runtime/server/endpoint.js +3 -4
  133. package/src/runtime/server/env_module.js +0 -5
  134. package/src/runtime/server/errors.js +160 -0
  135. package/src/runtime/server/fetch.js +31 -38
  136. package/src/runtime/server/index.js +90 -64
  137. package/src/runtime/server/internal.js +71 -0
  138. package/src/runtime/server/page/actions.js +84 -64
  139. package/src/runtime/server/page/crypto.js +2 -2
  140. package/src/runtime/server/page/csp.js +88 -104
  141. package/src/runtime/server/page/data_serializer.js +22 -23
  142. package/src/runtime/server/page/index.js +35 -53
  143. package/src/runtime/server/page/load_data.js +47 -54
  144. package/src/runtime/server/page/render.js +172 -238
  145. package/src/runtime/server/page/respond_with_error.js +16 -30
  146. package/src/runtime/server/page/serialize_data.js +2 -13
  147. package/src/runtime/server/page/server_routing.js +85 -26
  148. package/src/runtime/server/remote-functions.js +639 -0
  149. package/src/runtime/server/respond.js +188 -129
  150. package/src/runtime/server/sourcemaps.js +183 -0
  151. package/src/runtime/server/state.js +53 -0
  152. package/src/runtime/server/utils.js +12 -154
  153. package/src/runtime/shared.js +20 -40
  154. package/src/runtime/utils.js +3 -0
  155. package/src/types/ambient-private.d.ts +11 -1
  156. package/src/types/ambient.d.ts +87 -36
  157. package/src/types/global-private.d.ts +25 -25
  158. package/src/types/internal.d.ts +160 -150
  159. package/src/types/private.d.ts +41 -1
  160. package/src/utils/error.js +28 -4
  161. package/src/utils/escape.js +9 -25
  162. package/src/utils/features.js +1 -1
  163. package/src/utils/filesystem.js +1 -23
  164. package/src/utils/fork.js +7 -2
  165. package/src/utils/hash.js +21 -0
  166. package/src/utils/http.js +8 -7
  167. package/src/utils/import.js +9 -2
  168. package/src/utils/imports.js +83 -0
  169. package/src/utils/mime.js +9 -0
  170. package/src/utils/page_nodes.js +6 -7
  171. package/src/utils/params.js +67 -0
  172. package/src/utils/regex.js +9 -0
  173. package/src/utils/routing.js +145 -73
  174. package/src/utils/shared-iterator.js +5 -0
  175. package/src/utils/streaming.js +14 -4
  176. package/src/utils/url.js +33 -2
  177. package/src/version.js +1 -1
  178. package/types/index.d.ts +2291 -2135
  179. package/types/index.d.ts.map +116 -108
  180. package/src/core/sync/write_ambient.js +0 -18
  181. package/src/core/sync/write_root.js +0 -148
  182. package/src/core/sync/write_tsconfig.js +0 -250
  183. package/src/exports/internal/server.js +0 -22
  184. package/src/exports/node/polyfills.js +0 -30
  185. package/src/runtime/server/app.js +0 -9
  186. package/src/runtime/server/remote.js +0 -457
  187. package/src/runtime/shared-server.js +0 -7
  188. package/src/runtime/telemetry/otel.js +0 -21
  189. package/src/runtime/telemetry/record_span.js +0 -65
  190. package/src/types/synthetic/$lib.md +0 -5
  191. /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
  192. /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
@@ -1,10 +1,11 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import MagicString from 'magic-string';
4
- import { rimraf, walk } from '../../../utils/filesystem.js';
4
+ import { walk, resolve_entry } from '../../../utils/filesystem.js';
5
5
  import { compact } from '../../../utils/array.js';
6
6
  import { posixify } from '../../../utils/os.js';
7
7
  import { ts } from '../ts.js';
8
+ import { is_page_route } from '../create_manifest_data/index.js';
8
9
  const remove_relative_parent_traversals = (/** @type {string} */ path) =>
9
10
  path.replace(/\.\.\//g, '');
10
11
  const is_whitespace = (/** @type {string} */ char) => /\s/.test(char);
@@ -48,7 +49,7 @@ export function write_all_types(config, manifest_data, root) {
48
49
  for (const file of walk(types_dir)) {
49
50
  const dir = path.dirname(file);
50
51
  if (!expected_directories.has(dir)) {
51
- rimraf(path.join(types_dir, file));
52
+ fs.rmSync(path.join(types_dir, file), { force: true, recursive: true });
52
53
  }
53
54
  }
54
55
  }
@@ -186,7 +187,10 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
186
187
  const outdir = path.join(config.kit.outDir, 'types', routes_dir, route.id);
187
188
 
188
189
  // now generate new types
189
- const imports = ["import type * as Kit from '@sveltejs/kit';"];
190
+ const imports = [
191
+ "import type * as Kit from '@sveltejs/kit';",
192
+ "import { MatcherParam } from '@sveltejs/kit/params';"
193
+ ];
190
194
 
191
195
  /** @type {string[]} */
192
196
  const declarations = [];
@@ -198,11 +202,6 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
198
202
  // Makes sure a type is "repackaged" and therefore more readable
199
203
  declarations.push('type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;');
200
204
 
201
- // returns the predicate of a matcher's type guard - or string if there is no type guard
202
- declarations.push(
203
- 'type MatcherParam<M> = M extends (param : string) => param is (infer U extends string) ? U : string;'
204
- );
205
-
206
205
  declarations.push(
207
206
  'type RouteParams = ' + generate_params_type(route.params, outdir, config) + ';'
208
207
  );
@@ -236,7 +235,10 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
236
235
  'type OptionalUnion<U extends Record<string, any>, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;',
237
236
 
238
237
  // Re-export `Snapshot` from @sveltejs/kit — in future we could use this to infer <T> from the return type of `snapshot.capture`
239
- 'export type Snapshot<T = any> = Kit.Snapshot<T>;'
238
+ '/** @deprecated Use the `snapshot` helper from `$app/navigation` instead. */',
239
+ 'export type Snapshot<T = any> = Kit.Snapshot<T>;',
240
+
241
+ 'export type ErrorProps = { error: App.Error };'
240
242
  );
241
243
  }
242
244
 
@@ -268,15 +270,8 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
268
270
 
269
271
  if (route.leaf.server) {
270
272
  exports.push(
271
- 'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>'
272
- );
273
- exports.push(
274
- 'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>'
275
- );
276
- }
277
-
278
- if (route.leaf.server) {
279
- exports.push(
273
+ 'export type Action<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Action<RouteParams, OutputData, RouteId>',
274
+ 'export type Actions<OutputData extends Record<string, any> | void = Record<string, any> | void> = Kit.Actions<RouteParams, OutputData, RouteId>',
280
275
  'export type PageProps = { params: RouteParams; data: PageData; form: ActionData }'
281
276
  );
282
277
  } else {
@@ -288,7 +283,9 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
288
283
  let all_pages_have_load = true;
289
284
  /** @type {import('types').RouteParam[]} */
290
285
  const layout_params = [];
291
- const ids = ['RouteId'];
286
+ // a layout can live in a directory that has no `+page` of its own, in which case its own id
287
+ // is never the matched route — a request to a colocated `+server` doesn't execute layouts
288
+ const ids = is_page_route(route) ? ['RouteId'] : [];
292
289
 
293
290
  route.layout.child_pages?.forEach((page) => {
294
291
  const leaf = routes.get(page);
@@ -322,7 +319,7 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
322
319
  ids.push('null');
323
320
  }
324
321
 
325
- declarations.push(`type LayoutRouteId = ${ids.join(' | ')}`);
322
+ declarations.push(`type LayoutRouteId = ${ids.join(' | ') || 'never'}`);
326
323
 
327
324
  declarations.push(
328
325
  'type LayoutParams = RouteParams & ' + generate_params_type(layout_params, outdir, config)
@@ -437,7 +434,7 @@ function process_node(node, outdir, is_page, proxies, root, all_pages_have_load
437
434
  'type ExtractActionFailure<T> = T extends Kit.ActionFailure<infer X> ? X extends void ? never : X : never;',
438
435
  'type ActionsFailure<T extends Record<string, (...args: any) => any>> = { [Key in keyof T]: Exclude<ExtractActionFailure<Awaited<ReturnType<T[Key]>>>, void>; }[keyof T];',
439
436
  `type ActionsExport = typeof import('${from}').actions`,
440
- 'export type SubmitFunction = Kit.SubmitFunction<Expand<ActionsSuccess<ActionsExport>>, Expand<ActionsFailure<ActionsExport>>>'
437
+ "export type SubmitFunction = import('$app/forms').SubmitFunction<Expand<ActionsSuccess<ActionsExport>>, Expand<ActionsFailure<ActionsExport>>>"
441
438
  );
442
439
 
443
440
  type = 'Expand<Kit.AwaitedActions<ActionsExport>> | null';
@@ -604,16 +601,22 @@ function replace_ext_with_js(file_path) {
604
601
  * @param {import('types').ValidatedConfig} config
605
602
  */
606
603
  function generate_params_type(params, outdir, config) {
607
- /** @param {string} matcher */
608
- const path_to_matcher = (matcher) =>
609
- posixify(path.relative(outdir, path.join(config.kit.files.params, matcher + '.js')));
604
+ const path_to_params = () => {
605
+ const params_file =
606
+ resolve_entry(config.kit.files.params) ??
607
+ config.kit.files.params.replace(/\.(js|ts)$/, '') + '.js';
608
+
609
+ return posixify(path.relative(outdir, params_file));
610
+ };
611
+
612
+ const params_import = path_to_params();
610
613
 
611
614
  return `{ ${params
612
615
  .map(
613
616
  (param) =>
614
- `${param.name}${param.optional ? '?' : ''}: ${
617
+ `${/^\w+$/.test(param.name) ? param.name : `'${param.name}'`}${param.optional ? '?' : ''}: ${
615
618
  param.matcher
616
- ? `MatcherParam<typeof import('${path_to_matcher(param.matcher)}').match>`
619
+ ? `MatcherParam<(typeof import('${params_import}').params)[${JSON.stringify(param.matcher)}]>`
617
620
  : 'string'
618
621
  }${param.optional ? ' | undefined' : ''}`
619
622
  )
@@ -642,6 +645,16 @@ export function tweak_types(content, is_server) {
642
645
  const code = new MagicString(content);
643
646
 
644
647
  const exports = new Map();
648
+ /** @param {import('typescript').BindingName} name */
649
+ function add_export(name) {
650
+ if (ts.isIdentifier(name)) {
651
+ if (names.has(name.text)) exports.set(name.text, name.text);
652
+ } else {
653
+ for (const element of name.elements) {
654
+ if (ts.isBindingElement(element)) add_export(element.name);
655
+ }
656
+ }
657
+ }
645
658
 
646
659
  ast.forEachChild((node) => {
647
660
  if (
@@ -668,9 +681,7 @@ export function tweak_types(content, is_server) {
668
681
 
669
682
  if (ts.isVariableStatement(node)) {
670
683
  node.declarationList.declarations.forEach((declaration) => {
671
- if (ts.isIdentifier(declaration.name) && names.has(declaration.name.text)) {
672
- exports.set(declaration.name.text, declaration.name.text);
673
- }
684
+ add_export(declaration.name);
674
685
  });
675
686
  }
676
687
  }
@@ -713,6 +724,62 @@ export function tweak_types(content, is_server) {
713
724
  return _modified;
714
725
  }
715
726
 
727
+ /**
728
+ * @param {number} name_end position of the identifier the annotation is attached to
729
+ * @param {import('typescript').TypeNode} type_node
730
+ * @returns {string} the removed annotation's text
731
+ */
732
+ function strip_type_annotation(name_end, type_node) {
733
+ let a = type_node.pos;
734
+ const b = type_node.end;
735
+ while (is_whitespace(content[a])) a += 1;
736
+
737
+ const type = content.slice(a, b);
738
+ code.remove(name_end, type_node.end);
739
+ modified = true;
740
+ return type;
741
+ }
742
+
743
+ /**
744
+ * Types the first parameter of an untyped arrow/function expression.
745
+ * @param {import('typescript').Expression | undefined} rhs
746
+ * @param {string} type
747
+ * @returns {boolean} `false` if there was nothing to annotate
748
+ */
749
+ function annotate_first_param(rhs, type) {
750
+ if (
751
+ !rhs ||
752
+ !(ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) ||
753
+ !rhs.parameters.length
754
+ ) {
755
+ return false;
756
+ }
757
+
758
+ const arg = rhs.parameters[0];
759
+ const add_parens = content[arg.pos - 1] !== '(';
760
+
761
+ if (add_parens) code.prependRight(arg.pos, '(');
762
+
763
+ if (arg.type) return false;
764
+
765
+ code.appendLeft(arg.name.end, `: ${type}` + (add_parens ? ')' : ''));
766
+ return true;
767
+ }
768
+
769
+ /**
770
+ * @param {import('typescript').Expression | undefined} initializer
771
+ * @param {(prop: import('typescript').PropertyAssignment) => void} callback
772
+ */
773
+ function for_each_action(initializer, callback) {
774
+ if (initializer && ts.isObjectLiteralExpression(initializer)) {
775
+ for (const prop of initializer.properties) {
776
+ if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
777
+ callback(prop);
778
+ }
779
+ }
780
+ }
781
+ }
782
+
716
783
  ast.forEachChild((node) => {
717
784
  if (ts.isFunctionDeclaration(node) && node.name?.text && node.name?.text === 'load') {
718
785
  // remove JSDoc comment above `export function load ...`
@@ -738,42 +805,13 @@ export function tweak_types(content, is_server) {
738
805
  // edge case — remove JSDoc comment above individual export
739
806
  replace_jsdoc_type_tags(declaration, declaration.initializer);
740
807
 
741
- // remove type from `export const load: Load ...`
742
808
  if (declaration.type) {
743
- let a = declaration.type.pos;
744
- const b = declaration.type.end;
745
- while (is_whitespace(content[a])) a += 1;
809
+ const type = strip_type_annotation(declaration.name.end, declaration.type);
746
810
 
747
- const type = content.slice(a, b);
748
- code.remove(declaration.name.end, declaration.type.end);
749
-
750
- const rhs = declaration.initializer;
751
-
752
- if (
753
- rhs &&
754
- (ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
755
- rhs.parameters.length
756
- ) {
757
- const arg = rhs.parameters[0];
758
- const add_parens = content[arg.pos - 1] !== '(';
759
-
760
- if (add_parens) code.prependRight(arg.pos, '(');
761
-
762
- if (arg && !arg.type) {
763
- code.appendLeft(
764
- arg.name.end,
765
- `: Parameters<${type}>[0]` + (add_parens ? ')' : '')
766
- );
767
- } else {
768
- // prevent "type X is imported but not used" (isn't silenced by @ts-nocheck) when svelte-check runs
769
- code.append(`;null as any as ${type};`);
770
- }
771
- } else {
811
+ if (!annotate_first_param(declaration.initializer, `Parameters<${type}>[0]`)) {
772
812
  // prevent "type X is imported but not used" (isn't silenced by @ts-nocheck) when svelte-check runs
773
813
  code.append(`;null as any as ${type};`);
774
814
  }
775
-
776
- modified = true;
777
815
  }
778
816
  } else if (
779
817
  is_server &&
@@ -785,69 +823,34 @@ export function tweak_types(content, is_server) {
785
823
  const removed = replace_jsdoc_type_tags(node, declaration.initializer);
786
824
  // ... and move type to each individual action
787
825
  if (removed) {
788
- const rhs = declaration.initializer;
789
- if (ts.isObjectLiteralExpression(rhs)) {
790
- for (const prop of rhs.properties) {
791
- if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
792
- const rhs = prop.initializer;
793
- const replaced = replace_jsdoc_type_tags(prop, rhs);
794
- if (
795
- !replaced &&
796
- rhs &&
797
- (ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
798
- rhs.parameters?.[0]
799
- ) {
800
- const name = ts.isIdentifier(rhs.parameters[0].name)
801
- ? rhs.parameters[0].name.text
802
- : 'event';
803
- code.prependRight(
804
- rhs.pos,
805
- `/** @param {import('./$types').RequestEvent} ${name} */ `
806
- );
807
- }
808
- }
826
+ for_each_action(declaration.initializer, (prop) => {
827
+ const rhs = prop.initializer;
828
+ const replaced = replace_jsdoc_type_tags(prop, rhs);
829
+ if (
830
+ !replaced &&
831
+ rhs &&
832
+ (ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
833
+ rhs.parameters?.[0]
834
+ ) {
835
+ const name = ts.isIdentifier(rhs.parameters[0].name)
836
+ ? rhs.parameters[0].name.text
837
+ : 'event';
838
+ code.prependRight(
839
+ rhs.pos,
840
+ `/** @param {import('./$types').RequestEvent} ${name} */ `
841
+ );
809
842
  }
810
- }
843
+ });
811
844
  }
812
845
 
813
- // remove type from `export const actions: Actions ...`
814
846
  if (declaration.type) {
815
- let a = declaration.type.pos;
816
- const b = declaration.type.end;
817
- while (is_whitespace(content[a])) a += 1;
818
-
819
- const type = content.slice(a, b);
820
- code.remove(declaration.name.end, declaration.type.end);
847
+ const type = strip_type_annotation(declaration.name.end, declaration.type);
821
848
  code.append(`;null as any as ${type};`);
822
- modified = true;
823
849
 
824
850
  // ... and move type to each individual action
825
- const rhs = declaration.initializer;
826
- if (ts.isObjectLiteralExpression(rhs)) {
827
- for (const prop of rhs.properties) {
828
- if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
829
- const rhs = prop.initializer;
830
-
831
- if (
832
- rhs &&
833
- (ts.isArrowFunction(rhs) || ts.isFunctionExpression(rhs)) &&
834
- rhs.parameters.length
835
- ) {
836
- const arg = rhs.parameters[0];
837
- const add_parens = content[arg.pos - 1] !== '(';
838
-
839
- if (add_parens) code.prependRight(arg.pos, '(');
840
-
841
- if (arg && !arg.type) {
842
- code.appendLeft(
843
- arg.name.end,
844
- ": import('./$types').RequestEvent" + (add_parens ? ')' : '')
845
- );
846
- }
847
- }
848
- }
849
- }
850
- }
851
+ for_each_action(declaration.initializer, (prop) => {
852
+ annotate_first_param(prop.initializer, "import('./$types').RequestEvent");
853
+ });
851
854
  }
852
855
  }
853
856
  }
package/src/core/utils.js CHANGED
@@ -7,7 +7,7 @@ import { noop } from '../utils/functions.js';
7
7
  import { posixify } from '../utils/os.js';
8
8
 
9
9
  /**
10
- * Resolved path of the `runtime` directory
10
+ * Resolved path of the `runtime` directory posix-ified
11
11
  *
12
12
  * TODO Windows issue:
13
13
  * Vite or sth else somehow sets the driver letter inconsistently to lower or upper case depending on the run environment.
@@ -25,23 +25,48 @@ export const runtime_directory = posixify(fileURLToPath(new URL('../runtime', im
25
25
  */
26
26
  export function get_runtime_base(root) {
27
27
  return runtime_directory.startsWith(root)
28
- ? `/${path.relative(root, runtime_directory)}`
28
+ ? `/${posixify(path.relative(root, runtime_directory))}`
29
29
  : to_fs(runtime_directory);
30
30
  }
31
31
 
32
32
  /** @param {{ verbose: boolean }} opts */
33
- export function logger({ verbose }) {
33
+ export function logger({ verbose } = { verbose: true }) {
34
34
  /** @type {import('types').Logger} */
35
- const log = (msg) => console.log(msg.replace(/^/gm, ' '));
35
+ const log = (msg) => console.log(msg);
36
36
 
37
37
  /** @param {string} msg */
38
- const err = (msg) => console.error(msg.replace(/^/gm, ' '));
38
+ const err = (msg) => console.error(msg);
39
39
 
40
40
  log.success = (msg) => log(styleText('green', `✔ ${msg}`));
41
41
  log.error = (msg) => err(styleText(['bold', 'red'], msg));
42
42
  log.warn = (msg) => log(styleText(['bold', 'yellow'], msg));
43
43
  log.minor = verbose ? (msg) => log(styleText('grey', msg)) : noop;
44
44
  log.info = verbose ? log : noop;
45
+ log.err = err;
46
+
47
+ log.prettyError = (error, caller) => {
48
+ /** @type {unknown} */
49
+ let e = error;
50
+
51
+ while (e instanceof Error) {
52
+ let stack = e.stack;
53
+ if (stack) {
54
+ if (caller) {
55
+ const i = stack.indexOf(caller);
56
+ // Cut the stack trace off at the point when our internal one starts
57
+ stack = stack.slice(0, stack.lastIndexOf('\n', i));
58
+ }
59
+
60
+ err(stack);
61
+ }
62
+
63
+ e = e.cause;
64
+ }
65
+
66
+ if (e) {
67
+ err(String(e));
68
+ }
69
+ };
45
70
 
46
71
  return log;
47
72
  }
@@ -0,0 +1,77 @@
1
+ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
2
+ /** @import { DefinedEnvVars, EnvVarConfig } from '@sveltejs/kit/env' */
3
+
4
+ /**
5
+ * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
6
+ * which are made available via `$app/env/public` and `$app/env/private`.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * import { defineEnvVars } from '@sveltejs/kit/env';
11
+ * import * as v from 'valibot';
12
+ *
13
+ * export const variables = defineEnvVars({
14
+ * API_URL: {
15
+ * schema: v.pipe(v.string(), v.url())
16
+ * },
17
+ * PORT: {
18
+ * schema: (value) => {
19
+ * if (value === undefined) return 3000;
20
+ * const port = Number(value);
21
+ * if (!Number.isInteger(port)) throw new Error('PORT must be an integer');
22
+ * return port;
23
+ * }
24
+ * }
25
+ * });
26
+ * ```
27
+ *
28
+ * @template {Record<string, EnvVarConfig<any>>} T
29
+ * @param {T} variables
30
+ * @returns {DefinedEnvVars<T>}
31
+ */
32
+ export function defineEnvVars(variables) {
33
+ /** @type {Record<string, EnvVarConfig<any>>} */
34
+ const normalized = {};
35
+
36
+ for (const [name, config] of Object.entries(variables)) {
37
+ // standard schemas can be callable (e.g. ArkType), so a function is only a validator if it isn't one
38
+ normalized[name] =
39
+ typeof config.schema === 'function' && !('~standard' in config.schema)
40
+ ? { ...config, schema: normalize_env_schema(config.schema) }
41
+ : config;
42
+ }
43
+
44
+ return /** @type {DefinedEnvVars<T>} */ (normalized);
45
+ }
46
+
47
+ /**
48
+ * @param {(value: string | undefined) => any} fn
49
+ * @returns {StandardSchemaV1<string | undefined, any>}
50
+ */
51
+ function normalize_env_schema(fn) {
52
+ return /** @type {StandardSchemaV1<string | undefined, any>} */ (
53
+ /** @type {unknown} */ ({
54
+ '~standard': {
55
+ validate(/** @type {unknown} */ value) {
56
+ let result;
57
+
58
+ try {
59
+ result = fn(/** @type {string | undefined} */ (value));
60
+ } catch (error) {
61
+ return {
62
+ issues: [
63
+ {
64
+ message: error instanceof Error ? error.message || 'Invalid value' : String(error)
65
+ }
66
+ ]
67
+ };
68
+ }
69
+
70
+ if (result instanceof Promise) return result; // will be rejected upstream
71
+
72
+ return { value: result };
73
+ }
74
+ }
75
+ })
76
+ );
77
+ }
@@ -0,0 +1,55 @@
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+
3
+ export * from './index.js';
4
+
5
+ /**
6
+ * [Environment variables](https://svelte.dev/docs/kit/environment-variables) can be configured by exporting
7
+ * a `variables` object from `src/env.ts`, using [`defineEnvVars`](https://svelte.dev/docs/kit/@sveltejs-kit-env#defineEnvVars).
8
+ */
9
+ export interface EnvVarConfig<T> {
10
+ /**
11
+ * Whether the environment variable can be accessed by client-side code.
12
+ * - if `true`, it can be imported from `$app/env/public`
13
+ * - if `false`, it can be imported from `$app/env/private`, which is a [server-only module](https://svelte.dev/docs/kit/server-only-modules)
14
+ * @default false
15
+ */
16
+ public?: boolean;
17
+ /**
18
+ * Whether the value is determined at build time or when the app runs.
19
+ * - if `true`, the build time value is inlined into the bundle. This enables optimisations like dead-code elimination
20
+ * - if `false`, the value is read from the environment when the app starts
21
+ * @default false
22
+ */
23
+ static?: boolean;
24
+ /**
25
+ * A [Standard Schema](https://standardschema.dev/) validator that is applied to the value when the app starts.
26
+ * Alternatively, a function that returns the (possibly transformed) value, or throws an error explaining
27
+ * the problem. Returning `undefined` is valid, so a function can describe an optional variable.
28
+ * The validator can output any value — not necessarily a string — but public, non-static values must be
29
+ * serializable by [devalue](https://github.com/sveltejs/devalue) so that they can be sent to the browser.
30
+ *
31
+ * If omitted, the value must be set, but may be an empty string.
32
+ */
33
+ schema?: StandardSchemaV1<string | undefined, T> | ((value: string | undefined) => T | undefined);
34
+ /**
35
+ * A description of the variable that will be used for inline documentation on hover.
36
+ */
37
+ description?: string;
38
+ }
39
+
40
+ /**
41
+ * The return type of [`defineEnvVars`](https://svelte.dev/docs/kit/@sveltejs-kit-env#defineEnvVars).
42
+ */
43
+ export type DefinedEnvVars<T extends Record<string, EnvVarConfig<any>>> = {
44
+ readonly [K in keyof T]: EnvVarEntry<T[K]>;
45
+ };
46
+
47
+ /**
48
+ * Normalizes an environment variable config's schema (standard schema or function) to standard schema.
49
+ */
50
+ type EnvVarEntry<C extends EnvVarConfig<any>> =
51
+ C['schema'] extends StandardSchemaV1<any, any>
52
+ ? C
53
+ : C['schema'] extends (value: any) => infer R
54
+ ? Omit<C, 'schema'> & { schema: StandardSchemaV1<string | undefined, R> }
55
+ : C;
@@ -1,14 +1,8 @@
1
- /** @import { EnvVarConfig } from '@sveltejs/kit' */
2
-
3
1
  export { sequence } from './sequence.js';
4
2
 
5
3
  /**
6
- * Utility for defining [environment variables](https://svelte.dev/docs/kit/environment-variables),
7
- * which are made available via `$app/env/public` and `$app/env/private`.
8
- * @template {Record<string, EnvVarConfig<any>>} T
9
- * @param {T} variables
10
- * @returns {T}
4
+ * @internal
11
5
  */
12
- export function defineEnvVars(variables) {
13
- return variables;
6
+ export function defineEnvVars() {
7
+ throw new Error(`\`defineEnvVars\` has moved — import it from \`@sveltejs/kit/env\` instead`);
14
8
  }