@faasjs/http 0.0.3-beta.1 → 0.0.3-beta.100

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 CHANGED
@@ -200,7 +200,7 @@ ___
200
200
 
201
201
  ### useHttp
202
202
 
203
- ▸ **useHttp**<`TParams`, `TCookie`, `TSession`\>(`config?`): [`Http`](classes/Http.md)<`TParams`, `TCookie`, `TSession`\> & `UseifyPlugin`
203
+ ▸ **useHttp**<`TParams`, `TCookie`, `TSession`\>(`config?`): `UseifyPlugin`<[`Http`](classes/Http.md)<`TParams`, `TCookie`, `TSession`\>\>
204
204
 
205
205
  #### Type parameters
206
206
 
@@ -218,4 +218,4 @@ ___
218
218
 
219
219
  #### Returns
220
220
 
221
- [`Http`](classes/Http.md)<`TParams`, `TCookie`, `TSession`\> & `UseifyPlugin`
221
+ `UseifyPlugin`<[`Http`](classes/Http.md)<`TParams`, `TCookie`, `TSession`\>\>
@@ -0,0 +1,210 @@
1
+ import { Plugin, DeployData, Next, MountData, InvokeData, UseifyPlugin } from '@faasjs/func';
2
+ import { Logger } from '@faasjs/logger';
3
+
4
+ type SessionOptions = {
5
+ key: string;
6
+ secret: string;
7
+ salt?: string;
8
+ signedSalt?: string;
9
+ keylen?: number;
10
+ iterations?: number;
11
+ digest?: string;
12
+ cipherName?: string;
13
+ };
14
+ type SessionContent = string | number | {
15
+ [key: string]: any;
16
+ } | null | undefined;
17
+ declare class Session<S extends Record<string, string> = any, C extends Record<string, string> = any> {
18
+ content: Record<string, string | number>;
19
+ readonly config: {
20
+ key: string;
21
+ secret: string;
22
+ salt: string;
23
+ signedSalt: string;
24
+ keylen: number;
25
+ iterations: number;
26
+ digest: string;
27
+ cipherName: string;
28
+ };
29
+ private readonly secret;
30
+ private readonly signedSecret;
31
+ private readonly cookie;
32
+ private changed?;
33
+ constructor(cookie: Cookie<C, S>, config: SessionOptions);
34
+ invoke(cookie?: string, logger?: Logger): void;
35
+ encode(text: SessionContent): string;
36
+ decode<TData = any>(text: string): TData | SessionContent;
37
+ read(key: string): string | number;
38
+ write(key: string, value?: string | number | null): Session<S, C>;
39
+ update(): Session<S, C>;
40
+ }
41
+
42
+ type CookieOptions = {
43
+ domain?: string;
44
+ path?: string;
45
+ expires?: number;
46
+ secure?: boolean;
47
+ httpOnly?: boolean;
48
+ sameSite?: 'Strict' | 'Lax' | 'None';
49
+ session?: SessionOptions;
50
+ [key: string]: any;
51
+ };
52
+ declare class Cookie<C extends Record<string, string> = any, S extends Record<string, string> = any> {
53
+ session: Session<S, C>;
54
+ content: Record<string, string>;
55
+ readonly config: {
56
+ domain?: string;
57
+ path: string;
58
+ expires: number;
59
+ secure: boolean;
60
+ httpOnly: boolean;
61
+ sameSite?: 'Strict' | 'Lax' | 'None';
62
+ session: SessionOptions;
63
+ };
64
+ logger: Logger;
65
+ private setCookie;
66
+ constructor(config: CookieOptions, logger?: Logger);
67
+ invoke(cookie: string | undefined, logger: Logger): Cookie<C, S>;
68
+ read(key: string): any;
69
+ write(key: string, value: string, opts?: {
70
+ domain?: string;
71
+ path?: string;
72
+ expires?: number | string;
73
+ secure?: boolean;
74
+ httpOnly?: boolean;
75
+ sameSite?: 'Strict' | 'Lax' | 'None';
76
+ }): Cookie<C, S>;
77
+ headers(): {
78
+ 'Set-Cookie'?: string[];
79
+ };
80
+ }
81
+
82
+ type ValidatorRuleOptionsType = 'string' | 'number' | 'boolean' | 'object' | 'array';
83
+ type ValidatorRuleOptions = {
84
+ type?: ValidatorRuleOptionsType;
85
+ required?: boolean;
86
+ in?: any[];
87
+ default?: any;
88
+ config?: Partial<ValidatorOptions>;
89
+ regexp?: RegExp;
90
+ };
91
+ type ValidatorOptions<Content = Record<string, any>> = {
92
+ whitelist?: 'error' | 'ignore';
93
+ rules: {
94
+ [k in keyof Content]?: ValidatorRuleOptions;
95
+ };
96
+ onError?: (type: string, key: string | string[], value?: any) => {
97
+ statusCode?: number;
98
+ message: any;
99
+ } | void;
100
+ };
101
+ type Request<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> = {
102
+ headers: {
103
+ [key: string]: string;
104
+ };
105
+ params?: TParams;
106
+ cookie?: Cookie<TCookie, TSession>;
107
+ session?: Session<TSession, TCookie>;
108
+ };
109
+ type BeforeOption<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> = (request: Request<TParams, TCookie, TSession>) => Promise<void | {
110
+ statusCode?: number;
111
+ message: string;
112
+ }>;
113
+ type ValidatorConfig<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> = {
114
+ params?: ValidatorOptions<TParams>;
115
+ cookie?: ValidatorOptions<TCookie>;
116
+ session?: ValidatorOptions<TSession>;
117
+ before?: BeforeOption;
118
+ };
119
+ declare class Validator<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> {
120
+ before?: BeforeOption<TParams, TCookie, TSession>;
121
+ paramsConfig?: ValidatorOptions<TParams>;
122
+ cookieConfig?: ValidatorOptions<TCookie>;
123
+ sessionConfig?: ValidatorOptions<TSession>;
124
+ private request;
125
+ constructor(config: ValidatorConfig<TParams, TCookie, TSession>);
126
+ valid(request: Request<TParams, TCookie, TSession>, logger: Logger): Promise<void>;
127
+ validContent(type: string, params: {
128
+ [key: string]: any;
129
+ }, baseKey: string, config: ValidatorOptions, logger: Logger): void;
130
+ }
131
+
132
+ declare const ContentType: {
133
+ [key: string]: string;
134
+ };
135
+ type HttpConfig<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> = {
136
+ [key: string]: any;
137
+ name?: string;
138
+ config?: {
139
+ [key: string]: any;
140
+ /** POST as default */
141
+ method?: 'BEGIN' | 'GET' | 'POST' | 'DELETE' | 'HEAD' | 'PUT' | 'OPTIONS' | 'TRACE' | 'PATCH' | 'ANY';
142
+ timeout?: number;
143
+ /** file relative path as default */
144
+ path?: string;
145
+ ignorePathPrefix?: string;
146
+ functionName?: string;
147
+ cookie?: CookieOptions;
148
+ };
149
+ validator?: ValidatorConfig<TParams, TCookie, TSession>;
150
+ };
151
+ type Response = {
152
+ statusCode?: number;
153
+ headers?: {
154
+ [key: string]: string;
155
+ };
156
+ body?: string;
157
+ message?: string;
158
+ };
159
+ declare class HttpError extends Error {
160
+ readonly statusCode: number;
161
+ readonly message: string;
162
+ constructor({ statusCode, message }: {
163
+ statusCode?: number;
164
+ message: string;
165
+ });
166
+ }
167
+ declare class Http<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any> implements Plugin {
168
+ readonly type: string;
169
+ readonly name: string;
170
+ headers: {
171
+ [key: string]: string;
172
+ };
173
+ body: any;
174
+ params: TParams;
175
+ cookie: Cookie<TCookie, TSession>;
176
+ session: Session<TSession, TCookie>;
177
+ config: HttpConfig<TParams, TCookie, TSession>;
178
+ private readonly validatorOptions?;
179
+ private response?;
180
+ private validator?;
181
+ constructor(config?: HttpConfig<TParams, TCookie, TSession>);
182
+ onDeploy(data: DeployData, next: Next): Promise<void>;
183
+ onMount(data: MountData, next: Next): Promise<void>;
184
+ onInvoke(data: InvokeData, next: Next): Promise<void>;
185
+ /**
186
+ * set header
187
+ * @param key {string} key
188
+ * @param value {*} value
189
+ */
190
+ setHeader(key: string, value: string): Http<TParams, TCookie, TSession>;
191
+ /**
192
+ * set Content-Type
193
+ * @param type {string} 类型
194
+ * @param charset {string} 编码
195
+ */
196
+ setContentType(type: string, charset?: string): Http<TParams, TCookie, TSession>;
197
+ /**
198
+ * set status code
199
+ * @param code {number} 状态码
200
+ */
201
+ setStatusCode(code: number): Http<TParams, TCookie, TSession>;
202
+ /**
203
+ * set body
204
+ * @param body {*} 内容
205
+ */
206
+ setBody(body: string): Http<TParams, TCookie, TSession>;
207
+ }
208
+ declare function useHttp<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any>(config?: HttpConfig<TParams, TCookie, TSession>): UseifyPlugin<Http<TParams, TCookie, TSession>>;
209
+
210
+ export { ContentType, Cookie, CookieOptions, Http, HttpConfig, HttpError, Response, Session, SessionOptions, Validator, ValidatorConfig, ValidatorOptions, ValidatorRuleOptions, useHttp };
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ declare class Session<S extends Record<string, string> = any, C extends Record<s
31
31
  private readonly cookie;
