@adonisjs/session 8.0.0-next.4 → 8.0.0-next.6

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.
@@ -88,7 +88,7 @@ function defineConfig(config) {
88
88
  const stores = {
89
89
  file: (config) => {
90
90
  return configProvider.create(async () => {
91
- const { FileStore } = await import("./file-BBU02j4z.js");
91
+ const { FileStore } = await import("./file-DwH574p2.js");
92
92
  return (_, sessionConfig) => {
93
93
  return new FileStore(config, sessionConfig.age);
94
94
  };
@@ -96,7 +96,7 @@ const stores = {
96
96
  },
97
97
  redis: (config) => {
98
98
  return configProvider.create(async (app) => {
99
- const { RedisStore } = await import("./redis-rAHxNQ_8.js");
99
+ const { RedisStore } = await import("./redis-BQfYPsiI.js");
100
100
  const redis = await app.container.make("redis");
101
101
  return (_, sessionConfig) => {
102
102
  return new RedisStore(redis.connection(config.connection), sessionConfig.age);
@@ -105,7 +105,7 @@ const stores = {
105
105
  },
106
106
  cookie: () => {
107
107
  return configProvider.create(async () => {
108
- const { CookieStore } = await import("./cookie--JOJxrtW.js");
108
+ const { CookieStore } = await import("./cookie-DLgizSjS.js");
109
109
  return (ctx, sessionConfig) => {
110
110
  return new CookieStore(sessionConfig.cookie, ctx);
111
111
  };
@@ -113,7 +113,7 @@ const stores = {
113
113
  },
114
114
  dynamodb: (config) => {
115
115
  return configProvider.create(async () => {
116
- const { DynamoDBStore } = await import("./dynamodb-BFVgTQSf.js");
116
+ const { DynamoDBStore } = await import("./dynamodb-DaEv8Jfq.js");
117
117
  const { DynamoDBClient } = await import("@aws-sdk/client-dynamodb");
118
118
  const client = "clientConfig" in config ? new DynamoDBClient(config.clientConfig) : config.client;
119
119
  return (_, sessionConfig) => {
@@ -126,7 +126,7 @@ const stores = {
126
126
  },
127
127
  database: (config) => {
128
128
  return configProvider.create(async (app) => {
129
- const { DatabaseStore } = await import("./database-JbWAJqhn.js");
129
+ const { DatabaseStore } = await import("./database-CAwFE3R1.js");
130
130
  const db = await app.container.make("lucid.db");
131
131
  const connectionName = config?.connectionName || db.primaryConnectionName;
132
132
  if (!db.manager.has(connectionName)) throw new RuntimeException(`Invalid database connection "${connectionName}" referenced in session config`);
@@ -1,10 +1,11 @@
1
- import "../session-Dd5u7w5Y.js";
1
+ import "../session-DI1JHv1F.js";
2
2
  import "../main-kn40V-hF.js";
3
- import { t as defineConfig } from "../session-C9ZmQmpM.js";
3
+ import { t as defineConfig } from "../define_config-BPZ6wVlF.js";
4
4
  import "../debug-BZVg83L1.js";
5
5
  import "../values_store-CvR1Sn37.js";
6
- import "../session_collection-D9JQJjpq.js";
7
- import { t as SessionMiddleware } from "../session_middleware-BoOMxNVH.js";
6
+ import "../session_collection-SLmMBYfP.js";
7
+ import "../index.js";
8
+ import SessionMiddleware from "../src/session_middleware.js";
8
9
  import { Emitter } from "@adonisjs/core/events";
9
10
  import { AppFactory } from "@adonisjs/core/factories/app";
10
11
  var SessionMiddlewareFactory = class {
package/build/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { r as errors_exports, t as Session } from "./session-Dd5u7w5Y.js";
1
+ import { r as errors_exports, t as Session } from "./session-DI1JHv1F.js";
2
2
  import { t as stubsRoot } from "./main-kn40V-hF.js";
3
- import { n as stores, r as configure, t as defineConfig } from "./session-C9ZmQmpM.js";
3
+ import { n as stores, r as configure, t as defineConfig } from "./define_config-BPZ6wVlF.js";
4
4
  import "./debug-BZVg83L1.js";
5
5
  import { n as ValuesStore, t as ReadOnlyValuesStore } from "./values_store-CvR1Sn37.js";
6
- import { t as SessionCollection } from "./session_collection-D9JQJjpq.js";
6
+ import { t as SessionCollection } from "./session_collection-SLmMBYfP.js";
7
7
  export { ReadOnlyValuesStore, Session, SessionCollection, ValuesStore, configure, defineConfig, errors_exports as errors, stores, stubsRoot };
@@ -1,8 +1,8 @@
1
- import "../session-Dd5u7w5Y.js";
1
+ import "../session-DI1JHv1F.js";
2
2
  import "../debug-BZVg83L1.js";
3
3
  import "../values_store-CvR1Sn37.js";
4
- import { t as SessionCollection } from "../session_collection-D9JQJjpq.js";
5
- import { t as SessionMiddleware } from "../session_middleware-BoOMxNVH.js";
4
+ import { t as SessionCollection } from "../session_collection-SLmMBYfP.js";
5
+ import SessionMiddleware from "../src/session_middleware.js";
6
6
  import { RuntimeException } from "@adonisjs/core/exceptions";
7
7
  import { configProvider } from "@adonisjs/core";
8
8
  var SessionProvider = class {
@@ -7,13 +7,13 @@ import Macroable from "@poppinss/macroable";
7
7
  import lodash from "@poppinss/utils/lodash";
8
8
  import is from "@adonisjs/core/helpers/is";
9
9
  var __defProp = Object.defineProperty;
10
- var __exportAll = (all, symbols) => {
10
+ var __exportAll = (all, no_symbols) => {
11
11
  let target = {};
12
12
  for (var name in all) __defProp(target, name, {
13
13
  get: all[name],
14
14
  enumerable: true
15
15
  });
16
- if (symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
17
  return target;
18
18
  };
19
19
  var errors_exports = /* @__PURE__ */ __exportAll({
@@ -184,10 +184,17 @@ var Session = class extends Macroable {
184
184
  reflashExcept(keys) {
185
185
  this.#getFlashStore("write").set("reflashed", lodash.omit(this.flashMessages.all(), keys));
186
186
  }
187
+ supportsTagging() {
188
+ return "tag" in this.#store && "tagged" in this.#store;
189
+ }
187
190
  async tag(userId) {
188
191
  if (!("tag" in this.#store)) throw new E_SESSION_TAGGING_NOT_SUPPORTED();
189
192
  await this.#store.tag(this.#sessionId, userId);
190
193
  }
194
+ async untag(userId) {
195
+ if (!("tag" in this.#store)) throw new E_SESSION_TAGGING_NOT_SUPPORTED();
196
+ await this.#store.untag(this.#sessionId, userId);
197
+ }
191
198
  regenerate() {
192
199
  this.#sessionId = randomUUID();
193
200
  }
@@ -1,4 +1,4 @@
1
- import { n as E_SESSION_TAGGING_NOT_SUPPORTED } from "./session-Dd5u7w5Y.js";
1
+ import { n as E_SESSION_TAGGING_NOT_SUPPORTED } from "./session-DI1JHv1F.js";
2
2
  import { t as debug_default } from "./debug-BZVg83L1.js";
3
3
  var SessionCollection = class {
4
4
  #store;
@@ -1,2 +1,13 @@
1
+ /**
2
+ * Debug logger instance for AdonisJS session module.
3
+ * Logs debug information when NODE_DEBUG environment variable includes 'adonisjs:session'.
4
+ *
5
+ * @example
6
+ * // Enable debug logging by setting NODE_DEBUG environment variable
7
+ * // NODE_DEBUG=adonisjs:session node app.js
8
+ *
9
+ * debug('session initiated')
10
+ * debug('writing session data: %O', sessionData)
11
+ */
1
12
  declare const _default: import("node:util").DebugLogger;
2
13
  export default _default;
@@ -73,7 +73,19 @@ export declare class Session extends Macroable {
73
73
  * @param ctx - HTTP context
74
74
  */
75
75
  constructor(config: SessionConfig, storeFactory: SessionStoreFactory, emitter: EmitterService, ctx: HttpContext);
76
+ /**
77
+ * Determines whether a value should be stored in flash messages.
78
+ * Objects can opt out by setting a STORE_IN_FLASH symbol property to false.
79
+ *
80
+ * @param value - Value to check for flash storage eligibility
81
+ */
76
82
  protected shouldFlashValue(value: unknown): unknown;
83
+ /**
84
+ * Filters flash data to only include values that should be flashed.
85
+ * Removes values that have opted out of flash storage.
86
+ *
87
+ * @param data - Flash data to filter
88
+ */
77
89
  protected cleanupFlashData<T>(data: T): T | Record<string, any>;
78
90
  /**
79
91
  * Initiates the session store. The method results in a noop when called multiple times.
@@ -268,6 +280,16 @@ export declare class Session extends Macroable {
268
280
  * session.reflashExcept(['error', 'warning'])
269
281
  */
270
282
  reflashExcept(keys: string[]): void;
283
+ /**
284
+ * Checks if the current store supports session tagging.
285
+ * Only Memory, Redis, and Database stores support tagging.
286
+ *
287
+ * @example
288
+ * if (session.supportsTagging()) {
289
+ * await session.tag(String(user.id))
290
+ * }
291
+ */
292
+ supportsTagging(): boolean;
271
293
  /**
272
294
  * Tag the current session with a user ID.
273
295
  * Only supported by Memory, Redis, and Database stores.
@@ -280,6 +302,17 @@ export declare class Session extends Macroable {
280
302
  * await session.tag(String(user.id))
281
303
  */
282
304
  tag(userId: string): Promise<void>;
305
+ /**
306
+ * Removes the tag association between this session and a user ID.
307
+ * Only supported by Memory, Redis, and Database stores.
308
+ *
309
+ * @param userId - The user ID to untag this session from
310
+ *
311
+ * @example
312
+ * // During logout, untag the session
313
+ * await session.untag(String(user.id))
314
+ */
315
+ untag(userId: string): Promise<void>;
283
316
  /**
284
317
  * Re-generates the session id and migrates data to it
285
318
  *
@@ -6,7 +6,7 @@
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 type { ResolvedSessionConfig, SessionData, TaggedSession } from './types.ts';
9
+ import type { SessionData, TaggedSession, ResolvedSessionConfig } from './types.ts';
10
10
  /**
11
11
  * SessionCollection provides APIs for programmatic session
12
12
  * management. It allows reading, destroying, and tagging
@@ -35,7 +35,14 @@ export declare class SessionCollection {
35
35
  */
36
36
  constructor(config: ResolvedSessionConfig);
37
37
  /**
38
- * Check if the current store supports tagging
38
+ * Checks if the current store supports session tagging.
39
+ * Only Memory, Redis, and Database stores support tagging.
40
+ *
41
+ * @example
42
+ * const collection = await app.container.make(SessionCollection)
43
+ * if (collection.supportsTagging()) {
44
+ * await collection.tag(sessionId, userId)
45
+ * }
39
46
  */
40
47
  supportsTagging(): boolean;
41
48
  /**
@@ -1,5 +1,29 @@
1
- import "../session-Dd5u7w5Y.js";
1
+ import { t as Session } from "../session-DI1JHv1F.js";
2
2
  import "../debug-BZVg83L1.js";
3
3
  import "../values_store-CvR1Sn37.js";
4
- import { t as SessionMiddleware } from "../session_middleware-BoOMxNVH.js";
4
+ import { ExceptionHandler } from "@adonisjs/core/http";
5
+ const originalErrorHandler = ExceptionHandler.prototype.renderValidationErrorAsHTML;
6
+ ExceptionHandler.macro("renderValidationErrorAsHTML", async function(error, ctx) {
7
+ if (ctx.session) {
8
+ const withInput = ctx.request.header("X-Inertia") ? false : true;
9
+ ctx.session.flashValidationErrors(error, withInput);
10
+ ctx.response.redirect("back", true);
11
+ } else return originalErrorHandler(error, ctx);
12
+ });
13
+ var SessionMiddleware = class {
14
+ #config;
15
+ #emitter;
16
+ constructor(config, emitter) {
17
+ this.#config = config;
18
+ this.#emitter = emitter;
19
+ }
20
+ async handle(ctx, next) {
21
+ if (!this.#config.enabled) return next();
22
+ ctx.session = new Session(this.#config, this.#config.stores[this.#config.store], this.#emitter, ctx);
23
+ await ctx.session.initiate(false);
24
+ const response = await next();
25
+ await ctx.session.commit();
26
+ return response;
27
+ }
28
+ };
5
29
  export { SessionMiddleware as default };
@@ -9,10 +9,27 @@
9
9
  import type { QueryClientContract } from '@adonisjs/lucid/types/database';
10
10
  import type { SessionStoreWithTaggingContract, SessionData, TaggedSession } from '../types.ts';
11
11
  /**
12
- * Database store to read/write session to SQL databases using Lucid
12
+ * Database store to read/write session data to SQL databases using Lucid.
13
+ * Supports PostgreSQL, MySQL, SQLite, and other Lucid-compatible databases.
14
+ * Includes automatic garbage collection of expired sessions.
15
+ *
16
+ * @example
17
+ * const dbStore = new DatabaseStore(db.connection(), '2 hours', {
18
+ * tableName: 'sessions',
19
+ * gcProbability: 2
20
+ * })
13
21
  */
14
22
  export declare class DatabaseStore implements SessionStoreWithTaggingContract {
15
23
  #private;
24
+ /**
25
+ * Creates a new database store instance
26
+ *
27
+ * @param client - Lucid query client instance
28
+ * @param age - Session age in seconds or time expression (e.g. '2 hours')
29
+ * @param options - Configuration options
30
+ * @param options.tableName - Database table name (defaults to "sessions")
31
+ * @param options.gcProbability - Garbage collection probability in percent (defaults to 2)
32
+ */
16
33
  constructor(client: QueryClientContract, age: string | number, options?: {
17
34
  /**
18
35
  * Defaults to "sessions"
@@ -29,43 +46,73 @@ export declare class DatabaseStore implements SessionStoreWithTaggingContract {
29
46
  gcProbability?: number;
30
47
  });
31
48
  /**
32
- * Returns session data
49
+ * Reads session data from the database
33
50
  *
34
51
  * @param sessionId - Session identifier
52
+ *
53
+ * @example
54
+ * const data = await store.read('sess_abc123')
35
55
  */
36
56
  read(sessionId: string): Promise<SessionData | null>;
37
57
  /**
38
- * Write session values to the database
58
+ * Writes session values to the database with expiry.
59
+ * Uses UPSERT to handle both new and existing sessions.
39
60
  *
40
61
  * @param sessionId - Session identifier
41
62
  * @param values - Session data to store
63
+ *
64
+ * @example
65
+ * await store.write('sess_abc123', { userId: 123 })
42
66
  */
43
67
  write(sessionId: string, values: Object): Promise<void>;
44
68
  /**
45
- * Cleanup session by removing it
69
+ * Removes session data from the database
46
70
  *
47
- * @param sessionId - Session identifier
71
+ * @param sessionId - Session identifier to remove
72
+ *
73
+ * @example
74
+ * await store.destroy('sess_abc123')
48
75
  */
49
76
  destroy(sessionId: string): Promise<void>;
50
77
  /**
51
- * Updates the session expiry
78
+ * Updates the session expiry time in the database
52
79
  *
53
80
  * @param sessionId - Session identifier
81
+ *
82
+ * @example
83
+ * await store.touch('sess_abc123')
54
84
  */
55
85
  touch(sessionId: string): Promise<void>;
56
86
  /**
57
- * Tag a session with a user ID.
87
+ * Tags a session with a user ID for tracking user sessions.
58
88
  * Uses UPSERT to handle both existing and new sessions.
59
89
  *
60
90
  * @param sessionId - Session identifier
61
91
  * @param userId - User identifier to tag the session with
92
+ *
93
+ * @example
94
+ * await store.tag('sess_abc123', 'user_456')
62
95
  */
63
96
  tag(sessionId: string, userId: string | number): Promise<void>;
97
+ /**
98
+ * Removes the tag association between a session and a user ID.
99
+ * Sets the user_id column to null for the given session.
100
+ *
101
+ * @param sessionId - Session identifier
102
+ * @param userId - User identifier (for logging purposes)
103
+ *
104
+ * @example
105
+ * await store.untag('sess_abc123', 'user_456')
106
+ */
64
107
  untag(sessionId: string, userId: string | number): Promise<void>;
65
108
  /**
66
- * Get all sessions for a given user ID (tag)
109
+ * Returns all active sessions for a given user ID (tag).
110
+ * Only returns non-expired sessions.
67
111
  *
68
112
  * @param userId - User identifier to get sessions for
113
+ *
114
+ * @example
115
+ * const sessions = await store.tagged('user_456')
69
116
  */
70
117
  tagged(userId: string): Promise<TaggedSession[]>;
71
118
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonisjs/session",
3
3
  "description": "Session provider for AdonisJS",
4
- "version": "8.0.0-next.4",
4
+ "version": "8.0.0-next.6",
5
5
  "engines": {
6
6
  "node": ">=24.0.0"
7
7
  },
@@ -44,16 +44,16 @@
44
44
  "quick:test": "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts"
45
45
  },
46
46
  "devDependencies": {
47
- "@adonisjs/assembler": "^8.0.0-next.31",
48
- "@adonisjs/core": "^7.0.0-next.27",
47
+ "@adonisjs/assembler": "^8.0.0-next.33",
48
+ "@adonisjs/core": "^7.0.0-next.29",
49
49
  "@adonisjs/eslint-config": "^3.0.0-next.9",
50
50
  "@adonisjs/i18n": "^3.0.0-next.2",
51
- "@adonisjs/lucid": "^22.0.0-next.7",
51
+ "@adonisjs/lucid": "^22.0.0-next.9",
52
52
  "@adonisjs/prettier-config": "^1.4.5",
53
53
  "@adonisjs/redis": "^10.0.0-next.2",
54
54
  "@adonisjs/tsconfig": "^2.0.0-next.3",
55
- "@aws-sdk/client-dynamodb": "^3.980.0",
56
- "@aws-sdk/util-dynamodb": "^3.980.0",
55
+ "@aws-sdk/client-dynamodb": "^3.992.0",
56
+ "@aws-sdk/util-dynamodb": "^3.992.0",
57
57
  "@japa/api-client": "^3.2.1",
58
58
  "@japa/assert": "^4.2.0",
59
59
  "@japa/browser-client": "^2.3.0",
@@ -61,12 +61,12 @@
61
61
  "@japa/plugin-adonisjs": "^5.1.0-next.1",
62
62
  "@japa/runner": "^5.3.0",
63
63
  "@japa/snapshot": "^2.0.10",
64
- "@poppinss/ts-exec": "^1.4.3",
65
- "@release-it/conventional-changelog": "^10.0.4",
66
- "@types/node": "^25.1.0",
64
+ "@poppinss/ts-exec": "^1.4.4",
65
+ "@release-it/conventional-changelog": "^10.0.5",
66
+ "@types/node": "^25.2.3",
67
67
  "@types/set-cookie-parser": "^2.4.10",
68
68
  "@types/supertest": "^6.0.3",
69
- "@vinejs/vine": "^4.2.0",
69
+ "@vinejs/vine": "^4.3.0",
70
70
  "better-sqlite3": "^12.6.2",
71
71
  "c8": "^10.1.3",
72
72
  "copyfiles": "^2.4.1",
@@ -74,20 +74,20 @@
74
74
  "edge.js": "^6.4.0",
75
75
  "eslint": "^9.39.2",
76
76
  "get-port": "^7.1.0",
77
- "mysql2": "^3.16.2",
77
+ "mysql2": "^3.17.2",
78
78
  "pg": "^8.18.0",
79
- "playwright": "^1.58.1",
79
+ "playwright": "^1.58.2",
80
80
  "prettier": "^3.8.1",
81
81
  "release-it": "^19.2.4",
82
82
  "set-cookie-parser": "^3.0.1",
83
83
  "supertest": "^7.2.2",
84
- "tsdown": "^0.20.1",
85
- "typedoc": "^0.28.16",
84
+ "tsdown": "^0.20.3",
85
+ "typedoc": "^0.28.17",
86
86
  "typescript": "^5.9.3"
87
87
  },
88
88
  "dependencies": {
89
89
  "@poppinss/macroable": "^1.1.0",
90
- "@poppinss/utils": "^7.0.0-next.6"
90
+ "@poppinss/utils": "^7.0.0-next.7"
91
91
  },
92
92
  "peerDependencies": {
93
93
  "@adonisjs/assembler": "^8.0.0-next.26",
@@ -1,27 +0,0 @@
1
- import { t as Session } from "./session-Dd5u7w5Y.js";
2
- import { ExceptionHandler } from "@adonisjs/core/http";
3
- const originalErrorHandler = ExceptionHandler.prototype.renderValidationErrorAsHTML;
4
- ExceptionHandler.macro("renderValidationErrorAsHTML", async function(error, ctx) {
5
- if (ctx.session) {
6
- const withInput = ctx.request.header("X-Inertia") ? false : true;
7
- ctx.session.flashValidationErrors(error, withInput);
8
- ctx.response.redirect("back", true);
9
- } else return originalErrorHandler(error, ctx);
10
- });
11
- var SessionMiddleware = class {
12
- #config;
13
- #emitter;
14
- constructor(config, emitter) {
15
- this.#config = config;
16
- this.#emitter = emitter;
17
- }
18
- async handle(ctx, next) {
19
- if (!this.#config.enabled) return next();
20
- ctx.session = new Session(this.#config, this.#config.stores[this.#config.store], this.#emitter, ctx);
21
- await ctx.session.initiate(false);
22
- const response = await next();
23
- await ctx.session.commit();
24
- return response;
25
- }
26
- };
27
- export { SessionMiddleware as t };
File without changes
File without changes