@atproto/lex-server 0.0.7 → 0.0.9

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @atproto/lex-server
2
2
 
3
+ ## 0.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4603](https://github.com/bluesky-social/atproto/pull/4603) [`7b9a98a`](https://github.com/bluesky-social/atproto/commit/7b9a98a763636c5f66a06da11fe6013f29dd9157) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix flaky test
8
+
9
+ - [#4601](https://github.com/bluesky-social/atproto/pull/4601) [`ed61c62`](https://github.com/bluesky-social/atproto/commit/ed61c62f3161fcde85ee9a93f8ed339c7e06c015) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix `exports` field in package.json
10
+
11
+ - [#4601](https://github.com/bluesky-social/atproto/pull/4601) [`ed61c62`](https://github.com/bluesky-social/atproto/commit/ed61c62f3161fcde85ee9a93f8ed339c7e06c015) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add JSDoc
12
+
13
+ - Updated dependencies [[`7b9a98a`](https://github.com/bluesky-social/atproto/commit/7b9a98a763636c5f66a06da11fe6013f29dd9157), [`7b9a98a`](https://github.com/bluesky-social/atproto/commit/7b9a98a763636c5f66a06da11fe6013f29dd9157), [`ed61c62`](https://github.com/bluesky-social/atproto/commit/ed61c62f3161fcde85ee9a93f8ed339c7e06c015), [`ed61c62`](https://github.com/bluesky-social/atproto/commit/ed61c62f3161fcde85ee9a93f8ed339c7e06c015), [`7b9a98a`](https://github.com/bluesky-social/atproto/commit/7b9a98a763636c5f66a06da11fe6013f29dd9157), [`7b9a98a`](https://github.com/bluesky-social/atproto/commit/7b9a98a763636c5f66a06da11fe6013f29dd9157), [`ed61c62`](https://github.com/bluesky-social/atproto/commit/ed61c62f3161fcde85ee9a93f8ed339c7e06c015)]:
14
+ - @atproto/lex-schema@0.0.12
15
+ - @atproto/lex-json@0.0.11
16
+ - @atproto/lex-cbor@0.0.11
17
+ - @atproto/lex-data@0.0.11
18
+
19
+ ## 0.0.8
20
+
21
+ ### Patch Changes
22
+
23
+ - [#4589](https://github.com/bluesky-social/atproto/pull/4589) [`369bb02`](https://github.com/bluesky-social/atproto/commit/369bb02b9f80f0e15e5242e54f09bd4e01117f3a) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Make `LexRouter.handlers` property public
24
+
25
+ - [#4589](https://github.com/bluesky-social/atproto/pull/4589) [`369bb02`](https://github.com/bluesky-social/atproto/commit/369bb02b9f80f0e15e5242e54f09bd4e01117f3a) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose `sendResponse` for writing a `Response` object to a NodeJS `ServerResponse`
26
+
27
+ - Updated dependencies [[`369bb02`](https://github.com/bluesky-social/atproto/commit/369bb02b9f80f0e15e5242e54f09bd4e01117f3a)]:
28
+ - @atproto/lex-data@0.0.10
29
+ - @atproto/lex-cbor@0.0.10
30
+ - @atproto/lex-json@0.0.10
31
+ - @atproto/lex-schema@0.0.11
32
+
3
33
  ## 0.0.7
4
34
 
5
35
  ### Patch Changes
package/dist/errors.d.ts CHANGED
@@ -1,13 +1,107 @@
1
1
  import { LexError, LexErrorCode } from '@atproto/lex-data';
2
2
  import { WWWAuthenticate } from './lib/www-authenticate.js';
3
3
  export type { WWWAuthenticate };
4
+ /**
5
+ * Error class for authentication failures in XRPC server handlers.
6
+ *
7
+ * Extends {@link LexError} to include WWW-Authenticate header support,
8
+ * which is required by HTTP authentication standards (RFC 7235).
9
+ * The error automatically generates the appropriate 401 response with
10
+ * the WWW-Authenticate header when converted to a Response.
11
+ *
12
+ * @typeParam N - The Lexicon error code type
13
+ *
14
+ * @example Throwing an auth error
15
+ * ```typescript
16
+ * import { LexServerAuthError } from '@atproto/lex-server'
17
+ *
18
+ * throw new LexServerAuthError(
19
+ * 'AuthenticationRequired',
20
+ * 'Invalid or expired token',
21
+ * { Bearer: { error: 'InvalidToken', realm: 'api.example.com' } }
22
+ * )
23
+ * ```
24
+ *
25
+ * @example Converting from a LexError
26
+ * ```typescript
27
+ * try {
28
+ * await validateToken(token)
29
+ * } catch (error) {
30
+ * if (error instanceof LexError) {
31
+ * throw LexServerAuthError.from(error, {
32
+ * Bearer: { error: 'InvalidToken' }
33
+ * })
34
+ * }
35
+ * throw error
36
+ * }
37
+ * ```
38
+ */
4
39
  export declare class LexServerAuthError<N extends LexErrorCode = LexErrorCode> extends LexError<N> {
5
40
  readonly wwwAuthenticate: WWWAuthenticate;
6
41
  name: string;
42
+ /**
43
+ * Creates a new authentication error.
44
+ *
45
+ * @param error - The Lexicon error code (e.g., 'AuthenticationRequired')
46
+ * @param message - Human-readable error message
47
+ * @param wwwAuthenticate - WWW-Authenticate header parameters
48
+ * @param options - Standard Error options including `cause`
49
+ */
7
50
  constructor(error: N, message: string, wwwAuthenticate?: WWWAuthenticate, options?: ErrorOptions);
51
+ /**
52
+ * Gets the formatted WWW-Authenticate header value.
53
+ *
54
+ * @returns The formatted header string for the 401 response
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const error = new LexServerAuthError('AuthenticationRequired', 'Token required', {
59
+ * Bearer: { realm: 'api.example.com', error: 'MissingToken' }
60
+ * })
61
+ * console.log(error.wwwAuthenticateHeader)
62
+ * // Output: 'Bearer realm="api.example.com", error="MissingToken"'
63
+ * ```
64
+ */
8
65
  get wwwAuthenticateHeader(): string;
66
+ /**
67
+ * Converts the error to a JSON representation suitable for response bodies.
68
+ *
69
+ * If the error was created from another LexError (via `from()`), returns
70
+ * the original error's JSON representation.
71
+ *
72
+ * @returns JSON object with error code and message
73
+ */
9
74
  toJSON(): import("@atproto/lex-data").LexErrorData<any>;
75
+ /**
76
+ * Converts the error to an HTTP 401 Response with WWW-Authenticate header.
77
+ *
78
+ * The response includes:
79
+ * - Status code 401 (Unauthorized)
80
+ * - WWW-Authenticate header (if parameters were provided)
81
+ * - Access-Control-Expose-Headers for CORS compatibility
82
+ * - JSON body with error details
83
+ *
84
+ * @returns HTTP Response object ready to be sent to the client
85
+ */
10
86
  toResponse(): Response;
87
+ /**
88
+ * Creates a LexServerAuthError from an existing LexError.
89
+ *
90
+ * If the input is already a LexServerAuthError, returns it unchanged.
91
+ * Otherwise, wraps the error with the provided WWW-Authenticate parameters.
92
+ *
93
+ * @param cause - The original LexError to wrap
94
+ * @param wwwAuthenticate - WWW-Authenticate header parameters
95
+ * @returns A LexServerAuthError instance
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const lexError = new LexError('AuthenticationRequired', 'Token expired')
100
+ * const authError = LexServerAuthError.from(lexError, {
101
+ * Bearer: { error: 'ExpiredToken' }
102
+ * })
103
+ * ```
104
+ */
11
105
  static from(cause: LexError, wwwAuthenticate?: WWWAuthenticate): LexServerAuthError;
12
106
  }
13
107
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EACL,eAAe,EAEhB,MAAM,2BAA2B,CAAA;AAElC,YAAY,EAAE,eAAe,EAAE,CAAA;AAE/B,qBAAa,kBAAkB,CAC7B,CAAC,SAAS,YAAY,GAAG,YAAY,CACrC,SAAQ,QAAQ,CAAC,CAAC,CAAC;IAMjB,QAAQ,CAAC,eAAe,EAAE,eAAe;IAL3C,IAAI,SAAuB;gBAGzB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,MAAM,EACN,eAAe,GAAE,eAAoB,EAC9C,OAAO,CAAC,EAAE,YAAY;IAKxB,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,MAAM;IAKN,UAAU,IAAI,QAAQ;IAatB,MAAM,CAAC,IAAI,CACT,KAAK,EAAE,QAAQ,EACf,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB;CAMtB"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EACL,eAAe,EAEhB,MAAM,2BAA2B,CAAA;AAElC,YAAY,EAAE,eAAe,EAAE,CAAA;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,kBAAkB,CAC7B,CAAC,SAAS,YAAY,GAAG,YAAY,CACrC,SAAQ,QAAQ,CAAC,CAAC,CAAC;IAcjB,QAAQ,CAAC,eAAe,EAAE,eAAe;IAb3C,IAAI,SAAuB;IAE3B;;;;;;;OAOG;gBAED,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,MAAM,EACN,eAAe,GAAE,eAAoB,EAC9C,OAAO,CAAC,EAAE,YAAY;IAKxB;;;;;;;;;;;;;OAaG;IACH,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED;;;;;;;OAOG;IACH,MAAM;IAKN;;;;;;;;;;OAUG;IACH,UAAU,IAAI,QAAQ;IAatB;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,IAAI,CACT,KAAK,EAAE,QAAQ,EACf,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB;CAMtB"}
package/dist/errors.js CHANGED
@@ -3,20 +3,96 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LexServerAuthError = void 0;
4
4
  const lex_data_1 = require("@atproto/lex-data");
5
5
  const www_authenticate_js_1 = require("./lib/www-authenticate.js");
6
+ /**
7
+ * Error class for authentication failures in XRPC server handlers.
8
+ *
9
+ * Extends {@link LexError} to include WWW-Authenticate header support,
10
+ * which is required by HTTP authentication standards (RFC 7235).
11
+ * The error automatically generates the appropriate 401 response with
12
+ * the WWW-Authenticate header when converted to a Response.
13
+ *
14
+ * @typeParam N - The Lexicon error code type
15
+ *
16
+ * @example Throwing an auth error
17
+ * ```typescript
18
+ * import { LexServerAuthError } from '@atproto/lex-server'
19
+ *
20
+ * throw new LexServerAuthError(
21
+ * 'AuthenticationRequired',
22
+ * 'Invalid or expired token',
23
+ * { Bearer: { error: 'InvalidToken', realm: 'api.example.com' } }
24
+ * )
25
+ * ```
26
+ *
27
+ * @example Converting from a LexError
28
+ * ```typescript
29
+ * try {
30
+ * await validateToken(token)
31
+ * } catch (error) {
32
+ * if (error instanceof LexError) {
33
+ * throw LexServerAuthError.from(error, {
34
+ * Bearer: { error: 'InvalidToken' }
35
+ * })
36
+ * }
37
+ * throw error
38
+ * }
39
+ * ```
40
+ */
6
41
  class LexServerAuthError extends lex_data_1.LexError {
7
42
  wwwAuthenticate;
8
43
  name = 'LexServerAuthError';
44
+ /**
45
+ * Creates a new authentication error.
46
+ *
47
+ * @param error - The Lexicon error code (e.g., 'AuthenticationRequired')
48
+ * @param message - Human-readable error message
49
+ * @param wwwAuthenticate - WWW-Authenticate header parameters
50
+ * @param options - Standard Error options including `cause`
51
+ */
9
52
  constructor(error, message, wwwAuthenticate = {}, options) {
10
53
  super(error, message, options);
11
54
  this.wwwAuthenticate = wwwAuthenticate;
12
55
  }
56
+ /**
57
+ * Gets the formatted WWW-Authenticate header value.
58
+ *
59
+ * @returns The formatted header string for the 401 response
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * const error = new LexServerAuthError('AuthenticationRequired', 'Token required', {
64
+ * Bearer: { realm: 'api.example.com', error: 'MissingToken' }
65
+ * })
66
+ * console.log(error.wwwAuthenticateHeader)
67
+ * // Output: 'Bearer realm="api.example.com", error="MissingToken"'
68
+ * ```
69
+ */
13
70
  get wwwAuthenticateHeader() {
14
71
  return (0, www_authenticate_js_1.formatWWWAuthenticateHeader)(this.wwwAuthenticate);
15
72
  }
73
+ /**
74
+ * Converts the error to a JSON representation suitable for response bodies.
75
+ *
76
+ * If the error was created from another LexError (via `from()`), returns
77
+ * the original error's JSON representation.
78
+ *
79
+ * @returns JSON object with error code and message
80
+ */
16
81
  toJSON() {
17
82
  const { cause } = this;
18
83
  return cause instanceof lex_data_1.LexError ? cause.toJSON() : super.toJSON();
19
84
  }
85
+ /**
86
+ * Converts the error to an HTTP 401 Response with WWW-Authenticate header.
87
+ *
88
+ * The response includes:
89
+ * - Status code 401 (Unauthorized)
90
+ * - WWW-Authenticate header (if parameters were provided)
91
+ * - Access-Control-Expose-Headers for CORS compatibility
92
+ * - JSON body with error details
93
+ *
94
+ * @returns HTTP Response object ready to be sent to the client
95
+ */
20
96
  toResponse() {
21
97
  const { wwwAuthenticateHeader } = this;
22
98
  const headers = wwwAuthenticateHeader
@@ -27,6 +103,24 @@ class LexServerAuthError extends lex_data_1.LexError {
27
103
  : undefined;
28
104
  return Response.json(this.toJSON(), { status: 401, headers });
29
105
  }
106
+ /**
107
+ * Creates a LexServerAuthError from an existing LexError.
108
+ *
109
+ * If the input is already a LexServerAuthError, returns it unchanged.
110
+ * Otherwise, wraps the error with the provided WWW-Authenticate parameters.
111
+ *
112
+ * @param cause - The original LexError to wrap
113
+ * @param wwwAuthenticate - WWW-Authenticate header parameters
114
+ * @returns A LexServerAuthError instance
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const lexError = new LexError('AuthenticationRequired', 'Token expired')
119
+ * const authError = LexServerAuthError.from(lexError, {
120
+ * Bearer: { error: 'ExpiredToken' }
121
+ * })
122
+ * ```
123
+ */
30
124
  static from(cause, wwwAuthenticate) {
31
125
  if (cause instanceof LexServerAuthError)
32
126
  return cause;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,gDAA0D;AAC1D,mEAGkC;AAIlC,MAAa,kBAEX,SAAQ,mBAAW;IAMR;IALX,IAAI,GAAG,oBAAoB,CAAA;IAE3B,YACE,KAAQ,EACR,OAAe,EACN,kBAAmC,EAAE,EAC9C,OAAsB;QAEtB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QAHrB,oBAAe,GAAf,eAAe,CAAsB;IAIhD,CAAC;IAED,IAAI,qBAAqB;QACvB,OAAO,IAAA,iDAA2B,EAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;QACtB,OAAO,KAAK,YAAY,mBAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;IACpE,CAAC;IAED,UAAU;QACR,MAAM,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAA;QAEtC,MAAM,OAAO,GAAG,qBAAqB;YACnC,CAAC,CAAC,IAAI,OAAO,CAAC;gBACV,kBAAkB,EAAE,qBAAqB;gBACzC,+BAA+B,EAAE,kBAAkB,EAAE,OAAO;aAC7D,CAAC;YACJ,CAAC,CAAC,SAAS,CAAA;QAEb,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED,MAAM,CAAC,IAAI,CACT,KAAe,EACf,eAAiC;QAEjC,IAAI,KAAK,YAAY,kBAAkB;YAAE,OAAO,KAAK,CAAA;QACrD,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE;YACzE,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;CACF;AA7CD,gDA6CC","sourcesContent":["import { LexError, LexErrorCode } from '@atproto/lex-data'\nimport {\n WWWAuthenticate,\n formatWWWAuthenticateHeader,\n} from './lib/www-authenticate.js'\n\nexport type { WWWAuthenticate }\n\nexport class LexServerAuthError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexError<N> {\n name = 'LexServerAuthError'\n\n constructor(\n error: N,\n message: string,\n readonly wwwAuthenticate: WWWAuthenticate = {},\n options?: ErrorOptions,\n ) {\n super(error, message, options)\n }\n\n get wwwAuthenticateHeader(): string {\n return formatWWWAuthenticateHeader(this.wwwAuthenticate)\n }\n\n toJSON() {\n const { cause } = this\n return cause instanceof LexError ? cause.toJSON() : super.toJSON()\n }\n\n toResponse(): Response {\n const { wwwAuthenticateHeader } = this\n\n const headers = wwwAuthenticateHeader\n ? new Headers({\n 'WWW-Authenticate': wwwAuthenticateHeader,\n 'Access-Control-Expose-Headers': 'WWW-Authenticate', // CORS\n })\n : undefined\n\n return Response.json(this.toJSON(), { status: 401, headers })\n }\n\n static from(\n cause: LexError,\n wwwAuthenticate?: WWWAuthenticate,\n ): LexServerAuthError {\n if (cause instanceof LexServerAuthError) return cause\n return new LexServerAuthError(cause.error, cause.message, wwwAuthenticate, {\n cause,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,gDAA0D;AAC1D,mEAGkC;AAIlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAa,kBAEX,SAAQ,mBAAW;IAcR;IAbX,IAAI,GAAG,oBAAoB,CAAA;IAE3B;;;;;;;OAOG;IACH,YACE,KAAQ,EACR,OAAe,EACN,kBAAmC,EAAE,EAC9C,OAAsB;QAEtB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QAHrB,oBAAe,GAAf,eAAe,CAAsB;IAIhD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,IAAI,qBAAqB;QACvB,OAAO,IAAA,iDAA2B,EAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAC1D,CAAC;IAED;;;;;;;OAOG;IACH,MAAM;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;QACtB,OAAO,KAAK,YAAY,mBAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;IACpE,CAAC;IAED;;;;;;;;;;OAUG;IACH,UAAU;QACR,MAAM,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAA;QAEtC,MAAM,OAAO,GAAG,qBAAqB;YACnC,CAAC,CAAC,IAAI,OAAO,CAAC;gBACV,kBAAkB,EAAE,qBAAqB;gBACzC,+BAA+B,EAAE,kBAAkB,EAAE,OAAO;aAC7D,CAAC;YACJ,CAAC,CAAC,SAAS,CAAA;QAEb,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,IAAI,CACT,KAAe,EACf,eAAiC;QAEjC,IAAI,KAAK,YAAY,kBAAkB;YAAE,OAAO,KAAK,CAAA;QACrD,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE;YACzE,KAAK;SACN,CAAC,CAAA;IACJ,CAAC;CACF;AAxGD,gDAwGC","sourcesContent":["import { LexError, LexErrorCode } from '@atproto/lex-data'\nimport {\n WWWAuthenticate,\n formatWWWAuthenticateHeader,\n} from './lib/www-authenticate.js'\n\nexport type { WWWAuthenticate }\n\n/**\n * Error class for authentication failures in XRPC server handlers.\n *\n * Extends {@link LexError} to include WWW-Authenticate header support,\n * which is required by HTTP authentication standards (RFC 7235).\n * The error automatically generates the appropriate 401 response with\n * the WWW-Authenticate header when converted to a Response.\n *\n * @typeParam N - The Lexicon error code type\n *\n * @example Throwing an auth error\n * ```typescript\n * import { LexServerAuthError } from '@atproto/lex-server'\n *\n * throw new LexServerAuthError(\n * 'AuthenticationRequired',\n * 'Invalid or expired token',\n * { Bearer: { error: 'InvalidToken', realm: 'api.example.com' } }\n * )\n * ```\n *\n * @example Converting from a LexError\n * ```typescript\n * try {\n * await validateToken(token)\n * } catch (error) {\n * if (error instanceof LexError) {\n * throw LexServerAuthError.from(error, {\n * Bearer: { error: 'InvalidToken' }\n * })\n * }\n * throw error\n * }\n * ```\n */\nexport class LexServerAuthError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexError<N> {\n name = 'LexServerAuthError'\n\n /**\n * Creates a new authentication error.\n *\n * @param error - The Lexicon error code (e.g., 'AuthenticationRequired')\n * @param message - Human-readable error message\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @param options - Standard Error options including `cause`\n */\n constructor(\n error: N,\n message: string,\n readonly wwwAuthenticate: WWWAuthenticate = {},\n options?: ErrorOptions,\n ) {\n super(error, message, options)\n }\n\n /**\n * Gets the formatted WWW-Authenticate header value.\n *\n * @returns The formatted header string for the 401 response\n *\n * @example\n * ```typescript\n * const error = new LexServerAuthError('AuthenticationRequired', 'Token required', {\n * Bearer: { realm: 'api.example.com', error: 'MissingToken' }\n * })\n * console.log(error.wwwAuthenticateHeader)\n * // Output: 'Bearer realm=\"api.example.com\", error=\"MissingToken\"'\n * ```\n */\n get wwwAuthenticateHeader(): string {\n return formatWWWAuthenticateHeader(this.wwwAuthenticate)\n }\n\n /**\n * Converts the error to a JSON representation suitable for response bodies.\n *\n * If the error was created from another LexError (via `from()`), returns\n * the original error's JSON representation.\n *\n * @returns JSON object with error code and message\n */\n toJSON() {\n const { cause } = this\n return cause instanceof LexError ? cause.toJSON() : super.toJSON()\n }\n\n /**\n * Converts the error to an HTTP 401 Response with WWW-Authenticate header.\n *\n * The response includes:\n * - Status code 401 (Unauthorized)\n * - WWW-Authenticate header (if parameters were provided)\n * - Access-Control-Expose-Headers for CORS compatibility\n * - JSON body with error details\n *\n * @returns HTTP Response object ready to be sent to the client\n */\n toResponse(): Response {\n const { wwwAuthenticateHeader } = this\n\n const headers = wwwAuthenticateHeader\n ? new Headers({\n 'WWW-Authenticate': wwwAuthenticateHeader,\n 'Access-Control-Expose-Headers': 'WWW-Authenticate', // CORS\n })\n : undefined\n\n return Response.json(this.toJSON(), { status: 401, headers })\n }\n\n /**\n * Creates a LexServerAuthError from an existing LexError.\n *\n * If the input is already a LexServerAuthError, returns it unchanged.\n * Otherwise, wraps the error with the provided WWW-Authenticate parameters.\n *\n * @param cause - The original LexError to wrap\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @returns A LexServerAuthError instance\n *\n * @example\n * ```typescript\n * const lexError = new LexError('AuthenticationRequired', 'Token expired')\n * const authError = LexServerAuthError.from(lexError, {\n * Bearer: { error: 'ExpiredToken' }\n * })\n * ```\n */\n static from(\n cause: LexError,\n wwwAuthenticate?: WWWAuthenticate,\n ): LexServerAuthError {\n if (cause instanceof LexServerAuthError) return cause\n return new LexServerAuthError(cause.error, cause.message, wwwAuthenticate, {\n cause,\n })\n }\n}\n"]}