@ohos-ports/layer0-prefetch 4.20.0-beta.0 → 4.20.0-beta.1
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.
- package/node_modules/@layer0/core/README.md +50 -0
- package/node_modules/@layer0/core/build.d.ts +5 -0
- package/node_modules/@layer0/core/build.js +17 -0
- package/node_modules/@layer0/core/cache/Cache.d.ts +56 -0
- package/node_modules/@layer0/core/cache/Cache.js +138 -0
- package/node_modules/@layer0/core/cache/CacheKey.d.ts +52 -0
- package/node_modules/@layer0/core/cache/CacheKey.js +95 -0
- package/node_modules/@layer0/core/config.d.ts +53 -0
- package/node_modules/@layer0/core/config.js +113 -0
- package/node_modules/@layer0/core/constants.d.ts +214 -0
- package/node_modules/@layer0/core/constants.js +216 -0
- package/node_modules/@layer0/core/context.d.ts +38 -0
- package/node_modules/@layer0/core/context.js +98 -0
- package/node_modules/@layer0/core/default-app/all/layer0.config.js +60 -0
- package/node_modules/@layer0/core/default-app/js/routes.js +27 -0
- package/node_modules/@layer0/core/default-app/ts/routes.ts +27 -0
- package/node_modules/@layer0/core/deploy/DeploymentBuilder.d.ts +177 -0
- package/node_modules/@layer0/core/deploy/DeploymentBuilder.js +543 -0
- package/node_modules/@layer0/core/deploy/bundle-esbuild.d.ts +11 -0
- package/node_modules/@layer0/core/deploy/bundle-esbuild.js +67 -0
- package/node_modules/@layer0/core/deploy/bundle-ncc.d.ts +8 -0
- package/node_modules/@layer0/core/deploy/bundle-ncc.js +30 -0
- package/node_modules/@layer0/core/deploy/bundle-nft.d.ts +7 -0
- package/node_modules/@layer0/core/deploy/bundle-nft.js +41 -0
- package/node_modules/@layer0/core/deploy/bundle-webpack.d.ts +11 -0
- package/node_modules/@layer0/core/deploy/bundle-webpack.js +127 -0
- package/node_modules/@layer0/core/deploy/index.d.ts +19 -0
- package/node_modules/@layer0/core/deploy/index.js +6 -0
- package/node_modules/@layer0/core/deploy/listSources.d.ts +11 -0
- package/node_modules/@layer0/core/deploy/listSources.js +18 -0
- package/node_modules/@layer0/core/deploy/paths.d.ts +27 -0
- package/node_modules/@layer0/core/deploy/paths.js +33 -0
- package/node_modules/@layer0/core/deploy/resolveInPackage.d.ts +7 -0
- package/node_modules/@layer0/core/deploy/resolveInPackage.js +21 -0
- package/node_modules/@layer0/core/deploy/routeToFiles.d.ts +14 -0
- package/node_modules/@layer0/core/deploy/routeToFiles.js +24 -0
- package/node_modules/@layer0/core/dev/DevServerOptions.d.ts +33 -0
- package/node_modules/@layer0/core/dev/DevServerOptions.js +2 -0
- package/node_modules/@layer0/core/dev/createDevServer.d.ts +8 -0
- package/node_modules/@layer0/core/dev/createDevServer.js +114 -0
- package/node_modules/@layer0/core/dev/index.d.ts +3 -0
- package/node_modules/@layer0/core/dev/index.js +6 -0
- package/node_modules/@layer0/core/dev/runLocalApp.d.ts +8 -0
- package/node_modules/@layer0/core/dev/runLocalApp.js +73 -0
- package/node_modules/@layer0/core/dev/serverlessCompatibilityMiddleware.d.ts +11 -0
- package/node_modules/@layer0/core/dev/serverlessCompatibilityMiddleware.js +30 -0
- package/node_modules/@layer0/core/edge/EdgeErrorPageResponseWriter.d.ts +12 -0
- package/node_modules/@layer0/core/edge/EdgeErrorPageResponseWriter.js +22 -0
- package/node_modules/@layer0/core/edge/EdgeResponseWriter.d.ts +122 -0
- package/node_modules/@layer0/core/edge/EdgeResponseWriter.js +451 -0
- package/node_modules/@layer0/core/edge/createEdgeConfig.d.ts +16 -0
- package/node_modules/@layer0/core/edge/createEdgeConfig.js +284 -0
- package/node_modules/@layer0/core/environment.d.ts +24 -0
- package/node_modules/@layer0/core/environment.js +42 -0
- package/node_modules/@layer0/core/errors/BackendFetchError.d.ts +11 -0
- package/node_modules/@layer0/core/errors/BackendFetchError.js +17 -0
- package/node_modules/@layer0/core/errors/FrameworkBuildError.d.ts +7 -0
- package/node_modules/@layer0/core/errors/FrameworkBuildError.js +26 -0
- package/node_modules/@layer0/core/index.d.ts +3 -0
- package/node_modules/@layer0/core/index.js +9 -0
- package/node_modules/@layer0/core/init/addToPackageJson.d.ts +7 -0
- package/node_modules/@layer0/core/init/addToPackageJson.js +22 -0
- package/node_modules/@layer0/core/init/index.d.ts +2 -0
- package/node_modules/@layer0/core/init/index.js +6 -0
- package/node_modules/@layer0/core/init/init.d.ts +5 -0
- package/node_modules/@layer0/core/init/init.js +17 -0
- package/node_modules/@layer0/core/lambda/JSBackend.d.ts +30 -0
- package/node_modules/@layer0/core/lambda/JSBackend.js +51 -0
- package/node_modules/@layer0/core/lambda/RequestListenerJSBackend.d.ts +8 -0
- package/node_modules/@layer0/core/lambda/RequestListenerJSBackend.js +19 -0
- package/node_modules/@layer0/core/lambda/adaptResponseEncodingToDownstream.d.ts +17 -0
- package/node_modules/@layer0/core/lambda/adaptResponseEncodingToDownstream.js +132 -0
- package/node_modules/@layer0/core/lambda/consoleWrapper.d.ts +16 -0
- package/node_modules/@layer0/core/lambda/consoleWrapper.js +127 -0
- package/node_modules/@layer0/core/lambda/getBodyLoggingData.d.ts +10 -0
- package/node_modules/@layer0/core/lambda/getBodyLoggingData.js +108 -0
- package/node_modules/@layer0/core/lambda/handler.d.ts +1 -0
- package/node_modules/@layer0/core/lambda/handler.js +91 -0
- package/node_modules/@layer0/core/lambda/handler.js.map +7 -0
- package/node_modules/@layer0/core/lambda/innerHandler.d.ts +7 -0
- package/node_modules/@layer0/core/lambda/innerHandler.js +181 -0
- package/node_modules/@layer0/core/lambda/lambdaInstance.d.ts +29 -0
- package/node_modules/@layer0/core/lambda/lambdaInstance.js +71 -0
- package/node_modules/@layer0/core/lambda/reqResMapper.d.ts +24 -0
- package/node_modules/@layer0/core/lambda/reqResMapper.js +286 -0
- package/node_modules/@layer0/core/lambda/stdStreamsWrapper.d.ts +31 -0
- package/node_modules/@layer0/core/lambda/stdStreamsWrapper.js +196 -0
- package/node_modules/@layer0/core/lambda/toJSBackend.d.ts +10 -0
- package/node_modules/@layer0/core/lambda/toJSBackend.js +23 -0
- package/node_modules/@layer0/core/node_modules/esbuild/LICENSE.md +21 -0
- package/node_modules/@layer0/core/node_modules/esbuild/README.md +3 -0
- package/node_modules/@layer0/core/node_modules/esbuild/bin/esbuild +223 -0
- package/node_modules/@layer0/core/node_modules/esbuild/install.js +301 -0
- package/node_modules/@layer0/core/node_modules/esbuild/lib/main.d.ts +716 -0
- package/node_modules/@layer0/core/node_modules/esbuild/lib/main.js +2532 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/README.md +3 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/bin/esbuild +0 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/esbuild.wasm +0 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/package.json +28 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/wasm_exec.js +575 -0
- package/node_modules/@layer0/core/node_modules/esbuild/node_modules/@ohos-ports/esbuild-openharmony-arm64/wasm_exec_node.js +40 -0
- package/node_modules/@layer0/core/node_modules/esbuild/package.json +78 -0
- package/node_modules/@layer0/core/package.json +132 -0
- package/node_modules/@layer0/core/parser/parseRouter.d.ts +13 -0
- package/node_modules/@layer0/core/parser/parseRouter.js +77 -0
- package/node_modules/@layer0/core/plugins/PluginBase.d.ts +18 -0
- package/node_modules/@layer0/core/plugins/PluginBase.js +19 -0
- package/node_modules/@layer0/core/router/Backend.d.ts +69 -0
- package/node_modules/@layer0/core/router/Backend.js +176 -0
- package/node_modules/@layer0/core/router/BackendOptions.d.ts +11 -0
- package/node_modules/@layer0/core/router/BackendOptions.js +2 -0
- package/node_modules/@layer0/core/router/BaseResponseWriter.d.ts +65 -0
- package/node_modules/@layer0/core/router/BaseResponseWriter.js +81 -0
- package/node_modules/@layer0/core/router/BehindEdgeResponseWriterProxy.d.ts +4 -0
- package/node_modules/@layer0/core/router/BehindEdgeResponseWriterProxy.js +89 -0
- package/node_modules/@layer0/core/router/CacheManifest.d.ts +80 -0
- package/node_modules/@layer0/core/router/CacheManifest.js +83 -0
- package/node_modules/@layer0/core/router/CacheOptions.d.ts +171 -0
- package/node_modules/@layer0/core/router/CacheOptions.js +2 -0
- package/node_modules/@layer0/core/router/CustomCacheKey.d.ts +140 -0
- package/node_modules/@layer0/core/router/CustomCacheKey.js +272 -0
- package/node_modules/@layer0/core/router/GroupConfig.d.ts +7 -0
- package/node_modules/@layer0/core/router/GroupConfig.js +20 -0
- package/node_modules/@layer0/core/router/Groups.d.ts +7 -0
- package/node_modules/@layer0/core/router/Groups.js +21 -0
- package/node_modules/@layer0/core/router/Headers.d.ts +3 -0
- package/node_modules/@layer0/core/router/Headers.js +2 -0
- package/node_modules/@layer0/core/router/PathMatcher.d.ts +51 -0
- package/node_modules/@layer0/core/router/PathMatcher.js +73 -0
- package/node_modules/@layer0/core/router/Preload.d.ts +16 -0
- package/node_modules/@layer0/core/router/Preload.js +2 -0
- package/node_modules/@layer0/core/router/PreloadRequests.d.ts +23 -0
- package/node_modules/@layer0/core/router/PreloadRequests.js +66 -0
- package/node_modules/@layer0/core/router/Request.d.ts +74 -0
- package/node_modules/@layer0/core/router/Request.js +2 -0
- package/node_modules/@layer0/core/router/RequestContext.d.ts +12 -0
- package/node_modules/@layer0/core/router/RequestContext.js +11 -0
- package/node_modules/@layer0/core/router/Response.d.ts +55 -0
- package/node_modules/@layer0/core/router/Response.js +2 -0
- package/node_modules/@layer0/core/router/ResponseWriter.d.ts +1011 -0
- package/node_modules/@layer0/core/router/ResponseWriter.js +1341 -0
- package/node_modules/@layer0/core/router/Route.d.ts +124 -0
- package/node_modules/@layer0/core/router/Route.js +280 -0
- package/node_modules/@layer0/core/router/RouteCriteria.d.ts +68 -0
- package/node_modules/@layer0/core/router/RouteCriteria.js +2 -0
- package/node_modules/@layer0/core/router/RouteGroup.d.ts +157 -0
- package/node_modules/@layer0/core/router/RouteGroup.js +223 -0
- package/node_modules/@layer0/core/router/RouteGroupList.d.ts +45 -0
- package/node_modules/@layer0/core/router/RouteGroupList.js +73 -0
- package/node_modules/@layer0/core/router/Router.d.ts +439 -0
- package/node_modules/@layer0/core/router/Router.js +907 -0
- package/node_modules/@layer0/core/router/addBuiltInRoutes.d.ts +2 -0
- package/node_modules/@layer0/core/router/addBuiltInRoutes.js +58 -0
- package/node_modules/@layer0/core/router/addPreloadHeaders.d.ts +7 -0
- package/node_modules/@layer0/core/router/addPreloadHeaders.js +57 -0
- package/node_modules/@layer0/core/router/cacheManifestFromRouter.d.ts +6 -0
- package/node_modules/@layer0/core/router/cacheManifestFromRouter.js +85 -0
- package/node_modules/@layer0/core/router/createCustomCacheKey.d.ts +27 -0
- package/node_modules/@layer0/core/router/createCustomCacheKey.js +35 -0
- package/node_modules/@layer0/core/router/deriveSurrogateKeysFromJson.d.ts +36 -0
- package/node_modules/@layer0/core/router/deriveSurrogateKeysFromJson.js +70 -0
- package/node_modules/@layer0/core/router/index.d.ts +11 -0
- package/node_modules/@layer0/core/router/index.js +17 -0
- package/node_modules/@layer0/core/router/interpolateParams.d.ts +21 -0
- package/node_modules/@layer0/core/router/interpolateParams.js +150 -0
- package/node_modules/@layer0/core/router/loadRouter.d.ts +13 -0
- package/node_modules/@layer0/core/router/loadRouter.js +29 -0
- package/node_modules/@layer0/core/router/mergeQueryString.d.ts +1 -0
- package/node_modules/@layer0/core/router/mergeQueryString.js +23 -0
- package/node_modules/@layer0/core/router/normalizeCriteria.d.ts +6 -0
- package/node_modules/@layer0/core/router/normalizeCriteria.js +20 -0
- package/node_modules/@layer0/core/router/stream.d.ts +12 -0
- package/node_modules/@layer0/core/router/stream.js +30 -0
- package/node_modules/@layer0/core/router/universalRouteUtils.d.ts +55 -0
- package/node_modules/@layer0/core/router/universalRouteUtils.js +114 -0
- package/node_modules/@layer0/core/router/validateWriter.d.ts +41 -0
- package/node_modules/@layer0/core/router/validateWriter.js +120 -0
- package/node_modules/@layer0/core/serverless.yml +30 -0
- package/node_modules/@layer0/core/source.d.ts +9 -0
- package/node_modules/@layer0/core/source.js +17 -0
- package/node_modules/@layer0/core/test-utils/MockRequest.d.ts +15 -0
- package/node_modules/@layer0/core/test-utils/MockRequest.js +36 -0
- package/node_modules/@layer0/core/test-utils/MockResponse.d.ts +7 -0
- package/node_modules/@layer0/core/test-utils/MockResponse.js +24 -0
- package/node_modules/@layer0/core/test-utils/expect-extend.d.ts +1 -0
- package/node_modules/@layer0/core/test-utils/expect-extend.js +11 -0
- package/node_modules/@layer0/core/test-utils/index.d.ts +4 -0
- package/node_modules/@layer0/core/test-utils/index.js +11 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheBrowser.d.ts +19 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheBrowser.js +45 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheEdge.d.ts +19 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheEdge.js +38 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheServiceWorker.d.ts +19 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeCachedByTheServiceWorker.js +45 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeServedStale.d.ts +20 -0
- package/node_modules/@layer0/core/test-utils/matchers/toBeServedStale.js +50 -0
- package/node_modules/@layer0/core/test-utils/matchers/toHaveBody.d.ts +18 -0
- package/node_modules/@layer0/core/test-utils/matchers/toHaveBody.js +40 -0
- package/node_modules/@layer0/core/test-utils/matchers/toHaveHeader.d.ts +19 -0
- package/node_modules/@layer0/core/test-utils/matchers/toHaveHeader.js +43 -0
- package/node_modules/@layer0/core/test-utils/matchers.d.ts +6 -0
- package/node_modules/@layer0/core/test-utils/matchers.js +18 -0
- package/node_modules/@layer0/core/test-utils/utils/createRouteMock.d.ts +21 -0
- package/node_modules/@layer0/core/test-utils/utils/createRouteMock.js +27 -0
- package/node_modules/@layer0/core/test-utils/utils/getBackend.d.ts +13 -0
- package/node_modules/@layer0/core/test-utils/utils/getBackend.js +30 -0
- package/node_modules/@layer0/core/test-utils/utils/getMessage.d.ts +1 -0
- package/node_modules/@layer0/core/test-utils/utils/getMessage.js +16 -0
- package/node_modules/@layer0/core/test-utils/utils/runRoute.d.ts +10 -0
- package/node_modules/@layer0/core/test-utils/utils/runRoute.js +39 -0
- package/node_modules/@layer0/core/timing.d.ts +115 -0
- package/node_modules/@layer0/core/timing.js +200 -0
- package/node_modules/@layer0/core/transform/index.d.ts +1 -0
- package/node_modules/@layer0/core/transform/index.js +4 -0
- package/node_modules/@layer0/core/transform/transformMethod.d.ts +40 -0
- package/node_modules/@layer0/core/transform/transformMethod.js +58 -0
- package/node_modules/@layer0/core/types.d.ts +102 -0
- package/node_modules/@layer0/core/types.js +30 -0
- package/node_modules/@layer0/core/utils/Tasks.d.ts +32 -0
- package/node_modules/@layer0/core/utils/Tasks.js +80 -0
- package/node_modules/@layer0/core/utils/Validator.d.ts +18 -0
- package/node_modules/@layer0/core/utils/Validator.js +178 -0
- package/node_modules/@layer0/core/utils/bindParamsToPath.d.ts +15 -0
- package/node_modules/@layer0/core/utils/bindParamsToPath.js +49 -0
- package/node_modules/@layer0/core/utils/convertParamsToBackReferences.d.ts +16 -0
- package/node_modules/@layer0/core/utils/convertParamsToBackReferences.js +45 -0
- package/node_modules/@layer0/core/utils/convertStringMatcherToRegex.d.ts +7 -0
- package/node_modules/@layer0/core/utils/convertStringMatcherToRegex.js +26 -0
- package/node_modules/@layer0/core/utils/decode.d.ts +9 -0
- package/node_modules/@layer0/core/utils/decode.js +44 -0
- package/node_modules/@layer0/core/utils/esImport.d.ts +1 -0
- package/node_modules/@layer0/core/utils/esImport.js +9 -0
- package/node_modules/@layer0/core/utils/fs.d.ts +1 -0
- package/node_modules/@layer0/core/utils/fs.js +7 -0
- package/node_modules/@layer0/core/utils/get.d.ts +6 -0
- package/node_modules/@layer0/core/utils/get.js +19 -0
- package/node_modules/@layer0/core/utils/getPackageVersion.d.ts +7 -0
- package/node_modules/@layer0/core/utils/getPackageVersion.js +19 -0
- package/node_modules/@layer0/core/utils/has.d.ts +6 -0
- package/node_modules/@layer0/core/utils/has.js +15 -0
- package/node_modules/@layer0/core/utils/identity.d.ts +7 -0
- package/node_modules/@layer0/core/utils/identity.js +12 -0
- package/node_modules/@layer0/core/utils/index.d.ts +1 -0
- package/node_modules/@layer0/core/utils/index.js +4 -0
- package/node_modules/@layer0/core/utils/isEmpty.d.ts +6 -0
- package/node_modules/@layer0/core/utils/isEmpty.js +20 -0
- package/node_modules/@layer0/core/utils/isString.d.ts +1 -0
- package/node_modules/@layer0/core/utils/isString.js +6 -0
- package/node_modules/@layer0/core/utils/logo.d.ts +5 -0
- package/node_modules/@layer0/core/utils/logo.js +27 -0
- package/node_modules/@layer0/core/utils/mapValues.d.ts +7 -0
- package/node_modules/@layer0/core/utils/mapValues.js +16 -0
- package/node_modules/@layer0/core/utils/minBy.d.ts +8 -0
- package/node_modules/@layer0/core/utils/minBy.js +41 -0
- package/node_modules/@layer0/core/utils/nonWebpackRequire.d.ts +11 -0
- package/node_modules/@layer0/core/utils/nonWebpackRequire.js +28 -0
- package/node_modules/@layer0/core/utils/packageUtils.d.ts +12 -0
- package/node_modules/@layer0/core/utils/packageUtils.js +22 -0
- package/node_modules/@layer0/core/utils/ports.d.ts +5 -0
- package/node_modules/@layer0/core/utils/ports.js +7 -0
- package/node_modules/@layer0/core/utils/readBody.d.ts +7 -0
- package/node_modules/@layer0/core/utils/readBody.js +15 -0
- package/node_modules/@layer0/core/utils/readRawBody.d.ts +9 -0
- package/node_modules/@layer0/core/utils/readRawBody.js +21 -0
- package/node_modules/@layer0/core/utils/regExpEscape.d.ts +12 -0
- package/node_modules/@layer0/core/utils/regExpEscape.js +20 -0
- package/node_modules/@layer0/core/utils/requireInternal.d.ts +7 -0
- package/node_modules/@layer0/core/utils/requireInternal.js +24 -0
- package/node_modules/@layer0/core/utils/set.d.ts +10 -0
- package/node_modules/@layer0/core/utils/set.js +21 -0
- package/node_modules/@layer0/core/utils/toEdgeRegex.d.ts +11 -0
- package/node_modules/@layer0/core/utils/toEdgeRegex.js +23 -0
- package/node_modules/@layer0/core/utils/toHttpMethodMatchRegex.d.ts +12 -0
- package/node_modules/@layer0/core/utils/toHttpMethodMatchRegex.js +17 -0
- package/node_modules/@layer0/core/utils/toLower.d.ts +1 -0
- package/node_modules/@layer0/core/utils/toLower.js +9 -0
- package/node_modules/@layer0/core/utils/validateBackends.d.ts +5 -0
- package/node_modules/@layer0/core/utils/validateBackends.js +30 -0
- package/node_modules/@layer0/core/utils/watch.d.ts +10 -0
- package/node_modules/@layer0/core/utils/watch.js +17 -0
- package/package.json +47 -3
|
@@ -0,0 +1,907 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
6
|
+
if (mod && mod.__esModule) return mod;
|
|
7
|
+
var result = {};
|
|
8
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
9
|
+
result["default"] = mod;
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const constants_1 = require("../constants");
|
|
14
|
+
const timing_1 = require("../timing");
|
|
15
|
+
const uuid_1 = require("uuid");
|
|
16
|
+
const addBuiltInRoutes_1 = __importDefault(require("./addBuiltInRoutes"));
|
|
17
|
+
const BehindEdgeResponseWriterProxy_1 = __importDefault(require("./BehindEdgeResponseWriterProxy"));
|
|
18
|
+
const config_1 = __importDefault(require("../config"));
|
|
19
|
+
const createEdgeConfig_1 = __importDefault(require("../edge/createEdgeConfig"));
|
|
20
|
+
const interpolateParams_1 = __importDefault(require("./interpolateParams"));
|
|
21
|
+
const minBy_1 = __importDefault(require("../utils/minBy"));
|
|
22
|
+
const PreloadRequests_1 = __importDefault(require("./PreloadRequests"));
|
|
23
|
+
const readRawBody_1 = __importDefault(require("../utils/readRawBody"));
|
|
24
|
+
const RequestContext_1 = __importDefault(require("./RequestContext"));
|
|
25
|
+
const ResponseWriter_1 = __importDefault(require("./ResponseWriter"));
|
|
26
|
+
const RouteGroup_1 = __importStar(require("./RouteGroup"));
|
|
27
|
+
const RouteGroupList_1 = __importDefault(require("./RouteGroupList"));
|
|
28
|
+
const BROTLI_ENCODING_REGEX = /\bbr\b/;
|
|
29
|
+
const GZIP_ENCODING_REGEX = /\bgzip\b/;
|
|
30
|
+
/**
|
|
31
|
+
* A router.
|
|
32
|
+
*/
|
|
33
|
+
class Router {
|
|
34
|
+
constructor(options = {
|
|
35
|
+
excludeBuiltInRoutes: false,
|
|
36
|
+
allowReqQueryDuplicates: false,
|
|
37
|
+
}) {
|
|
38
|
+
var _a;
|
|
39
|
+
this.routeGroups = new RouteGroupList_1.default();
|
|
40
|
+
this.preloadRequests = new PreloadRequests_1.default();
|
|
41
|
+
this.plugins = [];
|
|
42
|
+
this.destinations = {};
|
|
43
|
+
this.nextRouterIndex = 0;
|
|
44
|
+
/**
|
|
45
|
+
* Index is used to determine the precedence of a router when routing rules
|
|
46
|
+
* have not resolved to a specific destination. The router with the lowest
|
|
47
|
+
* number wins.
|
|
48
|
+
* @private
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
this._index = 0;
|
|
52
|
+
/**
|
|
53
|
+
* Checks headers for validity and updates them as needed.
|
|
54
|
+
*
|
|
55
|
+
* Notes:
|
|
56
|
+
* - If x-request-id is not present we generate it and later inject it into
|
|
57
|
+
* the response.
|
|
58
|
+
* - If accept-encoding includes gzip then we use it but eliminating everything else
|
|
59
|
+
* as we don't support other encodings. If there is no gzip in accept-encoding
|
|
60
|
+
* then we delete it entirely forcing upstream to return uncoded response.
|
|
61
|
+
* - We emulate the edge router by injecting the same headers it injects:
|
|
62
|
+
* - x-0-client-ip
|
|
63
|
+
* - x-forwarded-for
|
|
64
|
+
*/
|
|
65
|
+
this.processRequestHeaders = (req) => {
|
|
66
|
+
if (!req.headers[constants_1.HTTP_HEADERS.xRequestId]) {
|
|
67
|
+
this.newRequestId = uuid_1.v4();
|
|
68
|
+
req.headers[constants_1.HTTP_HEADERS.xRequestId] = this.newRequestId;
|
|
69
|
+
}
|
|
70
|
+
// Normalize the accept encoding.
|
|
71
|
+
let acceptEncoding = req.headers[constants_1.HTTP_HEADERS.acceptEncoding];
|
|
72
|
+
if (typeof acceptEncoding === 'string') {
|
|
73
|
+
const acceptGzipEncoding = GZIP_ENCODING_REGEX.test(acceptEncoding);
|
|
74
|
+
const acceptBrotliEncoding = BROTLI_ENCODING_REGEX.test(acceptEncoding);
|
|
75
|
+
// Connasence of algorithm and values with edge: when both gzip and br are acceptable
|
|
76
|
+
// to the downstream, we normalize the accept-encoding and send them both to the upstream.
|
|
77
|
+
if (acceptGzipEncoding && acceptBrotliEncoding) {
|
|
78
|
+
acceptEncoding = `${constants_1.GZIP_ENCODING}, ${constants_1.BROTLI_ENCODING}`;
|
|
79
|
+
}
|
|
80
|
+
else if (acceptGzipEncoding) {
|
|
81
|
+
acceptEncoding = constants_1.GZIP_ENCODING;
|
|
82
|
+
}
|
|
83
|
+
else if (acceptBrotliEncoding) {
|
|
84
|
+
acceptEncoding = constants_1.BROTLI_ENCODING;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
acceptEncoding = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
acceptEncoding = null;
|
|
92
|
+
}
|
|
93
|
+
if (acceptEncoding) {
|
|
94
|
+
req.headers[constants_1.HTTP_HEADERS.acceptEncoding] = acceptEncoding;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
delete req.headers[constants_1.HTTP_HEADERS.acceptEncoding];
|
|
98
|
+
}
|
|
99
|
+
// Append the our local address to the x-forwarded-for header. If x-forwarded-for does not exist, we create it.
|
|
100
|
+
const connection = req.connection;
|
|
101
|
+
let localAddress = '127.0.0.1'; // put a default in, in case the underlying environment does not provide Ip.
|
|
102
|
+
if (connection && connection.remoteAddress) {
|
|
103
|
+
localAddress = connection.remoteAddress;
|
|
104
|
+
// By default we treat all local connections as if they were made on HTTPS.
|
|
105
|
+
// We treat the request as HTTP only if the user sends the x-0-protocol or
|
|
106
|
+
// they are running with cookie `local_layer0_emulate_http_protocol` set to `true`.
|
|
107
|
+
if (req.headers[constants_1.HTTP_HEADERS.x0Protocol] !== 'http') {
|
|
108
|
+
const cookie = req.headers[constants_1.HTTP_HEADERS.cookie];
|
|
109
|
+
if (typeof cookie === 'string' &&
|
|
110
|
+
/\blocal_layer0_emulate_http_protocol=true\b/.test(cookie)) {
|
|
111
|
+
req.headers[constants_1.HTTP_HEADERS.x0Protocol] = 'http';
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
req.headers[constants_1.HTTP_HEADERS.x0Protocol] = 'https';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Assume HTTPS request when not specified. This doesn't normally happen as downstream
|
|
120
|
+
// components will have injected x-0-protocol by the time the Router is reached.
|
|
121
|
+
// But in tests we often use plain objects for requests and directly send them to a Router.
|
|
122
|
+
if (!req.headers[constants_1.HTTP_HEADERS.x0Protocol]) {
|
|
123
|
+
req.headers[constants_1.HTTP_HEADERS.x0Protocol] = 'https';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (req.headers[constants_1.HTTP_HEADERS.xForwardedFor]) {
|
|
127
|
+
req.headers[constants_1.HTTP_HEADERS.xForwardedFor] = `${req.headers[constants_1.HTTP_HEADERS.xForwardedFor]}, ${localAddress}`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
req.headers[constants_1.HTTP_HEADERS.xForwardedFor] = `${localAddress}`;
|
|
131
|
+
}
|
|
132
|
+
if (!req.headers[constants_1.HTTP_HEADERS.x0ClientIp]) {
|
|
133
|
+
// The client Ip is always the left most x-forwarded-for: value.
|
|
134
|
+
req.headers[constants_1.HTTP_HEADERS.x0ClientIp] = (req.headers[constants_1.HTTP_HEADERS.xForwardedFor]).split(',')[0];
|
|
135
|
+
}
|
|
136
|
+
if (!Router.isRequestFromEdge(req)) {
|
|
137
|
+
this.processRequestDeviceHeaders(req);
|
|
138
|
+
this.processRequestGeoHeaders(req);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Emulates edge by injecting device headers into the request prior to routing.
|
|
143
|
+
*
|
|
144
|
+
* Notes:
|
|
145
|
+
* - This code must be the same as the the generated edge router.
|
|
146
|
+
* - This code has been directly translated from ECL compiler
|
|
147
|
+
* - We emulate the edge router by injecting the same headers it injects:
|
|
148
|
+
* - x-0-device
|
|
149
|
+
* - x-0-vendor
|
|
150
|
+
* - x-0-browser
|
|
151
|
+
* - x-0-device-is-bot
|
|
152
|
+
*/
|
|
153
|
+
this.processRequestDeviceHeaders = (req) => {
|
|
154
|
+
let device = 'desktop';
|
|
155
|
+
let vendor = 'generic';
|
|
156
|
+
let isBot = false;
|
|
157
|
+
let browser = 'generic';
|
|
158
|
+
// Note: unlike outer-edge code, we transform everything to lower case for faster matching
|
|
159
|
+
const ua = (req.headers[constants_1.HTTP_HEADERS.userAgent] || '').toLowerCase();
|
|
160
|
+
if (/ipad/.test(ua)) {
|
|
161
|
+
device = 'tablet';
|
|
162
|
+
vendor = 'apple';
|
|
163
|
+
}
|
|
164
|
+
else if (/ip(hone|od)/.test(ua)) {
|
|
165
|
+
device = 'smartphone';
|
|
166
|
+
vendor = 'apple';
|
|
167
|
+
}
|
|
168
|
+
else if (/android.*(mobile|mini)/.test(ua)) {
|
|
169
|
+
device = 'smartphone';
|
|
170
|
+
vendor = 'android';
|
|
171
|
+
}
|
|
172
|
+
else if (/android/.test(ua)) {
|
|
173
|
+
device = 'tablet';
|
|
174
|
+
vendor = 'android';
|
|
175
|
+
}
|
|
176
|
+
else if (/opera mobi/.test(ua)) {
|
|
177
|
+
device = 'smartphone';
|
|
178
|
+
vendor = 'android';
|
|
179
|
+
}
|
|
180
|
+
else if (/playbook u rim tablet/.test(ua)) {
|
|
181
|
+
device = 'tablet';
|
|
182
|
+
vendor = 'blackberry';
|
|
183
|
+
}
|
|
184
|
+
else if (/hp-tablet.*touchpad/.test(ua)) {
|
|
185
|
+
device = 'tablet';
|
|
186
|
+
vendor = 'hp';
|
|
187
|
+
}
|
|
188
|
+
else if (/kindle\/3/.test(ua)) {
|
|
189
|
+
device = 'tablet';
|
|
190
|
+
vendor = 'kindle';
|
|
191
|
+
}
|
|
192
|
+
else if (/mobile.+firefox/.test(ua)) {
|
|
193
|
+
device = 'mobile';
|
|
194
|
+
vendor = 'firefoxos';
|
|
195
|
+
}
|
|
196
|
+
else if (/^htc/.test(ua)) {
|
|
197
|
+
device = 'smartphone';
|
|
198
|
+
vendor = 'htc';
|
|
199
|
+
}
|
|
200
|
+
else if (/fennec/.test(ua)) {
|
|
201
|
+
device = 'smartphone';
|
|
202
|
+
vendor = 'fennec';
|
|
203
|
+
}
|
|
204
|
+
else if (/iemobile/.test(ua)) {
|
|
205
|
+
device = 'smartphone';
|
|
206
|
+
vendor = 'microsoft';
|
|
207
|
+
}
|
|
208
|
+
else if (/blackberry/.test(ua) || /bb10.*mobile/.test(ua)) {
|
|
209
|
+
device = 'smartphone';
|
|
210
|
+
vendor = 'blackberry';
|
|
211
|
+
}
|
|
212
|
+
else if (/gt-.*build\/gingerbread/.test(ua)) {
|
|
213
|
+
device = 'smartphone';
|
|
214
|
+
vendor = 'android';
|
|
215
|
+
}
|
|
216
|
+
else if (/symbianos.*applewebkit/.test(ua)) {
|
|
217
|
+
device = 'smartphone';
|
|
218
|
+
vendor = 'symbian';
|
|
219
|
+
}
|
|
220
|
+
else if (/symbian/.test(ua) ||
|
|
221
|
+
/^sonyericsson/.test(ua) ||
|
|
222
|
+
/^nokia/.test(ua) ||
|
|
223
|
+
/^samsung/.test(ua) ||
|
|
224
|
+
/^lg/.test(ua) ||
|
|
225
|
+
/bada/.test(ua) ||
|
|
226
|
+
/blazer/.test(ua) ||
|
|
227
|
+
/cellphone/.test(ua) ||
|
|
228
|
+
// /iemobile/.test(ua) || duplicate - this case never hits because it matches above
|
|
229
|
+
/midp-2.0/.test(ua) ||
|
|
230
|
+
/u990/.test(ua) ||
|
|
231
|
+
/netfront/.test(ua) ||
|
|
232
|
+
/opera mini/.test(ua) ||
|
|
233
|
+
/palm/.test(ua) ||
|
|
234
|
+
/nintendo wii/.test(ua) ||
|
|
235
|
+
/playstation portable/.test(ua) ||
|
|
236
|
+
/portalmmm/.test(ua) ||
|
|
237
|
+
/proxinet/.test(ua) ||
|
|
238
|
+
/sonyericsson/.test(ua) ||
|
|
239
|
+
// /symbian/.test(ua) || duplicate
|
|
240
|
+
/windows ?ce/.test(ua) ||
|
|
241
|
+
/winwap/.test(ua) ||
|
|
242
|
+
/eudoraweb/.test(ua) ||
|
|
243
|
+
// /htc/.test(ua) || duplicate
|
|
244
|
+
/240x320/.test(ua) ||
|
|
245
|
+
/avantgo/.test(ua)) {
|
|
246
|
+
device = 'mobile';
|
|
247
|
+
}
|
|
248
|
+
if (/bot/.test(ua) ||
|
|
249
|
+
/crawler/.test(ua) ||
|
|
250
|
+
/headless/.test(ua) ||
|
|
251
|
+
/prerender/.test(ua) ||
|
|
252
|
+
/preview/.test(ua) ||
|
|
253
|
+
/scanner/.test(ua) ||
|
|
254
|
+
/slurp/.test(ua) ||
|
|
255
|
+
/spider/.test(ua) ||
|
|
256
|
+
/(developers.google.com\/+\/web\/snippet|embedly|facebookexternalhit|flipboard|googlepagespeed|google page speed)/.test(ua) ||
|
|
257
|
+
/(ia_archiver|moov-prerender-cache-exerciser|nuzzel|outbrain|pinterest|qwantify|tumblr|vkshare)/.test(ua) ||
|
|
258
|
+
/(w3c_validator|whatsapp|xing-contenttabreceiver|yahoo)/.test(ua)) {
|
|
259
|
+
isBot = true;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
isBot = false;
|
|
263
|
+
}
|
|
264
|
+
if (/edge/.test(ua)) {
|
|
265
|
+
browser = 'edge';
|
|
266
|
+
}
|
|
267
|
+
else if (/chrome|chromium|crios/.test(ua)) {
|
|
268
|
+
browser = 'chrome';
|
|
269
|
+
}
|
|
270
|
+
else if (/firefox/.test(ua)) {
|
|
271
|
+
browser = 'firefox';
|
|
272
|
+
}
|
|
273
|
+
else if (/opera|opr/.test(ua)) {
|
|
274
|
+
browser = 'opera';
|
|
275
|
+
}
|
|
276
|
+
else if (/msie/.test(ua) || /trident/.test(ua)) {
|
|
277
|
+
browser = 'msie';
|
|
278
|
+
}
|
|
279
|
+
else if (/safari/.test(ua)) {
|
|
280
|
+
browser = 'safari';
|
|
281
|
+
}
|
|
282
|
+
req.headers[constants_1.HTTP_HEADERS.x0Device] = device;
|
|
283
|
+
req.headers[constants_1.HTTP_HEADERS.x0DeviceIsBot] = isBot ? '1' : '0';
|
|
284
|
+
req.headers[constants_1.HTTP_HEADERS.x0Vendor] = vendor;
|
|
285
|
+
req.headers[constants_1.HTTP_HEADERS.x0Browser] = browser;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Emulates edge by injecting Geolocation headers into the request prior to routing.
|
|
289
|
+
* - x-0-geo-city
|
|
290
|
+
* - x-0-geo-country-code
|
|
291
|
+
* - x-0-geo-latitude
|
|
292
|
+
* - x-0-geo-longitude
|
|
293
|
+
* - x-0-geo-postal-code
|
|
294
|
+
*/
|
|
295
|
+
this.processRequestGeoHeaders = (req) => {
|
|
296
|
+
req.headers[constants_1.HTTP_HEADERS.x0GeoCity] = 'San Francisco';
|
|
297
|
+
req.headers[constants_1.HTTP_HEADERS.x0GeoCountryCode] = 'US';
|
|
298
|
+
req.headers[constants_1.HTTP_HEADERS.x0GeoLatitude] = '37.792094';
|
|
299
|
+
req.headers[constants_1.HTTP_HEADERS.x0GeoLongitude] = '-122.401622';
|
|
300
|
+
req.headers[constants_1.HTTP_HEADERS.x0GeoPostalCode] = '94104';
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Adds the `rawBody` (Buffer) and `body` (String) to the request
|
|
304
|
+
* @param req
|
|
305
|
+
*/
|
|
306
|
+
this.processRequestBody = async (req) => {
|
|
307
|
+
req.rawBody = await readRawBody_1.default(req);
|
|
308
|
+
Object.defineProperty(req, 'body', {
|
|
309
|
+
configurable: true,
|
|
310
|
+
get() {
|
|
311
|
+
return this.rawBody.toString('utf8');
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* Checks if the number of user headers is within the limits.
|
|
317
|
+
*
|
|
318
|
+
* Notes:
|
|
319
|
+
* - User headers are all those that do not have `x-0-` prefix.
|
|
320
|
+
* - We check user headers counts in the router because in local
|
|
321
|
+
* development the router is running on "the edge" and we want to
|
|
322
|
+
* simulate the edge behavior (which actually has hard limits on
|
|
323
|
+
* header count - see `LAYER0_MAX_USER_HEADERS_ALLOWED` for more info)
|
|
324
|
+
*/
|
|
325
|
+
this.isUserHeaderCountWithinLimits = (headers) => {
|
|
326
|
+
const userHeaderNames = Object.keys(headers).filter(name => name.toLowerCase().indexOf(constants_1.LAYER0_HEADERS_PREFIX) !== 0);
|
|
327
|
+
return userHeaderNames.length <= constants_1.LAYER0_MAX_USER_HEADERS_ALLOWED;
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Patches writeHead method of the response so that we can do any post-response work.
|
|
331
|
+
*
|
|
332
|
+
* Notes:
|
|
333
|
+
* - Injects response ID header when this same component has generated the request ID.
|
|
334
|
+
* All components that actually generate the request ID before processing the request
|
|
335
|
+
* or going upstream are then also responsible for sending back the request ID downstream.
|
|
336
|
+
* - Return status 542 when there are too many response headers.
|
|
337
|
+
*
|
|
338
|
+
* @param req The request
|
|
339
|
+
* @param res The response
|
|
340
|
+
*/
|
|
341
|
+
this.patchResWriteHead = (req, res) => {
|
|
342
|
+
const originalWriteHead = res.writeHead;
|
|
343
|
+
res.writeHead = (...args) => {
|
|
344
|
+
res.writeHead = originalWriteHead;
|
|
345
|
+
if (this.newRequestId) {
|
|
346
|
+
res.setHeader(constants_1.HTTP_HEADERS.xRequestId, this.newRequestId);
|
|
347
|
+
}
|
|
348
|
+
const HEADERS_ARGS_INDEX = 2;
|
|
349
|
+
const headers = args[HEADERS_ARGS_INDEX];
|
|
350
|
+
if (headers) {
|
|
351
|
+
for (let key of Object.keys(headers)) {
|
|
352
|
+
res.setHeader(key, interpolateParams_1.default(req, res, headers[key]));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (this.isUserHeaderCountWithinLimits(res.getHeaders())) {
|
|
356
|
+
res.writeHead(...args);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
res.writeHead(constants_1.LAYER0_TOO_MANY_HEADERS_STATUS_CODE, 'Too many response headers');
|
|
360
|
+
};
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Handles a request, sending the response by running the handler for each matched route.
|
|
364
|
+
* @param req The request
|
|
365
|
+
* @param res The response
|
|
366
|
+
*/
|
|
367
|
+
this.run = async (req, res) => {
|
|
368
|
+
const routeMatchTime = new timing_1.InternalTiming(timing_1.InternalNames.routeMatching).start();
|
|
369
|
+
let router = this;
|
|
370
|
+
const context = new RequestContext_1.default();
|
|
371
|
+
this.processRequestHeaders(req);
|
|
372
|
+
if (!this.isUserHeaderCountWithinLimits(req.headers)) {
|
|
373
|
+
res.writeHead(constants_1.LAYER0_TOO_MANY_HEADERS_STATUS_CODE, 'Too many request headers');
|
|
374
|
+
res.end();
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
await this.processRequestBody(req);
|
|
378
|
+
this.patchResWriteHead(req, res);
|
|
379
|
+
if (Object.keys(this.destinations).length > 1) {
|
|
380
|
+
const { LAYER0_ROUTER_DESTINATION } = process.env;
|
|
381
|
+
let destinationName = ((req.headers[constants_1.HTTP_HEADERS.x0Destination] || LAYER0_ROUTER_DESTINATION));
|
|
382
|
+
if (!destinationName) {
|
|
383
|
+
// Connascence of algorithm between @layer0/core and @layer0/build-lambda:
|
|
384
|
+
// when destination cannot be determined by other means, then
|
|
385
|
+
// we choose the first router that was added to the list.
|
|
386
|
+
destinationName = minBy_1.default(Object.keys(this.destinations), destinationName => {
|
|
387
|
+
return this.destinations[destinationName]._index;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
router = this.destinations[destinationName];
|
|
391
|
+
if (!router) {
|
|
392
|
+
throw new Error(`Routing destination "${destinationName}" not found.`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
router.plugins.forEach(p => p.onRequest(req)); // this gives the plugin an opportunity to update the routes before the request is handled
|
|
396
|
+
const createResponseWriter = (route) => {
|
|
397
|
+
const writer = new ResponseWriter_1.default(req, res, route, context);
|
|
398
|
+
return Router.isRequestFromEdge(req) ? BehindEdgeResponseWriterProxy_1.default.create(writer) : writer;
|
|
399
|
+
};
|
|
400
|
+
// Loop thru route groups routes
|
|
401
|
+
const routes = router.routeGroups.getRoutes().filter(r => !r.isRespRoute());
|
|
402
|
+
const errorRoutes = router.routeGroups.getRoutes().filter(r => r.isRespRoute());
|
|
403
|
+
for (let route of routes) {
|
|
404
|
+
let writer;
|
|
405
|
+
try {
|
|
406
|
+
routeMatchTime.resume();
|
|
407
|
+
if (!route.match(req))
|
|
408
|
+
continue;
|
|
409
|
+
routeMatchTime.pause();
|
|
410
|
+
// Run different response writer depending on if the router
|
|
411
|
+
// is behind the edge or not.
|
|
412
|
+
writer = createResponseWriter(route);
|
|
413
|
+
await route.handler(writer);
|
|
414
|
+
// Stop running routes if the route has defined the send response,
|
|
415
|
+
// otherwise continue to the next route.
|
|
416
|
+
const done = await writer.sendResponse({
|
|
417
|
+
// We may need to alter the response based on the status code to issue a error page
|
|
418
|
+
beforeResponse: async (res) => {
|
|
419
|
+
// We only run the error page handler when accessed via permalink. Otherwise we may execute the
|
|
420
|
+
// error route in both edge and serverless and that will render the error page for error page rendered by serverless which is incorrect.
|
|
421
|
+
if (!Router.isRequestFromEdge(req)) {
|
|
422
|
+
/* istanbul ignore else */
|
|
423
|
+
for (let errorRoute of errorRoutes) {
|
|
424
|
+
routeMatchTime.resume();
|
|
425
|
+
if (!errorRoute.matchResponse(res))
|
|
426
|
+
continue;
|
|
427
|
+
routeMatchTime.pause();
|
|
428
|
+
writer = createResponseWriter(errorRoute);
|
|
429
|
+
await errorRoute.handler(writer);
|
|
430
|
+
writer.sendResponse();
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
// When nothing was matched by error handler or we are behind edge,
|
|
435
|
+
// return original response.
|
|
436
|
+
return true;
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
if (done) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch (e) {
|
|
444
|
+
// @ts-ignore
|
|
445
|
+
writer = writer || createResponseWriter(req, res, route, context);
|
|
446
|
+
writer.onRouteError(e);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
this.builtInFallback(req, res);
|
|
451
|
+
};
|
|
452
|
+
if (!options.excludeBuiltInRoutes) {
|
|
453
|
+
addBuiltInRoutes_1.default(this);
|
|
454
|
+
}
|
|
455
|
+
this.allowReqQueryDuplicates = (_a = options.allowReqQueryDuplicates) !== null && _a !== void 0 ? _a : false;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Returns a manifest of all static assets to be served via router.static
|
|
459
|
+
* @private
|
|
460
|
+
*/
|
|
461
|
+
getStaticAssetManifest() {
|
|
462
|
+
return RouteGroup_1.staticAssetManifest;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Allows the lambda handler to add the __js__ backend in the cloud
|
|
466
|
+
* @private
|
|
467
|
+
* @param name
|
|
468
|
+
* @param value
|
|
469
|
+
*/
|
|
470
|
+
setBackend(name, value) {
|
|
471
|
+
config_1.default.get('backends')[name] = value;
|
|
472
|
+
return this;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Constructs plugin and pushes it to registered plugins
|
|
476
|
+
* @param pluginInstance A plugin to use.
|
|
477
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
478
|
+
*/
|
|
479
|
+
use(pluginInstance) {
|
|
480
|
+
pluginInstance.onRegister(this);
|
|
481
|
+
this.plugins.push(pluginInstance);
|
|
482
|
+
return this;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Adds a named destination to which you can map traffic using the traffic shaping settings in your environment
|
|
486
|
+
* in Layer0 developer console
|
|
487
|
+
* @param name The name of the destination
|
|
488
|
+
* @param router A router to use when handling requests
|
|
489
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
490
|
+
*/
|
|
491
|
+
destination(name, router) {
|
|
492
|
+
router.setIndex(this.nextRouterIndex++);
|
|
493
|
+
this.destinations[name] = router;
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Returns all plugins, including those registered on destination routers.
|
|
498
|
+
*/
|
|
499
|
+
getPlugins() {
|
|
500
|
+
let plugins = this.plugins;
|
|
501
|
+
for (let router of Object.values(this.destinations)) {
|
|
502
|
+
plugins = plugins.concat(router.getPlugins());
|
|
503
|
+
}
|
|
504
|
+
return plugins;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Sets the index at which the router has been added to its parent router
|
|
508
|
+
* @private
|
|
509
|
+
* @param index
|
|
510
|
+
*/
|
|
511
|
+
setIndex(index) {
|
|
512
|
+
this._index = index;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Returns the index at which the router has been added to its parent router
|
|
516
|
+
* @private
|
|
517
|
+
* @returns router's index
|
|
518
|
+
*/
|
|
519
|
+
get index() {
|
|
520
|
+
return this._index;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Adds a RouteGroup to router and calls route register function for group.
|
|
524
|
+
* @private
|
|
525
|
+
* @param name Group name
|
|
526
|
+
* @param registerRoutesFn Group route register function
|
|
527
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
528
|
+
*/
|
|
529
|
+
group(name, registerRoutesFn) {
|
|
530
|
+
const newGroup = new RouteGroup_1.default(name);
|
|
531
|
+
registerRoutesFn(newGroup);
|
|
532
|
+
this.routeGroups.add(newGroup);
|
|
533
|
+
return this;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Adds a route matching all methods.
|
|
537
|
+
*
|
|
538
|
+
* Example:
|
|
539
|
+
*
|
|
540
|
+
* ```js
|
|
541
|
+
* new Router().match('/p/:productId', ({ cache, proxy }) => {
|
|
542
|
+
* cache({
|
|
543
|
+
* edge: {
|
|
544
|
+
* maxAgeSeconds: 60 * 60 * 24
|
|
545
|
+
* }
|
|
546
|
+
* })
|
|
547
|
+
*
|
|
548
|
+
* proxy('origin')
|
|
549
|
+
* })
|
|
550
|
+
* ```
|
|
551
|
+
*
|
|
552
|
+
* @param criteria Either the path as a string or an object with `path`, `method`, and `headers`.
|
|
553
|
+
* @param handler A handler function that will be called when the route is matched
|
|
554
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
555
|
+
*/
|
|
556
|
+
match(criteria, handler) {
|
|
557
|
+
return this.group('root', routeGroup => routeGroup.match(criteria, handler));
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Adds preload config for router
|
|
561
|
+
*
|
|
562
|
+
* ```js
|
|
563
|
+
* new Router().preload(
|
|
564
|
+
* async () => [{ path: '/foo', headers: { foo: 'bar' } }],
|
|
565
|
+
* [{ path: '/bar' }]
|
|
566
|
+
* )
|
|
567
|
+
* ```
|
|
568
|
+
*
|
|
569
|
+
* @param preloadOptions
|
|
570
|
+
*/
|
|
571
|
+
prerender(...preloadOptions) {
|
|
572
|
+
this.preloadRequests.push(...preloadOptions);
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Adds a route matching the given HTTP method.
|
|
577
|
+
*
|
|
578
|
+
* @param method HTTP method
|
|
579
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
580
|
+
* @param handler A handler function that will be called when the route is matched
|
|
581
|
+
* @private
|
|
582
|
+
*/
|
|
583
|
+
matchMethod(method, criteria, handler) {
|
|
584
|
+
if (typeof criteria === 'string') {
|
|
585
|
+
return this.match({
|
|
586
|
+
method,
|
|
587
|
+
path: criteria,
|
|
588
|
+
}, handler);
|
|
589
|
+
}
|
|
590
|
+
if (criteria.method) {
|
|
591
|
+
throw new Error(`Invalid criteria property method passed to call to Router#${method}. Specifying a method in the criteria is redundant.`);
|
|
592
|
+
}
|
|
593
|
+
return this.match({ ...criteria, method }, handler);
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Adds a route matching `HEAD` HTTP method.
|
|
597
|
+
*
|
|
598
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
599
|
+
* @param handler A handler function that will be called when the route is matched
|
|
600
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
601
|
+
*/
|
|
602
|
+
head(criteria, handler) {
|
|
603
|
+
return this.matchMethod(constants_1.HTTP_METHODS.head, criteria, handler);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Adds a route matching `GET` HTTP method.
|
|
607
|
+
*
|
|
608
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
609
|
+
* @param handler A handler function that will be called when the route is matched
|
|
610
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
611
|
+
*/
|
|
612
|
+
get(criteria, handler) {
|
|
613
|
+
return this.matchMethod(constants_1.HTTP_METHODS.get, criteria, handler);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Adds a route matching `POST` HTTP method.
|
|
617
|
+
*
|
|
618
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
619
|
+
* @param handler A handler function that will be called when the route is matched
|
|
620
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
621
|
+
*/
|
|
622
|
+
post(criteria, handler) {
|
|
623
|
+
return this.matchMethod(constants_1.HTTP_METHODS.post, criteria, handler);
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Adds a route matching `DELETE` HTTP method.
|
|
627
|
+
*
|
|
628
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
629
|
+
* @param handler A handler function that will be called when the route is matched
|
|
630
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
631
|
+
*/
|
|
632
|
+
delete(criteria, handler) {
|
|
633
|
+
return this.matchMethod(constants_1.HTTP_METHODS.delete, criteria, handler);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Adds a route matching `PUT` HTTP method.
|
|
637
|
+
*
|
|
638
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
639
|
+
* @param handler A handler function that will be called when the route is matched
|
|
640
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
641
|
+
*/
|
|
642
|
+
put(criteria, handler) {
|
|
643
|
+
return this.matchMethod(constants_1.HTTP_METHODS.put, criteria, handler);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Adds a route matching `PATCH` HTTP method.
|
|
647
|
+
*
|
|
648
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
649
|
+
* @param handler A handler function that will be called when the route is matched
|
|
650
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
651
|
+
*/
|
|
652
|
+
patch(criteria, handler) {
|
|
653
|
+
return this.matchMethod(constants_1.HTTP_METHODS.patch, criteria, handler);
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Adds a route matching `OPTIONS` HTTP method.
|
|
657
|
+
*
|
|
658
|
+
* @param criteria Either the path as a string or an object with `path`, `headers` and `cookies`.
|
|
659
|
+
* @param handler A handler function that will be called when the route is matched
|
|
660
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
661
|
+
*/
|
|
662
|
+
options(criteria, handler) {
|
|
663
|
+
return this.matchMethod(constants_1.HTTP_METHODS.options, criteria, handler);
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Adds a route that will run if no other routes are matched
|
|
667
|
+
* @param handler A handler function that will be called when no other route is matched
|
|
668
|
+
* @returns A self-reference, suitable for chaining.
|
|
669
|
+
*/
|
|
670
|
+
fallback(handler) {
|
|
671
|
+
this.routeGroups.setFallback(handler);
|
|
672
|
+
return this;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Adds a route that matches all requests with internal error header.
|
|
676
|
+
* @param handler A handler function that will be called when the route is matched
|
|
677
|
+
* @returns {Router} A self-reference, suitable for chaining.
|
|
678
|
+
*/
|
|
679
|
+
catch(error, handler) {
|
|
680
|
+
let errorRegex;
|
|
681
|
+
if (error instanceof RegExp) {
|
|
682
|
+
errorRegex = error;
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
errorRegex = new RegExp(`^${error.toString()}$`);
|
|
686
|
+
}
|
|
687
|
+
this.group(constants_1.ROUTES_CATCH_GROUP, routeGroup => routeGroup.match({ headers: { 'x-0-error-status-code': errorRegex }, response: { statusCode: errorRegex } }, async (writer) => {
|
|
688
|
+
await handler(writer);
|
|
689
|
+
writer.cache({
|
|
690
|
+
edge: false,
|
|
691
|
+
browser: {
|
|
692
|
+
maxAgeSeconds: 0,
|
|
693
|
+
},
|
|
694
|
+
});
|
|
695
|
+
}));
|
|
696
|
+
return this;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Disables crawling of permalinks by setting the `x-robots-tag: noindex` response header
|
|
700
|
+
* for hosts matching layer0.link or layer0-perma.link.
|
|
701
|
+
*
|
|
702
|
+
* ```js
|
|
703
|
+
* new Router().noIndexPermalink()
|
|
704
|
+
* ```
|
|
705
|
+
*
|
|
706
|
+
* * @returns {Router} A self-reference, suitable for chaining.
|
|
707
|
+
*/
|
|
708
|
+
noIndexPermalink() {
|
|
709
|
+
return this.group(constants_1.ROUTES_NOINDEX_GROUP, routeGroup => routeGroup.match({
|
|
710
|
+
headers: {
|
|
711
|
+
host: /layer0.link|layer0-perma.link/,
|
|
712
|
+
},
|
|
713
|
+
}, ({ setResponseHeader }) => {
|
|
714
|
+
setResponseHeader('x-robots-tag', 'noindex');
|
|
715
|
+
}));
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Both edge and @core/router have a built-in fallback that has the following rules:
|
|
719
|
+
*
|
|
720
|
+
* 1. On HTTP protocol return a 301 with the same request path in `location` header but on HTTPS
|
|
721
|
+
* protocol.
|
|
722
|
+
* 2. On HTTPS protocol return a 404.
|
|
723
|
+
*
|
|
724
|
+
* One complication is that in local development HTTPS does not exist - it is only emulated.
|
|
725
|
+
* Therefore in local development we could go into a redirect loop if the HTTP is emulated
|
|
726
|
+
* through the `local_layer0_emulate_http_protocol` cookie. There are a few options:
|
|
727
|
+
*
|
|
728
|
+
* 1. Always return 404 in local development.
|
|
729
|
+
* 2. If the cookie is present, issue 301 but unset the cookie in the response.
|
|
730
|
+
* 3. If the cookie is not present, return 301.
|
|
731
|
+
*
|
|
732
|
+
* We feel that the least surprising is simply always issuing 404 as that is also the original behavior.
|
|
733
|
+
*
|
|
734
|
+
* @param res
|
|
735
|
+
*/
|
|
736
|
+
builtInFallback(req, res) {
|
|
737
|
+
const connection = req.connection;
|
|
738
|
+
if (connection && connection.remoteAddress) {
|
|
739
|
+
res.writeHead(404);
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
if (req.headers[constants_1.HTTP_HEADERS.x0Protocol] === 'http') {
|
|
743
|
+
res.setHeader(constants_1.HTTP_HEADERS.location, `https://${req.headers[constants_1.HTTP_HEADERS.host]}${req.url}`);
|
|
744
|
+
res.writeHead(301);
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
res.writeHead(404);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
res.end();
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Adds routes for all static assets in a directory tree.
|
|
754
|
+
*
|
|
755
|
+
* **Example**
|
|
756
|
+
*
|
|
757
|
+
* ```js
|
|
758
|
+
* router.static('public')
|
|
759
|
+
* ```
|
|
760
|
+
*
|
|
761
|
+
* To only serve files matching a particular pattern, use the `glob` options:
|
|
762
|
+
*
|
|
763
|
+
* ```js
|
|
764
|
+
* router.static('public', {
|
|
765
|
+
* glob: '*.css'
|
|
766
|
+
* })
|
|
767
|
+
* ```
|
|
768
|
+
*
|
|
769
|
+
* By default the path on which files are served corresponds to the path within the directory,
|
|
770
|
+
* so for example, `public/css/main.css` would be served at `'/css/main.css'`,
|
|
771
|
+
* you can override this using the `path` option:
|
|
772
|
+
*
|
|
773
|
+
* ```js
|
|
774
|
+
* router.static('public', {
|
|
775
|
+
* paths: file => ['/assets/ + file] // will serve public/css/main.css at /assets/css/main.css
|
|
776
|
+
* })
|
|
777
|
+
* ```
|
|
778
|
+
*
|
|
779
|
+
* You can add caching or other additional handler logic using the `handler` option:
|
|
780
|
+
*
|
|
781
|
+
* ```js
|
|
782
|
+
* router.static('public', {
|
|
783
|
+
* handler: (file) => ({ cache }) => {
|
|
784
|
+
* cache({
|
|
785
|
+
* browser: {
|
|
786
|
+
* maxAgeSeconds: 60 * 60
|
|
787
|
+
* },
|
|
788
|
+
* edge: {
|
|
789
|
+
* maxAgeSeconds: 60 * 60 * 24,
|
|
790
|
+
* staleWhileRevalidateSeconds: 60 * 60
|
|
791
|
+
* }
|
|
792
|
+
* })
|
|
793
|
+
* }
|
|
794
|
+
* })
|
|
795
|
+
* ```
|
|
796
|
+
*
|
|
797
|
+
* @param sourcePath The path to a directory containing static assets relative to the root of your project.
|
|
798
|
+
* @param options
|
|
799
|
+
* @returns A self-reference, suitable for chaining.
|
|
800
|
+
*/
|
|
801
|
+
static(sourcePath, options = {}) {
|
|
802
|
+
return this.group('root', routeGroup => routeGroup.static(sourcePath, options));
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Shorthand for adding GraphQL body matching
|
|
806
|
+
*
|
|
807
|
+
* Examples:
|
|
808
|
+
*
|
|
809
|
+
* // by default the path is graphql
|
|
810
|
+
* new Router().graphqlOperation("GetRates")
|
|
811
|
+
*
|
|
812
|
+
* or
|
|
813
|
+
*
|
|
814
|
+
* // with optional non-default path
|
|
815
|
+
* new Router().graphqlOperation({ path: "/gql-api", name: "GetRates" })
|
|
816
|
+
*
|
|
817
|
+
* @param criteria Either the operation name as a string or an object with `path`, `name`.
|
|
818
|
+
* @param handler A handler function that will be called when the route is matched
|
|
819
|
+
*
|
|
820
|
+
* @returns A self-reference, suitable for chaining.
|
|
821
|
+
*/
|
|
822
|
+
graphqlOperation(criteria, handler) {
|
|
823
|
+
if (typeof criteria === 'string' || criteria instanceof RegExp) {
|
|
824
|
+
return this.post({ path: '/graphql', body: { parse: 'json', criteria: { operationName: criteria } } }, handler);
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
const { path, name } = criteria;
|
|
828
|
+
return this.post({ path, body: { parse: 'json', criteria: { operationName: name } } }, handler);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Adds Basic Authentication.
|
|
833
|
+
*
|
|
834
|
+
* **example**
|
|
835
|
+
*
|
|
836
|
+
* ```js
|
|
837
|
+
* router
|
|
838
|
+
* .requireBasicAuth({ username: 'user', password: 's3cr3t!' })
|
|
839
|
+
* // ...include additional routes below...
|
|
840
|
+
* ```
|
|
841
|
+
*
|
|
842
|
+
* You can also require basic auth for a subset of URLs using the `criteria` option:
|
|
843
|
+
*
|
|
844
|
+
* ```js
|
|
845
|
+
* router
|
|
846
|
+
* .requireBasicAuth({ criteria: '/secret/:path*', username: 'user', password: 's3cr3t!' })
|
|
847
|
+
* // ...include additional routes below...
|
|
848
|
+
* ```
|
|
849
|
+
*
|
|
850
|
+
* The criteria option accepts a path pattern as a string, or a RouteCriteria object.
|
|
851
|
+
*
|
|
852
|
+
* @param options
|
|
853
|
+
* @returns A self-reference, suitable for chaining.
|
|
854
|
+
*/
|
|
855
|
+
requireBasicAuth(options) {
|
|
856
|
+
return this.group('root', routeGroup => routeGroup.requireBasicAuth(options));
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Returns edge config from current router
|
|
860
|
+
* @private
|
|
861
|
+
*/
|
|
862
|
+
createEdgeConfig() {
|
|
863
|
+
return createEdgeConfig_1.default(this);
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Returns preload config from current router
|
|
867
|
+
* @private
|
|
868
|
+
*/
|
|
869
|
+
createPreloadConfig() {
|
|
870
|
+
return PreloadRequests_1.default.resolvePreloadConfig(this);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* @private
|
|
874
|
+
*/
|
|
875
|
+
getDestinations() {
|
|
876
|
+
return this.destinations;
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* @private
|
|
880
|
+
*/
|
|
881
|
+
getRouteGroups() {
|
|
882
|
+
return this.routeGroups;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Returns a string summarizing all routes for debugging purposes. Don't rely on the format
|
|
886
|
+
* of this string as we may improve it over time.
|
|
887
|
+
*/
|
|
888
|
+
toString() {
|
|
889
|
+
return ('Routes\n======\n' +
|
|
890
|
+
this.routeGroups
|
|
891
|
+
.getRoutes()
|
|
892
|
+
.map((r, i) => `${i}:\t${r.toString()}`)
|
|
893
|
+
.join('\n'));
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Returns true if the request came through Layer0 edge.
|
|
897
|
+
*
|
|
898
|
+
* Notes:
|
|
899
|
+
* - If the request came through Layer0 edge then `x-0-version` has been injected.
|
|
900
|
+
*
|
|
901
|
+
* @param req The request
|
|
902
|
+
*/
|
|
903
|
+
static isRequestFromEdge(req) {
|
|
904
|
+
return typeof req.headers[constants_1.HTTP_HEADERS.x0Version] == 'string';
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
exports.default = Router;
|