@faasjs/http 0.0.2-beta.26 → 0.0.2-beta.260

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/lib/index.js CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
-
7
- var deepMerge = _interopDefault(require('@faasjs/deep_merge'));
8
- var Logger = _interopDefault(require('@faasjs/logger'));
5
+ var func = require('@faasjs/func');
6
+ var deep_merge = require('@faasjs/deep_merge');
7
+ var logger = require('@faasjs/logger');
9
8
  var crypto = require('crypto');
9
+ var zlib = require('zlib');
10
10
 
11
11
  class Session {
12
12
  constructor(cookie, config) {
@@ -36,9 +36,8 @@ class Session {
36
36
  this.changed = false;
37
37
  }
38
38
  encode(text) {
39
- if (typeof text !== 'string') {
39
+ if (typeof text !== 'string')
40
40
  text = JSON.stringify(text);
41
- }
42
41
  const iv = crypto.randomBytes(16);
43
42
  const cipher = crypto.createCipheriv(this.config.cipherName, this.secret, iv);
44
43
  const encrypted = Buffer.concat([cipher.update(text), cipher.final()]).toString('base64');
@@ -54,9 +53,8 @@ class Session {
54
53
  const hmac = crypto.createHmac(this.config.digest, this.signedSecret);
55
54
  hmac.update(signedParts[0]);
56
55
  const digest = hmac.digest('hex');
57
- if (signedParts[1] !== digest) {
56
+ if (signedParts[1] !== digest)
58
57
  throw Error('Not valid');
59
- }
60
58
  const message = Buffer.from(signedParts[0], 'base64').toString();
61
59
  const parts = message.split('--').map(function (part) {
62
60
  return Buffer.from(part, 'base64');
@@ -71,26 +69,23 @@ class Session {
71
69
  return this.content[key];
72
70
  }
73
71
  write(key, value) {
74
- if (value === null || typeof value === 'undefined') {
72
+ if (value === null || typeof value === 'undefined')
75
73
  delete this.content[key];
76
- }
77
- else {
74
+ else
78
75
  this.content[key] = value;
79
- }
80
76
  this.changed = true;
81
77
  return this;
82
78
  }
83
79
  update() {
84
- if (this.changed) {
80
+ if (this.changed)
85
81
  this.cookie.write(this.config.key, this.encode(JSON.stringify(this.content)));
86
- }
87
82
  return this;
88
83
  }
89
84
  }
90
85
 
91
86
  class Cookie {
92
87
  constructor(config) {
93
- this.config = deepMerge({
88
+ this.config = deep_merge.deepMerge({
94
89
  path: '/',
95
90
  expires: 31536000,
96
91
  secure: true,
@@ -104,15 +99,13 @@ class Cookie {
104
99
  invoke(cookie) {
105
100
  this.content = Object.create(null);
106
101
  // 解析 cookie
107
- if (cookie) {
102
+ if (cookie)
108
103
  cookie.split(';').map((x) => {
109
104
  x = x.trim();
110
- const k = x.match(/([^=]+)/);
111
- if (k !== null) {
105
+ const k = /([^=]+)/.exec(x);
106
+ if (k !== null)
112
107
  this.content[k[0]] = decodeURIComponent(x.replace(`${k[0]}=`, '').replace(/;$/, ''));
113
- }
114
108
  });
115
- }
116
109
  this.setCookie = Object.create(null);
117
110
  // 预读取 session
118
111
  this.session.invoke(this.read(this.session.config.key));
@@ -133,78 +126,61 @@ class Cookie {
133
126
  cookie = `${key}=${encodeURIComponent(value)};`;
134
127
  this.content[key] = value;
135
128
  }
136
- if (typeof opts.expires === 'number') {
129
+ if (typeof opts.expires === 'number')
137
130
  cookie += `max-age=${opts.expires};`;
138
- }
139
- else if (typeof opts.expires === 'string') {
131
+ else if (typeof opts.expires === 'string')
140
132
  cookie += `expires=${opts.expires};`;
141
- }
142
133
  cookie += `path=${opts.path || '/'};`;
143
- if (opts.domain) {
134
+ if (opts.domain)
144
135
  cookie += `domain=${opts.domain};`;
145
- }
146
- if (opts.secure) {
136
+ if (opts.secure)
147
137
  cookie += 'Secure;';
148
- }
149
- if (opts.httpOnly) {
138
+ if (opts.httpOnly)
150
139
  cookie += 'HttpOnly;';
151
- }
152
- if (opts.sameSite) {
140
+ if (opts.sameSite)
153
141
  cookie += `SameSite=${opts.sameSite};`;
154
- }
155
142
  this.setCookie[key] = cookie;
156
143
  return this;
157
144
  }
158
145
  headers() {
159
- if (!Object.keys(this.setCookie).length) {
146
+ if (Object.keys(this.setCookie).length === 0)
160
147
  return {};
161
- }
162
- else {
163
- return {
164
- 'Set-Cookie': Object.values(this.setCookie)
165
- };
166
- }
148
+ else
149
+ return { 'Set-Cookie': Object.values(this.setCookie) };
167
150
  }
168
151
  }
169
152
 
170
- class ValidError extends Error {
171
- constructor({ statusCode, headers, message }) {
172
- super(message);
173
- this.statusCode = statusCode || 500;
174
- this.headers = headers || Object.create(null);
175
- }
176
- }
177
153
  class Validator {
178
154
  constructor(config) {
179
155
  this.paramsConfig = config.params;
180
156
  this.cookieConfig = config.cookie;
181
157
  this.sessionConfig = config.session;
182
- this.logger = new Logger('Http.Validator');
158
+ this.before = config.before;
159
+ this.logger = new logger.Logger('Http.Validator');
183
160
  }
184
- valid({ params, cookie, session }) {
185
- this.request = {
186
- params,
187
- cookie,
188
- session
189
- };
161
+ async valid(request) {
190
162
  this.logger.debug('Begin');
191
- if (this.paramsConfig) {
163
+ if (this.before) {
164
+ const result = await this.before(request);
165
+ if (result)
166
+ throw new HttpError(result);
167
+ }
168
+ this.request = request;
169
+ if (this.paramsConfig && request.params) {
192
170
  this.logger.debug('Valid params');
193
- this.validContent('params', params, '', this.paramsConfig);
171
+ this.validContent('params', request.params, '', this.paramsConfig);
194
172
  }
195
- if (this.cookieConfig) {
173
+ if (this.cookieConfig && request.cookie) {
196
174
  this.logger.debug('Valid cookie');
197
- if (!cookie) {
175
+ if (request.cookie == null)
198
176
  throw Error('Not found Cookie');
199
- }
200
- this.validContent('cookie', cookie.content, '', this.cookieConfig);
177
+ this.validContent('cookie', request.cookie.content, '', this.cookieConfig);
201
178
  }
202
- if (this.sessionConfig) {
179
+ if (this.sessionConfig && request.session) {
203
180
  this.logger.debug('Valid Session');
204
- if (!session) {
181
+ if (request.session == null)
205
182
  throw Error('Not found Session');
206
- }
207
- this.validContent('session', session.content, '', this.sessionConfig);
183
+ this.validContent('session', request.session.content, '', this.sessionConfig);
208
184
  }
209
185
  }
210
186
  validContent(type, params, baseKey, config) {
@@ -212,57 +188,50 @@ class Validator {
212
188
  const paramsKeys = Object.keys(params);
213
189
  const rulesKeys = Object.keys(config.rules);
214
190
  const diff = paramsKeys.filter(k => !rulesKeys.includes(k));
215
- if (diff.length) {
191
+ if (diff.length > 0)
216
192
  if (config.whitelist === 'error') {
217
193
  const diffKeys = diff.map(k => `${baseKey}${k}`);
218
194
  const error = Error(`[${type}] Unpermitted keys: ${diffKeys.join(', ')}`);
219
195
  if (config.onError) {
220
196
  const res = config.onError(`${type}.whitelist`, baseKey, diffKeys);
221
- if (res) {
222
- throw new ValidError(res);
223
- }
197
+ if (res)
198
+ throw new HttpError(res);
224
199
  }
225
200
  throw error;
226
201
  }
227
- else if (config.whitelist === 'ignore') {
228
- for (const key of diff) {
202
+ else if (config.whitelist === 'ignore')
203
+ for (const key of diff)
229
204
  delete params[key];
230
- }
231
- }
232
- }
233
205
  }
234
206
  for (const key in config.rules) {
235
207
  const rule = config.rules[key];
208
+ if (!rule)
209
+ continue;
236
210
  let value = params[key];
237
211
  // default
238
- if (rule.default) {
239
- if (type === 'cookie' || type === 'session') {
212
+ if (rule.default)
213
+ if (type === 'cookie' || type === 'session')
240
214
  this.logger.warn('Cookie and Session not support default rule.');
241
- }
242
215
  else if (typeof value === 'undefined' && rule.default) {
243
216
  value = typeof rule.default === 'function' ? rule.default(this.request) : rule.default;
244
217
  params[key] = value;
245
218
  }
246
- }
247
219
  // required
248
- if (rule.required === true) {
220
+ if (rule.required)
249
221
  if (typeof value === 'undefined' || value === null) {
250
222
  const error = Error(`[${type}] ${baseKey}${key} is required.`);
251
223
  if (config.onError) {
252
224
  const res = config.onError(`${type}.rule.required`, `${baseKey}${key}`, value);
253
- if (res) {
254
- throw new ValidError(res);
255
- }
225
+ if (res)
226
+ throw new HttpError(res);
256
227
  }
257
228
  throw error;
258
229
  }
259
- }
260
230
  if (typeof value !== 'undefined' && value !== null) {
261
231
  // type
262
- if (rule.type) {
263
- if (type === 'cookie') {
232
+ if (rule.type)
233
+ if (type === 'cookie')
264
234
  this.logger.warn('Cookie not support type rule');
265
- }
266
235
  else {
267
236
  let typed = true;
268
237
  switch (rule.type) {
@@ -280,43 +249,33 @@ class Validator {
280
249
  const error = Error(`[${type}] ${baseKey}${key} must be a ${rule.type}.`);
281
250
  if (config.onError) {
282
251
  const res = config.onError(`${type}.rule.type`, `${baseKey}${key}`, value);
283
- if (res) {
284
- throw new ValidError(res);
285
- }
252
+ if (res)
253
+ throw new HttpError(res);
286
254
  }
287
255
  throw error;
288
256
  }
289
257
  }
290
- }
291
258
  // in
292
- if (rule.in && !rule.in.includes(value)) {
259
+ if ((rule.in) && !rule.in.includes(value)) {
293
260
  const error = Error(`[${type}] ${baseKey}${key} must be in ${rule.in.join(', ')}.`);
294
261
  if (config.onError) {
295
262
  const res = config.onError(`${type}.rule.in`, `${baseKey}${key}`, value);
296
- if (res) {
297
- throw new ValidError(res);
298
- }
263
+ if (res)
264
+ throw new HttpError(res);
299
265
  }
300
266
  throw error;
301
267
  }
302
268
  // nest config
303
- if (rule.config) {
304
- if (type === 'cookie') {
269
+ if (rule.config)
270
+ if (type === 'cookie')
305
271
  this.logger.warn('Cookie not support nest rule.');
306
- }
307
- else {
308
- if (Array.isArray(value)) {
309
- // array
310
- for (const val of value) {
311
- this.validContent(type, val, (baseKey ? `${baseKey}.${key}.` : `${key}.`), rule.config);
312
- }
313
- }
314
- else if (typeof value === 'object') {
315
- // object
316
- this.validContent(type, value, (baseKey ? `${baseKey}.${key}.` : `${key}.`), rule.config);
317
- }
318
- }
319
- }
272
+ else if (Array.isArray(value))
273
+ // array
274
+ for (const val of value)
275
+ this.validContent(type, val, (baseKey ? `${baseKey}.${key}.` : `${key}.`), rule.config);
276
+ else if (typeof value === 'object')
277
+ // object
278
+ this.validContent(type, value, (baseKey ? `${baseKey}.${key}.` : `${key}.`), rule.config);
320
279
  }
321
280
  }
322
281
  }
@@ -332,12 +291,27 @@ const ContentType = {
332
291
  json: 'application/json',
333
292
  jsonp: 'application/javascript'
334
293
  };
294
+ class HttpError extends Error {
295
+ constructor({ statusCode, message }) {
296
+ super(message);
297
+ if (Error.captureStackTrace)
298
+ Error.captureStackTrace(this, HttpError);
299
+ this.statusCode = statusCode || 500;
300
+ this.message = message;
301
+ }
302
+ }
303
+ const Name = 'http';
304
+ const globals = {};
335
305
  class Http {
336
306
  /**
337
307
  * 创建 Http 插件实例
338
308
  * @param config {object} 配置项
339
309
  * @param config.name {string} 配置名
340
310
  * @param config.config {object} 网关配置
311
+ * @param config.config.method {string} 请求方法,默认为 POST
312
+ * @param config.config.path {string} 请求路径,默认为云函数文件路径
313
+ * @param config.config.ignorePathPrefix {string} 排除的路径前缀,当设置 path 时无效
314
+ * @param config.config.cookie {object} Cookie 配置
341
315
  * @param config.validator {object} 入参校验配置
342
316
  * @param config.validator.params {object} params 校验配置
343
317
  * @param config.validator.params.whitelist {string} 白名单配置
@@ -351,37 +325,51 @@ class Http {
351
325
  * @param config.validator.session.whitelist {string} 白名单配置
352
326
  * @param config.validator.session.onError {function} 自定义报错
353
327
  * @param config.validator.session.rules {object} 参数校验规则
328
+ * @param config.validator.before {function} 参数校验前自定义函数
354
329
  */
355
- constructor(config = Object.create(null)) {
356
- this.logger = new Logger('Http');
357
- this.type = 'http';
358
- this.name = config.name;
359
- this.config = config.config || Object.create(null);
360
- if (config.validator)
330
+ constructor(config) {
331
+ this.type = Name;
332
+ this.name = Name;
333
+ this.name = (config === null || config === void 0 ? void 0 : config.name) || this.type;
334
+ this.config = ((config === null || config === void 0 ? void 0 : config.config)) || Object.create(null);
335
+ if ((config === null || config === void 0 ? void 0 : config.validator))
361
336
  this.validatorOptions = config.validator;
337
+ this.logger = new logger.Logger(this.name);
362
338
  this.headers = Object.create(null);
363
339
  this.cookie = new Cookie(this.config.cookie || {});
364
340
  this.session = this.cookie.session;
365
341
  }
366
342
  async onDeploy(data, next) {
343
+ var _a;
367
344
  await next();
368
- this.logger.debug('[Http] 组装网关配置');
345
+ this.logger.debug('组装网关配置');
369
346
  this.logger.debug('%o', data);
370
- const config = deepMerge(data.config.plugins[this.name || this.type], { config: this.config });
347
+ const config = data.config.plugins ?
348
+ deep_merge.deepMerge(data.config.plugins[this.name || this.type], { config: this.config }) :
349
+ { config: this.config };
371
350
  // 根据文件及文件夹名生成路径
372
- config.config.path = '=/' + data.name.replace(/_/g, '/').replace(/\/index$/, '');
373
- this.logger.debug('[Http] 组装完成 %o', config);
351
+ if (!config.config.path) {
352
+ config.config.path = '=/' + ((_a = data.name) === null || _a === void 0 ? void 0 : _a.replace(/_/g, '/').replace(/\/index$/, ''));
353
+ if (config.config.path === '=/index')
354
+ config.config.path = '=/';
355
+ if (config.config.ignorePathPrefix) {
356
+ config.config.path = config.config.path.replace(new RegExp('^=' + config.config.ignorePathPrefix), '=');
357
+ if (config.config.path === '=')
358
+ config.config.path = '=/';
359
+ }
360
+ }
361
+ this.logger.debug('组装完成 %o', config);
374
362
  // 引用服务商部署插件
375
- // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
376
- const Provider = require(config.provider.type);
363
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
364
+ const Provider = require(config.provider.type).Provider;
377
365
  const provider = new Provider(config.provider.config);
378
366
  // 部署网关
379
367
  await provider.deploy(this.type, data, config);
380
368
  }
381
369
  async onMount(data, next) {
382
370
  this.logger.debug('[onMount] merge config');
383
- if (data.config.plugins[this.name || this.type])
384
- this.config = deepMerge(this.config, data.config.plugins[this.name || this.type].config);
371
+ if (data.config.plugins && data.config.plugins[this.name || this.type])
372
+ this.config = deep_merge.deepMerge(this.config, data.config.plugins[this.name || this.type].config);
385
373
  this.logger.debug('[onMount] prepare cookie & session');
386
374
  this.cookie = new Cookie(this.config.cookie || {});
387
375
  this.session = this.cookie.session;
@@ -389,11 +377,11 @@ class Http {
389
377
  this.logger.debug('[onMount] prepare validator');
390
378
  this.validator = new Validator(this.validatorOptions);
391
379
  }
380
+ globals[this.name] = this;
392
381
  await next();
393
382
  }
394
383
  async onInvoke(data, next) {
395
- this.logger.debug('[onInvoke] Parse & valid');
396
- this.logger.time('http');
384
+ var _a, _b;
397
385
  this.headers = data.event.headers || Object.create(null);
398
386
  this.params = Object.create(null);
399
387
  this.response = { headers: Object.create(null) };
@@ -410,14 +398,16 @@ class Http {
410
398
  this.logger.debug('[onInvoke] Parse params from queryString');
411
399
  this.params = data.event.queryString;
412
400
  }
401
+ this.logger.debug('[onInvoke] Params: %j', this.params);
413
402
  this.logger.debug('[onInvoke] Parse cookie');
414
- this.cookie.invoke(this.headers['cookie']);
415
- this.logger.debug('[onInvoke] Cookie: %o', this.cookie.content);
416
- this.logger.debug('[onInvoke] Session: %o', this.session.content);
417
- if (this.validator) {
403
+ this.cookie.invoke(this.headers.cookie);
404
+ this.logger.debug('[onInvoke] Cookie: %j', this.cookie.content);
405
+ this.logger.debug('[onInvoke] Session: %j', this.session.content);
406
+ if (this.validator && data.event.httpMethod) {
418
407
  this.logger.debug('[onInvoke] Valid request');
419
408
  try {
420
- this.validator.valid({
409
+ await this.validator.valid({
410
+ headers: this.headers,
421
411
  params: this.params,
422
412
  cookie: this.cookie,
423
413
  session: this.session
@@ -427,52 +417,88 @@ class Http {
427
417
  this.logger.error(error);
428
418
  data.response = {
429
419
  statusCode: error.statusCode || 500,
430
- headers: Object.assign({
420
+ headers: {
431
421
  'Content-Type': 'application/json; charset=utf-8',
432
- 'X-Request-Id': data.context.request_id
433
- }, error.headers || {}),
422
+ 'X-SCF-RequestId': data.context.request_id
423
+ },
434
424
  body: JSON.stringify({ error: { message: error.message } })
435
425
  };
436
426
  return;
437
427
  }
438
428
  }
439
- this.logger.timeEnd('http', '[onInvoke] Parse & valid done');
440
429
  try {
441
430
  await next();
442
431
  }
443
432
  catch (error) {
444
433
  data.response = error;
445
434
  }
446
- this.logger.debug('[onInvoke] Generate response');
447
- this.logger.time('http');
448
435
  // update seesion
449
436
  this.session.update();
450
437
  // 处理 body
451
438
  if (data.response)
452
- if (data.response instanceof Error || (data.response.constructor && data.response.constructor.name === 'Error')) {
439
+ if (data.response instanceof Error || ((_a = data.response.constructor) === null || _a === void 0 ? void 0 : _a.name) === 'Error') {
453
440
  // 当结果是错误类型时
454
441
  this.logger.error(data.response);
455
442
  this.response.body = JSON.stringify({ error: { message: data.response.message } });
456
- this.response.statusCode = 500;
443
+ try {
444
+ this.response.statusCode = data.response.statusCode || 500;
445
+ }
446
+ catch (error) {
447
+ this.response.statusCode = 500;
448
+ }
457
449
  }
458
- else if (Object.prototype.toString.call(data.response) === '[object Object]' && data.response.statusCode && data.response.headers) {
450
+ else if (Object.prototype.toString.call(data.response) === '[object Object]' && data.response.statusCode && data.response.headers)
459
451
  // 当返回结果是响应结构体时
460
452
  this.response = data.response;
461
- }
462
- else {
453
+ else
463
454
  this.response.body = JSON.stringify({ data: data.response });
464
- }
465
455
  // 处理 statusCode
466
456
  if (!this.response.statusCode)
467
457
  this.response.statusCode = this.response.body ? 200 : 201;
468
458
  // 处理 headers
469
459
  this.response.headers = Object.assign({
470
460
  'Content-Type': 'application/json; charset=utf-8',
471
- 'X-Request-Id': new Date().getTime().toString()
461
+ 'X-SCF-RequestId': data.context.request_id
472
462
  }, this.cookie.headers(), this.response.headers);
473
- /* eslint-disable-next-line require-atomic-updates */
474
463
  data.response = this.response;
475
- this.logger.timeEnd('http', '[onInvoke] done');
464
+ if (process.env.FaasMode === 'local') {
465
+ this.logger.debug('[onInvoke] Response: %j', data.response);
466
+ return;
467
+ }
468
+ // 判断是否需要压缩
469
+ if (data.response.isBase64Encoded ||
470
+ typeof data.response.body !== 'string' ||
471
+ !((_b = data.response.headers['Content-Type']) === null || _b === void 0 ? void 0 : _b.includes('json')) ||
472
+ data.response.body.length < 100)
473
+ return;
474
+ const acceptEncoding = this.headers['accept-encoding'] || this.headers['Accept-Encoding'];
475
+ if (!acceptEncoding || !/(br|gzip|deflate)/.test(acceptEncoding))
476
+ return;
477
+ const originBody = data.response.body;
478
+ try {
479
+ if (acceptEncoding.includes('br')) {
480
+ data.response.headers['Content-Encoding'] = 'br';
481
+ data.response.body = zlib.brotliCompressSync(originBody).toString('base64');
482
+ }
483
+ else if (acceptEncoding.includes('gzip')) {
484
+ data.response.headers['Content-Encoding'] = 'gzip';
485
+ data.response.body = zlib.gzipSync(originBody).toString('base64');
486
+ }
487
+ else if (acceptEncoding.includes('deflate')) {
488
+ data.response.headers['Content-Encoding'] = 'deflate';
489
+ data.response.body = zlib.deflateSync(originBody).toString('base64');
490
+ }
491
+ else
492
+ throw Error('No matched compression.');
493
+ data.response.isBase64Encoded = true;
494
+ data.response.originBody = originBody;
495
+ }
496
+ catch (error) {
497
+ console.error(error);
498
+ // 若压缩失败还原
499
+ data.response.body = originBody;
500
+ delete data.response.headers['Content-Encoding'];
501
+ }
476
502
  }
477
503
  /**
478
504
  * 设置 header
@@ -511,10 +537,18 @@ class Http {
511
537
  this.response.body = body;
512
538
  return this;
513
539
  }
540
+ }
541
+ function useHttp(config) {
542
+ const name = (config === null || config === void 0 ? void 0 : config.name) || Name;
543
+ if (process.env.FaasEnv !== 'testing' && globals[name])
544
+ return func.usePlugin(globals[name]);
545
+ return func.usePlugin(new Http(config));
514
546
  }
515
547
 
516
548
  exports.ContentType = ContentType;
517
549
  exports.Cookie = Cookie;
518
550
  exports.Http = Http;
551
+ exports.HttpError = HttpError;
519
552
  exports.Session = Session;
520
553
  exports.Validator = Validator;
554
+ exports.useHttp = useHttp;
package/lib/session.d.ts CHANGED
@@ -9,10 +9,11 @@ export interface SessionOptions {
9
9
  digest?: string;
10
10
  cipherName?: string;
11
11
  }
12
- export declare class Session {
13
- content: {
14
- [key: string]: any;
15
- };
12
+ export declare type SessionContent = string | number | {
13
+ [key: string]: any;
14
+ } | null | undefined;
15
+ export declare class Session<S, C> {
16
+ content: S;
16
17
  readonly config: {
17
18
  key: string;
18
19
  secret: string;
@@ -23,15 +24,15 @@ export declare class Session {
23
24
  digest: string;
24
25
  cipherName: string;
25
26
  };
26
- private secret;
27
- private signedSecret;
28
- private cookie;
27
+ private readonly secret;
28
+ private readonly signedSecret;
29
+ private readonly cookie;
29
30
  private changed?;
30
- constructor(cookie: Cookie, config: SessionOptions);
31
+ constructor(cookie: Cookie<C, S>, config: SessionOptions);
31
32
  invoke(cookie?: string): void;
32
- encode(text: any): string;
33
- decode(text: string): any;
34
- read(key: string): any;
35
- write(key: string, value?: any): this;
36
- update(): this;
33
+ encode(text: SessionContent): string;
34
+ decode(text: string): SessionContent;
35
+ read(key: string): string;
36
+ write(key: string, value?: SessionContent): Session<S, C>;
37
+ update(): Session<S, C>;
37
38
  }