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

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.
@@ -0,0 +1,107 @@
1
+ import { t as debug_default } from "./debug-Ba-0Cgn9.js";
2
+ import { InvalidArgumentsException } from "@adonisjs/core/exceptions";
3
+ import { configProvider } from "@adonisjs/core";
4
+ import string from "@adonisjs/core/helpers/string";
5
+ const stubsRoot = import.meta.dirname;
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
+ });
18
+ }
19
+ var MemoryStore = class MemoryStore {
20
+ static sessions = /* @__PURE__ */ new Map();
21
+ read(sessionId) {
22
+ return MemoryStore.sessions.get(sessionId) || null;
23
+ }
24
+ write(sessionId, values) {
25
+ MemoryStore.sessions.set(sessionId, values);
26
+ }
27
+ destroy(sessionId) {
28
+ MemoryStore.sessions.delete(sessionId);
29
+ }
30
+ touch(_) {}
31
+ };
32
+ function defineConfig(config) {
33
+ debug_default("processing session config %O", config);
34
+ if (!config.store) throw new InvalidArgumentsException("Missing \"store\" property inside the session config");
35
+ const { stores: stores$1, cookie, ...rest } = {
36
+ enabled: true,
37
+ age: "2h",
38
+ cookieName: "adonis_session",
39
+ clearWithBrowser: false,
40
+ ...config
41
+ };
42
+ const cookieOptions = { ...cookie };
43
+ if (!rest.clearWithBrowser) {
44
+ cookieOptions.maxAge = string.seconds.parse(rest.age);
45
+ debug_default("computing maxAge \"%s\" for session id cookie", cookieOptions.maxAge);
46
+ } else {
47
+ cookieOptions.maxAge = void 0;
48
+ cookieOptions.expires = void 0;
49
+ }
50
+ return configProvider.create(async (app) => {
51
+ const storesNames = Object.keys(config.stores);
52
+ const storesList = { memory: () => new MemoryStore() };
53
+ for (let storeName of storesNames) {
54
+ const store = config.stores[storeName];
55
+ if (typeof store === "function") storesList[storeName] = store;
56
+ else storesList[storeName] = await store.resolver(app);
57
+ }
58
+ const transformedConfig = {
59
+ ...rest,
60
+ cookie: cookieOptions,
61
+ stores: storesList
62
+ };
63
+ debug_default("transformed session config %O", transformedConfig);
64
+ return transformedConfig;
65
+ });
66
+ }
67
+ const stores = {
68
+ file: (config) => {
69
+ return configProvider.create(async () => {
70
+ const { FileStore } = await import("./file-CNxCs957.js");
71
+ return (_, sessionConfig) => {
72
+ return new FileStore(config, sessionConfig.age);
73
+ };
74
+ });
75
+ },
76
+ redis: (config) => {
77
+ return configProvider.create(async (app) => {
78
+ const { RedisStore } = await import("./redis-Bcjum7z7.js");
79
+ const redis = await app.container.make("redis");
80
+ return (_, sessionConfig) => {
81
+ return new RedisStore(redis.connection(config.connection), sessionConfig.age);
82
+ };
83
+ });
84
+ },
85
+ cookie: () => {
86
+ return configProvider.create(async () => {
87
+ const { CookieStore } = await import("./cookie-aLBno-zS.js");
88
+ return (ctx, sessionConfig) => {
89
+ return new CookieStore(sessionConfig.cookie, ctx);
90
+ };
91
+ });
92
+ },
93
+ dynamodb: (config) => {
94
+ return configProvider.create(async () => {
95
+ const { DynamoDBStore } = await import("./dynamodb-CU8BrQfU.js");
96
+ const { DynamoDBClient } = await import("@aws-sdk/client-dynamodb");
97
+ const client = "clientConfig" in config ? new DynamoDBClient(config.clientConfig) : config.client;
98
+ return (_, sessionConfig) => {
99
+ return new DynamoDBStore(client, sessionConfig.age, {
100
+ tableName: config.tableName,
101
+ keyAttribute: config.keyAttribute
102
+ });
103
+ };
104
+ });
105
+ }
106
+ };
107
+ export { stubsRoot as i, stores as n, configure as r, defineConfig as t };
@@ -0,0 +1,27 @@
1
+ import { t as Session } from "./session-CBqhcnvJ.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-Ba-0Cgn9.js";
2
+ import { n as ValuesStore } from "../values_store-smX0sQBJ.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
3
  import type { SessionConfig, FileStoreConfig, RedisStoreConfig, SessionStoreFactory, DynamoDBStoreConfig } 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
  /**
@@ -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>;
@@ -1,125 +1,75 @@
1
- import {
2
- debug_default
3
- } from "../../chunk-SBOMJK4T.js";
4
-
5
- // src/plugins/edge.ts
6
- var edgePluginSession = (edge) => {
7
- debug_default("registering session tags with edge");
8
- edge.registerTag({
9
- tagName: "flashMessage",
10
- seekable: true,
11
- block: true,
12
- compile(parser, buffer, token) {
13
- const expression = parser.utils.transformAst(
14
- parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
15
- token.filename,
16
- parser
17
- );
18
- const key = parser.utils.stringify(expression);
19
- buffer.writeStatement(
20
- `if (state.flashMessages.has(${key})) {`,
21
- token.filename,
22
- token.loc.start.line
23
- );
24
- buffer.writeExpression(
25
- `let $message = state.flashMessages.get(${key})`,
26
- token.filename,
27
- token.loc.start.line
28
- );
29
- parser.stack.defineScope();
30
- parser.stack.defineVariable("$message");
31
- token.children.forEach((child) => {
32
- parser.processToken(child, buffer);
33
- });
34
- parser.stack.clearScope();
35
- buffer.writeStatement(`}`, token.filename, token.loc.start.line);
36
- }
37
- });
38
- edge.registerTag({
39
- tagName: "inputError",
40
- seekable: true,
41
- block: true,
42
- compile(parser, buffer, token) {
43
- const expression = parser.utils.transformAst(
44
- parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
45
- token.filename,
46
- parser
47
- );
48
- const key = parser.utils.stringify(expression);
49
- buffer.writeStatement(
50
- `if (!!state.flashMessages.get('inputErrorsBag', {})[${key}]) {`,
51
- token.filename,
52
- token.loc.start.line
53
- );
54
- buffer.writeExpression(
55
- `let $messages = state.flashMessages.get('inputErrorsBag', {})[${key}]`,
56
- token.filename,
57
- token.loc.start.line
58
- );
59
- parser.stack.defineScope();
60
- parser.stack.defineVariable("$messages");
61
- token.children.forEach((child) => {
62
- parser.processToken(child, buffer);
63
- });
64
- parser.stack.clearScope();
65
- buffer.writeStatement(`}`, token.filename, token.loc.start.line);
66
- }
67
- });
68
- edge.registerTag({
69
- tagName: "error",
70
- seekable: true,
71
- block: true,
72
- compile(parser, buffer, token) {
73
- const expression = parser.utils.transformAst(
74
- parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
75
- token.filename,
76
- parser
77
- );
78
- const key = parser.utils.stringify(expression);
79
- buffer.writeStatement(
80
- `if (state.flashMessages.has(['errorsBag', ${key}])) {`,
81
- token.filename,
82
- token.loc.start.line
83
- );
84
- buffer.writeExpression(
85
- `let $message = state.flashMessages.get(['errorsBag', ${key}])`,
86
- token.filename,
87
- token.loc.start.line
88
- );
89
- parser.stack.defineScope();
90
- parser.stack.defineVariable("$message");
91
- token.children.forEach((child) => {
92
- parser.processToken(child, buffer);
93
- });
94
- parser.stack.clearScope();
95
- buffer.writeStatement(`}`, token.filename, token.loc.start.line);
96
- }
97
- });
98
- edge.registerTag({
99
- tagName: "errors",
100
- seekable: true,
101
- block: true,
102
- compile(parser, buffer, token) {
103
- buffer.writeStatement(
104
- `if (state.flashMessages.has('errorsBag')) {`,
105
- token.filename,
106
- token.loc.start.line
107
- );
108
- buffer.writeExpression(
109
- `let $messages = state.flashMessages.get('errorsBag')`,
110
- token.filename,
111
- token.loc.start.line
112
- );
113
- parser.stack.defineScope();
114
- parser.stack.defineVariable("$messages");
115
- token.children.forEach((child) => {
116
- parser.processToken(child, buffer);
117
- });
118
- parser.stack.clearScope();
119
- buffer.writeStatement(`}`, token.filename, token.loc.start.line);
120
- }
121
- });
122
- };
123
- export {
124
- edgePluginSession
1
+ import { t as debug_default } from "../../debug-Ba-0Cgn9.js";
2
+ const edgePluginSession = (edge) => {
3
+ debug_default("registering session tags with edge");
4
+ edge.registerTag({
5
+ tagName: "flashMessage",
6
+ seekable: true,
7
+ block: true,
8
+ compile(parser, buffer, token) {
9
+ const expression = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
10
+ const key = parser.utils.stringify(expression);
11
+ buffer.writeStatement(`if (state.flashMessages.has(${key})) {`, token.filename, token.loc.start.line);
12
+ buffer.writeExpression(`let $message = state.flashMessages.get(${key})`, token.filename, token.loc.start.line);
13
+ parser.stack.defineScope();
14
+ parser.stack.defineVariable("$message");
15
+ token.children.forEach((child) => {
16
+ parser.processToken(child, buffer);
17
+ });
18
+ parser.stack.clearScope();
19
+ buffer.writeStatement(`}`, token.filename, token.loc.start.line);
20
+ }
21
+ });
22
+ edge.registerTag({
23
+ tagName: "inputError",
24
+ seekable: true,
25
+ block: true,
26
+ compile(parser, buffer, token) {
27
+ const expression = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
28
+ const key = parser.utils.stringify(expression);
29
+ buffer.writeStatement(`if (!!state.flashMessages.get('inputErrorsBag', {})[${key}]) {`, token.filename, token.loc.start.line);
30
+ buffer.writeExpression(`let $messages = state.flashMessages.get('inputErrorsBag', {})[${key}]`, token.filename, token.loc.start.line);
31
+ parser.stack.defineScope();
32
+ parser.stack.defineVariable("$messages");
33
+ token.children.forEach((child) => {
34
+ parser.processToken(child, buffer);
35
+ });
36
+ parser.stack.clearScope();
37
+ buffer.writeStatement(`}`, token.filename, token.loc.start.line);
38
+ }
39
+ });
40
+ edge.registerTag({
41
+ tagName: "error",
42
+ seekable: true,
43
+ block: true,
44
+ compile(parser, buffer, token) {
45
+ const expression = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
46
+ const key = parser.utils.stringify(expression);
47
+ buffer.writeStatement(`if (state.flashMessages.has(['errorsBag', ${key}])) {`, token.filename, token.loc.start.line);
48
+ buffer.writeExpression(`let $message = state.flashMessages.get(['errorsBag', ${key}])`, token.filename, token.loc.start.line);
49
+ parser.stack.defineScope();
50
+ parser.stack.defineVariable("$message");
51
+ token.children.forEach((child) => {
52
+ parser.processToken(child, buffer);
53
+ });
54
+ parser.stack.clearScope();
55
+ buffer.writeStatement(`}`, token.filename, token.loc.start.line);
56
+ }
57
+ });
58
+ edge.registerTag({
59
+ tagName: "errors",
60
+ seekable: true,
61
+ block: true,
62
+ compile(parser, buffer, token) {
63
+ buffer.writeStatement(`if (state.flashMessages.has('errorsBag')) {`, token.filename, token.loc.start.line);
64
+ buffer.writeExpression(`let $messages = state.flashMessages.get('errorsBag')`, token.filename, token.loc.start.line);
65
+ parser.stack.defineScope();
66
+ parser.stack.defineVariable("$messages");
67
+ token.children.forEach((child) => {
68
+ parser.processToken(child, buffer);
69
+ });
70
+ parser.stack.clearScope();
71
+ buffer.writeStatement(`}`, token.filename, token.loc.start.line);
72
+ }
73
+ });
125
74
  };
75
+ export { edgePluginSession };
@@ -1,100 +1,80 @@
1
- import {
2
- SessionClient
3
- } from "../../../chunk-Y566BNUT.js";
4
- import "../../../chunk-HAD4PFFM.js";
5
- import "../../../chunk-SBOMJK4T.js";
6
-
7
- // src/plugins/japa/api_client.ts
8
- import "@japa/plugin-adonisjs";
1
+ import "../../../debug-Ba-0Cgn9.js";
2
+ import "../../../values_store-smX0sQBJ.js";
3
+ import { SessionClient } from "../../client.js";
4
+ import { RuntimeException } from "@adonisjs/core/exceptions";
9
5
  import lodash from "@poppinss/utils/lodash";
10
6
  import { configProvider } from "@adonisjs/core";
11
- import { RuntimeException } from "@adonisjs/core/exceptions";
7
+ import "@japa/plugin-adonisjs";
12
8
  import { ApiClient, ApiRequest, ApiResponse } from "@japa/api-client";
13
- var sessionApiClient = (app) => {
14
- const pluginFn = async function() {
15
- const sessionConfigProvider = app.config.get("session", {});
16
- const config = await configProvider.resolve(app, sessionConfigProvider);
17
- if (!config) {
18
- throw new RuntimeException(
19
- 'Invalid "config/session.ts" file. Make sure you are using the "defineConfig" method'
20
- );
21
- }
22
- ApiRequest.getter(
23
- "sessionClient",
24
- function() {
25
- return new SessionClient(config.stores.memory());
26
- },
27
- true
28
- );
29
- ApiRequest.macro("withSession", function(data) {
30
- this.sessionClient.merge(data);
31
- return this;
32
- });
33
- ApiRequest.macro("withFlashMessages", function(data) {
34
- this.sessionClient.flash(data);
35
- return this;
36
- });
37
- ApiResponse.macro("session", function(key) {
38
- return key ? lodash.get(this.sessionBag.values, key) : this.sessionBag.values;
39
- });
40
- ApiResponse.macro("flashMessages", function() {
41
- return this.sessionBag.flashMessages;
42
- });
43
- ApiResponse.macro("flashMessage", function(key) {
44
- return lodash.get(this.sessionBag.flashMessages, key);
45
- });
46
- ApiResponse.macro("assertSession", function(key, value) {
47
- this.assert.property(this.session(), key);
48
- if (value !== void 0) {
49
- this.assert.deepEqual(this.session(key), value);
50
- }
51
- });
52
- ApiResponse.macro("assertSessionMissing", function(key) {
53
- this.assert.notProperty(this.session(), key);
54
- });
55
- ApiResponse.macro("assertFlashMessage", function(key, value) {
56
- this.assert.property(this.flashMessages(), key);
57
- if (value !== void 0) {
58
- this.assert.deepEqual(this.flashMessage(key), value);
59
- }
60
- });
61
- ApiResponse.macro("assertFlashMissing", function(key) {
62
- this.assert.notProperty(this.flashMessages(), key);
63
- });
64
- ApiResponse.macro("assertHasValidationError", function(field) {
65
- this.assert.property(this.flashMessage("errors"), field);
66
- });
67
- ApiResponse.macro("assertDoesNotHaveValidationError", function(field) {
68
- this.assert.notProperty(this.flashMessage("errors"), field);
69
- });
70
- ApiResponse.macro("assertValidationError", function(field, message) {
71
- this.assert.include(this.flashMessage("errors")?.[field] || [], message);
72
- });
73
- ApiResponse.macro("assertValidationErrors", function(field, messages) {
74
- this.assert.deepEqual(this.flashMessage("errors")?.[field] || [], messages);
75
- });
76
- ApiClient.onRequest((request) => {
77
- request.setup(async () => {
78
- request.withCookie(config.cookieName, request.sessionClient.sessionId);
79
- await request.sessionClient.commit();
80
- return async (error) => {
81
- if (error) {
82
- await request.sessionClient.destroy();
83
- }
84
- };
85
- });
86
- request.teardown(async (response) => {
87
- const sessionId = response.cookie(config.cookieName);
88
- response.sessionBag = sessionId ? await response.request.sessionClient.load(sessionId.value) : {
89
- values: {},
90
- flashMessages: {}
91
- };
92
- await request.sessionClient.destroy(sessionId?.value);
93
- });
94
- });
95
- };
96
- return pluginFn;
97
- };
98
- export {
99
- sessionApiClient
9
+ const sessionApiClient = (app) => {
10
+ const pluginFn = async function() {
11
+ const sessionConfigProvider = app.config.get("session", {});
12
+ const config = await configProvider.resolve(app, sessionConfigProvider);
13
+ if (!config) throw new RuntimeException("Invalid \"config/session.ts\" file. Make sure you are using the \"defineConfig\" method");
14
+ ApiRequest.getter("sessionClient", function() {
15
+ return new SessionClient(config.stores.memory());
16
+ }, true);
17
+ ApiRequest.macro("withSession", function(data) {
18
+ this.sessionClient.merge(data);
19
+ return this;
20
+ });
21
+ ApiRequest.macro("withFlashMessages", function(data) {
22
+ this.sessionClient.flash(data);
23
+ return this;
24
+ });
25
+ ApiResponse.macro("session", function(key) {
26
+ return key ? lodash.get(this.sessionBag.values, key) : this.sessionBag.values;
27
+ });
28
+ ApiResponse.macro("flashMessages", function() {
29
+ return this.sessionBag.flashMessages;
30
+ });
31
+ ApiResponse.macro("flashMessage", function(key) {
32
+ return lodash.get(this.sessionBag.flashMessages, key);
33
+ });
34
+ ApiResponse.macro("assertSession", function(key, value) {
35
+ this.assert.property(this.session(), key);
36
+ if (value !== void 0) this.assert.deepEqual(this.session(key), value);
37
+ });
38
+ ApiResponse.macro("assertSessionMissing", function(key) {
39
+ this.assert.notProperty(this.session(), key);
40
+ });
41
+ ApiResponse.macro("assertFlashMessage", function(key, value) {
42
+ this.assert.property(this.flashMessages(), key);
43
+ if (value !== void 0) this.assert.deepEqual(this.flashMessage(key), value);
44
+ });
45
+ ApiResponse.macro("assertFlashMissing", function(key) {
46
+ this.assert.notProperty(this.flashMessages(), key);
47
+ });
48
+ ApiResponse.macro("assertHasValidationError", function(field) {
49
+ this.assert.property(this.flashMessage("errors"), field);
50
+ });
51
+ ApiResponse.macro("assertDoesNotHaveValidationError", function(field) {
52
+ this.assert.notProperty(this.flashMessage("errors"), field);
53
+ });
54
+ ApiResponse.macro("assertValidationError", function(field, message) {
55
+ this.assert.include(this.flashMessage("errors")?.[field] || [], message);
56
+ });
57
+ ApiResponse.macro("assertValidationErrors", function(field, messages) {
58
+ this.assert.deepEqual(this.flashMessage("errors")?.[field] || [], messages);
59
+ });
60
+ ApiClient.onRequest((request) => {
61
+ request.setup(async () => {
62
+ request.withCookie(config.cookieName, request.sessionClient.sessionId);
63
+ await request.sessionClient.commit();
64
+ return async (error) => {
65
+ if (error) await request.sessionClient.destroy();
66
+ };
67
+ });
68
+ request.teardown(async (response) => {
69
+ const sessionId = response.cookie(config.cookieName);
70
+ response.sessionBag = sessionId ? await response.request.sessionClient.load(sessionId.value) : {
71
+ values: {},
72
+ flashMessages: {}
73
+ };
74
+ await request.sessionClient.destroy(sessionId?.value);
75
+ });
76
+ });
77
+ };
78
+ return pluginFn;
100
79
  };
80
+ export { sessionApiClient };