@adonisjs/session 7.0.0-0 → 7.0.0-10

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.
Files changed (53) hide show
  1. package/README.md +18 -38
  2. package/build/configure.js +29 -2
  3. package/build/factories/main.d.ts +1 -0
  4. package/build/factories/main.js +9 -0
  5. package/build/factories/session_middleware_factory.d.ts +22 -0
  6. package/build/factories/session_middleware_factory.js +47 -0
  7. package/build/index.d.ts +5 -3
  8. package/build/index.js +5 -3
  9. package/build/providers/session_provider.d.ts +15 -4
  10. package/build/providers/session_provider.js +37 -20
  11. package/build/src/client.d.ts +13 -25
  12. package/build/src/client.js +24 -43
  13. package/build/src/debug.d.ts +3 -0
  14. package/build/src/debug.js +10 -0
  15. package/build/src/define_config.d.ts +6 -3
  16. package/build/src/define_config.js +34 -5
  17. package/build/src/drivers/cookie.d.ts +7 -9
  18. package/build/src/drivers/cookie.js +10 -6
  19. package/build/src/drivers/file.d.ts +11 -14
  20. package/build/src/drivers/file.js +90 -34
  21. package/build/src/drivers/memory.d.ts +4 -8
  22. package/build/src/drivers/memory.js +0 -3
  23. package/build/src/drivers/redis.d.ts +4 -6
  24. package/build/src/drivers/redis.js +25 -29
  25. package/build/src/drivers_collection.d.ts +22 -0
  26. package/build/src/drivers_collection.js +38 -0
  27. package/build/src/edge_plugin_adonisjs_session.d.ts +6 -0
  28. package/build/src/edge_plugin_adonisjs_session.js +92 -0
  29. package/build/src/errors.d.ts +8 -0
  30. package/build/src/errors.js +17 -0
  31. package/build/src/helpers.d.ts +6 -0
  32. package/build/src/helpers.js +43 -0
  33. package/build/src/session.d.ts +86 -59
  34. package/build/src/session.js +235 -224
  35. package/build/src/session_middleware.d.ts +19 -2
  36. package/build/src/session_middleware.js +43 -4
  37. package/build/src/store.d.ts +48 -35
  38. package/build/src/store.js +85 -57
  39. package/build/src/types/extended.d.ts +19 -0
  40. package/build/src/types/main.d.ts +106 -0
  41. package/build/src/types/main.js +9 -0
  42. package/build/stubs/config.stub +28 -92
  43. package/package.json +37 -26
  44. package/build/src/bindings/api_client.d.ts +0 -2
  45. package/build/src/bindings/api_client.js +0 -135
  46. package/build/src/bindings/http_context.d.ts +0 -5
  47. package/build/src/bindings/http_context.js +0 -17
  48. package/build/src/bindings/types.d.ts +0 -77
  49. package/build/src/session_manager.d.ts +0 -38
  50. package/build/src/session_manager.js +0 -149
  51. package/build/src/types.d.ts +0 -61
  52. package/build/src/types.js +0 -1
  53. /package/build/src/{bindings/types.js → types/extended.js} +0 -0
@@ -6,368 +6,379 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import { Exception } from '@poppinss/utils';
10
9
  import lodash from '@poppinss/utils/lodash';
11
10
  import { cuid } from '@adonisjs/core/helpers';
12
- import { Store } from './store.js';
11
+ import { ReadOnlyStore, Store } from './store.js';
12
+ import * as errors from './errors.js';
13
+ import debug from './debug.js';
13
14
  /**
14
- * Session class exposes the API to read/write values to the session for
15
- * a given request.
15
+ * The session class exposes the API to read and write values to
16
+ * the session store.
17
+ *
18
+ * A session instance is isolated between requests but
19
+ * uses a centralized persistence store and
16
20
  */