32
32
  private changed?;
33
33
  constructor(cookie: Cookie<C, S>, config: SessionOptions);
34
- invoke(cookie?: string): void;
34
+ invoke(cookie?: string, logger?: Logger): void;
35
35
  encode(text: SessionContent): string;
36
36
  decode<TData = any>(text: string): TData | SessionContent;
37
37
  read(key: string): string | number;
@@ -61,9 +61,10 @@ declare class Cookie<C extends Record<string, string> = any, S extends Record<st
61
61
  sameSite?: 'Strict' | 'Lax' | 'None';
62
62
  session: SessionOptions;
63
63
  };
64
+ logger: Logger;
64
65
  private setCookie;
65
- constructor(config: CookieOptions);
66
- invoke(cookie: string | undefined): Cookie<C, S>;
66
+ constructor(config: CookieOptions, logger?: Logger);
67
+ invoke(cookie: string | undefined, logger: Logger): Cookie<C, S>;
67
68
  read(key: string): any;
68
69
  write(key: string, value: string, opts?: {
69
70
  domain?: string;
@@ -204,6 +205,6 @@ declare class Http<TParams extends Record<string, any> = any, TCookie extends Re
204
205
  */
205
206
  setBody(body: string): Http<TParams, TCookie, TSession>;
206
207
  }
207
- declare function useHttp<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any>(config?: HttpConfig<TParams, TCookie, TSession>): Http<TParams, TCookie, TSession> & UseifyPlugin;
208
+ declare function useHttp<TParams extends Record<string, any> = any, TCookie extends Record<string, string> = any, TSession extends Record<string, string> = any>(config?: HttpConfig<TParams, TCookie, TSession>): UseifyPlugin<Http<TParams, TCookie, TSession>>;
208
209
 
209
210
  export { ContentType, Cookie, CookieOptions, Http, HttpConfig, HttpError, Response, Session, SessionOptions, Validator, ValidatorConfig, ValidatorOptions, ValidatorRuleOptions, useHttp };
package/dist/index.js CHANGED
@@ -1,74 +1,26 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ 'use strict';
19
2
 
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- ContentType: () => ContentType,
24
- Cookie: () => Cookie,
25
- Http: () => Http,
26
- HttpError: () => HttpError,
27
- Session: () => Session,
28
- Validator: () => Validator,
29
- useHttp: () => useHttp
30
- });
31
- module.exports = __toCommonJS(src_exports);
32
- var import_func = require("@faasjs/func");
3
+ var func = require('@faasjs/func');
4
+ var deep_merge = require('@faasjs/deep_merge');
5
+ var logger = require('@faasjs/logger');
6
+ var crypto = require('crypto');
7
+ var zlib = require('zlib');
33
8
 
