@fastly/expressly 1.0.0-alpha.2 → 1.0.0-alpha.5
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/README.md +2 -2
- package/dist/lib/routing/common.d.ts +11 -11
- package/dist/lib/routing/common.js +32 -33
- package/dist/lib/routing/error-middleware.d.ts +5 -5
- package/dist/lib/routing/mixin.d.ts +1 -0
- package/dist/lib/routing/mixin.js +9 -0
- package/dist/lib/routing/request/index.d.ts +15 -9
- package/dist/lib/routing/request/index.js +17 -19
- package/dist/lib/routing/request/request-url.d.ts +9 -0
- package/dist/lib/routing/request/request-url.js +37 -0
- package/dist/lib/routing/request-handler.d.ts +5 -5
- package/dist/lib/routing/response/index.d.ts +14 -2
- package/dist/lib/routing/response/index.js +6 -3
- package/dist/lib/routing/router.js +1 -0
- package/package.json +1 -1
- package/dist/lib/routing/middleware.d.ts +0 -10
- package/dist/lib/routing/middleware.js +0 -13
- package/dist/lib/routing/route.d.ts +0 -10
- package/dist/lib/routing/route.js +0 -12
package/README.md
CHANGED
|
@@ -17,11 +17,11 @@ First, head over to [developer.fastly.com](https://developer.fastly.com) to get
|
|
|
17
17
|
Install expressly from the [npm registry](https://www.npmjs.com/package/@fastly/expressly):
|
|
18
18
|
|
|
19
19
|
```shell
|
|
20
|
-
npm i @fastly/expressly
|
|
20
|
+
npm i @fastly/expressly
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
```shell
|
|
24
|
-
yarn add @fastly/expressly
|
|
24
|
+
yarn add @fastly/expressly
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### Your first expressly app
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
}
|
|
1
|
+
export declare function addCommonMethods<T extends new (...args: any[]) => any>(Base: T): {
|
|
2
|
+
new (...args: any[]): {
|
|
3
|
+
[x: string]: any;
|
|
4
|
+
set(headerNameOrObject: string | {
|
|
5
|
+
[key: string]: string;
|
|
6
|
+
}, value?: string): void;
|
|
7
|
+
append(headerNameOrObject: string | {
|
|
8
|
+
[key: string]: string | string[];
|
|
9
|
+
}, value?: string | string[]): void;
|
|
10
|
+
};
|
|
11
|
+
} & T;
|
|
@@ -1,36 +1,35 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
export function addCommonMethods(Base) {
|
|
2
|
+
return class extends Base {
|
|
3
|
+
// Header helpers.
|
|
4
|
+
set(headerNameOrObject, value) {
|
|
5
|
+
if (typeof headerNameOrObject === "string") {
|
|
6
|
+
this.headers.set(headerNameOrObject, value);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
Object.keys(headerNameOrObject).forEach((headerName) => {
|
|
10
|
+
this.headers.set(headerName, headerNameOrObject[headerName]);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
9
13
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
append(headerNameOrObject, value) {
|
|
15
|
+
const appendHeader = (headerName, headerValue) => {
|
|
16
|
+
if (typeof headerValue === "string") {
|
|
17
|
+
this.headers.append(headerName, headerValue);
|
|
18
|
+
}
|
|
19
|
+
else if (Array.isArray(headerValue)) {
|
|
20
|
+
headerValue.forEach((v) => {
|
|
21
|
+
this.headers.append(headerName, v);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
if (typeof headerNameOrObject === "string") {
|
|
26
|
+
appendHeader(headerNameOrObject, value);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
Object.keys(headerNameOrObject).forEach((headerName) => {
|
|
30
|
+
appendHeader(headerName, headerNameOrObject[headerName]);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
14
33
|
}
|
|
15
|
-
}
|
|
16
|
-
appendHeader(headerName, headerValue) {
|
|
17
|
-
if (typeof headerValue === "string") {
|
|
18
|
-
this.headers.append(headerName, headerValue);
|
|
19
|
-
}
|
|
20
|
-
else if (Array.isArray(headerValue)) {
|
|
21
|
-
headerValue.forEach((v) => {
|
|
22
|
-
this.headers.append(headerName, v);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
append(headerNameOrObject, value) {
|
|
27
|
-
if (typeof headerNameOrObject === "string") {
|
|
28
|
-
this.appendHeader(headerNameOrObject, value);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
Object.keys(headerNameOrObject).forEach((headerName) => {
|
|
32
|
-
this.appendHeader(headerName, headerNameOrObject[headerName]);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}
|
|
34
|
+
};
|
|
36
35
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export declare type ErrorMiddlewareCallback = (err: Error, req:
|
|
1
|
+
import { EReq } from "./request";
|
|
2
|
+
import { ERes } from "./response";
|
|
3
|
+
export declare type ErrorMiddlewareCallback = (err: Error, req: EReq, res: ERes) => Promise<any>;
|
|
4
4
|
export declare class ErrorMiddleware {
|
|
5
5
|
private matchFn;
|
|
6
6
|
private callback;
|
|
7
7
|
constructor(matchFn: Function, callback: ErrorMiddlewareCallback);
|
|
8
|
-
check(event:
|
|
9
|
-
run(err: Error, req:
|
|
8
|
+
check(event: EReq): 0 | 404 | string[];
|
|
9
|
+
run(err: Error, req: EReq, res: ERes): Promise<any>;
|
|
10
10
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function applyMixins(derivedConstructor: any, baseConstructors: any[]): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function applyMixins(derivedConstructor, baseConstructors) {
|
|
2
|
+
baseConstructors.forEach(baseConstructor => {
|
|
3
|
+
Object.getOwnPropertyNames(baseConstructor.prototype).forEach(name => {
|
|
4
|
+
if (name !== 'constructor') {
|
|
5
|
+
derivedConstructor.prototype[name] = baseConstructor.prototype[name];
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
/// <reference types="@fastly/js-compute" />
|
|
2
|
-
import { ECommonObject } from "../common";
|
|
3
2
|
import { CookieMap } from "./cookie-map";
|
|
4
3
|
import { EConfig } from "..";
|
|
5
|
-
|
|
4
|
+
declare class ERequestBase extends Request {
|
|
6
5
|
private config;
|
|
7
|
-
private event;
|
|
6
|
+
private readonly event;
|
|
8
7
|
readonly clientInfo: ClientInfo;
|
|
9
|
-
readonly method: string;
|
|
10
|
-
headers: Headers;
|
|
11
8
|
urlObj: URL;
|
|
12
9
|
query: URLSearchParams;
|
|
13
10
|
params: {
|
|
@@ -15,14 +12,23 @@ export declare class ERequest extends ECommonObject {
|
|
|
15
12
|
};
|
|
16
13
|
cookies: CookieMap;
|
|
17
14
|
constructor(config: EConfig, event: FetchEvent);
|
|
18
|
-
get url(): string;
|
|
19
15
|
get path(): string;
|
|
20
16
|
get ip(): string;
|
|
21
17
|
get protocol(): string;
|
|
22
18
|
get secure(): boolean;
|
|
23
19
|
get subdomains(): Array<string>;
|
|
24
20
|
get hostname(): string;
|
|
25
|
-
json(): Promise<any>;
|
|
26
|
-
text(): Promise<string>;
|
|
27
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
28
21
|
}
|
|
22
|
+
export declare const ERequest: {
|
|
23
|
+
new (...args: any[]): {
|
|
24
|
+
[x: string]: any;
|
|
25
|
+
set(headerNameOrObject: string | {
|
|
26
|
+
[key: string]: string;
|
|
27
|
+
}, value?: string): void;
|
|
28
|
+
append(headerNameOrObject: string | {
|
|
29
|
+
[key: string]: string | string[];
|
|
30
|
+
}, value?: string | string[]): void;
|
|
31
|
+
};
|
|
32
|
+
} & typeof ERequestBase;
|
|
33
|
+
export declare type EReq = InstanceType<typeof ERequest>;
|
|
34
|
+
export {};
|
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { addCommonMethods } from "../common";
|
|
2
2
|
import { CookieMap } from "./cookie-map";
|
|
3
|
-
|
|
3
|
+
// Will extend Request correctly after https://github.com/fastly/js-compute-runtime/pull/116 is merged
|
|
4
|
+
// See: https://github.com/fastly/js-compute-runtime/issues/113
|
|
5
|
+
class ERequestBase extends Request {
|
|
4
6
|
constructor(config, event) {
|
|
5
|
-
super(
|
|
7
|
+
super(event.request, {
|
|
8
|
+
headers: event.request.headers,
|
|
9
|
+
method: event.request.method,
|
|
10
|
+
body: event.request.body,
|
|
11
|
+
});
|
|
6
12
|
this.config = config;
|
|
7
13
|
this.event = event;
|
|
8
14
|
this.params = {};
|
|
9
|
-
this.clientInfo = event.client;
|
|
10
|
-
this.
|
|
11
|
-
this.urlObj = new URL(event.request.url);
|
|
15
|
+
this.clientInfo = this.event.client;
|
|
16
|
+
this.urlObj = new URL(this.url);
|
|
12
17
|
this.query = this.urlObj.searchParams;
|
|
13
|
-
this
|
|
18
|
+
Object.defineProperty(this, 'url', {
|
|
19
|
+
get() {
|
|
20
|
+
return this.urlObj.toString();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
14
23
|
// Parse cookies.
|
|
15
24
|
if (this.config.parseCookie) {
|
|
16
25
|
this.cookies = new CookieMap(this.headers);
|
|
17
26
|
}
|
|
18
27
|
}
|
|
19
28
|
// Express-like URL helpers.
|
|
20
|
-
get url() {
|
|
21
|
-
return this.urlObj.toString();
|
|
22
|
-
}
|
|
23
29
|
get path() {
|
|
24
30
|
return this.urlObj.pathname;
|
|
25
31
|
}
|
|
@@ -38,13 +44,5 @@ export class ERequest extends ECommonObject {
|
|
|
38
44
|
get hostname() {
|
|
39
45
|
return this.urlObj.hostname;
|
|
40
46
|
}
|
|
41
|
-
async json() {
|
|
42
|
-
return await this.event.request.json();
|
|
43
|
-
}
|
|
44
|
-
async text() {
|
|
45
|
-
return await this.event.request.text();
|
|
46
|
-
}
|
|
47
|
-
async arrayBuffer() {
|
|
48
|
-
return await this.event.request.arrayBuffer();
|
|
49
|
-
}
|
|
50
47
|
}
|
|
48
|
+
export const ERequest = addCommonMethods(ERequestBase);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import cookie from "cookie";
|
|
2
|
+
export class CookieMap extends Map {
|
|
3
|
+
constructor(headers) {
|
|
4
|
+
super();
|
|
5
|
+
this.headers = headers;
|
|
6
|
+
if (Boolean(this.headers.get("Cookie"))) {
|
|
7
|
+
for (const [key, value] of Object.entries(cookie.parse(this.headers.get("Cookie")))) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
super.set(key, value);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
clear() {
|
|
15
|
+
this.headers.delete("Cookie");
|
|
16
|
+
super.clear();
|
|
17
|
+
}
|
|
18
|
+
set(key, value) {
|
|
19
|
+
super.set(key, value);
|
|
20
|
+
this.serialize();
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
delete(key) {
|
|
24
|
+
const deleteResult = super.delete(key);
|
|
25
|
+
this.serialize();
|
|
26
|
+
return deleteResult;
|
|
27
|
+
}
|
|
28
|
+
serialize() {
|
|
29
|
+
if (this.size) {
|
|
30
|
+
const cookies = [];
|
|
31
|
+
for (const [key, value] of this.entries()) {
|
|
32
|
+
cookies.push(cookie.serialize(key, value));
|
|
33
|
+
}
|
|
34
|
+
this.headers.set("Cookie", cookies.join("; "));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export declare type RequestHandlerCallback = (req:
|
|
1
|
+
import { EReq } from "./request";
|
|
2
|
+
import { ERes } from "./response";
|
|
3
|
+
export declare type RequestHandlerCallback = (req: EReq, res: ERes) => Promise<any>;
|
|
4
4
|
export declare class RequestHandler {
|
|
5
5
|
private matchFn;
|
|
6
6
|
private callback;
|
|
7
7
|
constructor(matchFn: Function, callback: RequestHandlerCallback);
|
|
8
|
-
check(event:
|
|
9
|
-
run(req:
|
|
8
|
+
check(event: EReq): 0 | 404 | string[];
|
|
9
|
+
run(req: EReq, res: ERes): Promise<any>;
|
|
10
10
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/// <reference types="@fastly/js-compute" />
|
|
2
|
-
import { ECommonObject } from "../common";
|
|
3
2
|
import { SurrogateKeys } from "./surrogate-keys";
|
|
4
3
|
import { CookieOptions, EConfig } from "..";
|
|
5
|
-
|
|
4
|
+
declare class EResponseBase {
|
|
6
5
|
private config;
|
|
7
6
|
headers: Headers;
|
|
8
7
|
status: number;
|
|
@@ -22,3 +21,16 @@ export declare class EResponse extends ECommonObject {
|
|
|
22
21
|
text(data: string): void;
|
|
23
22
|
html(data: string, charset?: string): void;
|
|
24
23
|
}
|
|
24
|
+
export declare const EResponse: {
|
|
25
|
+
new (...args: any[]): {
|
|
26
|
+
[x: string]: any;
|
|
27
|
+
set(headerNameOrObject: string | {
|
|
28
|
+
[key: string]: string;
|
|
29
|
+
}, value?: string): void;
|
|
30
|
+
append(headerNameOrObject: string | {
|
|
31
|
+
[key: string]: string | string[];
|
|
32
|
+
}, value?: string | string[]): void;
|
|
33
|
+
};
|
|
34
|
+
} & typeof EResponseBase;
|
|
35
|
+
export declare type ERes = InstanceType<typeof EResponse>;
|
|
36
|
+
export {};
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import cookie from "cookie";
|
|
2
|
-
import {
|
|
2
|
+
import { addCommonMethods } from "../common";
|
|
3
3
|
import { statusText } from "./status-codes";
|
|
4
4
|
import { SurrogateKeys } from "./surrogate-keys";
|
|
5
|
-
|
|
5
|
+
// TODO: extends Response
|
|
6
|
+
// See: https://github.com/fastly/js-compute-runtime/issues/113
|
|
7
|
+
class EResponseBase {
|
|
6
8
|
constructor(config) {
|
|
7
|
-
super();
|
|
8
9
|
this.config = config;
|
|
9
10
|
this.headers = new Headers();
|
|
10
11
|
this.status = 0;
|
|
11
12
|
this.body = null;
|
|
12
13
|
this.hasEnded = false;
|
|
13
14
|
this.surrogateKeys = new SurrogateKeys(this.headers);
|
|
15
|
+
// super();
|
|
14
16
|
}
|
|
15
17
|
// Header helpers.
|
|
16
18
|
vary(field) {
|
|
@@ -99,3 +101,4 @@ export class EResponse extends ECommonObject {
|
|
|
99
101
|
this.send(data);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
104
|
+
export const EResponse = addCommonMethods(EResponseBase);
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import ERequest from "./request";
|
|
2
|
-
import EResponse from "./response";
|
|
3
|
-
export declare type MiddlewareCallback = (req: ERequest, res: EResponse, next?: () => void) => Promise<any>;
|
|
4
|
-
export declare class Middleware {
|
|
5
|
-
private matchFn;
|
|
6
|
-
private callback;
|
|
7
|
-
constructor(matchFn: Function, callback: MiddlewareCallback);
|
|
8
|
-
check(event: ERequest): 0 | 404 | 405;
|
|
9
|
-
run(req: ERequest, res: EResponse): Promise<any>;
|
|
10
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export class Middleware {
|
|
2
|
-
constructor(matchFn, callback) {
|
|
3
|
-
this.matchFn = matchFn;
|
|
4
|
-
this.callback = callback;
|
|
5
|
-
}
|
|
6
|
-
check(event) {
|
|
7
|
-
return this.matchFn(event);
|
|
8
|
-
}
|
|
9
|
-
async run(req, res) {
|
|
10
|
-
// Supply an empty callback as an equivalent of next() in Express.js.
|
|
11
|
-
await this.callback(req, res, () => { });
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import ERequest from "./request";
|
|
2
|
-
import EResponse from "./response";
|
|
3
|
-
export declare type RequestHandlerCallback = (req: ERequest, res: EResponse) => Promise<any>;
|
|
4
|
-
export declare class Route {
|
|
5
|
-
private matchFn;
|
|
6
|
-
private callback;
|
|
7
|
-
constructor(matchFn: Function, callback: RequestHandlerCallback);
|
|
8
|
-
check(event: ERequest): 0 | 404 | 405;
|
|
9
|
-
run(req: ERequest, res: EResponse): Promise<any>;
|
|
10
|
-
}
|