@adonisjs/session 8.0.0-next.0 → 8.0.0-next.2

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 (50) hide show
  1. package/build/commands/commands.json +1 -0
  2. package/build/commands/main.d.ts +4 -0
  3. package/build/commands/main.js +36 -0
  4. package/build/commands/make_session_table.d.ts +9 -0
  5. package/build/commands/make_session_table.js +13 -0
  6. package/build/cookie--JOJxrtW.js +31 -0
  7. package/build/database-vbrhCOPd.js +86 -0
  8. package/build/debug-BZVg83L1.js +3 -0
  9. package/build/dynamodb-BFVgTQSf.js +72 -0
  10. package/build/factories/main.js +27 -45
  11. package/build/file-BBU02j4z.js +71 -0
  12. package/build/index.d.ts +1 -0
  13. package/build/index.js +7 -25
  14. package/build/main-kn40V-hF.js +2 -0
  15. package/build/make/migration/sessions.stub +26 -0
  16. package/build/providers/session_provider.d.ts +2 -1
  17. package/build/providers/session_provider.js +34 -48
  18. package/build/redis-D8D9UtiD.js +91 -0
  19. package/build/session-C9DdRahS.js +215 -0
  20. package/build/session-Cb9-DoMh.js +139 -0
  21. package/build/session_collection-CvS5yIq6.js +31 -0
  22. package/build/session_middleware-gegOBxmm.js +27 -0
  23. package/build/src/client.js +38 -7
  24. package/build/src/debug.d.ts +1 -1
  25. package/build/src/define_config.d.ts +14 -6
  26. package/build/src/errors.d.ts +9 -0
  27. package/build/src/plugins/edge.d.ts +5 -1
  28. package/build/src/plugins/edge.js +74 -124
  29. package/build/src/plugins/japa/api_client.js +76 -96
  30. package/build/src/plugins/japa/browser_client.js +58 -81
  31. package/build/src/session.d.ts +12 -0
  32. package/build/src/session_collection.d.ts +81 -0
  33. package/build/src/session_middleware.js +5 -9
  34. package/build/src/stores/database.d.ts +70 -0
  35. package/build/src/stores/memory.d.ts +19 -2
  36. package/build/src/stores/redis.d.ts +15 -2
  37. package/build/src/types.d.ts +62 -8
  38. package/build/src/types.js +1 -0
  39. package/build/values_store-CvR1Sn37.js +78 -0
  40. package/package.json +65 -42
  41. package/build/chunk-DFXWYDMY.js +0 -62
  42. package/build/chunk-HAD4PFFM.js +0 -229
  43. package/build/chunk-MVBWJOEG.js +0 -187
  44. package/build/chunk-SBOMJK4T.js +0 -14
  45. package/build/chunk-SHD6OX52.js +0 -488
  46. package/build/chunk-Y566BNUT.js +0 -113
  47. package/build/cookie-YBBGLCO5.js +0 -88
  48. package/build/dynamodb-PLZABBFD.js +0 -153
  49. package/build/file-CCJ5ESE2.js +0 -151
  50. package/build/redis-NXJWWWVB.js +0 -89