34
- // ../deep_merge/src/index.ts
35
- var shouldMerge = function(item) {
36
- const type = Object.prototype.toString.call(item);
37
- return type === "[object Object]" || type === "[object Array]";
38
- };
39
- function deepMerge(...sources) {
40
- let acc = /* @__PURE__ */ Object.create(null);
41
- for (const source of sources)
42
- if (source instanceof Array) {
43
- if (!(acc instanceof Array))
44
- acc = [];
45
- acc = [...new Set(source.concat(...acc))];
46
- } else if (shouldMerge(source))
47
- for (const [key, value] of Object.entries(source)) {
48
- let val;
49
- if (shouldMerge(value))
50
- val = deepMerge(acc[key], value);
51
- else
52
- val = value;
53
- acc = {
54
- ...acc,
55
- [key]: val
56
- };
57
- }
58
- return acc;
59
- }
60
-
61
- // src/index.ts
62
- var import_logger = require("@faasjs/logger");
63
-
64
- // src/session.ts
65
- var import_crypto = require("crypto");
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined")
13
+ return require.apply(this, arguments);
14
+ throw Error('Dynamic require of "' + x + '" is not supported');
15
+ });
66
16
  var Session = class {
67
17
  constructor(cookie, config) {
68
18
  this.cookie = cookie;
19
+ if (!(config == null ? void 0 : config.secret))
20
+ cookie.logger.warn("Session's secret is missing.");
69
21
  this.config = Object.assign({
70
22
  key: "key",
71
- secret: (0, import_crypto.randomBytes)(128).toString("hex"),
23
+ secret: crypto.randomBytes(128).toString("hex"),
72
24
  salt: "salt",
73
25
  signedSalt: "signedSalt",
74
26
  keylen: 64,
@@ -76,14 +28,14 @@ var Session = class {
76
28
  digest: "sha256",
77
29
  cipherName: "aes-256-cbc"
78
30
  }, config);
79
- this.secret = (0, import_crypto.pbkdf2Sync)(
31
+ this.secret = crypto.pbkdf2Sync(
80
32
  this.config.secret,
81
33
  this.config.salt,
82
34
  this.config.iterations,
83
35
  this.config.keylen / 2,
84
36
  this.config.digest
85
37
  );
86
- this.signedSecret = (0, import_crypto.pbkdf2Sync)(
38
+ this.signedSecret = crypto.pbkdf2Sync(
87
39
  this.config.secret,
88
40
  this.config.signedSalt,
89
41
  this.config.iterations,
@@ -92,11 +44,11 @@ var Session = class {
92
44
  );
93
45
  this.content = /* @__PURE__ */ Object.create(null);
94
46
  }
95
- invoke(cookie) {
47
+ invoke(cookie, logger) {
96
48
  try {
97
49
  this.content = cookie ? this.decode(cookie) : /* @__PURE__ */ Object.create(null);
98
50
  } catch (error) {
99
- console.error(error);
51
+ logger == null ? void 0 : logger.error(error);
100
52
  this.content = /* @__PURE__ */ Object.create(null);
101
53
  }
102
54
  this.changed = false;
@@ -104,11 +56,11 @@ var Session = class {
104
56
  encode(text) {
105
57
  if (typeof text !== "string")
106
58
  text = JSON.stringify(text);
107
- const iv = (0, import_crypto.randomBytes)(16);
108
- const cipher = (0, import_crypto.createCipheriv)(this.config.cipherName, this.secret, iv);
59
+ const iv = crypto.randomBytes(16);
60
+ const cipher = crypto.createCipheriv(this.config.cipherName, this.secret, iv);
109
61
  const encrypted = Buffer.concat([cipher.update(text), cipher.final()]).toString("base64");
110
62
  const main = Buffer.from([encrypted, iv.toString("base64")].join("--")).toString("base64");
111
- const hmac = (0, import_crypto.createHmac)(this.config.digest, this.signedSecret);
63
+ const hmac = crypto.createHmac(this.config.digest, this.signedSecret);
112
64
  hmac.update(main);
113
65
  const digest = hmac.digest("hex");
114
66
  return main + "--" + digest;
@@ -116,16 +68,16 @@ var Session = class {
116
68
  decode(text) {
117
69
  text = decodeURIComponent(text);
118
70
  const signedParts = text.split("--");
119
- const hmac = (0, import_crypto.createHmac)(this.config.digest, this.signedSecret);
71
+ const hmac = crypto.createHmac(this.config.digest, this.signedSecret);
120
72
  hmac.update(signedParts[0]);
121
73
  const digest = hmac.digest("hex");
122
74
  if (signedParts[1] !== digest)
123
- throw Error("Not valid");
75
+ throw Error("Session Not valid");
124
76
  const message = Buffer.from(signedParts[0], "base64").toString();
125
77
  const parts = message.split("--").map(function(part2) {
126
78
  return Buffer.from(part2, "base64");
127
79
  });
128
- const cipher = (0, import_crypto.createDecipheriv)(this.config.cipherName, this.secret, parts[1]);
80
+ const cipher = crypto.createDecipheriv(this.config.cipherName, this.secret, parts[1]);
129
81
  const part = Buffer.from(cipher.update(parts[0])).toString("utf8");
130
82
  const final = cipher.final("utf8");
131
83
  const decrypt = [part, final].join("");
@@ -148,11 +100,10 @@ var Session = class {
148
100
  return this;
149
101
  }
150
102
  };
151
-
152
- // src/cookie.ts
153
103
  var Cookie = class {
154
- constructor(config) {
155
- this.config = deepMerge({
104
+ constructor(config, logger) {
105
+ this.logger = logger;
106
+ this.config = deep_merge.deepMerge({
156
107
  path: "/",
157
108
  expires: 31536e3,
158
109
  secure: true,
@@ -163,7 +114,7 @@ var Cookie = class {
163
114
  this.content = /* @__PURE__ */ Object.create(null);
164
115
  this.setCookie = /* @__PURE__ */ Object.create(null);
165
116
  }
166
- invoke(cookie) {
117
+ invoke(cookie, logger) {
167
118
  this.content = /* @__PURE__ */ Object.create(null);
168
119
  if (cookie)
169
120
  cookie.split(";").forEach((x) => {
@@ -173,7 +124,7 @@ var Cookie = class {
173
124
  this.content[k[0]] = decodeURIComponent(x.replace(`${k[0]}=`, "").replace(/;$/, ""));
174
125
  });
175
126
  this.setCookie = /* @__PURE__ */ Object.create(null);
176
- this.session.invoke(this.read(this.session.config.key));
127
+ this.session.invoke(this.read(this.session.config.key), logger);
177
128
  return this;
178
129
  }
179
130
  read(key) {
@@ -396,9 +347,6 @@ var Validator = class {
396
347
  }
397
348
  }
398
349
  };
399
-
400
- // src/index.ts
401
- var import_zlib = require("zlib");
402
350
  var ContentType = {
403
351
  plain: "text/plain",
404
352
  html: "text/html",
@@ -409,14 +357,14 @@ var ContentType = {
409
357
  json: "application/json",
410
358
  jsonp: "application/javascript"
411
359
  };
412
- var HttpError = class extends Error {
360
+ var HttpError = class _HttpError extends Error {
413
361
  constructor({
414
362
  statusCode,
415
363
  message
416
364
  }) {
417
365
  super(message);
418
366
  if (Error.captureStackTrace)
419
- Error.captureStackTrace(this, HttpError);
367
+ Error.captureStackTrace(this, _HttpError);
420
368
  this.statusCode = statusCode || 500;
421
369
  this.message = message;
422
370
  }
@@ -430,18 +378,15 @@ var Http = class {
430
378
  this.config = (config == null ? void 0 : config.config) || /* @__PURE__ */ Object.create(null);
431
379
  if (config == null ? void 0 : config.validator)
432
380
  this.validatorOptions = config.validator;
433
- this.headers = /* @__PURE__ */ Object.create(null);
434
- this.cookie = new Cookie(this.config.cookie || {});
435
- this.session = this.cookie.session;
436
381
  }
437
382
  async onDeploy(data, next) {
438
383
  var _a;
439
384
  data.dependencies["@faasjs/http"] = "*";
440
385
  await next();
441
- const logger = new import_logger.Logger(this.name);
442
- logger.debug("Generate api gateway's config");
443
- logger.debug("%j", data);
444
- const config = data.config.plugins ? deepMerge(data.config.plugins[this.name || this.type], { config: this.config }) : { config: this.config };
386
+ const logger$1 = new logger.Logger(this.name);
387
+ logger$1.debug("Generate api gateway's config");
388
+ logger$1.debug("%j", data);
389
+ const config = data.config.plugins ? deep_merge.deepMerge(data.config.plugins[this.name || this.type], { config: this.config }) : { config: this.config };
445
390
  if (!config.config.path) {
446
391
  config.config.path = "/" + ((_a = data.name) == null ? void 0 : _a.replace(/_/g, "/").replace(/\/index$/, ""));
447
392
  if (config.config.path === "/index")
@@ -452,17 +397,34 @@ var Http = class {
452
397
  config.config.path = "/";
453
398
  }
454
399
  }
455
- logger.debug("Api gateway's config: %j", config);
456
- const Provider = require(config.provider.type).Provider;
400
+ logger$1.debug("Api gateway's config: %j", config);
401
+ const Provider = __require(config.provider.type).Provider;
457
402
  const provider = new Provider(config.provider.config);
458
403
  await provider.deploy(this.type, data, config);
459
404
  }
460
405
  async onMount(data, next) {
461
406
  data.logger.debug("[onMount] merge config");
407
+ const prefix = `SECRET_${this.name.toUpperCase()}_`;
408
+ for (let key in process.env)
409
+ if (key.startsWith(prefix)) {
410
+ const value = process.env[key];
411
+ key = key.replace(prefix, "").toLowerCase();
412
+ if (key.includes("_")) {
413
+ let config = this.config;
414
+ const keys = key.split("_");
415
+ keys.slice(0, keys.length - 1).forEach((k) => {
416
+ if (!config[k])
417
+ config[k] = /* @__PURE__ */ Object.create(null);
418
+ config = config[k];
419
+ });
420
+ config[keys[keys.length - 1]] = value;
421
+ } else
422
+ this.config[key] = value;
423
+ }
462
424
  if (data.config.plugins && data.config.plugins[this.name || this.type])
463
- this.config = deepMerge(this.config, data.config.plugins[this.name || this.type].config);
425
+ this.config = deep_merge.deepMerge(this.config, data.config.plugins[this.name || this.type].config);
464
426
  data.logger.debug("[onMount] prepare cookie & session");
465
- this.cookie = new Cookie(this.config.cookie || {});
427
+ this.cookie = new Cookie(this.config.cookie || {}, data.logger);
466
428
  this.session = this.cookie.session;
467
429
  if (this.validatorOptions) {
468
430
  data.logger.debug("[onMount] prepare validator");
@@ -477,16 +439,23 @@ var Http = class {
477
439
  this.params = data.event.queryString || /* @__PURE__ */ Object.create(null);
478
440
  this.response = { headers: /* @__PURE__ */ Object.create(null) };
479
441
  if (data.event.body) {
480
- if ((_a = this.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) {
442
+ if (((_a = this.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) && typeof data.event.body === "string" && data.event.body.length > 1) {
481
443
  data.logger.debug("[onInvoke] Parse params from json body");
482
- this.params = Object.assign(this.params, JSON.parse(data.event.body));
444
+ try {
445
+ this.params = Object.keys(this.params).length ? Object.assign(this.params, JSON.parse(data.event.body)) : JSON.parse(data.event.body);
446
+ } catch (error) {
447
+ data.logger.error("[onInvoke] Parse params from json body failed: %s", error.message);
448
+ }
483
449
  } else {
484
450
  data.logger.debug("[onInvoke] Parse params from raw body");
485
451
  this.params = data.event.body || /* @__PURE__ */ Object.create(null);
486
452
  }
453
+ if (this.params && typeof this.params === "object" && this.params["_"])
454
+ delete this.params["_"];
455
+ data.event.params = JSON.parse(JSON.stringify(this.params));
487
456
  data.logger.debug("[onInvoke] Params: %j", this.params);
488
457
  }
489
- this.cookie.invoke(this.headers.cookie);
458
+ this.cookie.invoke(this.headers.cookie, data.logger);
490
459
  if (this.headers.cookie) {
491
460
  data.logger.debug("[onInvoke] Cookie: %j", this.cookie.content);
492
461
  data.logger.debug("[onInvoke] Session: %j", this.session.content);
@@ -523,7 +492,8 @@ var Http = class {
523
492
  this.response.statusCode = this.response.body ? 200 : 201;
524
493
  this.response.headers = Object.assign({
525
494
  "Content-Type": "application/json; charset=utf-8",
526
- "Cache-Control": "no-cache, no-store"
495
+ "Cache-Control": "no-cache, no-store",
496
+ "X-FaasJS-Request-Id": data.logger.label
527
497
  }, this.cookie.headers(), this.response.headers);
528
498
  data.response = Object.assign({}, data.response, this.response);
529
499
  const originBody = data.response.body;
@@ -538,13 +508,13 @@ var Http = class {
538
508
  try {
539
509
  if (acceptEncoding.includes("br")) {
540
510
  data.response.headers["Content-Encoding"] = "br";
541
- data.response.body = (0, import_zlib.brotliCompressSync)(originBody).toString("base64");
511
+ data.response.body = zlib.brotliCompressSync(originBody).toString("base64");
542
512
  } else if (acceptEncoding.includes("gzip")) {
543
513
  data.response.headers["Content-Encoding"] = "gzip";
544
- data.response.body = (0, import_zlib.gzipSync)(originBody).toString("base64");
514
+ data.response.body = zlib.gzipSync(originBody).toString("base64");
545
515
  } else if (acceptEncoding.includes("deflate")) {
546
516
  data.response.headers["Content-Encoding"] = "deflate";
547
- data.response.body = (0, import_zlib.deflateSync)(originBody).toString("base64");
517
+ data.response.body = zlib.deflateSync(originBody).toString("base64");
548
518
  } else
549
519
  throw Error("No matched compression.");
550
520
  data.response.isBase64Encoded = true;
@@ -554,10 +524,20 @@ var Http = class {
554
524
  delete data.response.headers["Content-Encoding"];
555
525
  }
556
526
  }
527
+ /**
528
+ * set header
529
+ * @param key {string} key
530
+ * @param value {*} value
531
+ */
557
532
  setHeader(key, value) {
558
533
  this.response.headers[key] = value;
559
534
  return this;
560
535
  }
536
+ /**
537
+ * set Content-Type
538
+ * @param type {string} 类型
539
+ * @param charset {string} 编码
540
+ */
561
541
  setContentType(type, charset = "utf-8") {
562
542
  if (ContentType[type])
563
543
  this.setHeader("Content-Type", `${ContentType[type]}; charset=${charset}`);
@@ -565,25 +545,31 @@ var Http = class {
565
545
  this.setHeader("Content-Type", `${type}; charset=${charset}`);
566
546
  return this;
567
547
  }
548
+ /**
549
+ * set status code
550
+ * @param code {number} 状态码
551
+ */
568
552
  setStatusCode(code) {
569
553
  this.response.statusCode = code;
570
554
  return this;
571
555
  }
556
+ /**
557
+ * set body
558
+ * @param body {*} 内容
559
+ */
572
560
  setBody(body) {
573
561
  this.response.body = body;
574
562
  return this;
575
563
  }
576
564
  };
577
565
  function useHttp(config) {
578
- return (0, import_func.usePlugin)(new Http(config));
566
+ return func.usePlugin(new Http(config));
579
567
  }
580
- // Annotate the CommonJS export names for ESM import in node:
581
- 0 && (module.exports = {
582
- ContentType,
583
- Cookie,
584
- Http,
585
- HttpError,
586
- Session,
587
- Validator,
588
- useHttp
589
- });
568
+
569
+ exports.ContentType = ContentType;
570
+ exports.Cookie = Cookie;
571
+ exports.Http = Http;
572
+ exports.HttpError = HttpError;
573
+ exports.Session = Session;
574
+ exports.Validator = Validator;
575
+ exports.useHttp = useHttp;
package/dist/index.mjs CHANGED
@@ -1,57 +1,21 @@
1
+ import { usePlugin } from '@faasjs/func';
2
+ import { deepMerge } from '@faasjs/deep_merge';
3
+ import { Logger } from '@faasjs/logger';
4
+ import { randomBytes, pbkdf2Sync, createCipheriv, createHmac, createDecipheriv } from 'crypto';
5
+ import { brotliCompressSync, gzipSync, deflateSync } from 'zlib';
6
+
1
7
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
8
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
9
  }) : x)(function(x) {
4
10
  if (typeof require !== "undefined")
5
11
  return require.apply(this, arguments);
6
- throw new Error('Dynamic require of "' + x + '" is not supported');
12
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
13
  });
8
-
9
- // src/index.ts
10
- import {
11
- usePlugin
12
- } from "@faasjs/func";
13
-
14
- // ../deep_merge/src/index.ts
15
- var shouldMerge = function(item) {
16
- const type = Object.prototype.toString.call(item);
17
- return type === "[object Object]" || type === "[object Array]";
18
- };
19
- function deepMerge(...sources) {
20
- let acc = /* @__PURE__ */ Object.create(null);
21
- for (const source of sources)
22
- if (source instanceof Array) {
23
- if (!(acc instanceof Array))
24
- acc = [];
25
- acc = [...new Set(source.concat(...acc))];
26
- } else if (shouldMerge(source))
27
- for (const [key, value] of Object.entries(source)) {
28
- let val;
29
- if (shouldMerge(value))
30
- val = deepMerge(acc[key], value);
31
- else
32
- val = value;
33
- acc = {
34
- ...acc,
35
- [key]: val
36
- };
37
- }
38
- return acc;
39
- }
40
-
41
- // src/index.ts
42
- import { Logger } from "@faasjs/logger";
43
-
44
- // src/session.ts
45
- import {
46
- randomBytes,
47
- pbkdf2Sync,
48
- createCipheriv,
49
- createHmac,
50
- createDecipheriv
51
- } from "crypto";
52
14
  var Session = class {
53
15
  constructor(cookie, config) {
54
16
  this.cookie = cookie;
17
+ if (!(config == null ? void 0 : config.secret))
18
+ cookie.logger.warn("Session's secret is missing.");
55
19
  this.config = Object.assign({
56
20
  key: "key",
57
21
  secret: randomBytes(128).toString("hex"),
@@ -78,11 +42,11 @@ var Session = class {
78
42
  );
79
43
  this.content = /* @__PURE__ */ Object.create(null);
80
44
  }
81
- invoke(cookie) {
45
+ invoke(cookie, logger) {
82
46
  try {
83
47
  this.content = cookie ? this.decode(cookie) : /* @__PURE__ */ Object.create(null);
84
48
  } catch (error) {
85
- console.error(error);
49
+ logger == null ? void 0 : logger.error(error);
86
50
  this.content = /* @__PURE__ */ Object.create(null);
87
51
  }
88
52
  this.changed = false;
@@ -106,7 +70,7 @@ var Session = class {
106
70
  hmac.update(signedParts[0]);
107
71
  const digest = hmac.digest("hex");
108
72
  if (signedParts[1] !== digest)
109
- throw Error("Not valid");
73
+ throw Error("Session Not valid");
110
74
  const message = Buffer.from(signedParts[0], "base64").toString();
111
75
  const parts = message.split("--").map(function(part2) {
112
76
  return Buffer.from(part2, "base64");
@@ -134,10 +98,9 @@ var Session = class {
134
98
  return this;
135
99
  }
136
100
  };
137
-
138
- // src/cookie.ts
139
101
  var Cookie = class {
140
- constructor(config) {
102
+ constructor(config, logger) {
103
+ this.logger = logger;
141
104
  this.config = deepMerge({
142
105
  path: "/",
143
106
  expires: 31536e3,
@@ -149,7 +112,7 @@ var Cookie = class {
149
112
  this.content = /* @__PURE__ */ Object.create(null);
150
113
  this.setCookie = /* @__PURE__ */ Object.create(null);
151
114
  }
152
- invoke(cookie) {
115
+ invoke(cookie, logger) {
153
116
  this.content = /* @__PURE__ */ Object.create(null);
154
117
  if (cookie)
155
118
  cookie.split(";").forEach((x) => {
@@ -159,7 +122,7 @@ var Cookie = class {
159
122
  this.content[k[0]] = decodeURIComponent(x.replace(`${k[0]}=`, "").replace(/;$/, ""));
160
123
  });
161
124
  this.setCookie = /* @__PURE__ */ Object.create(null);
162
- this.session.invoke(this.read(this.session.config.key));
125
+ this.session.invoke(this.read(this.session.config.key), logger);
163
126
  return this;
164
127
  }
165
128
  read(key) {
@@ -382,13 +345,6 @@ var Validator = class {
382
345
  }
383
346
  }
384
347
  };
385
-
386
- // src/index.ts
387
- import {
388
- gzipSync,
389
- deflateSync,
390
- brotliCompressSync
391
- } from "zlib";
392
348
  var ContentType = {
393
349
  plain: "text/plain",
394
350
  html: "text/html",
@@ -399,14 +355,14 @@ var ContentType = {
399
355
  json: "application/json",
400
356
  jsonp: "application/javascript"
401
357
  };
402
- var HttpError = class extends Error {
358
+ var HttpError = class _HttpError extends Error {
403
359
  constructor({
404
360
  statusCode,
405
361
  message
406
362
  }) {
407
363
  super(message);
408
364
  if (Error.captureStackTrace)
409
- Error.captureStackTrace(this, HttpError);
365
+ Error.captureStackTrace(this, _HttpError);
410
366
  this.statusCode = statusCode || 500;
411
367
  this.message = message;
412
368
  }
@@ -420,9 +376,6 @@ var Http = class {
420
376
  this.config = (config == null ? void 0 : config.config) || /* @__PURE__ */ Object.create(null);
421
377
  if (config == null ? void 0 : config.validator)
422
378
  this.validatorOptions = config.validator;
423
- this.headers = /* @__PURE__ */ Object.create(null);
424
- this.cookie = new Cookie(this.config.cookie || {});
425
- this.session = this.cookie.session;
426
379
  }
427
380
  async onDeploy(data, next) {
428
381
  var _a;
@@ -449,10 +402,27 @@ var Http = class {
449
402
  }
450
403
  async onMount(data, next) {
451
404
  data.logger.debug("[onMount] merge config");
405
+ const prefix = `SECRET_${this.name.toUpperCase()}_`;
406
+ for (let key in process.env)
407
+ if (key.startsWith(prefix)) {
408
+ const value = process.env[key];
409
+ key = key.replace(prefix, "").toLowerCase();
410
+ if (key.includes("_")) {
411
+ let config = this.config;
412
+ const keys = key.split("_");
413
+ keys.slice(0, keys.length - 1).forEach((k) => {
414
+ if (!config[k])
415
+ config[k] = /* @__PURE__ */ Object.create(null);
416
+ config = config[k];
417
+ });
418
+ config[keys[keys.length - 1]] = value;
419
+ } else
420
+ this.config[key] = value;
421
+ }
452
422
  if (data.config.plugins && data.config.plugins[this.name || this.type])
453
423
  this.config = deepMerge(this.config, data.config.plugins[this.name || this.type].config);
454
424
  data.logger.debug("[onMount] prepare cookie & session");
455
- this.cookie = new Cookie(this.config.cookie || {});
425
+ this.cookie = new Cookie(this.config.cookie || {}, data.logger);
456
426
  this.session = this.cookie.session;
457
427
  if (this.validatorOptions) {
458
428
  data.logger.debug("[onMount] prepare validator");
@@ -467,16 +437,23 @@ var Http = class {
467
437
  this.params = data.event.queryString || /* @__PURE__ */ Object.create(null);
468
438
  this.response = { headers: /* @__PURE__ */ Object.create(null) };
469
439
  if (data.event.body) {
470
- if ((_a = this.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) {
440
+ if (((_a = this.headers["content-type"]) == null ? void 0 : _a.includes("application/json")) && typeof data.event.body === "string" && data.event.body.length > 1) {
471
441
  data.logger.debug("[onInvoke] Parse params from json body");
472
- this.params = Object.assign(this.params, JSON.parse(data.event.body));
442
+ try {
443
+ this.params = Object.keys(this.params).length ? Object.assign(this.params, JSON.parse(data.event.body)) : JSON.parse(data.event.body);
444
+ } catch (error) {
445
+ data.logger.error("[onInvoke] Parse params from json body failed: %s", error.message);
446
+ }
473
447
  } else {
474
448
  data.logger.debug("[onInvoke] Parse params from raw body");
475
449
  this.params = data.event.body || /* @__PURE__ */ Object.create(null);
476
450
  }
451
+ if (this.params && typeof this.params === "object" && this.params["_"])
452
+ delete this.params["_"];
453
+ data.event.params = JSON.parse(JSON.stringify(this.params));
477
454
  data.logger.debug("[onInvoke] Params: %j", this.params);
478
455
  }
479
- this.cookie.invoke(this.headers.cookie);
456
+ this.cookie.invoke(this.headers.cookie, data.logger);
480
457
  if (this.headers.cookie) {
481
458
  data.logger.debug("[onInvoke] Cookie: %j", this.cookie.content);
482
459
  data.logger.debug("[onInvoke] Session: %j", this.session.content);
@@ -513,7 +490,8 @@ var Http = class {
513
490
  this.response.statusCode = this.response.body ? 200 : 201;
514
491
  this.response.headers = Object.assign({
515
492
  "Content-Type": "application/json; charset=utf-8",
516
- "Cache-Control": "no-cache, no-store"
493
+ "Cache-Control": "no-cache, no-store",
494
+ "X-FaasJS-Request-Id": data.logger.label
517
495
  }, this.cookie.headers(), this.response.headers);
518
496
  data.response = Object.assign({}, data.response, this.response);
519
497
  const originBody = data.response.body;
@@ -544,10 +522,20 @@ var Http = class {
544
522
  delete data.response.headers["Content-Encoding"];
545
523
  }
546
524
  }
525
+ /**
526
+ * set header
527
+ * @param key {string} key
528
+ * @param value {*} value
529
+ */
547
530
  setHeader(key, value) {
548
531
  this.response.headers[key] = value;
549
532
  return this;
550
533
  }
534
+ /**
535
+ * set Content-Type
536
+ * @param type {string} 类型
537
+ * @param charset {string} 编码
538
+ */
551
539
  setContentType(type, charset = "utf-8") {
552
540
  if (ContentType[type])
553
541
  this.setHeader("Content-Type", `${ContentType[type]}; charset=${charset}`);
@@ -555,10 +543,18 @@ var Http = class {
555
543
  this.setHeader("Content-Type", `${type}; charset=${charset}`);
556
544
  return this;
557
545
  }
546
+ /**
547
+ * set status code
548
+ * @param code {number} 状态码
549
+ */
558
550
  setStatusCode(code) {
559
551
  this.response.statusCode = code;
560
552
  return this;
561
553
  }
554
+ /**
555
+ * set body
556
+ * @param body {*} 内容
557
+ */
562
558
  setBody(body) {
563
559
  this.response.body = body;
564
560
  return this;
@@ -567,12 +563,5 @@ var Http = class {
567
563
  function useHttp(config) {
568
564
  return usePlugin(new Http(config));
569
565
  }
570
- export {
571
- ContentType,
572
- Cookie,
573
- Http,
574
- HttpError,
575
- Session,
576
- Validator,
577
- useHttp
578
- };
566
+
567
+ export { ContentType, Cookie, Http, HttpError, Session, Validator, useHttp };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faasjs/http",
3
- "version": "0.0.3-beta.1",
3
+ "version": "0.0.3-beta.100",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,15 +16,14 @@
16
16
  },
17
17
  "funding": "https://github.com/sponsors/faasjs",
18
18
  "scripts": {
19
- "build": "tsup-node src/index.ts --format esm,cjs",
20
- "build:types": "tsup-node src/index.ts --dts-only"
19
+ "build": "tsup-node src/index.ts --config ../../tsup.config.json"
21
20
  },
22
21
  "files": [
23
22
  "dist"
24
23
  ],
25
24
  "dependencies": {
26
- "@faasjs/func": "^0.0.3-beta.1",
27
- "@faasjs/logger": "^0.0.3-beta.1"
25
+ "@faasjs/func": "0.0.3-beta.100",
26
+ "@faasjs/logger": "0.0.3-beta.100"
28
27
  },
29
28
  "engines": {
30
29
  "npm": ">=8.0.0",