@boo-labs/server 1.0.1 → 1.0.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 (24) hide show
  1. package/package.json +1 -1
  2. package/source/core/IPCMain/IPCProtocol.mjs +80 -75
  3. package/source/shared/domain/UUIDV7/index.mjs +31 -39
  4. package/source/shared/errors/ServerError/index.mjs +48 -2
  5. package/source/shared/outcome/Result/index.mjs +77 -130
  6. package/source/shared/outcome/Validation/index.mjs +56 -114
  7. package/source/shared/validations/Middleware/index.mjs +32 -23
  8. package/source/shared/validations/PathnamePattern/index.mjs +38 -39
  9. package/source/shared/validations/Server/NotFoundHandler/index.mjs +25 -15
  10. package/source/shared/validations/Server/Router/index.mjs +24 -14
  11. package/source/shared/validations/Server/ServerConfiguration/index.mjs +24 -14
  12. package/source/shared/validations/Server/SystemErrorHandler/index.mjs +25 -15
  13. package/source/shared/validations/ServerConfiguration/CORSOptions/index.mjs +95 -91
  14. package/source/shared/validations/ServerConfiguration/CSRFOptions/index.mjs +96 -96
  15. package/source/shared/validations/ServerConfiguration/CompressOptions/index.mjs +55 -43
  16. package/source/shared/validations/ServerConfiguration/CookieParserOptions/index.mjs +28 -13
  17. package/source/shared/validations/ServerConfiguration/CookieSessionOptions/index.mjs +101 -111
  18. package/source/shared/validations/ServerConfiguration/ListenOptions/index.mjs +55 -43
  19. package/source/shared/validations/ServerConfiguration/RateLimitOptions/index.mjs +71 -61
  20. package/source/shared/validations/ServerConfiguration/RequestOptions/index.mjs +44 -31
  21. package/source/shared/validations/ServerConfiguration/ResponseOptions/index.mjs +39 -25
  22. package/source/shared/validations/ServerConfiguration/SecurityHeadersOptions/index.mjs +27 -14
  23. package/source/shared/validations/ServerConfiguration/StaticOptions/index.mjs +85 -84
  24. package/source/shared/outcome/ErrorSchema.mjs +0 -361
@@ -14,6 +14,20 @@
14
14
  import Validation from '#shared/outcome/Validation';
15
15
  import ServerConfigurationError from '#shared/errors/ServerConfigurationError';
16
16
 
17
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
+ /**
19
+ * A successful {@link Validation} instance.
20
+ *
21
+ * @typedef {import('#shared/outcome/Validation').SuccessValidation} SuccessValidation
22
+ */
23
+
24
+ /**
25
+ * A failed {@link Validation} instance.
26
+ *
27
+ * @template {Error} E
28
+ * @typedef {import('#shared/outcome/Validation').FailureValidation<E>} FailureValidation
29
+ */
30
+
17
31
  // ━━ CONSTANTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
