Merge pull request #21865 from brikou/next

[next] Change query params type to use string or string[] instead of any
This commit is contained in:
Mine Starks
2017-12-13 10:48:53 -08:00
committed by GitHub
14 changed files with 333 additions and 170 deletions

View File

@@ -1,4 +1,4 @@
import * as React from 'react';
import * as React from "react";
export interface DocumentProps {
__NEXT_DATA__?: any;

View File

@@ -1,16 +1,29 @@
import * as React from 'react';
import * as React from "react";
export interface DynamicOptions<TCProps, TLProps> {
loading?: React.ComponentType<TLProps>;
ssr?: boolean;
modules?(props: TCProps & TLProps): { [key: string]: Promise<React.ComponentType<any>> };
render?(props: TCProps & TLProps, modules: { [key: string]: React.ComponentType<any> }): void;
modules?(
props: TCProps & TLProps,
): { [key: string]: Promise<React.ComponentType<any>> };
render?(
props: TCProps & TLProps,
modules: { [key: string]: React.ComponentType<any> },
): void;
}
export class SameLoopPromise<T> extends Promise<T> {
constructor(executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void);
constructor(
executor: (
resolve: (value?: T) => void,
reject: (reason?: any) => void,
) => void,
);
setResult(value: T): void;
setError(value: any): void;
runIfNeeded(): void;
}
export default function<TCProps, TLProps>(componentPromise: Promise<React.ComponentType<TCProps>>, options?: DynamicOptions<TCProps, TLProps>): React.ComponentType<TCProps & TLProps>;
export default function<TCProps, TLProps>(
componentPromise: Promise<React.ComponentType<TCProps>>,
options?: DynamicOptions<TCProps, TLProps>,
): React.ComponentType<TCProps & TLProps>;

View File

@@ -1,2 +1,2 @@
import * as React from 'react';
export default class extends React.Component<{statusCode: number}> {}
import * as React from "react";
export default class extends React.Component<{ statusCode: number }> {}

View File

@@ -1,4 +1,4 @@
import * as React from 'react';
import * as React from "react";
export function defaultHead(): JSX.Element[];
export default class extends React.Component {

172
types/next/index.d.ts vendored
View File

@@ -1,63 +1,147 @@
// Type definitions for next 2.4
// Project: https://github.com/zeit/next.js
// Definitions by: Drew Hays <https://github.com/dru89>
// Brice BERNARD <https://github.com/brikou>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
/// <reference types="node" />
import * as http from 'http';
import * as url from 'url';
import * as http from "http";
import * as url from "url";
declare namespace next {
type UrlLike = url.UrlObject | url.Url;
type UrlLike = url.UrlObject | url.Url;
interface ServerConfig {
// known keys
webpack?: any;
webpackDevMiddleware?: any;
poweredByHeader?: boolean;
distDir?: string;
assetPrefix?: string;
configOrigin?: string;
useFileSystemPublicRoutes?: boolean;
interface ServerConfig {
// known keys
webpack?: any;
webpackDevMiddleware?: any;
poweredByHeader?: boolean;
distDir?: string;
assetPrefix?: string;
configOrigin?: string;
useFileSystemPublicRoutes?: boolean;
// and since this is a config, it can take anything else, too.
[key: string]: any;
}
// and since this is a config, it can take anything else, too.
[key: string]: any;
}
interface ServerOptions {
dir?: string;
dev?: boolean;
staticMarkup?: boolean;
quiet?: boolean;
conf?: ServerConfig;
}
interface ServerOptions {
dir?: string;
dev?: boolean;
staticMarkup?: boolean;
quiet?: boolean;
conf?: ServerConfig;
}
interface Server {
handleRequest(req: http.IncomingMessage, res: http.ServerResponse, parsedUrl?: UrlLike): Promise<void>;
getRequestHandler(): (req: http.IncomingMessage, res: http.ServerResponse, parsedUrl?: UrlLike) => Promise<void>;
prepare(): Promise<void>;
close(): Promise<void>;
defineRoutes(): Promise<void>;
start(): Promise<void>;
run(req: http.IncomingMessage, res: http.ServerResponse, parsedUrl: UrlLike): Promise<void>;
interface Server {
handleRequest(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl?: UrlLike,
): Promise<void>;
getRequestHandler(): (
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl?: UrlLike,
) => Promise<void>;
prepare(): Promise<void>;
close(): Promise<void>;
defineRoutes(): Promise<void>;
start(): Promise<void>;
run(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl: UrlLike,
): Promise<void>;
render(req: http.IncomingMessage, res: http.ServerResponse, pathname: string, query?: {[key: string]: any}, parsedUrl?: UrlLike): Promise<void>;
renderError(err: any, req: http.IncomingMessage, res: http.ServerResponse, pathname: string, query?: {[key: string]: any}): Promise<void>;
render404(req: http.IncomingMessage, res: http.ServerResponse, parsedUrl: UrlLike): Promise<void>;
renderToHTML(req: http.IncomingMessage, res: http.ServerResponse, pathname: string, query?: {[key: string]: any}): Promise<string>;
renderErrorToHTML(err: any, req: http.IncomingMessage, res: http.ServerResponse, pathname: string, query?: {[key: string]: any}): Promise<string>;
render(
req: http.IncomingMessage,
res: http.ServerResponse,
pathname: string,
query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
},
parsedUrl?: UrlLike,
): Promise<void>;
renderError(
err: any,
req: http.IncomingMessage,
res: http.ServerResponse,
pathname: string,
query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
},
): Promise<void>;
render404(
req: http.IncomingMessage,
res: http.ServerResponse,
parsedUrl: UrlLike,
): Promise<void>;
renderToHTML(
req: http.IncomingMessage,
res: http.ServerResponse,
pathname: string,
query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
},
): Promise<string>;
renderErrorToHTML(
err: any,
req: http.IncomingMessage,
res: http.ServerResponse,
pathname: string,
query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
},
): Promise<string>;
serveStatic(req: http.IncomingMessage, res: http.ServerResponse, path: string): Promise<void>;
isServeableUrl(path: string): boolean;
isInternalUrl(req: http.IncomingMessage): boolean;
readBuildId(): string;
handleBuildId(buildId: string, res: http.ServerResponse): boolean;
getCompilationError(page: string, req: http.IncomingMessage, res: http.ServerResponse): Promise<any>;
handleBuildHash(filename: string, hash: string, res: http.ServerResponse): void;
send404(res: http.ServerResponse): void;
}
serveStatic(
req: http.IncomingMessage,
res: http.ServerResponse,
path: string,
): Promise<void>;
isServeableUrl(path: string): boolean;
isInternalUrl(req: http.IncomingMessage): boolean;
readBuildId(): string;
handleBuildId(buildId: string, res: http.ServerResponse): boolean;
getCompilationError(
page: string,
req: http.IncomingMessage,
res: http.ServerResponse,
): Promise<any>;
handleBuildHash(
filename: string,
hash: string,
res: http.ServerResponse,
): void;
send404(res: http.ServerResponse): void;
}
}
declare function next(options?: next.ServerOptions): next.Server;