@@ -0,0 +1,91 @@
1
+ import { t as debug_default } from "./debug-BZVg83L1.js";
2
+ import string from "@adonisjs/core/helpers/string";
3
+ import { MessageBuilder } from "@adonisjs/core/helpers";
4
+ var RedisStore = class {
5
+ #connection;
6
+ #ttlSeconds;
7
+ constructor(connection, age) {
8
+ this.#connection = connection;
9
+ this.#ttlSeconds = string.seconds.parse(age);
10
+ debug_default("initiating redis store");
11
+ }
12
+ #processSessionResult(options) {
13
+ if (!options.contents) return {
14
+ session: null,
15
+ isInvalid: true
16
+ };
17
+ const data = this.#parseSessionData(options.contents, options.sessionId);
18
+ if (!data) return {
19
+ session: null,
20
+ isInvalid: true
21
+ };
22
+ return {
23
+ session: {
24
+ id: options.sessionId,
25
+ data
26
+ },
27
+ isInvalid: false
28
+ };
29
+ }
30
+ async #fetchSessionContents(sessionIds) {
31
+ const pipeline = this.#connection.pipeline();
32
+ sessionIds.forEach((sessionId) => pipeline.get(sessionId));
33
+ return (await pipeline.exec())?.map((result) => result[1]) ?? [];
34
+ }
35
+ async #cleanupInvalidSessions(userId, invalidSessionIds) {
36
+ if (invalidSessionIds.length === 0) return;
37
+ await this.#connection.srem(this.#getTagKey(userId), ...invalidSessionIds);
38
+ }
39
+ #getTagKey(userId) {
40
+ return `session_tag:${userId}`;
41
+ }
42
+ #parseSessionData(contents, sessionId) {
43
+ try {
44
+ return new MessageBuilder().verify(contents, sessionId);
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+ async read(sessionId) {
50
+ debug_default("redis store: reading session data %s", sessionId);
51
+ const contents = await this.#connection.get(sessionId);
52
+ if (!contents) return null;
53
+ try {
54
+ return new MessageBuilder().verify(contents, sessionId);
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+ async write(sessionId, values) {
60
+ debug_default("redis store: writing session data %s, %O", sessionId, values);
61
+ const message = new MessageBuilder().build(values, void 0, sessionId);
62
+ await this.#connection.setex(sessionId, this.#ttlSeconds, message);
63
+ }
64
+ async destroy(sessionId) {
65
+ debug_default("redis store: destroying session data %s", sessionId);
66
+ await this.#connection.del(sessionId);
67
+ }
68
+ async touch(sessionId) {
69
+ debug_default("redis store: touching session data %s", sessionId);
70
+ await this.#connection.expire(sessionId, this.#ttlSeconds);
71
+ }
72
+ async tag(sessionId, userId) {
73
+ debug_default("redis store: tagging session %s with user %s", sessionId, userId);
74
+ await this.#connection.sadd(this.#getTagKey(userId), sessionId);
75
+ }
76
+ async tagged(userId) {
77
+ debug_default("redis store: getting sessions tagged with user %s", userId);
78
+ const sessionIds = await this.#connection.smembers(this.#getTagKey(userId));
79
+ if (sessionIds.length === 0) return [];
80
+ const contents = await this.#fetchSessionContents(sessionIds);
81
+ const results = sessionIds.map((sessionId, index) => this.#processSessionResult({
82
+ sessionId,
83
+ contents: contents[index]
84
+ }));
85
+ const validSessions = results.filter((r) => r.session !== null).map((r) => r.session);
86
+ const invalidSessionIds = results.map((result, index) => result.isInvalid ? sessionIds[index] : null).filter((id) => id !== null);
87
+ await this.#cleanupInvalidSessions(userId, invalidSessionIds);
88
+ return validSessions;
89
+ }
90
+ };
91
+ export { RedisStore };
@@ -0,0 +1,215 @@
1
+ import { t as debug_default } from "./debug-BZVg83L1.js";
2
+ import { n as ValuesStore, t as ReadOnlyValuesStore } from "./values_store-CvR1Sn37.js";
3
+ import "node:module";
4
+ import { createError } from "@adonisjs/core/exceptions";
5
+ import { randomUUID } from "node:crypto";
6
+ import Macroable from "@poppinss/macroable";
7
+ import lodash from "@poppinss/utils/lodash";
8
+ var __defProp = Object.defineProperty;
9
+ var __export = (all, symbols) => {
10
+ let target = {};
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ if (symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return target;
17
+ };
18
+ var errors_exports = /* @__PURE__ */ __export({
19
+ E_SESSION_NOT_MUTABLE: () => E_SESSION_NOT_MUTABLE,
20
+ E_SESSION_NOT_READY: () => E_SESSION_NOT_READY,
21
+ E_SESSION_TAGGING_NOT_SUPPORTED: () => E_SESSION_TAGGING_NOT_SUPPORTED
22
+ });
23
+ const E_SESSION_NOT_MUTABLE = createError("Session store is in readonly mode and cannot be mutated", "E_SESSION_NOT_MUTABLE", 500);
24
+ const E_SESSION_NOT_READY = createError("Session store has not been initiated. Make sure you have registered the session middleware", "E_SESSION_NOT_READY", 500);
25
+ const E_SESSION_TAGGING_NOT_SUPPORTED = createError("Session store does not support tagging. Use memory, redis, or database store instead", "E_SESSION_TAGGING_NOT_SUPPORTED", 500);
26
+ var Session = class extends Macroable {
27
+ #store;
28
+ #emitter;
29
+ #ctx;
30
+ #readonly = false;
31
+ #valuesStore;
32
+ #sessionId;
33
+ #sessionIdFromCookie;
34
+ responseFlashMessages = new ValuesStore({});
35
+ flashMessages = new ValuesStore({});
36
+ flashKey = "__flash__";
37
+ get sessionId() {
38
+ return this.#sessionId;
39
+ }
40
+ get fresh() {
41
+ return this.#sessionIdFromCookie === void 0;
42
+ }
43
+ get readonly() {
44
+ return this.#readonly;
45
+ }
46
+ get initiated() {
47
+ return !!this.#valuesStore;
48
+ }
49
+ get hasRegeneratedSession() {
50
+ return !!(this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId);
51
+ }
52
+ get isEmpty() {
53
+ return this.#valuesStore?.isEmpty ?? true;
54
+ }
55
+ get hasBeenModified() {
56
+ return this.#valuesStore?.hasBeenModified ?? false;
57
+ }
58
+ constructor(config, storeFactory, emitter, ctx) {
59
+ super();
60
+ this.config = config;
61
+ this.#ctx = ctx;
62
+ this.#emitter = emitter;
63
+ this.#store = storeFactory(ctx, config);
64
+ this.#sessionIdFromCookie = ctx.request.cookie(config.cookieName, void 0);
65
+ this.#sessionId = this.#sessionIdFromCookie || randomUUID();
66
+ }
67
+ #getFlashStore(mode) {
68
+ if (!this.#valuesStore) throw new E_SESSION_NOT_READY();
69
+ if (mode === "write" && this.readonly) throw new E_SESSION_NOT_MUTABLE();
70
+ return this.responseFlashMessages;
71
+ }
72
+ #getValuesStore(mode) {
73
+ if (!this.#valuesStore) throw new E_SESSION_NOT_READY();
74
+ if (mode === "write" && this.readonly) throw new E_SESSION_NOT_MUTABLE();
75
+ return this.#valuesStore;
76
+ }
77
+ async initiate(readonly) {
78
+ if (this.#valuesStore) return;
79
+ debug_default("initiating session (readonly: %s)", readonly);
80
+ this.#readonly = readonly;
81
+ this.#valuesStore = new ValuesStore(await this.#store.read(this.#sessionId));
82
+ if (this.has(this.flashKey)) {
83
+ debug_default("reading flash data");
84
+ if (this.#readonly) this.flashMessages.update(this.get(this.flashKey, null));
85
+ else this.flashMessages.update(this.pull(this.flashKey, null));
86
+ }
87
+ if ("view" in this.#ctx) this.#ctx.view.share({
88
+ session: new ReadOnlyValuesStore(this.#valuesStore.all()),
89
+ flashMessages: new ReadOnlyValuesStore(this.flashMessages.all()),
90
+ old: function(key, defaultValue) {
91
+ return this.flashMessages.get(key, defaultValue);
92
+ }
93
+ });
94
+ this.#emitter.emit("session:initiated", { session: this });
95
+ }
96
+ put(key, value) {
97
+ this.#getValuesStore("write").set(key, value);
98
+ }
99
+ has(key) {
100
+ return this.#getValuesStore("read").has(key);
101
+ }
102
+ get(key, defaultValue) {
103
+ return this.#getValuesStore("read").get(key, defaultValue);
104
+ }
105
+ all() {
106
+ return this.#getValuesStore("read").all();
107
+ }
108
+ forget(key) {
109
+ return this.#getValuesStore("write").unset(key);
110
+ }
111
+ pull(key, defaultValue) {
112
+ return this.#getValuesStore("write").pull(key, defaultValue);
113
+ }
114
+ increment(key, steps = 1) {
115
+ return this.#getValuesStore("write").increment(key, steps);
116
+ }
117
+ decrement(key, steps = 1) {
118
+ return this.#getValuesStore("write").decrement(key, steps);
119
+ }
120
+ clear() {
121
+ return this.#getValuesStore("write").clear();
122
+ }
123
+ flash(key, value) {
124
+ if (typeof key === "string") {
125
+ if (value) this.#getFlashStore("write").set(key, value);
126
+ } else this.#getFlashStore("write").merge(key);
127
+ }
128
+ flashErrors(errorsCollection) {
129
+ this.flash({ errorsBag: errorsCollection });
130
+ }
131
+ flashValidationErrors(error, withInput = true) {
132
+ const errorsBag = error.messages.reduce((result, message) => {
133
+ if (result[message.field]) result[message.field].push(message.message);
134
+ else result[message.field] = [message.message];
135
+ return result;
136
+ }, {});
137
+ if (withInput) this.flashExcept([
138
+ "_csrf",
139
+ "_method",
140
+ "password",
141
+ "password_confirmation"
142
+ ]);
143
+ let summary = "The form could not be saved. Please check the errors below.";
144
+ if ("i18n" in this.#ctx) summary = this.#ctx.i18n.t(`errors.${error.code}`, { count: error.messages.length }, summary);
145
+ this.flashErrors({ [String(error.code)]: summary });
146
+ this.flash("inputErrorsBag", errorsBag);
147
+ }
148
+ flashAll() {
149
+ return this.#getFlashStore("write").set("input", this.#ctx.request.original());
150
+ }
151
+ flashExcept(keys) {
152
+ this.#getFlashStore("write").set("input", lodash.omit(this.#ctx.request.original(), keys));
153
+ }
154
+ flashOnly(keys) {
155
+ this.#getFlashStore("write").set("input", lodash.pick(this.#ctx.request.original(), keys));
156
+ }
157
+ reflash() {
158
+ this.#getFlashStore("write").set("reflashed", this.flashMessages.all());
159
+ }
160
+ reflashOnly(keys) {
161
+ this.#getFlashStore("write").set("reflashed", lodash.pick(this.flashMessages.all(), keys));
162
+ }
163
+ reflashExcept(keys) {
164
+ this.#getFlashStore("write").set("reflashed", lodash.omit(this.flashMessages.all(), keys));
165
+ }
166
+ async tag(userId) {
167
+ if (!("tag" in this.#store)) throw new E_SESSION_TAGGING_NOT_SUPPORTED();
168
+ await this.#store.tag(this.#sessionId, userId);
169
+ }
170
+ regenerate() {
171
+ this.#sessionId = randomUUID();
172
+ }
173
+ async commit() {
174
+ if (!this.#valuesStore || this.readonly) return;
175
+ if (!this.responseFlashMessages.isEmpty) {
176
+ const { input, reflashed, ...others } = this.responseFlashMessages.all();
177
+ this.put(this.flashKey, {
178
+ ...reflashed,
179
+ ...input,
180
+ ...others
181
+ });
182
+ }
183
+ debug_default("committing session data");
184
+ this.#ctx.response.cookie(this.config.cookieName, this.#sessionId, this.config.cookie);
185
+ if (this.isEmpty) {
186
+ if (this.#sessionIdFromCookie) await this.#store.destroy(this.#sessionIdFromCookie);
187
+ this.#emitter.emit("session:committed", { session: this });
188
+ return;
189
+ }
190
+ if (!this.hasBeenModified) {
191
+ if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
192
+ await this.#store.destroy(this.#sessionIdFromCookie);
193
+ await this.#store.write(this.#sessionId, this.#valuesStore.toJSON());
194
+ this.#emitter.emit("session:migrated", {
195
+ fromSessionId: this.#sessionIdFromCookie,
196
+ toSessionId: this.sessionId,
197
+ session: this
198
+ });
199
+ } else await this.#store.touch(this.#sessionId);
200
+ this.#emitter.emit("session:committed", { session: this });
201
+ return;
202
+ }
203
+ if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
204
+ await this.#store.destroy(this.#sessionIdFromCookie);
205
+ await this.#store.write(this.#sessionId, this.#valuesStore.toJSON());
206
+ this.#emitter.emit("session:migrated", {
207
+ fromSessionId: this.#sessionIdFromCookie,
208
+ toSessionId: this.sessionId,
209
+ session: this
210
+ });
211
+ } else await this.#store.write(this.#sessionId, this.#valuesStore.toJSON());
212
+ this.#emitter.emit("session:committed", { session: this });
213
+ }
214
+ };
215
+ export { E_SESSION_TAGGING_NOT_SUPPORTED as n, errors_exports as r, Session as t };
@@ -0,0 +1,139 @@
1
+ import { t as stubsRoot } from "./main-kn40V-hF.js";
2
+ import { t as debug_default } from "./debug-BZVg83L1.js";
3
+ import { InvalidArgumentsException, RuntimeException } from "@adonisjs/core/exceptions";
4
+ import { configProvider } from "@adonisjs/core";
5
+ import string from "@adonisjs/core/helpers/string";
6
+ async function configure(command) {
7
+ const codemods = await command.createCodemods();
8
+ await codemods.makeUsingStub(stubsRoot, "config/session.stub", {});
9
+ await codemods.defineEnvVariables({ SESSION_DRIVER: "cookie" });
10
+ await codemods.defineEnvValidations({
11
+ variables: { SESSION_DRIVER: `Env.schema.enum(['cookie', 'memory'] as const)` },
12
+ leadingComment: "Variables for configuring session package"
13
+ });
14
+ await codemods.registerMiddleware("router", [{ path: "@adonisjs/session/session_middleware" }]);
15
+ await codemods.updateRcFile((rcFile) => {
16
+ rcFile.addProvider("@adonisjs/session/session_provider");
17
+ rcFile.addCommand("@adonisjs/session/commands");
18
+ });
19
+ }
20
+ var MemoryStore = class MemoryStore {
21
+ static sessions = /* @__PURE__ */ new Map();
22
+ static tags = /* @__PURE__ */ new Map();
23
+ read(sessionId) {
24
+ return MemoryStore.sessions.get(sessionId) || null;
25
+ }
26
+ write(sessionId, values) {
27
+ MemoryStore.sessions.set(sessionId, values);
28
+ }
29
+ destroy(sessionId) {
30
+ MemoryStore.sessions.delete(sessionId);
31
+ MemoryStore.tags.delete(sessionId);
32
+ }
33
+ touch(_) {}
34
+ tag(sessionId, userId) {
35
+ MemoryStore.tags.set(sessionId, userId);
36
+ }
37
+ tagged(userId) {
38
+ const sessions = [];
39
+ for (const [sessionId, tagUserId] of MemoryStore.tags) {
40
+ if (tagUserId !== userId) continue;
41
+ const data = MemoryStore.sessions.get(sessionId);
42
+ if (data) sessions.push({
43
+ id: sessionId,
44
+ data
45
+ });
46
+ }
47
+ return sessions;
48
+ }
49
+ };
50
+ function defineConfig(config) {
51
+ debug_default("processing session config %O", config);
52
+ if (!config.store) throw new InvalidArgumentsException("Missing \"store\" property inside the session config");
53
+ const { stores: stores$1, cookie, ...rest } = {
54
+ enabled: true,
55
+ age: "2h",
56
+ cookieName: "adonis_session",
57
+ clearWithBrowser: false,
58
+ ...config
59
+ };
60
+ const cookieOptions = { ...cookie };
61
+ if (!rest.clearWithBrowser) {
62
+ cookieOptions.maxAge = string.seconds.parse(rest.age);
63
+ debug_default("computing maxAge \"%s\" for session id cookie", cookieOptions.maxAge);
64
+ } else {
65
+ cookieOptions.maxAge = void 0;
66
+ cookieOptions.expires = void 0;
67
+ }
68
+ return configProvider.create(async (app) => {
69
+ const storesNames = Object.keys(config.stores);
70
+ const storesList = { memory: () => new MemoryStore() };
71
+ for (let storeName of storesNames) {
72
+ const store = config.stores[storeName];
73
+ if (typeof store === "function") storesList[storeName] = store;
74
+ else storesList[storeName] = await store.resolver(app);
75
+ }
76
+ const transformedConfig = {
77
+ ...rest,
78
+ cookie: cookieOptions,
79
+ stores: storesList
80
+ };
81
+ debug_default("transformed session config %O", transformedConfig);
82
+ return transformedConfig;
83
+ });
84
+ }
85
+ const stores = {
86
+ file: (config) => {
87
+ return configProvider.create(async () => {
88
+ const { FileStore } = await import("./file-BBU02j4z.js");
89
+ return (_, sessionConfig) => {
90
+ return new FileStore(config, sessionConfig.age);
91
+ };
92
+ });
93
+ },
94
+ redis: (config) => {
95
+ return configProvider.create(async (app) => {
96
+ const { RedisStore } = await import("./redis-D8D9UtiD.js");
97
+ const redis = await app.container.make("redis");
98
+ return (_, sessionConfig) => {
99
+ return new RedisStore(redis.connection(config.connection), sessionConfig.age);
100
+ };
101
+ });
102
+ },
103
+ cookie: () => {
104
+ return configProvider.create(async () => {
105
+ const { CookieStore } = await import("./cookie--JOJxrtW.js");
106
+ return (ctx, sessionConfig) => {
107
+ return new CookieStore(sessionConfig.cookie, ctx);
108
+ };
109
+ });
110
+ },
111
+ dynamodb: (config) => {
112
+ return configProvider.create(async () => {
113
+ const { DynamoDBStore } = await import("./dynamodb-BFVgTQSf.js");
114
+ const { DynamoDBClient } = await import("@aws-sdk/client-dynamodb");
115
+ const client = "clientConfig" in config ? new DynamoDBClient(config.clientConfig) : config.client;
116
+ return (_, sessionConfig) => {
117
+ return new DynamoDBStore(client, sessionConfig.age, {
118
+ tableName: config.tableName,
119
+ keyAttribute: config.keyAttribute
120
+ });
121
+ };
122
+ });
123
+ },
124
+ database: (config) => {
125
+ return configProvider.create(async (app) => {
126
+ const { DatabaseStore } = await import("./database-vbrhCOPd.js");
127
+ const db = await app.container.make("lucid.db");
128
+ const connectionName = config?.connectionName || db.primaryConnectionName;
129
+ if (!db.manager.has(connectionName)) throw new RuntimeException(`Invalid database connection "${connectionName}" referenced in session config`);
130
+ return (_, sessionConfig) => {
131
+ return new DatabaseStore(db.connection(connectionName), sessionConfig.age, {
132
+ tableName: config?.tableName,
133
+ gcProbability: config?.gcProbability
134
+ });
135
+ };
136
+ });
137
+ }
138
+ };
139
+ export { stores as n, configure as r, defineConfig as t };
@@ -0,0 +1,31 @@
1
+ import { n as E_SESSION_TAGGING_NOT_SUPPORTED } from "./session-C9DdRahS.js";
2
+ import { t as debug_default } from "./debug-BZVg83L1.js";
3
+ var SessionCollection = class {
4
+ #store;
5
+ constructor(config) {
6
+ const storeFactory = config.stores[config.store];
7
+ this.#store = storeFactory(null, config);
8
+ }
9
+ supportsTagging() {
10
+ return "tag" in this.#store && "tagged" in this.#store;
11
+ }
12
+ async get(sessionId) {
13
+ debug_default("session collection: getting session data %s", sessionId);
14
+ return this.#store.read(sessionId);
15
+ }
16
+ async destroy(sessionId) {
17
+ debug_default("session collection: destroying session %s", sessionId);
18
+ return this.#store.destroy(sessionId);
19
+ }
20
+ async tag(sessionId, userId) {
21
+ debug_default("session collection: tagging session %s with user %s", sessionId, userId);
22
+ if (!this.supportsTagging()) throw new E_SESSION_TAGGING_NOT_SUPPORTED();
23
+ return this.#store.tag(sessionId, userId);
24
+ }
25
+ async tagged(userId) {
26
+ debug_default("session collection: getting sessions tagged with user %s", userId);
27
+ if (!this.supportsTagging()) throw new E_SESSION_TAGGING_NOT_SUPPORTED();
28
+ return this.#store.tagged(userId);
29
+ }
30
+ };
31
+ export { SessionCollection as t };
@@ -0,0 +1,27 @@
1
+ import { t as Session } from "./session-C9DdRahS.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 };
@@ -1,8 +1,39 @@
1
- import {
2
- SessionClient
3
- } from "../chunk-Y566BNUT.js";
4
- import "../chunk-HAD4PFFM.js";
5
- import "../chunk-SBOMJK4T.js";
6
- export {
7
- SessionClient
1
+ import { t as debug_default } from "../debug-BZVg83L1.js";
2
+ import { n as ValuesStore } from "../values_store-CvR1Sn37.js";
3
+ import { randomUUID } from "node:crypto";
4
+ var SessionClient = class {
5
+ #valuesStore = new ValuesStore({});
6
+ #flashMessagesStore = new ValuesStore({});
7
+ #store;
8
+ flashKey = "__flash__";
9
+ sessionId = randomUUID();
10
+ constructor(store) {
11
+ this.#store = store;
12
+ }
13
+ merge(values) {
14
+ this.#valuesStore.merge(values);
15
+ return this;
16
+ }
17
+ flash(values) {
18
+ this.#flashMessagesStore.merge(values);
19
+ return this;
20
+ }
21
+ async commit() {
22
+ if (!this.#flashMessagesStore.isEmpty) this.#valuesStore.set(this.flashKey, this.#flashMessagesStore.toJSON());
23
+ debug_default("committing session data during api request");
24
+ if (!this.#valuesStore.isEmpty) this.#store.write(this.sessionId, this.#valuesStore.toJSON());
25
+ }
26
+ async destroy(sessionId) {
27
+ debug_default("destroying session data during api request");
28
+ this.#store.destroy(sessionId || this.sessionId);
29
+ }
30
+ async load(sessionId) {
31
+ const store = new ValuesStore(await this.#store.read(sessionId || this.sessionId));
32
+ const flashMessages = store.pull(this.flashKey, {});
33
+ return {
34
+ values: store.all(),
35
+ flashMessages
36
+ };
37
+ }
8
38
  };
39
+ export { SessionClient };
@@ -1,2 +1,2 @@
1
- declare const _default: import("util").DebugLogger;
1
+ declare const _default: import("node:util").DebugLogger;
2
2
  export default _default;
@@ -1,13 +1,23 @@
1
1
  import type { ConfigProvider } from '@adonisjs/core/types';
2
2
  import type { CookieOptions } from '@adonisjs/core/types/http';
3
- import type { SessionConfig, FileStoreConfig, RedisStoreConfig, SessionStoreFactory, DynamoDBStoreConfig } from './types.ts';
3
+ import type { SessionConfig, FileStoreConfig, RedisStoreConfig, SessionStoreFactory, DynamoDBStoreConfig, DatabaseStoreConfig } from './types.ts';
4
+ type ConfigInput<KnownStores extends Record<string, SessionStoreFactory | ConfigProvider<SessionStoreFactory>>> = Partial<SessionConfig> & {
5
+ store: keyof KnownStores | 'memory';
6
+ stores: KnownStores;
7
+ /**
8
+ * Whether to clear the session cookie when the browser is closed.
9
+ * When true, creates a session cookie that expires on browser close.
10
+ * Note: Persisted session data continues to exist until it expires.
11
+ */
12
+ clearWithBrowser?: boolean;
13
+ cookie?: Omit<Partial<CookieOptions>, 'maxAge' | 'expires'>;
14
+ };
4
15
  /**
5
16
  * Resolved session configuration with all stores resolved
6
17
  */
7
18
  type ResolvedConfig<KnownStores extends Record<string, SessionStoreFactory>> = SessionConfig & {
8
19
  store: keyof KnownStores;
9
20
  stores: KnownStores;
10
- cookie: Partial<CookieOptions>;
11
21
  };
12
22
  /**
13
23
  * Defines and validates session configuration with store setup.
@@ -29,10 +39,7 @@ type ResolvedConfig<KnownStores extends Record<string, SessionStoreFactory>> = S
29
39
  * }
30
40
  * })
31
41
  */
32
- export declare function defineConfig<KnownStores extends Record<string, SessionStoreFactory | ConfigProvider<SessionStoreFactory>>>(config: Partial<SessionConfig> & {
33
- store: keyof KnownStores | 'memory';
34
- stores: KnownStores;
35
- }): ConfigProvider<ResolvedConfig<{
42
+ export declare function defineConfig<KnownStores extends Record<string, SessionStoreFactory | ConfigProvider<SessionStoreFactory>>>(config: ConfigInput<KnownStores>): ConfigProvider<ResolvedConfig<{
36
43
  [K in keyof KnownStores]: SessionStoreFactory;
37
44
  }>>;
38
45
  /**
@@ -59,5 +66,6 @@ export declare const stores: {
59
66
  redis: (config: RedisStoreConfig) => ConfigProvider<SessionStoreFactory>;
60
67
  cookie: () => ConfigProvider<SessionStoreFactory>;
61
68
  dynamodb: (config: DynamoDBStoreConfig) => ConfigProvider<SessionStoreFactory>;
69
+ database: (config?: DatabaseStoreConfig) => ConfigProvider<SessionStoreFactory>;
62
70
  };
63
71
  export {};
@@ -22,3 +22,12 @@ export declare const E_SESSION_NOT_MUTABLE: new (args?: any, options?: ErrorOpti
22
22
  * session.put('key', 'value') // Works fine
23
23
  */
24
24
  export declare const E_SESSION_NOT_READY: new (args?: any, options?: ErrorOptions) => import("@adonisjs/core/exceptions").Exception;
25
+ /**
26
+ * Error thrown when attempting to use tagging features with a store that doesn't support it.
27
+ * Only Memory, Redis, and Database stores support session tagging.
28
+ *
29
+ * @example
30
+ * // This will throw E_SESSION_TAGGING_NOT_SUPPORTED when using cookie store
31
+ * const sessions = await sessionCollection.tagged(userId)
32
+ */
33
+ export declare const E_SESSION_TAGGING_NOT_SUPPORTED: new (args?: any, options?: ErrorOptions) => import("@adonisjs/core/exceptions").Exception;
@@ -1,16 +1,20 @@
1
1
  import type { PluginFn } from 'edge.js/types';
2
2
  /**
3
3
  * The edge plugin for AdonisJS Session adds template tags to read flash messages.
4
- * Provides @flashMessage, @inputError, @error, and @errors tags for templates.
4
+ * Provides @flashMessage, @inputError, @error, and \@errors tags for templates.
5
5
  *
6
6
  * @example
7
+ * ```ts
7
8
  * // Register the plugin with Edge
8
9
  * import { edgePluginSession } from '@adonisjs/session/plugins/edge'
9
10
  * edge.use(edgePluginSession)
11
+ * ```
10
12
  *
13
+ * ```edge
11
14
  * // Use in templates
12
15
  * @flashMessage('success')
13
16
  * <div class="alert alert-success">{{ $message }}</div>
14
17
  * @end
18
+ * ```
15
19
  */
16
20
  export declare const edgePluginSession: PluginFn<undefined>;