diff --git a/packages/kit/scripts/extract-types.js b/packages/kit/scripts/extract-types.js index 787c307fa8e43..1c1c7c06f3d4a 100644 --- a/packages/kit/scripts/extract-types.js +++ b/packages/kit/scripts/extract-types.js @@ -29,7 +29,7 @@ for (const statement of node.statements) { } const i = code.indexOf('export', start); - start = i + 6; + start = i >= 0 ? i + 6 : start; const snippet = prettier.format(code.slice(start, statement.end).trim(), { parser: 'typescript', @@ -39,7 +39,9 @@ for (const statement of node.statements) { trailingComma: 'none' }); - types.push({ name, comment, snippet }); + if (snippet) { + types.push({ name, comment, snippet }); + } } } diff --git a/packages/kit/src/core/dev/plugin.js b/packages/kit/src/core/dev/plugin.js index 578072c4c48c8..b0ed9f0d09e0a 100644 --- a/packages/kit/src/core/dev/plugin.js +++ b/packages/kit/src/core/dev/plugin.js @@ -38,7 +38,7 @@ export async function create_plugin(config, cwd) { configureServer(vite) { __fetch_polyfill(); - /** @type {import('types').SSRManifest} */ + /** @type {import('types').SSRManifestInternal} */ let manifest; function update_manifest() { diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index 86831230e8197..bb778fea9e22e 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -101,7 +101,7 @@ export function get_mime_lookup(manifest_data) { return mime; } -/** @param {import('@sveltejs/kit').ValidatedConfig} config */ +/** @param {import('types').ValidatedConfig} config */ export function get_aliases(config) { const alias = { __GENERATED__: path.posix.resolve(`${SVELTE_KIT}/generated`), diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index eb26351dca460..081b2bd244c37 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -94,7 +94,7 @@ export async function respond(request, options, state = {}) { rawBody: body_getter }); - /** @type {import('types').RequiredResolveOptions} */ + /** @type {Required} */ let resolve_opts = { ssr: true, transformPage: default_transform diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 09a444f165929..84e27b9dd8255 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -6,7 +6,7 @@ import { respond } from './respond.js'; * @param {import('types').SSRPage} route * @param {import('types').SSROptions} options * @param {import('types').SSRState} state - * @param {import('types').RequiredResolveOptions} resolve_opts + * @param {Required} resolve_opts * @returns {Promise} */ export async function render_page(event, route, options, state, resolve_opts) { diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 6970d2e944a7b..a17133eb7d8ed 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -25,7 +25,7 @@ const updated = { * error?: Error; * url: URL; * params: Record; - * resolve_opts: import('types').RequiredResolveOptions; + * resolve_opts: Required; * stuff: Record; * }} opts */ diff --git a/packages/kit/src/runtime/server/page/respond.js b/packages/kit/src/runtime/server/page/respond.js index 3f610540a8715..88692763a6d52 100644 --- a/packages/kit/src/runtime/server/page/respond.js +++ b/packages/kit/src/runtime/server/page/respond.js @@ -16,7 +16,7 @@ import { coalesce_to_error } from '../../../utils/error.js'; * options: SSROptions; * state: SSRState; * $session: any; - * resolve_opts: import('types').RequiredResolveOptions; + * resolve_opts: Required; * route: import('types').SSRPage; * params: Record; * }} opts diff --git a/packages/kit/src/runtime/server/page/respond_with_error.js b/packages/kit/src/runtime/server/page/respond_with_error.js index 6830b63c9f650..29c6c32aedc42 100644 --- a/packages/kit/src/runtime/server/page/respond_with_error.js +++ b/packages/kit/src/runtime/server/page/respond_with_error.js @@ -16,7 +16,7 @@ import { coalesce_to_error } from '../../../utils/error.js'; * $session: any; * status: number; * error: Error; - * resolve_opts: import('types').RequiredResolveOptions; + * resolve_opts: Required; * }} opts */ export async function respond_with_error({ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 666d8dcfd2792..c040d2325316e 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -2,22 +2,6 @@ /// import { CompileOptions } from 'svelte/types/compiler/interfaces'; -import { - Logger, - PrerenderOnErrorValue, - SSRNodeLoader, - SSRRoute, - TrailingSlash, - Either, - MaybePromise, - RecursiveRequired, - RouteDefinition, - AdapterEntry, - ResponseHeaders, - Fallthrough, - RequiredResolveOptions, - Body -} from './internal'; import './ambient'; export interface Adapter { @@ -25,13 +9,39 @@ export interface Adapter { adapt(builder: Builder): Promise; } +interface AdapterEntry { + /** + * A string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication. + * For example, `/foo/a-[b]` and `/foo/[c]` are different routes, but would both + * be represented in a Netlify _redirects file as `/foo/:param`, so they share an ID + */ + id: string; + + /** + * A function that compares the candidate route with the current route to determine + * if it should be treated as a fallback for the current route. For example, `/foo/[c]` + * is a fallback for `/foo/a-[b]`, and `/[...catchall]` is a fallback for all routes + */ + filter: (route: RouteDefinition) => boolean; + + /** + * A function that is invoked once the entry has been created. This is where you + * should write the function to the filesystem and generate redirect manifests. + */ + complete: (entry: { + generateManifest: (opts: { relativePath: string; format?: 'esm' | 'cjs' }) => string; + }) => void; +} + +type Body = JSONValue | Uint8Array | ReadableStream | import('stream').Readable; + export interface Builder { log: Logger; rimraf(dir: string): void; mkdirp(dir: string): void; appDir: string; - trailingSlash: 'always' | 'never' | 'ignore'; + trailingSlash: TrailingSlash; /** * Create entry points that map to individual functions @@ -249,6 +259,8 @@ export type CspDirectives = { >; }; +type Either = Only | Only; + export interface EndpointOutput { status?: number; headers?: Headers | Partial; @@ -268,6 +280,10 @@ export interface ExternalFetch { (req: Request): Promise; } +interface Fallthrough { + fallthrough: true; +} + export interface GetSession { (event: RequestEvent): MaybePromise; } @@ -283,6 +299,12 @@ export interface HandleError { (input: { error: Error & { frame?: string }; event: RequestEvent }): void; } +type HttpMethod = 'get' | 'head' | 'post' | 'put' | 'delete' | 'patch'; + +type JSONObject = { [key: string]: JSONValue }; + +type JSONValue = string | number | boolean | null | ToJSON | JSONValue[] | JSONObject; + export interface Load, Props = Record> { (input: LoadInput): MaybePromise>>; } @@ -305,6 +327,19 @@ export interface LoadOutput> { maxage?: number; } +interface Logger { + (msg: string): void; + success(msg: string): void; + error(msg: string): void; + warn(msg: string): void; + minor(msg: string): void; + info(msg: string): void; +} + +type MaybePromise = T | Promise; + +type Only = { [P in keyof T]: T[P] } & { [P in Exclude]?: never }; + export interface Prerendered { pages: Map< string, @@ -340,6 +375,11 @@ export interface PrerenderErrorHandler { }): void; } +type PrerenderOnErrorValue = 'fail' | 'continue' | PrerenderErrorHandler; + +/** `string[]` is only for set-cookie, everything else must be type of `string` */ +type ResponseHeaders = Record; + export interface RequestEvent> { request: Request; url: URL; @@ -364,28 +404,34 @@ export interface RequestOptions { platform?: App.Platform; } -export type ResolveOptions = Partial; +export type ResolveOptions = { + ssr?: boolean; + transformPage?: ({ html }: { html: string }) => MaybePromise; +}; export class Server { constructor(manifest: SSRManifest); respond(request: Request, options?: RequestOptions): Promise; } +interface RouteDefinition { + type: 'page' | 'endpoint'; + pattern: RegExp; + segments: RouteSegment[]; + methods: HttpMethod[]; +} + +interface RouteSegment { + content: string; + dynamic: boolean; + rest: boolean; +} + +type ToJSON = { toJSON(...args: any[]): Exclude }; + +type TrailingSlash = 'never' | 'always' | 'ignore'; + export interface SSRManifest { appDir: string; assets: Set; - /** private fields */ - _: { - mime: Record; - entry: { - file: string; - js: string[]; - css: string[]; - }; - nodes: SSRNodeLoader[]; - routes: SSRRoute[]; - }; } - -// TODO should this be public? -export type ValidatedConfig = RecursiveRequired; diff --git a/packages/kit/types/internal.d.ts b/packages/kit/types/internal.d.ts index de78a52be9451..010de88ed8f07 100644 --- a/packages/kit/types/internal.d.ts +++ b/packages/kit/types/internal.d.ts @@ -1,41 +1,38 @@ import { OutputAsset, OutputChunk } from 'rollup'; import { - SSRManifest, - ValidatedConfig, - RequestHandler, - Load, + Config, + Either, ExternalFetch, + Fallthrough, GetSession, Handle, HandleError, + HttpMethod, + JSONObject, + Load, + MaybePromise, RequestEvent, RequestOptions, - PrerenderErrorHandler, - Server + RequestHandler, + ResponseHeaders, + RouteSegment, + Server, + SSRManifest, + TrailingSlash } from './index'; -export interface AdapterEntry { - /** - * A string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication. - * For example, `/foo/a-[b]` and `/foo/[c]` are different routes, but would both - * be represented in a Netlify _redirects file as `/foo/:param`, so they share an ID - */ - id: string; - - /** - * A function that compares the candidate route with the current route to determine - * if it should be treated as a fallback for the current route. For example, `/foo/[c]` - * is a fallback for `/foo/a-[b]`, and `/[...catchall]` is a fallback for all routes - */ - filter: (route: RouteDefinition) => boolean; - - /** - * A function that is invoked once the entry has been created. This is where you - * should write the function to the filesystem and generate redirect manifests. - */ - complete: (entry: { - generateManifest: (opts: { relativePath: string; format?: 'esm' | 'cjs' }) => string; - }) => void; +export interface SSRManifestInternal extends SSRManifest { + /** private fields */ + _: { + mime: Record; + entry: { + file: string; + js: string[]; + css: string[]; + }; + nodes: SSRNodeLoader[]; + routes: SSRRoute[]; + }; } export interface ServerModule { @@ -58,8 +55,6 @@ export interface Asset { type: string | null; } -export type Body = JSONValue | Uint8Array | ReadableStream | import('stream').Readable; - export interface BuildData { app_dir: string; manifest_data: ManifestData; @@ -89,8 +84,6 @@ export type CSRComponentLoader = () => Promise; export type CSRRoute = [RegExp, CSRComponentLoader[], CSRComponentLoader[], GetParams?, HasShadow?]; -export type Either = Only | Only; - export interface EndpointData { type: 'endpoint'; key: string; @@ -100,10 +93,6 @@ export interface EndpointData { file: string; } -export interface Fallthrough { - fallthrough: true; -} - export type GetParams = (match: RegExpExecArray) => Record; type HasShadow = 1; @@ -115,8 +104,6 @@ export interface Hooks { handleError: HandleError; } -export type HttpMethod = 'get' | 'head' | 'post' | 'put' | 'delete' | 'patch'; - export class InternalServer extends Server { respond( request: Request, @@ -126,19 +113,6 @@ export class InternalServer extends Server { ): Promise; } -export type JSONObject = { [key: string]: JSONValue }; - -export type JSONValue = string | number | boolean | null | ToJSON | JSONValue[] | JSONObject; - -export interface Logger { - (msg: string): void; - success(msg: string): void; - error(msg: string): void; - warn(msg: string): void; - minor(msg: string): void; - info(msg: string): void; -} - export interface ManifestData { assets: Asset[]; layout: string; @@ -147,8 +121,6 @@ export interface ManifestData { routes: RouteData[]; } -export type MaybePromise = T | Promise; - export interface MethodOverride { parameter: string; allowed: string[]; @@ -166,8 +138,6 @@ export type NormalizedLoadOutput = Either< Fallthrough >; -type Only = { [P in keyof T]: T[P] } & { [P in Exclude]?: never }; - export interface PageData { type: 'page'; key: string; @@ -185,8 +155,6 @@ export interface PrerenderDependency { body: null | string | Uint8Array; } -export type PrerenderOnErrorValue = 'fail' | 'continue' | PrerenderErrorHandler; - export interface PrerenderOptions { fallback?: string; all: boolean; @@ -204,33 +172,12 @@ export type RecursiveRequired = { : T[K]; // Use the exact type for everything else }; -export interface RequiredResolveOptions { - ssr: boolean; - transformPage: ({ html }: { html: string }) => MaybePromise; -} - export interface Respond { (request: Request, options: SSROptions, state?: SSRState): Promise; } -/** `string[]` is only for set-cookie, everything else must be type of `string` */ -export type ResponseHeaders = Record; - export type RouteData = PageData | EndpointData; -export interface RouteDefinition { - type: 'page' | 'endpoint'; - pattern: RegExp; - segments: RouteSegment[]; - methods: HttpMethod[]; -} - -export interface RouteSegment { - content: string; - dynamic: boolean; - rest: boolean; -} - export interface ShadowEndpointOutput { status?: number; headers?: Partial; @@ -301,7 +248,7 @@ export interface SSROptions { handle_error(error: Error & { frame?: string }, event: RequestEvent): void; hooks: Hooks; hydrate: boolean; - manifest: SSRManifest; + manifest: SSRManifestInternal; method_override: MethodOverride; paths: { base: string; @@ -365,8 +312,6 @@ export interface SSRState { export type StrictBody = string | Uint8Array; -type ToJSON = { toJSON(...args: any[]): Exclude }; - -export type TrailingSlash = 'never' | 'always' | 'ignore'; +export type ValidatedConfig = RecursiveRequired; export * from './index';