View File

@@ -1,5 +1,5 @@
import * as url from 'url';
import * as React from 'react';
import * as url from "url";
import * as React from "react";
export type UrlLike = url.UrlObject | url.Url;
export interface LinkState {

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import * as url from 'url';
import * as React from "react";
import * as url from "url";
type UrlLike = url.UrlObject | url.Url;
@@ -14,17 +14,35 @@ export interface SingletonRouter {
ready(cb: RouterCallback): void;
// router properties
readonly components: { [key: string]: { Component: React.ComponentType<any>, err: any } };
readonly components: {
[key: string]: { Component: React.ComponentType<any>; err: any };
};
readonly pathname: string;
readonly route: string;
readonly asPath?: string;
readonly query?: { [key: string]: any };
readonly query?: {
[key: string]:
| boolean
| boolean[]
| number
| number[]
| string
| string[];
};
// router methods
reload(route: string): Promise<void>;
back(): void;
push(url: string|UrlLike, as?: string|UrlLike, options?: EventChangeOptions): Promise<boolean>;
replace(url: string|UrlLike, as?: string|UrlLike, options?: EventChangeOptions): Promise<boolean>;
push(
url: string | UrlLike,
as?: string | UrlLike,
options?: EventChangeOptions,
): Promise<boolean>;
replace(
url: string | UrlLike,
as?: string | UrlLike,
options?: EventChangeOptions,
): Promise<boolean>;
prefetch(url: string): Promise<React.ComponentType<any>>;
// router events
@@ -35,7 +53,9 @@ export interface SingletonRouter {
onRouteChangeError?(error: any, url: string): void;
}
export function withRouter<T extends {}>(Component: React.ComponentType<T & {router: SingletonRouter}>): React.ComponentType<T>;
export function withRouter<T extends {}>(
Component: React.ComponentType<T & { router: SingletonRouter }>,
): React.ComponentType<T>;
export const Singleton: SingletonRouter;
export default Singleton;

View File

@@ -1,12 +1,12 @@
import Document, * as document from 'next/document';
import * as React from 'react';
import Document, * as document from "next/document";
import * as React from "react";
const results = (
<Document any="property" should="work" here>
<document.Head some="more" properties>
<meta name="description" content="Head can have children, too!" />
</document.Head>
<document.Main />
<document.NextScript />
</Document>
<Document any="property" should="work" here>
<document.Head some="more" properties>
<meta name="description" content="Head can have children, too!" />
</document.Head>
<document.Main />
<document.NextScript />
</Document>
);

View File

@@ -1,23 +1,25 @@
import dynamic, * as d from 'next/dynamic';
import * as React from 'react';
import dynamic, * as d from "next/dynamic";
import * as React from "react";
// typically you'd use this with an esnext-style import() statement, but we'll make do without
interface DynamicComponentProps {
foo: string;
bar: number;
foo: string;
bar: number;
}
async function getComponent() {
return (
(props: DynamicComponentProps) => <div>I'm an async component! {props.foo} {props.bar}</div>
);
return (props: DynamicComponentProps) => (
<div>
I'm an async component! {props.foo} {props.bar}
</div>
);
}
interface LoadingComponentProps {
baz: boolean;
baz: boolean;
}
const DynamicComponent = dynamic(getComponent(), {
loading: (props: LoadingComponentProps) => <div>Loading! {props.baz}</div>
loading: (props: LoadingComponentProps) => <div>Loading! {props.baz}</div>,
});
const jsx = (<DynamicComponent foo='five' bar={5} baz />);
const jsx = <DynamicComponent foo="five" bar={5} baz />;

View File

@@ -1,6 +1,4 @@
import * as React from 'react';
import ErrorComponent from 'next/error';
import * as React from "react";
import ErrorComponent from "next/error";
const result = (
<ErrorComponent statusCode={404} />
);
const result = <ErrorComponent statusCode={404} />;

View File

@@ -1,19 +1,11 @@
import Head, * as head from 'next/head';
import * as React from 'react';
import Head, * as head from "next/head";
import * as React from "react";
const elements: JSX.Element[] = head.defaultHead();
const jsx = (
<Head>
{elements}
</Head>
);
const jsx = <Head>{elements}</Head>;
if (!Head.canUseDOM) {
Head.rewind().map(
x => [x.key, x.props, x.type]
);
Head.rewind().map(x => [x.key, x.props, x.type]);
}
Head.peek().map(
x => [x.key, x.props, x.type]
);
Head.peek().map(x => [x.key, x.props, x.type]);

View File

@@ -1,13 +1,23 @@
import Link from 'next/link';
import * as React from 'react';
import Link from "next/link";
import * as React from "react";
const links = (
<div>
<Link as="foo" href="https://www.example.com" onError={(e: any) => { console.log("Handled error!", e); }} prefetch replace scroll shallow>
<a>Gotta link to somewhere!</a>
</Link>
<Link>
<a>All props are optional!</a>
</Link>
</div>
<div>
<Link
as="foo"
href="https://www.example.com"
onError={(e: any) => {
console.log("Handled error!", e);
}}
prefetch
replace
scroll
shallow
>
<a>Gotta link to somewhere!</a>
</Link>
<Link>
<a>All props are optional!</a>
</Link>
</div>
);

View File

@@ -1,28 +1,34 @@
import Router, * as r from 'next/router';
import * as React from 'react';
import * as qs from 'querystring';
import Router, * as r from "next/router";
import * as React from "react";
import * as qs from "querystring";
Router.readyCallbacks.push(() => { console.log("I'll get called when the router initializes."); });
Router.ready(() => { console.log("I'll get called immediately if the router initializes, or when it eventually does."); });
Router.readyCallbacks.push(() => {
console.log("I'll get called when the router initializes.");
});
Router.ready(() => {
console.log(
"I'll get called immediately if the router initializes, or when it eventually does.",
);
});
// Access readonly properties of the router.
Object.keys(Router.components).forEach(key => {
const c = Router.components[key];
c.err.isAnAny;
const c = Router.components[key];
c.err.isAnAny;
return <c.Component />;
return <c.Component />;
});
function split(routeLike: string) {
routeLike.split('/').forEach(part => {
console.log("path part: ", part);
});
routeLike.split("/").forEach(part => {
console.log("path part: ", part);
});
}
if (Router.asPath) {
split(Router.asPath);
split(Router.asPath);
split(Router.asPath);
split(Router.asPath);
}
split(Router.pathname);
@@ -31,25 +37,41 @@ const query = `?${qs.stringify(Router.query)}`;
// Assign some callback methods.
Router.onAppUpdated = (nextRoute: string) => console.log(nextRoute);
Router.onRouteChangeStart = (url: string) => console.log("Route is starting to change.", url);
Router.onBeforeHistoryChange = (as: string) => console.log("History hasn't changed yet.", as);
Router.onRouteChangeComplete = (url: string) => console.log("Route chaneg is complete.", url);
Router.onRouteChangeError = (err: any, url: string) => console.log("Route is starting to change.", url, err);
Router.onRouteChangeStart = (url: string) =>
console.log("Route is starting to change.", url);
Router.onBeforeHistoryChange = (as: string) =>
console.log("History hasn't changed yet.", as);
Router.onRouteChangeComplete = (url: string) =>
console.log("Route chaneg is complete.", url);
Router.onRouteChangeError = (err: any, url: string) =>
console.log("Route is starting to change.", url, err);
// Call methods on the router itself.
Router.reload('/route').then(() => console.log('route was reloaded'));
Router.reload("/route").then(() => console.log("route was reloaded"));
Router.back();
Router.push('/route').then((success: boolean) => console.log('route push success: ', success));
Router.push('/route', '/asRoute').then((success: boolean) => console.log('route push success: ', success));
Router.push('/route', '/asRoute', {shallow: false}).then((success: boolean) => console.log('route push success: ', success));
Router.push("/route").then((success: boolean) =>
console.log("route push success: ", success),
);
Router.push("/route", "/asRoute").then((success: boolean) =>
console.log("route push success: ", success),
);
Router.push("/route", "/asRoute", { shallow: false }).then((success: boolean) =>
console.log("route push success: ", success),
);
Router.replace('/route').then((success: boolean) => console.log('route replace success: ', success));
Router.replace('/route', '/asRoute').then((success: boolean) => console.log('route replace success: ', success));
Router.replace('/route', '/asRoute', {shallow: false}).then((success: boolean) => console.log('route replace success: ', success));
Router.replace("/route").then((success: boolean) =>
console.log("route replace success: ", success),
);
Router.replace("/route", "/asRoute").then((success: boolean) =>
console.log("route replace success: ", success),
);
Router.replace("/route", "/asRoute", {
shallow: false,
}).then((success: boolean) => console.log("route replace success: ", success));
Router.prefetch('/route').then(Component => {
const element = (<Component />);
Router.prefetch("/route").then(Component => {
const element = <Component />;
});
r.withRouter(props => <div />);

View File

@@ -1,56 +1,78 @@
import createServer = require('next');
import * as http from 'http';
import * as url from 'url';
import createServer = require("next");
import * as http from "http";
import * as url from "url";
const defaultServer: createServer.Server = createServer();
const server = createServer({
dir: '..',
quiet: true,
conf: {
distDir: './dist',
useFileSystemPublicRoutes: false,
anotherProperty: {
key: true
}
},
dir: "..",
quiet: true,
conf: {
distDir: "./dist",
useFileSystemPublicRoutes: false,
anotherProperty: {
key: true,
},
},
});
const voidFunc = () => {};
const stringFunc = (x: string) => x.split('\n');
const stringFunc = (x: string) => x.split("\n");
server.prepare().then(voidFunc);
server.close().then(voidFunc);
server.defineRoutes().then(voidFunc);
server.start().then(voidFunc);
const parsedUrl = url.parse('https://www.example.com');
const parsedUrl = url.parse("https://www.example.com");
const handler = server.getRequestHandler();
function handle(req: http.IncomingMessage, res: http.ServerResponse) {
handler(req, res);
handler(req, res, parsedUrl).then(voidFunc);
server.run(req, res, parsedUrl).then(voidFunc);
handler(req, res);
handler(req, res, parsedUrl).then(voidFunc);
server.run(req, res, parsedUrl).then(voidFunc);
server.render(req, res, '/path/to/resource').then(voidFunc);
server.render(req, res, '/path/to/resource', {}, parsedUrl).then(voidFunc);
server.render(req, res, '/path/to/resource', { key: 'value' }, parsedUrl).then(voidFunc);
server.renderError(new Error(), req, res, '/path/to/resource').then(voidFunc);
server.renderError(new Error(), req, res, '/path/to/resource', { key: 'value' }).then(voidFunc);
server.renderError('this can be an error, too!', req, res, '/path/to/resource', { key: 'value' }).then(voidFunc);
server.render404(req, res, parsedUrl).then(voidFunc);
server.render(req, res, "/path/to/resource").then(voidFunc);
server.render(req, res, "/path/to/resource", {}, parsedUrl).then(voidFunc);
server
.render(req, res, "/path/to/resource", { key: "value" }, parsedUrl)
.then(voidFunc);
server
.renderError(new Error(), req, res, "/path/to/resource")
.then(voidFunc);
server
.renderError(new Error(), req, res, "/path/to/resource", {
key: "value",
})
.then(voidFunc);
server
.renderError(
"this can be an error, too!",
req,
res,
"/path/to/resource",
{ key: "value" },
)
.then(voidFunc);
server.render404(req, res, parsedUrl).then(voidFunc);
server.renderToHTML(req, res, '/path/to/resource', { foo: 'bar' }).then(x => x.split('\n'));
server.renderErrorToHTML(new Error(), req, res, '/path/to/resource', { foo: 'bar' }).then(x => x.split('\n'));
server
.renderToHTML(req, res, "/path/to/resource", { foo: "bar" })
.then(x => x.split("\n"));
server
.renderErrorToHTML(new Error(), req, res, "/path/to/resource", {
foo: "bar",
})
.then(x => x.split("\n"));
server.serveStatic(req, res, '/path/to/thing').then(voidFunc);
server.serveStatic(req, res, "/path/to/thing").then(voidFunc);
let b: boolean;
b = server.isServeableUrl('/path/to/thing');
b = server.isInternalUrl(req);
b = server.handleBuildId('{buildId}', res);
let b: boolean;
b = server.isServeableUrl("/path/to/thing");
b = server.isInternalUrl(req);
b = server.handleBuildId("{buildId}", res);
const s: string = server.readBuildId();
server.getCompilationError('page', req, res).then(err => err.thisIsAnAny);
server.handleBuildHash('filename', 'hash', res);
server.send404(res);
const s: string = server.readBuildId();
server.getCompilationError("page", req, res).then(err => err.thisIsAnAny);
server.handleBuildHash("filename", "hash", res);
server.send404(res);
}