next-server
Advanced tools
Comparing version 8.1.1-canary.61 to 8.1.1-canary.62
@@ -1,3 +0,3 @@ | ||
export declare function isAmp({ enabled, hybrid, hasQuery, }?: { | ||
enabled?: boolean | undefined; | ||
export declare function isInAmpMode({ ampFirst, hybrid, hasQuery, }?: { | ||
ampFirst?: boolean | undefined; | ||
hybrid?: boolean | undefined; | ||
@@ -4,0 +4,0 @@ hasQuery?: boolean | undefined; |
@@ -7,11 +7,11 @@ "use strict"; | ||
const react_1 = __importDefault(require("react")); | ||
const amphtml_context_1 = require("./amphtml-context"); | ||
function isAmp({ enabled = false, hybrid = false, hasQuery = false, } = {}) { | ||
return enabled && (!hybrid || (hybrid && hasQuery)); | ||
const amp_context_1 = require("./amp-context"); | ||
function isInAmpMode({ ampFirst = false, hybrid = false, hasQuery = false, } = {}) { | ||
return ampFirst || (hybrid && hasQuery); | ||
} | ||
exports.isAmp = isAmp; | ||
exports.isInAmpMode = isInAmpMode; | ||
function useAmp() { | ||
const ampMode = react_1.default.useContext(amphtml_context_1.AmpModeContext); | ||
const ampState = react_1.default.useContext(amp_context_1.AmpStateContext); | ||
// un-comment below to not be considered AMP in dirty mode | ||
return isAmp(ampMode); // && ampMode.hasQuery | ||
return isInAmpMode(ampState); // && ampMode.hasQuery | ||
} | ||
@@ -24,5 +24,5 @@ exports.useAmp = useAmp; | ||
function WithAmpWrapper(props = {}) { | ||
const ampMode = react_1.default.useContext(amphtml_context_1.AmpModeContext); | ||
ampMode.enabled = true; | ||
ampMode.hybrid = hybrid; | ||
const ampState = react_1.default.useContext(amp_context_1.AmpStateContext); | ||
ampState.ampFirst = !hybrid; | ||
ampState.hybrid = hybrid; | ||
return react_1.default.createElement(Component, props); | ||
@@ -29,0 +29,0 @@ } |
@@ -22,5 +22,2 @@ "use strict"; | ||
exports.noSSR = noSSR; | ||
function DefaultLoading() { | ||
return react_1.default.createElement("p", null, "loading..."); | ||
} | ||
// function dynamic<P = {}, O extends DynamicOptions>(options: O): | ||
@@ -36,3 +33,3 @@ function dynamic(dynamicOptions, options) { | ||
if (isLoading) { | ||
return react_1.default.createElement(DefaultLoading, null); | ||
return null; | ||
} | ||
@@ -46,3 +43,3 @@ if (error) { | ||
} | ||
return react_1.default.createElement(DefaultLoading, null); | ||
return null; | ||
}, | ||
@@ -49,0 +46,0 @@ }; |
import React from 'react'; | ||
export declare function defaultHead(className?: string, isAmp?: boolean): JSX.Element[]; | ||
export declare function defaultHead(className?: string, inAmpMode?: boolean): JSX.Element[]; | ||
/** | ||
@@ -4,0 +4,0 @@ * This component injects elements to `<head>` of your page. |
@@ -8,8 +8,8 @@ "use strict"; | ||
const side_effect_1 = __importDefault(require("./side-effect")); | ||
const amphtml_context_1 = require("./amphtml-context"); | ||
const amp_context_1 = require("./amp-context"); | ||
const head_manager_context_1 = require("./head-manager-context"); | ||
const amp_1 = require("./amp"); | ||
function defaultHead(className = 'next-head', isAmp = false) { | ||
function defaultHead(className = 'next-head', inAmpMode = false) { | ||
const head = [react_1.default.createElement("meta", { key: "charSet", charSet: "utf-8", className: className })]; | ||
if (!isAmp) { | ||
if (!inAmpMode) { | ||
head.push(react_1.default.createElement("meta", { key: "viewport", name: "viewport", content: "width=device-width,minimum-scale=1,initial-scale=1", className: className })); | ||
@@ -98,3 +98,3 @@ } | ||
.reverse() | ||
.concat(defaultHead('', props.isAmp)) | ||
.concat(defaultHead('', props.inAmpMode)) | ||
.filter(unique()) | ||
@@ -118,5 +118,5 @@ .reverse() | ||
function Head({ children }) { | ||
return (react_1.default.createElement(amphtml_context_1.AmpModeContext.Consumer, null, ampMode => (react_1.default.createElement(head_manager_context_1.HeadManagerContext.Consumer, null, updateHead => (react_1.default.createElement(Effect, { reduceComponentsToState: reduceComponents, handleStateChange: updateHead, isAmp: amp_1.isAmp(ampMode) }, children)))))); | ||
return (react_1.default.createElement(amp_context_1.AmpStateContext.Consumer, null, ampState => (react_1.default.createElement(head_manager_context_1.HeadManagerContext.Consumer, null, updateHead => (react_1.default.createElement(Effect, { reduceComponentsToState: reduceComponents, handleStateChange: updateHead, inAmpMode: amp_1.isInAmpMode(ampState) }, children)))))); | ||
} | ||
Head.rewind = Effect.rewind; | ||
exports.default = Head; |
@@ -6,3 +6,3 @@ import React from 'react'; | ||
handleStateChange?: (state: State) => void; | ||
isAmp?: boolean; | ||
inAmpMode?: boolean; | ||
}; | ||
@@ -9,0 +9,0 @@ declare const _default: () => { |
@@ -101,4 +101,4 @@ /// <reference types="node" /> | ||
ampPath: string; | ||
amphtml: boolean; | ||
hasAmp: boolean; | ||
inAmpMode: boolean; | ||
hybridAmp: boolean; | ||
staticMarkup: boolean; | ||
@@ -105,0 +105,0 @@ devFiles: string[]; |
/// <reference types="node" /> | ||
import { IncomingMessage } from 'http'; | ||
import { NextApiResponse, NextApiRequest } from '../lib/utils'; | ||
import { Params } from './router'; | ||
export declare type NextApiRequestCookies = { | ||
[key: string]: string; | ||
}; | ||
export declare type NextApiRequestQuery = { | ||
[key: string]: string | string[]; | ||
}; | ||
/** | ||
* Parse incoming message like `json` or `urlencoded` | ||
* @param req | ||
* @param req request object | ||
*/ | ||
@@ -14,4 +21,9 @@ export declare function parseBody(req: NextApiRequest, limit?: string): Promise<any>; | ||
*/ | ||
export declare function parseQuery({ url }: IncomingMessage): any; | ||
export declare function getQueryParser({ url }: IncomingMessage): () => NextApiRequestQuery; | ||
/** | ||
* Parse cookeies from `req` header | ||
* @param req request object | ||
*/ | ||
export declare function getCookieParser(req: IncomingMessage): () => NextApiRequestCookies; | ||
/** | ||
* | ||
@@ -48,1 +60,13 @@ * @param res response object | ||
export declare function sendError(res: NextApiResponse, statusCode: number, message: string): void; | ||
interface LazyProps { | ||
req: NextApiRequest; | ||
params?: Params | boolean; | ||
} | ||
/** | ||
* Execute getter function only if its needed | ||
* @param LazyProps `req` and `params` for lazyProp | ||
* @param prop name of property | ||
* @param getter function to get data | ||
*/ | ||
export declare function setLazyProp<T>({ req, params }: LazyProps, prop: string, getter: () => T): void; | ||
export {}; |
@@ -8,7 +8,6 @@ "use strict"; | ||
const raw_body_1 = __importDefault(require("raw-body")); | ||
const url_1 = require("url"); | ||
const content_type_1 = require("content-type"); | ||
/** | ||
* Parse incoming message like `json` or `urlencoded` | ||
* @param req | ||
* @param req request object | ||
*/ | ||
@@ -61,14 +60,31 @@ async function parseBody(req, limit = '1mb') { | ||
*/ | ||
function parseQuery({ url }) { | ||
if (url) { | ||
// This is just for parsing search params, base it's not important | ||
const params = new url_1.URL(url, 'https://n').searchParams; | ||
return reduceParams(params.entries()); | ||
} | ||
else { | ||
return {}; | ||
} | ||
function getQueryParser({ url }) { | ||
return function parseQuery() { | ||
const { URL } = require('url'); | ||
// we provide a placeholder base url because we only want searchParams | ||
const params = new URL(url, 'https://n').searchParams; | ||
const query = {}; | ||
for (const [key, value] of params) { | ||
query[key] = value; | ||
} | ||
return query; | ||
}; | ||
} | ||
exports.parseQuery = parseQuery; | ||
exports.getQueryParser = getQueryParser; | ||
/** | ||
* Parse cookeies from `req` header | ||
* @param req request object | ||
*/ | ||
function getCookieParser(req) { | ||
return function parseCookie() { | ||
const header = req.headers.cookie; | ||
if (!header) { | ||
return {}; | ||
} | ||
const { parse } = require('cookie'); | ||
return parse(Array.isArray(header) ? header.join(';') : header); | ||
}; | ||
} | ||
exports.getCookieParser = getCookieParser; | ||
/** | ||
* | ||
@@ -131,9 +147,2 @@ * @param res response object | ||
exports.sendJson = sendJson; | ||
function reduceParams(params) { | ||
const obj = {}; | ||
for (const [key, value] of params) { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
/** | ||
@@ -161,1 +170,23 @@ * Custom error class | ||
exports.sendError = sendError; | ||
/** | ||
* Execute getter function only if its needed | ||
* @param LazyProps `req` and `params` for lazyProp | ||
* @param prop name of property | ||
* @param getter function to get data | ||
*/ | ||
function setLazyProp({ req, params }, prop, getter) { | ||
const opts = { configurable: true, enumerable: true }; | ||
const optsReset = Object.assign({}, opts, { writable: true }); | ||
Object.defineProperty(req, prop, Object.assign({}, opts, { get: () => { | ||
let value = getter(); | ||
if (params && typeof params !== 'boolean') { | ||
value = Object.assign({}, value, params); | ||
} | ||
// we set the property on the object to avoid recalculating it | ||
Object.defineProperty(req, prop, Object.assign({}, optsReset, { value })); | ||
return value; | ||
}, set: value => { | ||
Object.defineProperty(req, prop, Object.assign({}, optsReset, { value })); | ||
} })); | ||
} | ||
exports.setLazyProp = setLazyProp; |
@@ -33,5 +33,4 @@ "use strict"; | ||
(os_1.default.cpus() || { length: 1 }).length) - 1), | ||
autoExport: false, | ||
ampBindInitData: false, | ||
exportTrailingSlash: true, | ||
exportTrailingSlash: false, | ||
terserLoader: false, | ||
@@ -38,0 +37,0 @@ profiling: false, |
export declare function interopDefault(mod: any): any; | ||
export interface IPageConfig { | ||
amp?: boolean | 'hybrid'; | ||
api?: { | ||
bodyParser?: boolean; | ||
}; | ||
} | ||
@@ -5,0 +8,0 @@ export declare type LoadComponentsReturnType = { |
@@ -41,3 +41,2 @@ /// <reference types="node" /> | ||
canonicalBase: string; | ||
autoExport: boolean; | ||
documentMiddlewareEnabled: boolean; | ||
@@ -44,0 +43,0 @@ dev?: boolean; |
@@ -20,3 +20,2 @@ "use strict"; | ||
const envConfig = __importStar(require("../lib/runtime-config")); | ||
const cookie_1 = require("cookie"); | ||
const api_utils_1 = require("./api-utils"); | ||
@@ -50,3 +49,2 @@ const config_1 = __importDefault(require("./config")); | ||
canonicalBase: this.nextConfig.amp.canonicalBase, | ||
autoExport: this.nextConfig.experimental.autoExport, | ||
documentMiddlewareEnabled: this.nextConfig.experimental | ||
@@ -183,4 +181,17 @@ .documentMiddleware, | ||
async handleApiRequest(req, res, pathname) { | ||
const resolverFunction = await this.resolveApiRequest(pathname); | ||
if (resolverFunction === null) { | ||
let bodyParser = true; | ||
let params = false; | ||
let resolverFunction = await this.resolveApiRequest(pathname); | ||
if (this.dynamicRoutes && | ||
this.dynamicRoutes.length > 0 && | ||
!resolverFunction) { | ||
for (const dynamicRoute of this.dynamicRoutes) { | ||
params = dynamicRoute.match(pathname); | ||
if (params) { | ||
resolverFunction = await this.resolveApiRequest(dynamicRoute.page); | ||
break; | ||
} | ||
} | ||
} | ||
if (!resolverFunction) { | ||
res.statusCode = 404; | ||
@@ -191,12 +202,21 @@ res.end('Not Found'); | ||
try { | ||
const resolverModule = require(resolverFunction); | ||
if (resolverModule.config) { | ||
const config = resolverModule.config; | ||
if (config.api && config.api.bodyParser === false) { | ||
bodyParser = false; | ||
} | ||
} | ||
// Parsing of cookies | ||
req.cookies = cookie_1.parse(req.headers.cookie || ''); | ||
api_utils_1.setLazyProp({ req }, 'cookies', api_utils_1.getCookieParser(req)); | ||
// Parsing query string | ||
req.query = api_utils_1.parseQuery(req); | ||
api_utils_1.setLazyProp({ req, params }, 'query', api_utils_1.getQueryParser(req)); | ||
// // Parsing of body | ||
req.body = await api_utils_1.parseBody(req); | ||
if (bodyParser) { | ||
req.body = await api_utils_1.parseBody(req); | ||
} | ||
res.status = statusCode => api_utils_1.sendStatusCode(res, statusCode); | ||
res.send = data => api_utils_1.sendData(res, data); | ||
res.json = data => api_utils_1.sendJson(res, data); | ||
const resolver = load_components_1.interopDefault(require(resolverFunction)); | ||
const resolver = load_components_1.interopDefault(resolverModule); | ||
resolver(req, res); | ||
@@ -203,0 +223,0 @@ } |
@@ -10,3 +10,2 @@ /// <reference types="node" /> | ||
declare type RenderOpts = { | ||
autoExport: boolean; | ||
documentMiddlewareEnabled: boolean; | ||
@@ -26,7 +25,7 @@ ampBindInitData: boolean; | ||
dev?: boolean; | ||
ampMode?: any; | ||
ampPath?: string; | ||
amphtml?: boolean; | ||
hasAmp?: boolean; | ||
ampMode?: any; | ||
dataOnly?: boolean; | ||
inAmpMode?: boolean; | ||
hybridAmp?: boolean; | ||
buildManifest: BuildManifest; | ||
@@ -33,0 +32,0 @@ reactLoadableManifest: ReactLoadableManifest; |
@@ -27,3 +27,3 @@ "use strict"; | ||
const get_page_files_1 = require("./get-page-files"); | ||
const amphtml_context_1 = require("../lib/amphtml-context"); | ||
const amp_context_1 = require("../lib/amp-context"); | ||
const optimize_amp_1 = __importDefault(require("./optimize-amp")); | ||
@@ -90,9 +90,9 @@ const amp_1 = require("../lib/amp"); | ||
finally { | ||
head = head_1.default.rewind() || head_1.defaultHead(undefined, amp_1.isAmp(ampMode)); | ||
head = head_1.default.rewind() || head_1.defaultHead(undefined, amp_1.isInAmpMode(ampMode)); | ||
} | ||
return { html, head }; | ||
} | ||
function renderDocument(Document, { dataManagerData, props, docProps, pathname, query, buildId, canonicalBase, dynamicBuildId = false, assetPrefix, runtimeConfig, nextExport, dynamicImportsIds, dangerousAsPath, err, dev, ampPath, amphtml, hasAmp, ampMode, staticMarkup, devFiles, files, dynamicImports, }) { | ||
function renderDocument(Document, { dataManagerData, props, docProps, pathname, query, buildId, canonicalBase, dynamicBuildId = false, assetPrefix, runtimeConfig, nextExport, dynamicImportsIds, dangerousAsPath, err, dev, ampPath, ampState, inAmpMode, hybridAmp, staticMarkup, devFiles, files, dynamicImports, }) { | ||
return ('<!DOCTYPE html>' + | ||
server_1.renderToStaticMarkup(react_1.default.createElement(amphtml_context_1.AmpModeContext.Provider, { value: ampMode }, | ||
server_1.renderToStaticMarkup(react_1.default.createElement(amp_context_1.AmpStateContext.Provider, { value: ampState }, | ||
react_1.default.createElement(Document, Object.assign({ __NEXT_DATA__: { | ||
@@ -110,7 +110,7 @@ dataManager: dataManagerData, | ||
err: err ? serializeError(dev, err) : undefined, | ||
}, dangerousAsPath: dangerousAsPath, canonicalBase: canonicalBase, ampPath: ampPath, amphtml: amphtml, hasAmp: hasAmp, staticMarkup: staticMarkup, devFiles: devFiles, files: files, dynamicImports: dynamicImports, assetPrefix: assetPrefix }, docProps))))); | ||
}, dangerousAsPath: dangerousAsPath, canonicalBase: canonicalBase, ampPath: ampPath, inAmpMode: inAmpMode, hybridAmp: hybridAmp, staticMarkup: staticMarkup, devFiles: devFiles, files: files, dynamicImports: dynamicImports, assetPrefix: assetPrefix }, docProps))))); | ||
} | ||
async function renderToHTML(req, res, pathname, query, renderOpts) { | ||
pathname = pathname === '/index' ? '/' : pathname; | ||
const { err, dev = false, autoExport = false, documentMiddlewareEnabled = false, ampBindInitData = false, staticMarkup = false, ampPath = '', App, Document, PageConfig, DocumentMiddleware, Component, buildManifest, reactLoadableManifest, ErrorDebug, } = renderOpts; | ||
const { err, dev = false, documentMiddlewareEnabled = false, ampBindInitData = false, staticMarkup = false, ampPath = '', App, Document, PageConfig, DocumentMiddleware, Component, buildManifest, reactLoadableManifest, ErrorDebug, } = renderOpts; | ||
await loadable_1.default.preloadAll(); // Make sure all dynamic imports are loaded | ||
@@ -129,13 +129,11 @@ let isStaticPage = false; | ||
} | ||
if (autoExport) { | ||
isStaticPage = typeof Component.getInitialProps !== 'function'; | ||
const defaultAppGetInitialProps = App.getInitialProps === App.origGetInitialProps; | ||
isStaticPage = isStaticPage && defaultAppGetInitialProps; | ||
if (isStaticPage) { | ||
// remove query values except ones that will be set during export | ||
query = { | ||
amp: query.amp, | ||
}; | ||
renderOpts.nextExport = true; | ||
} | ||
isStaticPage = typeof Component.getInitialProps !== 'function'; | ||
const defaultAppGetInitialProps = App.getInitialProps === App.origGetInitialProps; | ||
isStaticPage = isStaticPage && defaultAppGetInitialProps; | ||
if (isStaticPage) { | ||
// remove query values except ones that will be set during export | ||
query = { | ||
amp: query.amp, | ||
}; | ||
renderOpts.nextExport = true; | ||
} | ||
@@ -181,2 +179,7 @@ } | ||
} | ||
const ampState = { | ||
ampFirst: PageConfig.amp === true, | ||
hasQuery: Boolean(query.amp), | ||
hybrid: PageConfig.amp === 'hybrid', | ||
}; | ||
const reactLoadableModules = []; | ||
@@ -188,3 +191,3 @@ const renderElementToString = staticMarkup | ||
if (ctx.err && ErrorDebug) { | ||
return render(renderElementToString, react_1.default.createElement(ErrorDebug, { error: ctx.err }), ampMode); | ||
return render(renderElementToString, react_1.default.createElement(ErrorDebug, { error: ctx.err }), ampState); | ||
} | ||
@@ -196,7 +199,2 @@ if (dev && (props.router || props.Component)) { | ||
let renderPage; | ||
const ampMode = { | ||
enabled: Boolean(PageConfig.amp), | ||
hasQuery: Boolean(query.amp), | ||
hybrid: PageConfig.amp === 'hybrid', | ||
}; | ||
if (ampBindInitData) { | ||
@@ -212,3 +210,3 @@ const ssrPrepass = require('react-ssr-prepass'); | ||
react_1.default.createElement(data_manager_context_1.DataManagerContext.Provider, { value: dataManager }, | ||
react_1.default.createElement(amphtml_context_1.AmpModeContext.Provider, { value: ampMode }, | ||
react_1.default.createElement(amp_context_1.AmpStateContext.Provider, { value: ampState }, | ||
react_1.default.createElement(loadable_context_1.LoadableContext.Provider, { value: moduleName => reactLoadableModules.push(moduleName) }, | ||
@@ -218,3 +216,3 @@ react_1.default.createElement(EnhancedApp, Object.assign({ Component: EnhancedComponent, router: router }, props)))))))); | ||
try { | ||
return render(renderElementToString, element, ampMode); | ||
return render(renderElementToString, element, ampState); | ||
} | ||
@@ -232,3 +230,3 @@ catch (err) { | ||
else { | ||
return render(renderElementToString, element, ampMode); | ||
return render(renderElementToString, element, ampState); | ||
} | ||
@@ -248,5 +246,5 @@ } | ||
react_1.default.createElement(router_context_1.RouterContext.Provider, { value: router }, | ||
react_1.default.createElement(amphtml_context_1.AmpModeContext.Provider, { value: ampMode }, | ||
react_1.default.createElement(amp_context_1.AmpStateContext.Provider, { value: ampState }, | ||
react_1.default.createElement(loadable_context_1.LoadableContext.Provider, { value: moduleName => reactLoadableModules.push(moduleName) }, | ||
react_1.default.createElement(EnhancedApp, Object.assign({ Component: EnhancedComponent, router: router }, props)))))), ampMode); | ||
react_1.default.createElement(EnhancedApp, Object.assign({ Component: EnhancedComponent, router: router }, props)))))), ampState); | ||
}; | ||
@@ -275,9 +273,9 @@ } | ||
]; | ||
const amphtml = amp_1.isAmp(ampMode); | ||
const hasAmp = !amphtml && ampMode.enabled; | ||
// update renderOpts so export knows it's AMP | ||
renderOpts.amphtml = amphtml; | ||
renderOpts.hasAmp = hasAmp; | ||
const inAmpMode = amp_1.isInAmpMode(ampState); | ||
const hybridAmp = ampState.hybrid; | ||
// update renderOpts so export knows it's AMP state | ||
renderOpts.inAmpMode = inAmpMode; | ||
renderOpts.hybridAmp = hybridAmp; | ||
let html = renderDocument(Document, Object.assign({}, renderOpts, { dangerousAsPath: router.asPath, dataManagerData, | ||
ampMode, | ||
ampState, | ||
props, | ||
@@ -287,5 +285,5 @@ docProps, | ||
ampPath, | ||
amphtml, | ||
hasAmp, | ||
query, | ||
inAmpMode, | ||
hybridAmp, | ||
dynamicImportsIds, | ||
@@ -295,3 +293,3 @@ dynamicImports, | ||
devFiles })); | ||
if (amphtml && html) { | ||
if (inAmpMode && html) { | ||
// use replace to allow rendering directly to body in AMP mode | ||
@@ -304,3 +302,3 @@ html = html.replace('__NEXT_AMP_RENDER_TARGET__', `<!-- __NEXT_DATA__ -->${docProps.html}`); | ||
} | ||
if (amphtml || hasAmp) { | ||
if (inAmpMode || hybridAmp) { | ||
// fix & being escaped for amphtml rel link | ||
@@ -307,0 +305,0 @@ html = html.replace(/&amp=1/g, '&=1'); |
@@ -5,3 +5,3 @@ /// <reference types="node" /> | ||
export declare const route: (path: string) => (pathname: string | undefined, params?: any) => any; | ||
declare type Params = { | ||
export declare type Params = { | ||
[param: string]: any; | ||
@@ -20,2 +20,1 @@ }; | ||
} | ||
export {}; |
{ | ||
"name": "next-server", | ||
"version": "8.1.1-canary.61", | ||
"version": "8.1.1-canary.62", | ||
"main": "./index.js", | ||
@@ -73,3 +73,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "44d8c624f4a178275f8432570ebd203ff63b93b9" | ||
"gitHead": "808a3bcc66b13ef4a2a59fd741550c79d77331b1" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
135525
3428