32
  /**
19
33
  * Minimum valid compression level.
@@ -70,6 +84,7 @@ function everyNonEmptyString(values) {
70
84
  return values.every(isNonEmptyString);
71
85
  }
72
86
 
87
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
73
88
  /**
74
89
  * Validates compression options.
75
90
  *
@@ -82,7 +97,8 @@ function everyNonEmptyString(values) {
82
97
  * 5. `types`, if present, must be an array of non-empty strings.
83
98
  *
84
99
  * @param {unknown} options - Compression options to validate.
85
- * @returns {Validation} Validation result.
100
+ * @returns {SuccessValidation|FailureValidation<ServerConfigurationError>} Validation result.
101
+ *
86
102
  * @example
87
103
  * ```js
88
104
  * const validation = validateCompressOptions({ threshold: 1024, level: 6 });
@@ -105,33 +121,31 @@ export function validateCompressOptions(options) {
105
121
  }
106
122
 
107
123
  if (!isPlainObject(options)) {
108
- return Validation.failure({
109
- error: ServerConfigurationError,
110
- code: 'INVALID_COMPRESS_OPTIONS',
111
- custom: true,
112
- options: { values: { received: typeof options } },
113
- });
124
+ return Validation.failure(
125
+ new ServerConfigurationError('INVALID_COMPRESS_OPTIONS', {
126
+ values: { received: typeof options },
127
+ }),
128
+ );
114
129
  }
115
130
 
116
131
  if ('threshold' in options) {
117
132
  const { threshold } = options;
118
133
 
119
134
  if (typeof threshold !== 'number') {
120
- return Validation.failure({
121
- error: ServerConfigurationError,
122
- code: 'INVALID_COMPRESS_THRESHOLD_TYPE',
123
- custom: true,
124
- options: { values: { received: typeof threshold } },
125
- });
135
+ return Validation.failure(
136
+ new ServerConfigurationError('INVALID_COMPRESS_THRESHOLD_TYPE', {
137
+ values: { received: typeof threshold },
138
+ }),
139
+ );
126
140
  }
127
141
 
128
142
  if (!Number.isInteger(threshold) || threshold < 0) {
129
- return Validation.failure({
130
- error: ServerConfigurationError,
131
- code: 'INVALID_COMPRESS_THRESHOLD_RANGE',
132
- custom: true,
133
- options: { details: { threshold } },
134
- });
143
+ return Validation.failure(
144
+ new ServerConfigurationError('INVALID_COMPRESS_THRESHOLD_RANGE', {
145
+ values: { threshold },
146
+ details: { threshold },
147
+ }),
148
+ );
135
149
  }
136
150
  }
137
151
 
@@ -139,21 +153,20 @@ export function validateCompressOptions(options) {
139
153
  const { level } = options;
140
154
 
141
155
  if (typeof level !== 'number') {
142
- return Validation.failure({
143
- error: ServerConfigurationError,
144
- code: 'INVALID_COMPRESS_LEVEL_TYPE',
145
- custom: true,
146
- options: { values: { received: typeof level } },
147
- });
156
+ return Validation.failure(
157
+ new ServerConfigurationError('INVALID_COMPRESS_LEVEL_TYPE', {
158
+ values: { received: typeof level },
159
+ }),
160
+ );
148
161
  }
149
162
 
150
163
  if (!Number.isInteger(level) || level < MIN_LEVEL || level > MAX_LEVEL) {
151
- return Validation.failure({
152
- error: ServerConfigurationError,
153
- code: 'INVALID_COMPRESS_LEVEL_RANGE',
154
- custom: true,
155
- options: { details: { level } },
156
- });
164
+ return Validation.failure(
165
+ new ServerConfigurationError('INVALID_COMPRESS_LEVEL_RANGE', {
166
+ values: { level },
167
+ details: { level },
168
+ }),
169
+ );
157
170
  }
158
171
  }
159
172
 
@@ -161,21 +174,19 @@ export function validateCompressOptions(options) {
161
174
  const { types } = options;
162
175
 
163
176
  if (!Array.isArray(types)) {
164
- return Validation.failure({
165
- error: ServerConfigurationError,
166
- code: 'INVALID_COMPRESS_TYPES_TYPE',
167
- custom: true,
168
- options: { values: { received: typeof types } },
169
- });
177
+ return Validation.failure(
178
+ new ServerConfigurationError('INVALID_COMPRESS_TYPES_TYPE', {
179
+ values: { received: typeof types },
180
+ }),
181
+ );
170
182
  }
171
183
 
172
184
  if (!everyNonEmptyString(types)) {
173
- return Validation.failure({
174
- error: ServerConfigurationError,
175
- code: 'INVALID_COMPRESS_TYPES_ITEM',
176
- custom: true,
177
- options: { details: { types } },
178
- });
185
+ return Validation.failure(
186
+ new ServerConfigurationError('INVALID_COMPRESS_TYPES_ITEM', {
187
+ details: { types },
188
+ }),
189
+ );
179
190
  }
180
191
  }
181
192
 
@@ -190,6 +201,7 @@ export function validateCompressOptions(options) {
190
201
  * @throws {ServerConfigurationError} If `threshold` is not a non-negative integer.
191
202
  * @throws {ServerConfigurationError} If `level` is not an integer between `-1` and `11`.
192
203
  * @throws {ServerConfigurationError} If `types` is not an array of non-empty strings.
204
+ *
193
205
  * @example
194
206
  * ```js
195
207
  * assertCompressOptions({ threshold: 1024, level: 6 });
@@ -13,6 +13,20 @@
13
13
  import Validation from '#shared/outcome/Validation';
14
14
  import ServerConfigurationError from '#shared/errors/ServerConfigurationError';
15
15
 
16
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
17
+ /**
18
+ * A successful {@link Validation} instance.
19
+ *
20
+ * @typedef {import('#shared/outcome/Validation').SuccessValidation} SuccessValidation
21
+ */
22
+
23
+ /**
24
+ * A failed {@link Validation} instance.
25
+ *
26
+ * @template {Error} E
27
+ * @typedef {import('#shared/outcome/Validation').FailureValidation<E>} FailureValidation
28
+ */
29
+
16
30
  // ━━ FUNCTIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
