forked from koajs/session
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession.ts
More file actions
139 lines (125 loc) · 3.14 KB
/
Copy pathsession.ts
File metadata and controls
139 lines (125 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { inspect } from 'node:util';
import type { ContextSession } from './context.js';
type Callback = (err?: Error) => void;
/**
* Session model
*/
export class Session {
#sessCtx: ContextSession;
#ctx: any;
#externalKey?: string;
isNew = false;
_requireSave = false;
// session expire time, will be set from sessionData
_expire?: number;
constructor(sessionContext: ContextSession, sessionData?: Record<string, unknown>, externalKey?: string) {
this.#sessCtx = sessionContext;
this.#ctx = sessionContext.ctx;
this.#externalKey = externalKey;
if (!sessionData) {
this.isNew = true;
} else {
for (const k in sessionData) {
// restore maxAge from store
if (k === '_maxAge') {
this.#ctx.sessionOptions.maxAge = sessionData._maxAge;
} else if (k === '_session') {
// set maxAge to 'session' if it's a session lifetime
this.#ctx.sessionOptions.maxAge = 'session';
} else {
Reflect.set(this, k, sessionData[k]);
}
}
}
}
/**
* JSON representation of the session.
*/
toJSON() {
const obj: Record<string, unknown> = {};
for (const key in this) {
if (key === 'isNew') continue;
// skip private stuff
if (key[0] === '_') continue;
const value = this[key];
// skip functions
if (typeof value === 'function') continue;
obj[key] = value;
}
return obj;
}
/**
* alias to `toJSON`
*/
[inspect.custom]() {
return this.toJSON();
}
/**
* Return how many values there are in the session object.
* Used to see if it's "populated".
*/
get length() {
return Object.keys(this.toJSON()).length;
}
/**
* populated flag, which is just a boolean alias of .length.
*/
get populated() {
return !!this.length;
}
/**
* get session maxAge
*/
get maxAge(): number {
return this.#ctx.sessionOptions.maxAge;
}
/**
* set session maxAge
*/
set maxAge(val: number) {
this.#ctx.sessionOptions.maxAge = val;
// maxAge changed, must save to cookie and store
this._requireSave = true;
}
/**
* get session external key
* only exist if opts.store present
*/
get externalKey() {
return this.#externalKey;
}
/**
* save this session no matter whether it is populated
*
* @param {Function} [callback] the optional function to call after saving the session
*/
save(callback?: Callback) {
return this.commit({ save: true }, callback);
}
/**
* regenerate this session
*
* @param {Function} [callback] the optional function to call after regenerating the session
*/
regenerate(callback?: Callback) {
return this.commit({ regenerate: true }, callback);
}
/**
* commit this session's headers if autoCommit is set to false
*/
manuallyCommit() {
return this.commit();
}
commit(options?: any, callback?: Callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
const promise = this.#sessCtx.commit(options);
if (callback) {
promise.then(() => callback(), callback);
} else {
return promise;
}
}
}