Skip to content

Commit

Permalink
Ensure public types don't reference internal types
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Feb 21, 2022
1 parent 231d0c8 commit e3e7252
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 123 deletions.
6 changes: 4 additions & 2 deletions packages/kit/scripts/extract-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -39,7 +39,9 @@ for (const statement of node.statements) {
trailingComma: 'none'
});

types.push({ name, comment, snippet });
if (snippet) {
types.push({ name, comment, snippet });
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/dev/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`),
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export async function respond(request, options, state = {}) {
rawBody: body_getter
});

/** @type {import('types').RequiredResolveOptions} */
/** @type {Required<import('types').ResolveOptions>} */
let resolve_opts = {
ssr: true,
transformPage: default_transform
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<import('types').ResolveOptions>} resolve_opts
* @returns {Promise<Response | undefined>}
*/
export async function render_page(event, route, options, state, resolve_opts) {
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/page/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const updated = {
* error?: Error;
* url: URL;
* params: Record<string, string>;
* resolve_opts: import('types').RequiredResolveOptions;
* resolve_opts: Required<import('types').ResolveOptions>;
* stuff: Record<string, any>;
* }} opts
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/page/respond.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<import('types').ResolveOptions>;
* route: import('types').SSRPage;
* params: Record<string, string>;
* }} opts
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/page/respond_with_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<import('types').ResolveOptions>;
* }} opts
*/
export async function respond_with_error({
Expand Down
110 changes: 78 additions & 32 deletions packages/kit/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,46 @@
/// <reference types="vite/client" />

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 {
name: string;
adapt(builder: Builder): Promise<void>;
}

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
Expand Down Expand Up @@ -249,6 +259,8 @@ export type CspDirectives = {
>;
};

type Either<T, U> = Only<T, U> | Only<U, T>;

export interface EndpointOutput<Output extends Body = Body> {
status?: number;
headers?: Headers | Partial<ResponseHeaders>;
Expand All @@ -268,6 +280,10 @@ export interface ExternalFetch {
(req: Request): Promise<Response>;
}

interface Fallthrough {
fallthrough: true;
}

export interface GetSession {
(event: RequestEvent): MaybePromise<App.Session>;
}
Expand All @@ -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<Params = Record<string, string>, Props = Record<string, any>> {
(input: LoadInput<Params>): MaybePromise<Either<Fallthrough, LoadOutput<Props>>>;
}
Expand All @@ -305,6 +327,19 @@ export interface LoadOutput<Props = Record<string, any>> {
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> = T | Promise<T>;

type Only<T, U> = { [P in keyof T]: T[P] } & { [P in Exclude<keyof U, keyof T>]?: never };

export interface Prerendered {
pages: Map<
string,
Expand Down Expand Up @@ -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<string, string | number | string[]>;

export interface RequestEvent<Params = Record<string, string>> {
request: Request;
url: URL;
Expand All @@ -364,28 +404,34 @@ export interface RequestOptions {
platform?: App.Platform;
}

export type ResolveOptions = Partial<RequiredResolveOptions>;
export type ResolveOptions = {
ssr?: boolean;
transformPage?: ({ html }: { html: string }) => MaybePromise<string>;
};

export class Server {
constructor(manifest: SSRManifest);
respond(request: Request, options?: RequestOptions): Promise<Response>;
}

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<JSONValue, ToJSON> };

type TrailingSlash = 'never' | 'always' | 'ignore';

export interface SSRManifest {
appDir: string;
assets: Set<string>;
/** private fields */
_: {
mime: Record<string, string>;
entry: {
file: string;
js: string[];
css: string[];
};
nodes: SSRNodeLoader[];
routes: SSRRoute[];
};
}

// TODO should this be public?
export type ValidatedConfig = RecursiveRequired<Config>;
Loading

0 comments on commit e3e7252

Please sign in to comment.