17
31
  /**
18
32
  * Determines whether a value is a non-null plain object.
@@ -25,6 +39,7 @@ function isPlainObject(value) {
25
39
  return typeof value === 'object' && value !== null && !Array.isArray(value);
26
40
  }
27
41
 
42
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
28
43
  /**
29
44
  * Validates cookie parser options.
30
45
  *
@@ -35,7 +50,8 @@ function isPlainObject(value) {
35
50
  * 3. `decode`, if present, must be a boolean.
36
51
  *
37
52
  * @param {unknown} options - Cookie parser options to validate.
38
- * @returns {Validation} Validation result.
53
+ * @returns {SuccessValidation|FailureValidation<ServerConfigurationError>} Validation result.
54
+ *
39
55
  * @example
40
56
  * ```js
41
57
  * const validation = validateCookieParserOptions({ decode: true });
@@ -58,24 +74,22 @@ export function validateCookieParserOptions(options) {
58
74
  }
59
75
 
60
76
  if (!isPlainObject(options)) {
61
- return Validation.failure({
62
- error: ServerConfigurationError,
63
- code: 'INVALID_COOKIE_PARSER_OPTIONS',
64
- custom: true,
65
- options: { values: { received: typeof options } },
66
- });
77
+ return Validation.failure(
78
+ new ServerConfigurationError('INVALID_COOKIE_PARSER_OPTIONS', {
79
+ values: { received: typeof options },
80
+ }),
81
+ );
67
82
  }
68
83
 
69
84
  if ('decode' in options) {
70
85
  const { decode } = options;
71
86
 
72
87
  if (typeof decode !== 'boolean') {
73
- return Validation.failure({
74
- error: ServerConfigurationError,
75
- code: 'INVALID_COOKIE_PARSER_DECODE_TYPE',
76
- custom: true,
77
- options: { values: { received: typeof decode } },
78
- });
88
+ return Validation.failure(
89
+ new ServerConfigurationError('INVALID_COOKIE_PARSER_DECODE_TYPE', {
90
+ values: { received: typeof decode },
91
+ }),
92
+ );
79
93
  }
80
94
  }
81
95
 
@@ -88,6 +102,7 @@ export function validateCookieParserOptions(options) {
88
102
  * @param {unknown} options - Cookie parser options to validate.
89
103
  * @throws {ServerConfigurationError} If `options` is not a plain object.
90
104
  * @throws {ServerConfigurationError} If `decode` is not a boolean.
105
+ *
91
106
  * @example
92
107
  * ```js
93
108
  * assertCookieParserOptions({ decode: true });
@@ -14,6 +14,20 @@
14
14
  import Validation from '#shared/outcome/Validation';
15
15
  import ServerConfigurationError from '#shared/errors/ServerConfigurationError';
16
16
 
17
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
+ /**
19
+ * A successful {@link Validation} instance.
20
+ *
21
+ * @typedef {import('#shared/outcome/Validation').SuccessValidation} SuccessValidation
22
+ */
23
+
24
+ /**
25
+ * A failed {@link Validation} instance.
26
+ *
27
+ * @template {Error} E
28
+ * @typedef {import('#shared/outcome/Validation').FailureValidation<E>} FailureValidation
29
+ */
30
+
17
31
  // ━━ CONSTANTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