17
21
  export class Session {
18
- /**
19
- * Session id for the current request. It will be different
20
- * from the "this.sessionId" when regenerate is called.
21
- */
22
- #currentSessionId;
23
- /**
24
- * A instance of store with values read from the driver. The store
25
- * in initiated inside the [[initiate]] method
26
- */
27
- #store;
28
- /**
29
- * Whether or not to re-generate the session id before committing
30
- * session values.
31
- */
32
- #regeneratedSessionId = false;
33
- /**
34
- * Session key for setting flash messages
35
- */
36
- #flashMessagesKey = '__flash__';
37
- /**
38
- * The HTTP context for the current request.
39
- */
40
- #ctx;
41
- /**
42
- * Configuration for the session
43
- */
44
22
  #config;
45
- /**
46
- * The session driver instance used to read and write session data.
47
- */
48
23
  #driver;
24
+ #emitter;
25
+ #ctx;
26
+ #readonly = false;
27
+ #store;
49
28
  /**
50
- * Set to true inside the `initiate` method
51
- */
52
- initiated = false;
53
- /**
54
- * A boolean to know if it's a fresh session or not. Fresh
55
- * sessions are those, whose session id is not present
56
- * in cookie
29
+ * Session id refers to the session id that will be committed
30
+ * as a cookie during the response.
57
31
  */
58
- fresh = false;
32
+ #sessionId;
59
33
  /**
60
- * A boolean to know if store is initiated in readonly mode
61
- * or not. This is done during Websocket requests
34
+ * Session id from cookie refers to the value we read from the
35
+ * cookie during the HTTP request.
36
+ *
37
+ * This only might not exist during the first request. Also during
38
+ * session id re-generation, this value will be different from
39
+ * the session id.
62
40
  */
63
- readonly = false;
41
+ #sessionIdFromCookie;
64
42
  /**
65
- * Session id for the given request. A new session id is only
66
- * generated when the cookie for the session id is missing
43
+ * Store of flash messages that be written during the
44
+ * HTTP request
67
45
  */
68
- sessionId;
46
+ responseFlashMessages = new Store({});
69
47
  /**
70
- * A copy of previously set flash messages
48
+ * Store of flash messages for the current HTTP request.
71
49
  */
72
50
  flashMessages = new Store({});
73
51
  /**
74
- * A copy of flash messages. The `input` messages
75
- * are overwritten when any of the input related
76
- * methods are used.
77
- *
78
- * The `others` object is expanded with each call.
52
+ * The key to use for storing flash messages inside
53
+ * the session store.
79
54
  */
80
- responseFlashMessages = new Store({});
81
- constructor(ctx, config, driver) {
82
- this.#ctx = ctx;
83
- this.#config = config;
84
- this.#driver = driver;
85
- this.sessionId = this.#getSessionId();
86
- this.#currentSessionId = this.sessionId;
87
- }
55
+ flashKey = '__flash__';
88
56
  /**
89
- * Returns a merged copy of flash messages or null
90
- * when nothing is set
57
+ * Session id for the current HTTP request
91
58
  */
92
- #setFlashMessages() {
93
- if (this.responseFlashMessages.isEmpty) {
94
- return;
95
- }
96
- const { input, ...others } = this.responseFlashMessages.all();
97
- this.put(this.#flashMessagesKey, { ...input, ...others });
59
+ get sessionId() {
60
+ return this.#sessionId;
98
61
  }
99
62
  /**
100
- * Returns the existing session id or creates one.
63
+ * A boolean to know if a fresh session is created during
64
+ * the request
101
65
  */
102
- #getSessionId() {
103
- const sessionId = this.#ctx.request.cookie(this.#config.cookieName);
104
- if (sessionId) {
105
- return sessionId;
106
- }
107
- this.fresh = true;
108
- return cuid();
66
+ get fresh() {
67
+ return this.#sessionIdFromCookie === undefined;
109
68
  }
110
69
  /**
111
- * Ensures the session store is initialized
70
+ * A boolean to know if session is in readonly
71
+ * state
112
72
  */
113
- #ensureIsReady() {
114
- if (!this.initiated) {
115
- throw new Exception('Session store is not initiated yet. Make sure you are using the session hook', { code: 'E_RUNTIME_EXCEPTION', status: 500 });
116
- }
73
+ get readonly() {
74
+ return this.#readonly;
117
75
  }
118
76
  /**
119
- * Raises exception when session store is in readonly mode
77
+ * A boolean to know if session store has been initiated
120
78
  */
121
- #ensureIsMutable() {
122
- if (this.readonly) {
123
- throw new Exception('Session store is in readonly mode and cannot be mutated', {
124
- status: 500,
125
- code: 'E_RUNTIME_EXCEPTION',
126
- });
127
- }
79
+ get initiated() {
80
+ return !!this.#store;
128
81
  }
129
82
  /**
130
- * Touches the session cookie
83
+ * A boolean to know if the session id has been re-generated
84
+ * during the current request
131
85
  */
132
- #touchSessionCookie() {
133
- this.#ctx.logger.trace('touching session cookie');
134
- this.#ctx.response.cookie(this.#config.cookieName, this.sessionId, this.#config.cookie);
86
+ get hasRegeneratedSession() {
87
+ return !!(this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId);
135
88
  }
136
89
  /**
137
- * Commits the session value to the store
90
+ * A boolean to know if the session store is empty
138
91
  */
139
- async #commitValuesToStore() {
140
- this.#ctx.logger.trace('persist session store with driver');
141
- await this.#driver.write(this.sessionId, this.#store.toJSON());
92
+ get isEmpty() {
93
+ return this.#store?.isEmpty ?? true;
142
94
  }
143
95
  /**
144
- * Touches the driver to make sure the session values doesn't expire
96
+ * A boolean to know if the session store has been
97
+ * modified
145
98
  */
146
- async #touchDriver() {
147
- this.#ctx.logger.trace('touch driver for liveliness');
148
- await this.#driver.touch(this.sessionId);
99
+ get hasBeenModified() {
100
+ return this.#store?.hasBeenModified ?? false;
101
+ }
102
+ constructor(config, driver, emitter, ctx) {
103
+ this.#ctx = ctx;
104
+ this.#config = config;
105
+ this.#driver = driver;
106
+ this.#emitter = emitter;
107
+ this.#sessionIdFromCookie = ctx.request.cookie(config.cookieName, undefined);
108
+ this.#sessionId = this.#sessionIdFromCookie || cuid();
149
109
  }
150
110
  /**
151
- * Reading flash messages from the last HTTP request and
152
- * updating the flash messages bag
111
+ * Returns the flash messages store for a given
112
+ * mode
153
113
  */
154
- #readLastRequestFlashMessage() {
155
- if (this.readonly) {
156
- return;
114
+ #getFlashStore(mode) {
115
+ if (!this.#store) {
116
+ throw new errors.E_SESSION_NOT_READY();
157
117
  }
158
- this.flashMessages.update(this.pull(this.#flashMessagesKey, null));
118
+ if (mode === 'write' && this.readonly) {
119
+ throw new errors.E_SESSION_NOT_MUTABLE();
120
+ }
121
+ return this.responseFlashMessages;
159
122
  }
160
123
  /**
161
- * Share flash messages & read only session's functions with views
162
- * (only when view property exists)
124
+ * Returns the store instance for a given mode
163
125
  */
164
- #shareLocalsWithView() {
165
- // @ts-ignore may need to expose ./types/extended from adonisjs/view
166
- if (!this.#ctx['view'] || typeof this.#ctx['view'].share !== 'function') {
167
- return;
126
+ #getStore(mode) {
127
+ if (!this.#store) {
128
+ throw new errors.E_SESSION_NOT_READY();
129
+ }
130
+ if (mode === 'write' && this.readonly) {
131
+ throw new errors.E_SESSION_NOT_MUTABLE();
168
132
  }
169
- // @ts-ignore may need to expose ./types/extended from adonisjs/view
170
- this.#ctx['view'].share({
171
- flashMessages: this.flashMessages,
172
- session: {
173
- get: this.get.bind(this),
174
- has: this.has.bind(this),
175
- all: this.all.bind(this),
176
- },
177
- });
133
+ return this.#store;
178
134
  }
179
135
  /**
180
- * Initiating the session by reading it's value from the
181
- * driver and feeding it to a store.
182
- *
183
- * Multiple calls to `initiate` results in a noop.
136
+ * Initiates the session store. The method results in a noop
137
+ * when called multiple times
184
138
  */
185
139
  async initiate(readonly) {
186
- if (this.initiated) {
140
+ if (this.#store) {
187
141
  return;
188
142
  }
189
- this.readonly = readonly;
190
- const contents = await this.#driver.read(this.sessionId);
143
+ debug('initiating session (readonly: %s)', readonly);
144
+ this.#readonly = readonly;
145
+ const contents = await this.#driver.read(this.#sessionId);
191
146
  this.#store = new Store(contents);
192
- this.initiated = true;
193
- this.#readLastRequestFlashMessage();
194
- this.#shareLocalsWithView();
195
- }
196
- /**
197
- * Re-generates the session id. This can is used to avoid
198
- * session fixation attacks.
199
- */
200
- regenerate() {
201
- this.#ctx.logger.trace('explicitly re-generating session id');
202
- this.sessionId = cuid();
203
- this.#regeneratedSessionId = true;
147
+ /**
148
+ * Extract flash messages from the store and keep a local
149
+ * copy of it.
150
+ */
151
+ if (this.has(this.flashKey)) {
152
+ debug('reading flash data');
153
+ if (this.#readonly) {
154
+ this.flashMessages.update(this.get(this.flashKey, null));
155
+ }
156
+ else {
157
+ this.flashMessages.update(this.pull(this.flashKey, null));
158
+ }
159
+ }
160
+ /**
161
+ * Share session with the templates. We assume the view property
162
+ * is a reference to edge templates
163
+ */
164
+ if ('view' in this.#ctx) {
165
+ this.#ctx.view.share({
166
+ session: new ReadOnlyStore(this.#store.all()),
167
+ flashMessages: new ReadOnlyStore(this.flashMessages.all()),
168
+ old: function (key, defaultValue) {
169
+ return this.flashMessages.get(key, defaultValue);
170
+ },
171
+ });
172
+ }
173
+ this.#emitter.emit('session:initiated', { session: this });
204
174
  }
205
175
  /**
206
- * Set/update session value
176
+ * Put a key-value pair to the session data store
207
177
  */
208
178
  put(key, value) {
209
- this.#ensureIsReady();
210
- this.#ensureIsMutable();
211
- this.#store.set(key, value);
179
+ this.#getStore('write').set(key, value);
212
180
  }
213
181
  /**
214
- * Find if the value exists in the session
182
+ * Check if a key exists inside the datastore
215
183
  */
216
184
  has(key) {
217
- this.#ensureIsReady();
218
- return this.#store.has(key);
185
+ return this.#getStore('read').has(key);
219
186
  }
220
187
  /**
221
- * Get value from the session. The default value is returned
222
- * when actual value is `undefined`
188
+ * Get the value of a key from the session datastore.
189
+ * You can specify a default value to use, when key
190
+ * does not exists or has undefined value.
223
191
  */
224
192
  get(key, defaultValue) {
225
- this.#ensureIsReady();
226
- return this.#store.get(key, defaultValue);
193
+ return this.#getStore('read').get(key, defaultValue);
227
194
  }
228
195
  /**
229
- * Returns everything from the session
196
+ * Get everything from the session store
230
197
  */
231
198
  all() {
232
- this.#ensureIsReady();
233
- return this.#store.all();
199
+ return this.#getStore('read').all();
234
200
  }
235
201
  /**
236
- * Remove value for a given key from the session
202
+ * Remove a key from the session datastore
237
203
  */
238
204
  forget(key) {
239
- this.#ensureIsReady();
240
- this.#ensureIsMutable();
241
- this.#store.unset(key);
205
+ return this.#getStore('write').unset(key);
242
206
  }
243
207
  /**
244
- * The method is equivalent to calling `session.get` followed
245
- * by `session.forget`
208
+ * Read value for a key from the session datastore
209
+ * and remove it simultaneously.
246
210
  */
247
211
  pull(key, defaultValue) {
248
- this.#ensureIsReady();
249
- this.#ensureIsMutable();
250
- return this.#store.pull(key, defaultValue);
212
+ return this.#getStore('write').pull(key, defaultValue);
251
213
  }
252
214
  /**
253
- * Increment value for a number inside the session store. The
254
- * method raises an error when underlying value is not
255
- * a number
215
+ * Increment the value of a key inside the session
216
+ * store.
217
+ *
218
+ * A new key will be defined if does not exists already.
219
+ * The value of a new key will be 1
256
220
  */
257
221
  increment(key, steps = 1) {
258
- this.#ensureIsReady();
259
- this.#ensureIsMutable();
260
- this.#store.increment(key, steps);
222
+ return this.#getStore('write').increment(key, steps);
261
223
  }
262
224
  /**
263
- * Decrement value for a number inside the session store. The
264
- * method raises an error when underlying value is not
265
- * a number
225
+ * Increment the value of a key inside the session
226
+ * store.
227
+ *
228
+ * A new key will be defined if does not exists already.
229
+ * The value of a new key will be -1
266
230
  */
267
231
  decrement(key, steps = 1) {
268
- this.#ensureIsReady();
269
- this.#ensureIsMutable();
270
- this.#store.decrement(key, steps);
232
+ return this.#getStore('write').decrement(key, steps);
271
233
  }
272
234
  /**
273
- * Remove everything from the session
235
+ * Empty the session store
274
236
  */
275
237
  clear() {
276
- this.#ensureIsReady();
277
- this.#ensureIsMutable();
278
- this.#store.clear();
238
+ return this.#getStore('write').clear();
279
239
  }
280
240
  /**
281
- * Add a new flash message
241
+ * Flash validation error messages. Make sure the error
242
+ * is an instance of VineJS ValidationException
282
243
  */
244
+ flashValidationErrors(error) {
245
+ const errorsBag = error.messages.reduce((result, message) => {
246
+ if (result[message.field]) {
247
+ result[message.field].push(message.message);
248
+ }
249
+ else {
250
+ result[message.field] = [message.message];
251
+ }
252
+ return result;
253
+ }, {});
254
+ this.flashExcept(['_csrf', '_method']);
255
+ this.flash('errors', errorsBag);
256
+ }
283
257
  flash(key, value) {
284
- this.#ensureIsReady();
285
- this.#ensureIsMutable();
286
- /**
287
- * Update value
288
- */
289
258
  if (typeof key === 'string') {
290
259
  if (value) {
291
- this.responseFlashMessages.set(key, value);
260
+ this.#getFlashStore('write').set(key, value);
292
261
  }
293
262
  }
294
263
  else {
295
- this.responseFlashMessages.merge(key);
264
+ this.#getFlashStore('write').merge(key);
296
265
  }
297
266
  }
298
267
  /**
299
- * Flash all form values
268
+ * Flash form input data to the flash messages store
300
269
  */
301
270
  flashAll() {
302
- this.#ensureIsReady();
303
- this.#ensureIsMutable();
304
- this.responseFlashMessages.set('input', this.#ctx.request.original());
271
+ return this.#getFlashStore('write').set('input', this.#ctx.request.original());
305
272
  }
306
273
  /**
307
- * Flash all form values except mentioned keys
274
+ * Flash form input data (except some keys) to the flash messages store
308
275
  */
309
276
  flashExcept(keys) {
310
- this.#ensureIsReady();
311
- this.#ensureIsMutable();
312
- this.responseFlashMessages.set('input', lodash.omit(this.#ctx.request.original(), keys));
277
+ this.#getFlashStore('write').set('input', lodash.omit(this.#ctx.request.original(), keys));
313
278
  }
314
279
  /**
315
- * Flash only defined keys from the form values
280
+ * Flash form input data (only some keys) to the flash messages store
316
281
  */
317
282
  flashOnly(keys) {
318
- this.#ensureIsReady();
319
- this.#ensureIsMutable();
320
- this.responseFlashMessages.set('input', lodash.pick(this.#ctx.request.original(), keys));
283
+ this.#getFlashStore('write').set('input', lodash.pick(this.#ctx.request.original(), keys));
321
284
  }
322
285
  /**
323
- * Reflash existing flash messages
286
+ * Reflash messages from the last request in the current response
324
287
  */
325
288
  reflash() {
326
- this.flash(this.flashMessages.all());
289
+ this.#getFlashStore('write').set('reflashed', this.flashMessages.all());
327
290
  }
328
291
  /**
329
- * Reflash selected keys from the existing flash messages
292
+ * Reflash messages (only some keys) from the last
293
+ * request in the current response
330
294
  */
331
295
  reflashOnly(keys) {
332
- this.flash(lodash.pick(this.flashMessages.all(), keys));
296
+ this.#getFlashStore('write').set('reflashed', lodash.pick(this.flashMessages.all(), keys));
333
297
  }
334
298
  /**
335
- * Omit selected keys from the existing flash messages
336
- * and flash the rest of values
299
+ * Reflash messages (except some keys) from the last
300
+ * request in the current response
337
301
  */
338
302
  reflashExcept(keys) {
339
- this.flash(lodash.omit(this.flashMessages.all(), keys));
303
+ this.#getFlashStore('write').set('reflashed', lodash.omit(this.flashMessages.all(), keys));
304
+ }
305
+ /**
306
+ * Re-generate the session id and migrate data to it.
307
+ */
308
+ regenerate() {
309
+ this.#sessionId = cuid();
340
310
  }
341
311
  /**
342
- * Writes value to the underlying session driver.
312
+ * Commit session changes. No more mutations will be
313
+ * allowed after commit.
343
314
  */
344
315
  async commit() {
345
- if (!this.initiated) {
346
- this.#touchSessionCookie();
347
- await this.#touchDriver();
316
+ if (!this.#store || this.readonly) {
348
317
  return;
349
318
  }
350
319
  /**
351
- * Cleanup old session and re-generate new session
320
+ * If the flash messages store is not empty, we should put
321
+ * its messages inside main session store.
322
+ */
323
+ if (!this.responseFlashMessages.isEmpty) {
324
+ const { input, reflashed, ...others } = this.responseFlashMessages.all();
325
+ this.put(this.flashKey, { ...reflashed, ...input, ...others });
326
+ }
327
+ debug('committing session data');
328
+ /**
329
+ * Touch the session id cookie to stay alive
330
+ */
331
+ this.#ctx.response.cookie(this.#config.cookieName, this.#sessionId, this.#config.cookie);
332
+ /**
333
+ * Delete the session data when the session store
334
+ * is empty.
335
+ *
336
+ * Also we only destroy the session id we read from the cookie.
337
+ * If there was no session id in the cookie, there won't be
338
+ * any data inside the store either.
352
339
  */
353
- if (this.#regeneratedSessionId) {
354
- await this.#driver.destroy(this.#currentSessionId);
340
+ if (this.isEmpty) {
341
+ if (this.#sessionIdFromCookie) {
342
+ await this.#driver.destroy(this.#sessionIdFromCookie);
343
+ }
344
+ this.#emitter.emit('session:committed', { session: this });
345
+ return;
355
346
  }
356
347
  /**
357
- * Touch the session cookie to keep it alive.
348
+ * Touch the store expiry when the session store was
349
+ * not modified.
358
350
  */
359
- this.#touchSessionCookie();
360
- this.#setFlashMessages();
351
+ if (!this.hasBeenModified) {
352
+ if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
353
+ await this.#driver.destroy(this.#sessionIdFromCookie);
354
+ await this.#driver.write(this.#sessionId, this.#store.toJSON());
355
+ this.#emitter.emit('session:migrated', {
356
+ fromSessionId: this.#sessionIdFromCookie,
357
+ toSessionId: this.sessionId,
358
+ session: this,
359
+ });
360
+ }
361
+ else {
362
+ await this.#driver.touch(this.#sessionId);
363
+ }
364
+ this.#emitter.emit('session:committed', { session: this });
365
+ return;
366
+ }
361
367
  /**
362
- * Commit values to the store if not empty.
363
- * Otherwise delete the session store to cleanup
364
- * the storage space.
368
+ * Otherwise commit to the session store
365
369
  */
366
- if (!this.#store.isEmpty) {
367
- await this.#commitValuesToStore();
370
+ if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
371
+ await this.#driver.destroy(this.#sessionIdFromCookie);
372
+ await this.#driver.write(this.#sessionId, this.#store.toJSON());
373
+ this.#emitter.emit('session:migrated', {
374
+ fromSessionId: this.#sessionIdFromCookie,
375
+ toSessionId: this.sessionId,
376
+ session: this,
377
+ });
368
378
  }
369
379
  else {
370
- await this.#driver.destroy(this.sessionId);
380
+ await this.#driver.write(this.#sessionId, this.#store.toJSON());
371
381
  }
382
+ this.#emitter.emit('session:committed', { session: this });
372
383
  }
373
384
  }
@@ -1,5 +1,22 @@
1
- import type { HttpContext } from '@adonisjs/core/http';
1
+ import { EmitterService } from '@adonisjs/core/types';
2
2
  import type { NextFn } from '@adonisjs/core/types/http';
3
+ import { HttpContext } from '@adonisjs/core/http';
4
+ import { Session } from './session.js';
5
+ import type { SessionConfig } from './types/main.js';
6
+ /**
7
+ * HttpContext augmentations
8
+ */
9
+ declare module '@adonisjs/http-server' {
10
+ interface HttpContext {
11
+ session: Session;
12
+ }
13
+ }
14
+ /**
15
+ * Session middleware is used to initiate the session store
16
+ * and commit its values during an HTTP request
17
+ */
3
18
  export default class SessionMiddleware {
4
- handle(ctx: HttpContext, next: NextFn): Promise<void>;
19
+ #private;
20
+ constructor(config: SessionConfig, emitter: EmitterService);
21
+ handle(ctx: HttpContext, next: NextFn): Promise<any>;
5
22
  }