moleculer-web
Advanced tools
Comparing version 0.10.4 to 0.10.5
@@ -0,1 +1,29 @@ | ||
<a name="0.10.5"></a> | ||
# 0.10.5 (2022-12-17) | ||
## Changes | ||
- improving d.ts | ||
- register on close and error event on response. [#299](https://github.com/moleculerjs/moleculer-web/pull/299) | ||
- resolve promise when close event is fired for res. [#301](https://github.com/moleculerjs/moleculer-web/pull/301) | ||
- add default reqTimeout. [#312](https://github.com/moleculerjs/moleculer-web/pull/312) | ||
- improve rate limiter. [#317](https://github.com/moleculerjs/moleculer-web/pull/317) | ||
- add 201 Created to status codes. [#297](https://github.com/moleculerjs/moleculer-web/pull/297) | ||
----------------------------- | ||
<a name="0.10.4"></a> | ||
# 0.10.4 (2022-01-09) | ||
## What's Changed | ||
* d.ts for v0.10.2 v0.10.3 by @0x0a0d in https://github.com/moleculerjs/moleculer-web/pull/280 | ||
* skip services without settings by @kechkibet in https://github.com/moleculerjs/moleculer-web/pull/283 | ||
* Fix to comment in multi-auth example by @machinaexdeo in https://github.com/moleculerjs/moleculer-web/pull/286 | ||
* Add alias as last parameter by @icebob in https://github.com/moleculerjs/moleculer-web/pull/290 | ||
* Fix cors problem in assets by @moonrailgun in https://github.com/moleculerjs/moleculer-web/pull/289 | ||
* Broadcast event after alias regeneration by @icebob in https://github.com/moleculerjs/moleculer-web/pull/292 | ||
## Other changes | ||
- update dependencies. | ||
- change to @fastify/busboy implementation. [#287](https://github.com/moleculerjs/moleculer-web/issues/287) | ||
----------------------------- | ||
<a name="0.10.3"></a> | ||
@@ -2,0 +30,0 @@ # 0.10.3 (2021-10-17) |
293
index.d.ts
declare module "moleculer-web" { | ||
import { | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import type { | ||
ActionEndpoint, | ||
@@ -7,13 +8,13 @@ ActionSchema, | ||
Context, | ||
Errors, | ||
LogLevels, | ||
Service, | ||
ServiceBroker, | ||
ServiceSchema, | ||
} from "moleculer"; | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { Errors } from "moleculer"; | ||
// RateLimit | ||
type generateRateLimitKey = (req: IncomingMessage) => string | ||
export type generateRateLimitKey = (req: IncomingMessage) => string; | ||
interface RateLimit { | ||
export interface RateLimitSettings { | ||
/** | ||
@@ -23,3 +24,3 @@ * How long to keep record of requests in memory (in milliseconds). | ||
*/ | ||
window?: number, | ||
window?: number; | ||
@@ -30,3 +31,3 @@ /** | ||
*/ | ||
limit?: number, | ||
limit?: number; | ||
@@ -37,3 +38,3 @@ /** | ||
*/ | ||
headers?: boolean, | ||
headers?: boolean; | ||
@@ -44,3 +45,3 @@ /** | ||
*/ | ||
key?: generateRateLimitKey, | ||
key?: generateRateLimitKey; | ||
@@ -52,12 +53,22 @@ /** | ||
*/ | ||
StoreFactory?: MemoryStore | ||
StoreFactory?: typeof RateLimitStore; | ||
} | ||
class MemoryStore { | ||
constructor(clearPeriod: number, opts: RateLimit) | ||
export abstract class RateLimitStore { | ||
resetTime: number; | ||
constructor(clearPeriod: number, opts?: RateLimitSettings, broker?: ServiceBroker); | ||
inc(key: string): number | Promise<number>; | ||
} | ||
interface RateLimitStores { | ||
MemoryStore: typeof MemoryStore; | ||
} | ||
class MemoryStore extends RateLimitStore { | ||
constructor(clearPeriod: number, opts?: RateLimitSettings, broker?: ServiceBroker); | ||
/** | ||
* Increment the counter by key | ||
*/ | ||
inc(key: string): number | ||
inc(key: string): number; | ||
@@ -67,3 +78,3 @@ /** | ||
*/ | ||
reset(): void | ||
reset(): void; | ||
} | ||
@@ -137,7 +148,7 @@ | ||
type bodyParserOptions = { | ||
json?: BodyParser.OptionsJson | boolean | ||
urlencoded?: BodyParser.OptionsUrlencoded | boolean | ||
text?: BodyParser.OptionsText | boolean | ||
raw?: BodyParser.Options | boolean | ||
} | ||
json?: BodyParser.OptionsJson | boolean; | ||
urlencoded?: BodyParser.OptionsUrlencoded | boolean; | ||
text?: BodyParser.OptionsText | boolean; | ||
raw?: BodyParser.Options | boolean; | ||
}; | ||
@@ -152,11 +163,13 @@ // BusboyConfig | ||
preservePath?: boolean | undefined; | ||
limits?: { | ||
fieldNameSize?: number | undefined; | ||
fieldSize?: number | undefined; | ||
fields?: number | undefined; | ||
fileSize?: number | undefined; | ||
files?: number | undefined; | ||
parts?: number | undefined; | ||
headerPairs?: number | undefined; | ||
} | undefined; | ||
limits?: | ||
| { | ||
fieldNameSize?: number | undefined; | ||
fieldSize?: number | undefined; | ||
fields?: number | undefined; | ||
fileSize?: number | undefined; | ||
files?: number | undefined; | ||
parts?: number | undefined; | ||
headerPairs?: number | undefined; | ||
} | ||
| undefined; | ||
} | ||
@@ -173,4 +186,4 @@ | ||
encoding: string, | ||
mimetype: string | ||
) => void | ||
mimetype: string, | ||
) => void, | ||
): this; | ||
@@ -184,4 +197,4 @@ on( | ||
encoding: string, | ||
mimetype: string | ||
) => void | ||
mimetype: string, | ||
) => void, | ||
): this; | ||
@@ -196,8 +209,8 @@ on(event: "finish", callback: () => void): this; | ||
type onEventBusboyConfig<T> = (busboy: busboy.Busboy, alias: T, service: Service) => void | ||
type onEventBusboyConfig<T> = (busboy: busboy.Busboy, alias: T, service: Service) => void; | ||
type BusboyConfig<T> = busboy.BusboyConfig & { | ||
onFieldsLimit?: T | ||
onFilesLimit?: T | ||
onPartsLimit?: T | ||
} | ||
onFieldsLimit?: T; | ||
onFilesLimit?: T; | ||
onPartsLimit?: T; | ||
}; | ||
@@ -283,8 +296,8 @@ // AssetsConfig | ||
*/ | ||
folder: string | ||
folder: string; | ||
/** | ||
* Further options to `server-static` module | ||
*/ | ||
options?: ServeStaticOptions | ||
} | ||
options?: ServeStaticOptions; | ||
}; | ||
@@ -306,10 +319,26 @@ // CorsOptions | ||
class InvalidRequestBodyError extends Errors.MoleculerError { constructor(body: any, error: any) } | ||
class InvalidResponseTypeError extends Errors.MoleculerError { constructor(dataType: string) } | ||
class UnAuthorizedError extends Errors.MoleculerError { constructor(type: string|null|undefined, data: any) } | ||
class ForbiddenError extends Errors.MoleculerError { constructor(type: string, data: any) } | ||
class BadRequestError extends Errors.MoleculerError { constructor(type: string, data: any) } | ||
class RateLimitExceeded extends Errors.MoleculerClientError { constructor(type: string, data: any) } | ||
class NotFoundError extends Errors.MoleculerClientError { constructor(type: string, data: any) } | ||
class ServiceUnavailableError extends Errors.MoleculerError { constructor(type: string, data: any) } | ||
class InvalidRequestBodyError extends Errors.MoleculerError { | ||
constructor(body: any, error: any); | ||
} | ||
class InvalidResponseTypeError extends Errors.MoleculerError { | ||
constructor(dataType: string); | ||
} | ||
class UnAuthorizedError extends Errors.MoleculerError { | ||
constructor(type: string | null | undefined, data: any); | ||
} | ||
class ForbiddenError extends Errors.MoleculerError { | ||
constructor(type: string, data: any); | ||
} | ||
class BadRequestError extends Errors.MoleculerError { | ||
constructor(type: string, data: any); | ||
} | ||
class RateLimitExceeded extends Errors.MoleculerClientError { | ||
constructor(type: string, data: any); | ||
} | ||
class NotFoundError extends Errors.MoleculerClientError { | ||
constructor(type: string, data: any); | ||
} | ||
class ServiceUnavailableError extends Errors.MoleculerError { | ||
constructor(type: string, data: any); | ||
} | ||
@@ -332,3 +361,3 @@ interface ApiGatewayErrors { | ||
class Alias { | ||
export class Alias { | ||
_generated: boolean; | ||
@@ -340,7 +369,7 @@ service: Service; | ||
path: string; | ||
handler: null | Array<Function>; | ||
handler: null | Function[]; | ||
action: string; | ||
} | ||
class Route { | ||
export class Route { | ||
callOptions: any; | ||
@@ -352,3 +381,3 @@ cors: CorsOptions; | ||
mappingPolicy: string; | ||
middlewares: Array<Function>; | ||
middlewares: Function[]; | ||
onBeforeCall?: onBeforeCall; | ||
@@ -358,7 +387,18 @@ onAfterCall?: onAfterCall; | ||
path: string; | ||
whitelist: Array<string>; | ||
whitelist: string[]; | ||
} | ||
type onBeforeCall = (ctx: Context, route: Route, req: IncomingMessage, res: ServerResponse) => void | ||
type onAfterCall = (ctx: Context, route: Route, req: IncomingMessage, res: ServerResponse, data: any) => any | ||
type onBeforeCall = ( | ||
ctx: Context, | ||
route: Route, | ||
req: IncomingRequest, | ||
res: GatewayResponse, | ||
) => void; | ||
type onAfterCall = ( | ||
ctx: Context, | ||
route: Route, | ||
req: IncomingRequest, | ||
res: GatewayResponse, | ||
data: any, | ||
) => any; | ||
@@ -384,16 +424,25 @@ /** | ||
type routeMiddleware = (req: IncomingMessage, res: ServerResponse, next: NextFunction) => void | ||
type routeMiddlewareError = (err: any, req: IncomingMessage, res: ServerResponse, next: NextFunction) => void | ||
type routeMiddleware = (req: IncomingMessage, res: ServerResponse, next: NextFunction) => void; | ||
type routeMiddlewareError = ( | ||
err: any, | ||
req: IncomingMessage, | ||
res: ServerResponse, | ||
next: NextFunction, | ||
) => void; | ||
type ETagFunction = (body: any) => string | ||
type AliasFunction = (req: IncomingRequest, res: GatewayResponse, next?: (err?: any) => void) => void | ||
type ETagFunction = (body: any) => string; | ||
type AliasFunction = ( | ||
req: IncomingRequest, | ||
res: GatewayResponse, | ||
next?: (err?: any) => void, | ||
) => void; | ||
type AliasRouteSchema = { | ||
type?: "call" | "multipart" | "stream" | string | ||
method?: "GET" | "POST" | "PUT" | "DELETE" | "*" | "HEAD" | "OPTIONS" | "PATCH" | string | ||
path?: string | ||
handler?: AliasFunction | ||
action?: string | ||
busboyConfig?: BusboyConfig<onEventBusboyConfig<Alias>> | ||
[k: string]: any | ||
} | ||
type?: "call" | "multipart" | "stream" | string; | ||
method?: "GET" | "POST" | "PUT" | "DELETE" | "*" | "HEAD" | "OPTIONS" | "PATCH" | string; | ||
path?: string; | ||
handler?: AliasFunction; | ||
action?: string; | ||
busboyConfig?: BusboyConfig<onEventBusboyConfig<Alias>>; | ||
[k: string]: any; | ||
}; | ||
@@ -419,3 +468,3 @@ type CommonSettingSchema = { | ||
*/ | ||
cors?: CorsOptions | ||
cors?: CorsOptions; | ||
/** | ||
@@ -426,3 +475,3 @@ * The etag option value can be `false`, `true`, `weak`, `strong`, or a custom `Function` | ||
*/ | ||
etag?: boolean | "weak" | "strong" | ETagFunction | ||
etag?: boolean | "weak" | "strong" | ETagFunction; | ||
/** | ||
@@ -433,3 +482,3 @@ * You can add route-level & global-level custom error handlers.<br> | ||
*/ | ||
onError?: (req: IncomingMessage, res: ServerResponse, error: Error) => void | ||
onError?: (req: IncomingMessage, res: ServerResponse, error: Error) => void; | ||
/** | ||
@@ -439,3 +488,3 @@ * The Moleculer-Web has a built-in rate limiter with a memory store. | ||
*/ | ||
rateLimit?: RateLimit | ||
rateLimit?: RateLimitSettings; | ||
/** | ||
@@ -448,4 +497,4 @@ * It supports Connect-like middlewares in global-level, route-level & alias-level.<br> | ||
*/ | ||
use?: (routeMiddleware | routeMiddlewareError)[] | ||
} | ||
use?: (routeMiddleware | routeMiddlewareError)[]; | ||
}; | ||
export type ApiRouteSchema = CommonSettingSchema & { | ||
@@ -458,4 +507,4 @@ /** | ||
aliases?: { | ||
[k: string]: string | AliasFunction | Array<AliasFunction | string> | AliasRouteSchema | ||
} | ||
[k: string]: string | AliasFunction | (AliasFunction | string)[] | AliasRouteSchema; | ||
}; | ||
/** | ||
@@ -471,3 +520,3 @@ * To enable the support for authentication, you need to do something similar to what is describe in the Authorization paragraph.<br> | ||
*/ | ||
authentication?: boolean | string | ||
authentication?: boolean | string; | ||
/** | ||
@@ -481,3 +530,3 @@ * You can implement authorization. Do 2 things to enable it. | ||
*/ | ||
authorization?: boolean | string | ||
authorization?: boolean | string; | ||
/** | ||
@@ -490,3 +539,3 @@ * The auto-alias feature allows you to declare your route alias directly in your services.<br> | ||
*/ | ||
autoAliases?: boolean | ||
autoAliases?: boolean; | ||
/** | ||
@@ -496,3 +545,3 @@ * Parse incoming request bodies, available under the `ctx.params` property | ||
*/ | ||
bodyParsers?: bodyParserOptions | boolean | ||
bodyParsers?: bodyParserOptions | boolean; | ||
/** | ||
@@ -505,3 +554,3 @@ * API Gateway has implemented file uploads.<br> | ||
*/ | ||
busboyConfig?: BusboyConfig<onEventBusboyConfig<Alias>> | ||
busboyConfig?: BusboyConfig<onEventBusboyConfig<Alias>>; | ||
/** | ||
@@ -511,3 +560,3 @@ * The route has a callOptions property which is passed to broker.call. So you can set timeout, retries or fallbackResponse options for routes. | ||
*/ | ||
callingOptions?: CallingOptions | ||
callingOptions?: CallingOptions; | ||
/** | ||
@@ -519,3 +568,3 @@ * If alias handler not found, `api` will try to call service by action name<br> | ||
*/ | ||
camelCaseNames?: boolean | ||
camelCaseNames?: boolean; | ||
/** | ||
@@ -525,3 +574,3 @@ * Debounce wait time before call to regenerated aliases when got event "$services.changed" | ||
*/ | ||
debounceTime?: number | ||
debounceTime?: number; | ||
/** | ||
@@ -531,3 +580,3 @@ * Enable/disable logging | ||
*/ | ||
logging?: boolean | ||
logging?: boolean; | ||
/** | ||
@@ -540,3 +589,3 @@ * The route has a `mappingPolicy` property to handle routes without aliases.<br> | ||
*/ | ||
mappingPolicy?: "all" | "restrict" | ||
mappingPolicy?: "all" | "restrict"; | ||
/** | ||
@@ -547,3 +596,3 @@ * To disable parameter merging set `mergeParams: false` in route settings.<br> | ||
*/ | ||
mergeParams?: boolean | ||
mergeParams?: boolean; | ||
/** | ||
@@ -555,3 +604,3 @@ * `From v0.10.2` | ||
*/ | ||
name?: string | ||
name?: string; | ||
/** | ||
@@ -561,3 +610,3 @@ * The route has before & after call hooks. You can use it to set `ctx.meta`, access `req.headers` or modify the response data. | ||
*/ | ||
onBeforeCall?: onBeforeCall | ||
onBeforeCall?: onBeforeCall; | ||
/** | ||
@@ -568,7 +617,7 @@ * You could manipulate the data in `onAfterCall`.<br> | ||
*/ | ||
onAfterCall?: onAfterCall | ||
onAfterCall?: onAfterCall; | ||
/** | ||
* Path prefix to this route | ||
*/ | ||
path: string | ||
path: string; | ||
/** | ||
@@ -582,4 +631,4 @@ * If you don’t want to publish all actions, you can filter them with whitelist option.<br> | ||
*/ | ||
whitelist?: Array<string|RegExp> | ||
} | ||
whitelist?: (string | RegExp)[]; | ||
}; | ||
@@ -591,3 +640,3 @@ export type ApiSettingsSchema = CommonSettingSchema & { | ||
*/ | ||
assets?: AssetsConfig | ||
assets?: AssetsConfig; | ||
/** | ||
@@ -597,3 +646,3 @@ * Use HTTP2 server (experimental) | ||
*/ | ||
http2?: boolean, | ||
http2?: boolean; | ||
@@ -604,3 +653,3 @@ /** | ||
*/ | ||
httpServerTimeout?: number, | ||
httpServerTimeout?: number; | ||
@@ -614,3 +663,3 @@ /** | ||
*/ | ||
internalServiceSpecialChar?: string | RegExp, | ||
internalServiceSpecialChar?: string | RegExp; | ||
@@ -621,3 +670,3 @@ /** | ||
*/ | ||
ip?: string, | ||
ip?: string; | ||
@@ -628,3 +677,3 @@ /** | ||
*/ | ||
log4XXResponses?: boolean, | ||
log4XXResponses?: boolean; | ||
@@ -635,3 +684,3 @@ /** | ||
*/ | ||
logRequest?: LogLevels, | ||
logRequest?: LogLevels | null; | ||
@@ -642,3 +691,3 @@ /** | ||
*/ | ||
logRequestParams?: LogLevels, | ||
logRequestParams?: LogLevels | null; | ||
@@ -649,3 +698,3 @@ /** | ||
*/ | ||
logResponse?: LogLevels, | ||
logResponse?: LogLevels | null; | ||
@@ -656,3 +705,3 @@ /** | ||
*/ | ||
logResponseData?: LogLevels, | ||
logResponseData?: LogLevels | null; | ||
@@ -663,3 +712,3 @@ /** | ||
*/ | ||
logRouteRegistration?: LogLevels, | ||
logRouteRegistration?: LogLevels | null; | ||
@@ -670,3 +719,3 @@ /** | ||
*/ | ||
optimizeOrder?: boolean, | ||
optimizeOrder?: boolean; | ||
@@ -676,3 +725,3 @@ /** | ||
*/ | ||
path?: string | ||
path?: string; | ||
/** | ||
@@ -682,3 +731,3 @@ * Exposed port | ||
*/ | ||
port?: number, | ||
port?: number; | ||
@@ -689,3 +738,3 @@ /** | ||
*/ | ||
routes?: ApiRouteSchema[], | ||
routes?: ApiRouteSchema[]; | ||
@@ -696,3 +745,3 @@ /** | ||
*/ | ||
rootCallOptions?: CallingOptions | ||
rootCallOptions?: CallingOptions; | ||
@@ -704,9 +753,14 @@ /** | ||
*/ | ||
server?: boolean, | ||
} | ||
server?: boolean; | ||
class IncomingRequest extends IncomingMessage { | ||
/** | ||
* for extra setting's keys | ||
*/ | ||
[k: string]: any; | ||
}; | ||
export class IncomingRequest extends IncomingMessage { | ||
$action: ActionSchema; | ||
$alias: Alias; | ||
$ctx: Context; | ||
$ctx: Context<{ req: IncomingMessage; res: ServerResponse; }>; | ||
$endpoint: ActionEndpoint; | ||
@@ -717,13 +771,22 @@ $next: any; | ||
$service: Service; | ||
$startTime: Array<number>; | ||
$startTime: number[]; | ||
originalUrl: string; | ||
parsedUrl: string; | ||
query: Record<string, string>; | ||
} | ||
class GatewayResponse extends ServerResponse { | ||
export class GatewayResponse extends ServerResponse { | ||
$ctx: Context; | ||
$route: Route; | ||
$service: Service; | ||
locals: Record<string, unknown>; | ||
} | ||
const ApiGatewayService: ServiceSchema & { Errors: ApiGatewayErrors, IncomingRequest: IncomingRequest, GatewayResponse: GatewayResponse }; | ||
const ApiGatewayService: ServiceSchema & { | ||
Errors: ApiGatewayErrors; | ||
IncomingRequest: IncomingRequest; | ||
GatewayResponse: GatewayResponse; | ||
RateLimitStores: RateLimitStores; | ||
}; | ||
export default ApiGatewayService; | ||
} |
{ | ||
"name": "moleculer-web", | ||
"version": "0.10.4", | ||
"version": "0.10.5", | ||
"description": "Official API Gateway service for Moleculer framework", | ||
@@ -42,3 +42,3 @@ "main": "index.js", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-promise": "^5.1.0", | ||
"eslint-plugin-promise": "^6.1.1", | ||
"eslint-plugin-security": "^1.4.0", | ||
@@ -45,0 +45,0 @@ "express": "^4.17.1", |
@@ -93,2 +93,5 @@ /* | ||
// Request Timeout. More info: https://github.com/moleculerjs/moleculer-web/issues/206 | ||
requestTimeout: 300000, // Sets node.js v18 default timeout: https://nodejs.org/api/http.html#serverrequesttimeout | ||
// Optimize route order | ||
@@ -303,2 +306,5 @@ optimizeOrder: true, | ||
} | ||
this.server.requestTimeout = this.settings.requestTimeout; | ||
this.logger.debug("Setting http(s) server request timeout to:", this.settings.requestTimeout); | ||
}, | ||
@@ -421,2 +427,4 @@ | ||
res.once("finish", () => resolve(true)); | ||
res.once("close", () => resolve(true)); | ||
res.once("error", (err) => reject(err)); | ||
@@ -524,3 +532,3 @@ try { | ||
if (key) { | ||
const remaining = opts.limit - store.inc(key); | ||
const remaining = opts.limit - await store.inc(key); | ||
if (opts.headers) { | ||
@@ -707,3 +715,3 @@ res.setHeader("X-Rate-Limit-Limit", opts.limit); | ||
// Redirect | ||
if (res.statusCode >= 300 && res.statusCode < 400 && res.statusCode !== 304) { | ||
if (res.statusCode==201 || (res.statusCode >= 300 && res.statusCode < 400 && res.statusCode !== 304)) { | ||
const location = ctx.meta.$location; | ||
@@ -1343,5 +1351,5 @@ /* istanbul ignore next */ | ||
if (opts.StoreFactory) | ||
route.rateLimit.store = new opts.StoreFactory(opts.window, opts); | ||
route.rateLimit.store = new opts.StoreFactory(opts.window, opts, this.broker); | ||
else | ||
route.rateLimit.store = new MemoryStore(opts.window, opts); | ||
route.rateLimit.store = new MemoryStore(opts.window, opts, this.broker); | ||
@@ -1730,2 +1738,5 @@ } | ||
Errors: require("./errors"), | ||
RateLimitStores: { | ||
MemoryStore: require("./memory-store") | ||
} | ||
}; |
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
132741
15
2799