32
  /**
19
33
  * Valid values for the SameSite cookie attribute.
@@ -57,6 +71,7 @@ function everyNonEmptyString(values) {
57
71
  return values.every(isNonEmptyString);
58
72
  }
59
73
 
74
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
60
75
  /**
61
76
  * Validates cookie session options.
62
77
  *
@@ -78,7 +93,8 @@ function everyNonEmptyString(values) {
78
93
  *
79
94
  * @param {unknown} options - Cookie session options to validate.
80
95
  * @param {boolean} [hasParser] - Whether a cookie parser is configured.
81
- * @returns {Validation} Validation result.
96
+ * @returns {SuccessValidation|FailureValidation<ServerConfigurationError>} Validation result.
97
+ *
82
98
  * @example
83
99
  * ```js
84
100
  * const validation = validateCookieSessionOptions({ keys: ['secret'] }, true);
@@ -101,99 +117,83 @@ export function validateCookieSessionOptions(options, hasParser) {
101
117
  }
102
118
 
103
119
  if (!isPlainObject(options)) {
104
- return Validation.failure({
105
- error: ServerConfigurationError,
106
- code: 'INVALID_COOKIE_SESSION_OPTIONS',
107
- custom: true,
108
- options: { values: { received: typeof options } },
109
- });
120
+ return Validation.failure(
121
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_OPTIONS', {
122
+ values: { received: typeof options },
123
+ }),
124
+ );
110
125
  }
111
126
 
112
127
  if (hasParser !== true) {
113
- return Validation.failure({
114
- error: ServerConfigurationError,
115
- code: 'COOKIE_SESSION_REQUIRES_COOKIE_PARSER',
116
- custom: true,
117
- });
128
+ return Validation.failure(
129
+ new ServerConfigurationError('COOKIE_SESSION_REQUIRES_COOKIE_PARSER'),
130
+ );
118
131
  }
119
132
 
120
133
  if ('name' in options) {
121
134
  const { name } = options;
122
135
 
123
136
  if (typeof name !== 'string') {
124
- return Validation.failure({
125
- error: ServerConfigurationError,
126
- code: 'INVALID_COOKIE_SESSION_NAME_TYPE',
127
- custom: true,
128
- options: { values: { received: typeof name } },
129
- });
137
+ return Validation.failure(
138
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_NAME_TYPE', {
139
+ values: { received: typeof name },
140
+ }),
141
+ );
130
142
  }
131
143
 
132
144
  if (name.length === 0) {
133
- return Validation.failure({
134
- error: ServerConfigurationError,
135
- code: 'INVALID_COOKIE_SESSION_NAME_VALUE',
136
- custom: true,
137
- options: { details: { name } },
138
- });
145
+ return Validation.failure(
146
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_NAME_VALUE', {
147
+ details: { name },
148
+ }),
149
+ );
139
150
  }
140
151
  }
141
152
 
142
153
  const { keys } = options;
143
154
 
144
155
  if (keys === undefined) {
145
- return Validation.failure({
146
- error: ServerConfigurationError,
147
- code: 'MISSING_COOKIE_SESSION_KEYS',
148
- custom: true,
149
- });
156
+ return Validation.failure(new ServerConfigurationError('MISSING_COOKIE_SESSION_KEYS'));
150
157
  }
151
158
 
152
159
  if (!Array.isArray(keys)) {
153
- return Validation.failure({
154
- error: ServerConfigurationError,
155
- code: 'INVALID_COOKIE_SESSION_KEYS_TYPE',
156
- custom: true,
157
- options: { values: { received: typeof keys } },
158
- });
160
+ return Validation.failure(
161
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_KEYS_TYPE', {
162
+ values: { received: typeof keys },
163
+ }),
164
+ );
159
165
  }
160
166
 
161
167
  if (keys.length === 0) {
162
- return Validation.failure({
163
- error: ServerConfigurationError,
164
- code: 'MISSING_COOKIE_SESSION_KEYS',
165
- custom: true,
166
- });
168
+ return Validation.failure(new ServerConfigurationError('MISSING_COOKIE_SESSION_KEYS'));
167
169
  }
168
170
 
169
171
  if (!everyNonEmptyString(keys)) {
170
- return Validation.failure({
171
- error: ServerConfigurationError,
172
- code: 'INVALID_COOKIE_SESSION_KEYS_ITEM',
173
- custom: true,
174
- options: { details: { keys } },
175
- });
172
+ return Validation.failure(
173
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_KEYS_ITEM', {
174
+ details: { keys },
175
+ }),
176
+ );
176
177
  }
177
178
 
178
179
  if ('maxAge' in options) {
179
180
  const { maxAge } = options;
180
181
 
181
182
  if (typeof maxAge !== 'number') {
182
- return Validation.failure({
183
- error: ServerConfigurationError,
184
- code: 'INVALID_COOKIE_SESSION_MAX_AGE_TYPE',
185
- custom: true,
186
- options: { values: { received: typeof maxAge } },
187
- });
183
+ return Validation.failure(
184
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_MAX_AGE_TYPE', {
185
+ values: { received: typeof maxAge },
186
+ }),
187
+ );
188
188
  }
189
189
 
190
190
  if (!Number.isInteger(maxAge) || maxAge <= 0) {
191
- return Validation.failure({
192
- error: ServerConfigurationError,
193
- code: 'INVALID_COOKIE_SESSION_MAX_AGE_RANGE',
194
- custom: true,
195
- options: { details: { maxAge } },
196
- });
191
+ return Validation.failure(
192
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_MAX_AGE_RANGE', {
193
+ values: { maxAge },
194
+ details: { maxAge },
195
+ }),
196
+ );
197
197
  }
198
198
  }
199
199
 
@@ -201,21 +201,19 @@ export function validateCookieSessionOptions(options, hasParser) {
201
201
  const { path } = options;
202
202
 
203
203
  if (typeof path !== 'string') {
204
- return Validation.failure({
205
- error: ServerConfigurationError,
206
- code: 'INVALID_COOKIE_SESSION_PATH_TYPE',
207
- custom: true,
208
- options: { values: { received: typeof path } },
209
- });
204
+ return Validation.failure(
205
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_PATH_TYPE', {
206
+ values: { received: typeof path },
207
+ }),
208
+ );
210
209
  }
211
210
 
212
211
  if (path.length === 0) {
213
- return Validation.failure({
214
- error: ServerConfigurationError,
215
- code: 'INVALID_COOKIE_SESSION_PATH_VALUE',
216
- custom: true,
217
- options: { details: { path } },
218
- });
212
+ return Validation.failure(
213
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_PATH_VALUE', {
214
+ details: { path },
215
+ }),
216
+ );
219
217
  }
220
218
  }
221
219
 
@@ -223,21 +221,19 @@ export function validateCookieSessionOptions(options, hasParser) {
223
221
  const { domain } = options;
224
222
 
225
223
  if (typeof domain !== 'string') {
226
- return Validation.failure({
227
- error: ServerConfigurationError,
228
- code: 'INVALID_COOKIE_SESSION_DOMAIN_TYPE',
229
- custom: true,
230
- options: { values: { received: typeof domain } },
231
- });
224
+ return Validation.failure(
225
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_DOMAIN_TYPE', {
226
+ values: { received: typeof domain },
227
+ }),
228
+ );
232
229
  }
233
230
 
234
231
  if (domain.length === 0) {
235
- return Validation.failure({
236
- error: ServerConfigurationError,
237
- code: 'INVALID_COOKIE_SESSION_DOMAIN_VALUE',
238
- custom: true,
239
- options: { details: { domain } },
240
- });
232
+ return Validation.failure(
233
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_DOMAIN_VALUE', {
234
+ details: { domain },
235
+ }),
236
+ );
241
237
  }
242
238
  }
243
239
 
@@ -245,12 +241,11 @@ export function validateCookieSessionOptions(options, hasParser) {
245
241
  const { secure } = options;
246
242
 
247
243
  if (typeof secure !== 'boolean') {
248
- return Validation.failure({
249
- error: ServerConfigurationError,
250
- code: 'INVALID_COOKIE_SESSION_SECURE_TYPE',
251
- custom: true,
252
- options: { values: { received: typeof secure } },
253
- });
244
+ return Validation.failure(
245
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_SECURE_TYPE', {
246
+ values: { received: typeof secure },
247
+ }),
248
+ );
254
249
  }
255
250
  }
256
251
 
@@ -258,12 +253,11 @@ export function validateCookieSessionOptions(options, hasParser) {
258
253
  const { httpOnly } = options;
259
254
 
260
255
  if (typeof httpOnly !== 'boolean') {
261
- return Validation.failure({
262
- error: ServerConfigurationError,
263
- code: 'INVALID_COOKIE_SESSION_HTTP_ONLY_TYPE',
264
- custom: true,
265
- options: { values: { received: typeof httpOnly } },
266
- });
256
+ return Validation.failure(
257
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_HTTP_ONLY_TYPE', {
258
+ values: { received: typeof httpOnly },
259
+ }),
260
+ );
267
261
  }
268
262
  }
269
263
 
@@ -271,12 +265,12 @@ export function validateCookieSessionOptions(options, hasParser) {
271
265
  const { sameSite } = options;
272
266
 
273
267
  if (sameSite !== undefined && !SAME_SITE_VALUES.includes(String(sameSite))) {
274
- return Validation.failure({
275
- error: ServerConfigurationError,
276
- code: 'INVALID_COOKIE_SESSION_SAME_SITE_VALUE',
277
- custom: true,
278
- options: { details: { sameSite } },
279
- });
268
+ return Validation.failure(
269
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_SAME_SITE_VALUE', {
270
+ values: { received: sameSite },
271
+ details: { sameSite },
272
+ }),
273
+ );
280
274
  }
281
275
  }
282
276
 
@@ -284,12 +278,11 @@ export function validateCookieSessionOptions(options, hasParser) {
284
278
  const { overwrite } = options;
285
279
 
286
280
  if (typeof overwrite !== 'boolean') {
287
- return Validation.failure({
288
- error: ServerConfigurationError,
289
- code: 'INVALID_COOKIE_SESSION_OVERWRITE_TYPE',
290
- custom: true,
291
- options: { values: { received: typeof overwrite } },
292
- });
281
+ return Validation.failure(
282
+ new ServerConfigurationError('INVALID_COOKIE_SESSION_OVERWRITE_TYPE', {
283
+ values: { received: typeof overwrite },
284
+ }),
285
+ );
293
286
  }
294
287
  }
295
288
 
@@ -298,11 +291,7 @@ export function validateCookieSessionOptions(options, hasParser) {
298
291
  const effectiveSecure = options.secure ?? true;
299
292
 
300
293
  if (effectiveSameSite === 'None' && effectiveSecure === false) {
301
- return Validation.failure({
302
- error: ServerConfigurationError,
303
- code: 'COOKIE_SESSION_NONE_REQUIRES_SECURE',
304
- custom: true,
305
- });
294
+ return Validation.failure(new ServerConfigurationError('COOKIE_SESSION_NONE_REQUIRES_SECURE'));
306
295
  }
307
296
 
308
297
  return Validation.success();
@@ -318,6 +307,7 @@ export function validateCookieSessionOptions(options, hasParser) {
318
307
  * @throws {ServerConfigurationError} If `keys` is missing or invalid.
319
308
  * @throws {ServerConfigurationError} If any other option is invalid.
320
309
  * @throws {ServerConfigurationError} If `sameSite: 'None'` is used without `secure: true`.
310
+ *
321
311
  * @example
322
312
  * ```js
323
313
  * assertCookieSessionOptions({ keys: ['secret'] }, true);