@metamask-previews/json-rpc-engine 10.1.1-preview-317c0a9f → 10.1.1-preview-c96ff8f

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 (59) hide show
  1. package/CHANGELOG.md +2 -3
  2. package/README.md +27 -0
  3. package/dist/asV2Middleware.cjs +8 -3
  4. package/dist/asV2Middleware.cjs.map +1 -1
  5. package/dist/asV2Middleware.d.cts +1 -1
  6. package/dist/asV2Middleware.d.cts.map +1 -1
  7. package/dist/asV2Middleware.d.mts +1 -1
  8. package/dist/asV2Middleware.d.mts.map +1 -1
  9. package/dist/asV2Middleware.mjs +9 -4
  10. package/dist/asV2Middleware.mjs.map +1 -1
  11. package/dist/v2/JsonRpcEngineV2.cjs +5 -2
  12. package/dist/v2/JsonRpcEngineV2.cjs.map +1 -1
  13. package/dist/v2/JsonRpcEngineV2.d.cts +18 -5
  14. package/dist/v2/JsonRpcEngineV2.d.cts.map +1 -1
  15. package/dist/v2/JsonRpcEngineV2.d.mts +18 -5
  16. package/dist/v2/JsonRpcEngineV2.d.mts.map +1 -1
  17. package/dist/v2/JsonRpcEngineV2.mjs +5 -2
  18. package/dist/v2/JsonRpcEngineV2.mjs.map +1 -1
  19. package/dist/v2/JsonRpcServer.cjs +5 -6
  20. package/dist/v2/JsonRpcServer.cjs.map +1 -1
  21. package/dist/v2/JsonRpcServer.d.cts +12 -6
  22. package/dist/v2/JsonRpcServer.d.cts.map +1 -1
  23. package/dist/v2/JsonRpcServer.d.mts +12 -6
  24. package/dist/v2/JsonRpcServer.d.mts.map +1 -1
  25. package/dist/v2/JsonRpcServer.mjs +5 -6
  26. package/dist/v2/JsonRpcServer.mjs.map +1 -1
  27. package/dist/v2/MiddlewareContext.cjs +42 -1
  28. package/dist/v2/MiddlewareContext.cjs.map +1 -1
  29. package/dist/v2/MiddlewareContext.d.cts +15 -2
  30. package/dist/v2/MiddlewareContext.d.cts.map +1 -1
  31. package/dist/v2/MiddlewareContext.d.mts +15 -2
  32. package/dist/v2/MiddlewareContext.d.mts.map +1 -1
  33. package/dist/v2/MiddlewareContext.mjs +42 -1
  34. package/dist/v2/MiddlewareContext.mjs.map +1 -1
  35. package/dist/v2/compatibility-utils.cjs +3 -3
  36. package/dist/v2/compatibility-utils.cjs.map +1 -1
  37. package/dist/v2/compatibility-utils.d.cts +1 -1
  38. package/dist/v2/compatibility-utils.d.mts +1 -1
  39. package/dist/v2/compatibility-utils.mjs +1 -1
  40. package/dist/v2/compatibility-utils.mjs.map +1 -1
  41. package/dist/v2/createScaffoldMiddleware.cjs.map +1 -1
  42. package/dist/v2/createScaffoldMiddleware.d.cts +12 -3
  43. package/dist/v2/createScaffoldMiddleware.d.cts.map +1 -1
  44. package/dist/v2/createScaffoldMiddleware.d.mts +12 -3
  45. package/dist/v2/createScaffoldMiddleware.d.mts.map +1 -1
  46. package/dist/v2/createScaffoldMiddleware.mjs.map +1 -1
  47. package/dist/v2/index.cjs.map +1 -1
  48. package/dist/v2/index.d.cts +2 -2
  49. package/dist/v2/index.d.cts.map +1 -1
  50. package/dist/v2/index.d.mts +2 -2
  51. package/dist/v2/index.d.mts.map +1 -1
  52. package/dist/v2/index.mjs.map +1 -1
  53. package/dist/v2/utils.cjs +2 -2
  54. package/dist/v2/utils.cjs.map +1 -1
  55. package/dist/v2/utils.d.cts.map +1 -1
  56. package/dist/v2/utils.d.mts.map +1 -1
  57. package/dist/v2/utils.mjs +2 -2
  58. package/dist/v2/utils.mjs.map +1 -1
  59. package/package.json +3 -1
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _JsonRpcServer_instances, _JsonRpcServer_engine, _JsonRpcServer_onError, _JsonRpcServer_coerceRequest;
13
+ var _a, _JsonRpcServer_engine, _JsonRpcServer_onError, _JsonRpcServer_coerceRequest;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.JsonRpcServer = void 0;
16
16
  const rpc_errors_1 = require("@metamask/rpc-errors");
@@ -57,7 +57,6 @@ class JsonRpcServer {
57
57
  * `engine`.
58
58
  */
59
59
  constructor(options) {
60
- _JsonRpcServer_instances.add(this);
61
60
  _JsonRpcServer_engine.set(this, void 0);
62
61
  _JsonRpcServer_onError.set(this, void 0);
63
62
  __classPrivateFieldSet(this, _JsonRpcServer_onError, options.onError, "f");
@@ -70,16 +69,16 @@ class JsonRpcServer {
70
69
  __classPrivateFieldSet(this, _JsonRpcServer_engine, JsonRpcEngineV2_1.JsonRpcEngineV2.create({ middleware: options.middleware }), "f");
71
70
  }
72
71
  }
73
- async handle(rawRequest) {
72
+ async handle(rawRequest, options) {
74
73
  // If rawRequest is not a notification, the originalId will be attached
75
74
  // to the response. We attach our own, trusted id in #coerceRequest()
76
75
  // while the request is being handled.
77
76
  const [originalId, isRequest] = getOriginalId(rawRequest);
78
77
  try {
79
- const request = __classPrivateFieldGet(this, _JsonRpcServer_instances, "m", _JsonRpcServer_coerceRequest).call(this, rawRequest, isRequest);
78
+ const request = __classPrivateFieldGet(_a, _a, "m", _JsonRpcServer_coerceRequest).call(_a, rawRequest, isRequest);
80
79
  // @ts-expect-error - The request may not be of the type expected by the engine,
81
80
  // and we intentionally allow this to happen.
82
- const result = await __classPrivateFieldGet(this, _JsonRpcServer_engine, "f").handle(request);
81
+ const result = await __classPrivateFieldGet(this, _JsonRpcServer_engine, "f").handle(request, options);
83
82
  if (result !== undefined) {
84
83
  return {
85
84
  jsonrpc,
@@ -107,7 +106,7 @@ class JsonRpcServer {
107
106
  }
108
107
  }
109
108
  exports.JsonRpcServer = JsonRpcServer;
110
- _JsonRpcServer_engine = new WeakMap(), _JsonRpcServer_onError = new WeakMap(), _JsonRpcServer_instances = new WeakSet(), _JsonRpcServer_coerceRequest = function _JsonRpcServer_coerceRequest(rawRequest, isRequest) {
109
+ _a = JsonRpcServer, _JsonRpcServer_engine = new WeakMap(), _JsonRpcServer_onError = new WeakMap(), _JsonRpcServer_coerceRequest = function _JsonRpcServer_coerceRequest(rawRequest, isRequest) {
111
110
  if (!isMinimalRequest(rawRequest)) {
112
111
  throw rpc_errors_1.rpcErrors.invalidRequest({
113
112
  data: {
@@ -1 +1 @@
1
- {"version":3,"file":"JsonRpcServer.cjs","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type {\n JsonRpcNotification,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n NonEmptyArray,\n} from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport type {\n JsonRpcMiddleware,\n MergedContextOf,\n RequestOf,\n ResultConstraint,\n} from './JsonRpcEngineV2';\nimport { JsonRpcEngineV2 } from './JsonRpcEngineV2';\nimport type { JsonRpcCall } from './utils';\nimport { getUniqueId } from '../getUniqueId';\n\ntype OnError = (error: unknown) => void;\n\ntype Options<Middleware extends JsonRpcMiddleware> = {\n onError?: OnError;\n} & (\n | {\n engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;\n }\n | {\n middleware: NonEmptyArray<Middleware>;\n }\n);\n\nconst jsonrpc = '2.0' as const;\n\n/**\n * A JSON-RPC server that handles requests and notifications.\n *\n * Essentially wraps a {@link JsonRpcEngineV2} in order to create a conformant\n * yet permissive JSON-RPC 2.0 server.\n *\n * Note that the server will accept both requests and notifications via {@link handle},\n * even if the underlying engine is only able to handle one or the other.\n *\n * @example\n * ```ts\n * const server = new JsonRpcServer({\n * engine,\n * onError,\n * });\n *\n * const response = await server.handle(request);\n * if ('result' in response) {\n * // Handle result\n * } else {\n * // Handle error\n * }\n * ```\n */\nexport class JsonRpcServer<\n Middleware extends JsonRpcMiddleware<\n // Non-polluting `any` constraint.\n /* eslint-disable @typescript-eslint/no-explicit-any */\n any,\n ResultConstraint<any>,\n any\n /* eslint-enable @typescript-eslint/no-explicit-any */\n > = JsonRpcMiddleware,\n> {\n readonly #engine: JsonRpcEngineV2<\n RequestOf<Middleware>,\n MergedContextOf<Middleware>\n >;\n\n readonly #onError?: OnError | undefined;\n\n /**\n * Construct a new JSON-RPC server.\n *\n * @param options - The options for the server.\n * @param options.onError - The callback to handle errors thrown by the\n * engine. Errors always result in a failed response object, containing a\n * JSON-RPC 2.0 serialized version of the original error. If you need to\n * access the original error, use the `onError` callback.\n * @param options.engine - The engine to use. Mutually exclusive with\n * `middleware`.\n * @param options.middleware - The middleware to use. Mutually exclusive with\n * `engine`.\n */\n constructor(options: Options<Middleware>) {\n this.#onError = options.onError;\n\n if (hasProperty(options, 'engine')) {\n // @ts-expect-error - hasProperty fails to narrow the type.\n this.#engine = options.engine;\n } else {\n // @ts-expect-error - TypeScript complains that engine is of the wrong type, but clearly it's not.\n this.#engine = JsonRpcEngineV2.create({ middleware: options.middleware });\n }\n }\n\n /**\n * Handle a JSON-RPC request.\n *\n * This method never throws. For requests, a response is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine can only handle notifications.\n *\n * @param request - The request to handle.\n * @returns The JSON-RPC response.\n */\n async handle(request: JsonRpcRequest): Promise<JsonRpcResponse>;\n\n /**\n * Handle a JSON-RPC notification.\n *\n * This method never throws. For notifications, `undefined` is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine cannot handle notifications.\n *\n * @param notification - The notification to handle.\n */\n async handle(notification: JsonRpcNotification): Promise<void>;\n\n /**\n * Handle an alleged JSON-RPC request or notification. Permits any plain\n * object with `{ method: string }`, so long as any present JSON-RPC 2.0\n * properties are valid. If the object has an `id` property, it will be\n * treated as a request, otherwise it will be treated as a notification.\n *\n * This method never throws. All errors are passed to the engine's\n * `onError` callback. A JSON-RPC response is always returned for requests,\n * and `undefined` is returned for notifications.\n *\n * **WARNING**: The request will fail if its coerced type (i.e. request or\n * response) is not of the type expected by the underlying engine.\n *\n * @param rawRequest - The raw request to handle.\n * @returns The JSON-RPC response, or `undefined` if the request is a\n * notification.\n */\n async handle(rawRequest: unknown): Promise<JsonRpcResponse | void>;\n\n async handle(rawRequest: unknown): Promise<JsonRpcResponse | void> {\n // If rawRequest is not a notification, the originalId will be attached\n // to the response. We attach our own, trusted id in #coerceRequest()\n // while the request is being handled.\n const [originalId, isRequest] = getOriginalId(rawRequest);\n\n try {\n const request = this.#coerceRequest(rawRequest, isRequest);\n // @ts-expect-error - The request may not be of the type expected by the engine,\n // and we intentionally allow this to happen.\n const result = await this.#engine.handle(request);\n\n if (result !== undefined) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n result,\n };\n }\n } catch (error) {\n this.#onError?.(error);\n\n if (isRequest) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n error: serializeError(error, {\n shouldIncludeStack: false,\n shouldPreserveMessage: true,\n }),\n };\n }\n }\n return undefined;\n }\n\n #coerceRequest(rawRequest: unknown, isRequest: boolean): JsonRpcCall {\n if (!isMinimalRequest(rawRequest)) {\n throw rpcErrors.invalidRequest({\n data: {\n request: rawRequest,\n },\n });\n }\n\n const request: JsonRpcCall = {\n jsonrpc,\n method: rawRequest.method,\n };\n\n if (hasProperty(rawRequest, 'params')) {\n request.params = rawRequest.params as JsonRpcParams;\n }\n\n if (isRequest) {\n (request as JsonRpcRequest).id = getUniqueId();\n }\n\n return request;\n }\n}\n\n/**\n * The most minimally conformant request object that we will accept.\n */\ntype MinimalRequest = {\n method: string;\n params?: JsonRpcParams;\n} & Record<string, unknown>;\n\n/**\n * Check if an unvalidated request is a minimal request.\n *\n * @param rawRequest - The raw request to check.\n * @returns `true` if the request is a {@link MinimalRequest}, `false` otherwise.\n */\nfunction isMinimalRequest(rawRequest: unknown): rawRequest is MinimalRequest {\n return (\n isObject(rawRequest) &&\n hasProperty(rawRequest, 'method') &&\n typeof rawRequest.method === 'string' &&\n hasValidParams(rawRequest)\n );\n}\n\n/**\n * Check if a request has valid params, i.e. an array or object.\n * The contents of the params are not inspected.\n *\n * @param rawRequest - The request to check.\n * @returns `true` if the request has valid params, `false` otherwise.\n */\nfunction hasValidParams(\n rawRequest: Record<string, unknown>,\n): rawRequest is { params?: JsonRpcParams } {\n if (hasProperty(rawRequest, 'params')) {\n return Array.isArray(rawRequest.params) || isObject(rawRequest.params);\n }\n return true;\n}\n\n/**\n * Get the original id from a request.\n *\n * @param rawRequest - The request to get the original id from.\n * @returns The original id and a boolean indicating if the request is a request\n * (as opposed to a notification).\n */\nfunction getOriginalId(rawRequest: unknown): [unknown, boolean] {\n if (isObject(rawRequest) && hasProperty(rawRequest, 'id')) {\n return [rawRequest.id, true];\n }\n return [undefined, false];\n}\n"]}
1
+ {"version":3,"file":"JsonRpcServer.cjs","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type {\n JsonRpcNotification,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n NonEmptyArray,\n} from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport type {\n HandleOptions,\n JsonRpcMiddleware,\n MergedContextOf,\n MiddlewareConstraint,\n RequestOf,\n} from './JsonRpcEngineV2';\nimport { JsonRpcEngineV2 } from './JsonRpcEngineV2';\nimport type { JsonRpcCall } from './utils';\nimport { getUniqueId } from '../getUniqueId';\n\ntype OnError = (error: unknown) => void;\n\ntype Options<Middleware extends MiddlewareConstraint> = {\n onError?: OnError;\n} & (\n | {\n engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;\n }\n | {\n middleware: NonEmptyArray<Middleware>;\n }\n);\n\nconst jsonrpc = '2.0' as const;\n\n/**\n * A JSON-RPC server that handles requests and notifications.\n *\n * Essentially wraps a {@link JsonRpcEngineV2} in order to create a conformant\n * yet permissive JSON-RPC 2.0 server.\n *\n * Note that the server will accept both requests and notifications via {@link handle},\n * even if the underlying engine is only able to handle one or the other.\n *\n * @example\n * ```ts\n * const server = new JsonRpcServer({\n * engine,\n * onError,\n * });\n *\n * const response = await server.handle(request);\n * if ('result' in response) {\n * // Handle result\n * } else {\n * // Handle error\n * }\n * ```\n */\nexport class JsonRpcServer<\n Middleware extends MiddlewareConstraint = JsonRpcMiddleware,\n> {\n readonly #engine: JsonRpcEngineV2<\n RequestOf<Middleware>,\n MergedContextOf<Middleware>\n >;\n\n readonly #onError?: OnError | undefined;\n\n /**\n * Construct a new JSON-RPC server.\n *\n * @param options - The options for the server.\n * @param options.onError - The callback to handle errors thrown by the\n * engine. Errors always result in a failed response object, containing a\n * JSON-RPC 2.0 serialized version of the original error. If you need to\n * access the original error, use the `onError` callback.\n * @param options.engine - The engine to use. Mutually exclusive with\n * `middleware`.\n * @param options.middleware - The middleware to use. Mutually exclusive with\n * `engine`.\n */\n constructor(options: Options<Middleware>) {\n this.#onError = options.onError;\n\n if (hasProperty(options, 'engine')) {\n // @ts-expect-error - hasProperty fails to narrow the type.\n this.#engine = options.engine;\n } else {\n // @ts-expect-error - TypeScript complains that engine is of the wrong type, but clearly it's not.\n this.#engine = JsonRpcEngineV2.create({ middleware: options.middleware });\n }\n }\n\n /**\n * Handle a JSON-RPC request.\n *\n * This method never throws. For requests, a response is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine can only handle notifications.\n *\n * @param request - The request to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n * @returns The JSON-RPC response.\n */\n async handle(\n request: JsonRpcRequest,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse>;\n\n /**\n * Handle a JSON-RPC notification.\n *\n * This method never throws. For notifications, `undefined` is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine cannot handle notifications.\n *\n * @param notification - The notification to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n */\n async handle(\n notification: JsonRpcNotification,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<void>;\n\n /**\n * Handle an alleged JSON-RPC request or notification. Permits any plain\n * object with `{ method: string }`, so long as any present JSON-RPC 2.0\n * properties are valid. If the object has an `id` property, it will be\n * treated as a request, otherwise it will be treated as a notification.\n *\n * This method never throws. All errors are passed to the engine's\n * `onError` callback. A JSON-RPC response is always returned for requests,\n * and `undefined` is returned for notifications.\n *\n * **WARNING**: The request will fail if its coerced type (i.e. request or\n * response) is not of the type expected by the underlying engine.\n *\n * @param rawRequest - The raw request to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n * @returns The JSON-RPC response, or `undefined` if the request is a\n * notification.\n */\n async handle(\n rawRequest: unknown,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse | void>;\n\n async handle(\n rawRequest: unknown,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse | void> {\n // If rawRequest is not a notification, the originalId will be attached\n // to the response. We attach our own, trusted id in #coerceRequest()\n // while the request is being handled.\n const [originalId, isRequest] = getOriginalId(rawRequest);\n\n try {\n const request = JsonRpcServer.#coerceRequest(rawRequest, isRequest);\n // @ts-expect-error - The request may not be of the type expected by the engine,\n // and we intentionally allow this to happen.\n const result = await this.#engine.handle(request, options);\n\n if (result !== undefined) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n result,\n };\n }\n } catch (error) {\n this.#onError?.(error);\n\n if (isRequest) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n error: serializeError(error, {\n shouldIncludeStack: false,\n shouldPreserveMessage: true,\n }),\n };\n }\n }\n return undefined;\n }\n\n static #coerceRequest(rawRequest: unknown, isRequest: boolean): JsonRpcCall {\n if (!isMinimalRequest(rawRequest)) {\n throw rpcErrors.invalidRequest({\n data: {\n request: rawRequest,\n },\n });\n }\n\n const request: JsonRpcCall = {\n jsonrpc,\n method: rawRequest.method,\n };\n\n if (hasProperty(rawRequest, 'params')) {\n request.params = rawRequest.params as JsonRpcParams;\n }\n\n if (isRequest) {\n (request as JsonRpcRequest).id = getUniqueId();\n }\n\n return request;\n }\n}\n\n/**\n * The most minimally conformant request object that we will accept.\n */\ntype MinimalRequest = {\n method: string;\n params?: JsonRpcParams;\n} & Record<string, unknown>;\n\n/**\n * Check if an unvalidated request is a minimal request.\n *\n * @param rawRequest - The raw request to check.\n * @returns `true` if the request is a {@link MinimalRequest}, `false` otherwise.\n */\nfunction isMinimalRequest(rawRequest: unknown): rawRequest is MinimalRequest {\n return (\n isObject(rawRequest) &&\n hasProperty(rawRequest, 'method') &&\n typeof rawRequest.method === 'string' &&\n hasValidParams(rawRequest)\n );\n}\n\n/**\n * Check if a request has valid params, i.e. an array or object.\n * The contents of the params are not inspected.\n *\n * @param rawRequest - The request to check.\n * @returns `true` if the request has valid params, `false` otherwise.\n */\nfunction hasValidParams(\n rawRequest: Record<string, unknown>,\n): rawRequest is { params?: JsonRpcParams } {\n if (hasProperty(rawRequest, 'params')) {\n return Array.isArray(rawRequest.params) || isObject(rawRequest.params);\n }\n return true;\n}\n\n/**\n * Get the original id from a request.\n *\n * @param rawRequest - The request to get the original id from.\n * @returns The original id and a boolean indicating if the request is a request\n * (as opposed to a notification).\n */\nfunction getOriginalId(rawRequest: unknown): [unknown, boolean] {\n if (isObject(rawRequest) && hasProperty(rawRequest, 'id')) {\n return [rawRequest.id, true];\n }\n return [undefined, false];\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import type { JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, NonEmptyArray } from "@metamask/utils";
2
- import type { JsonRpcMiddleware, ResultConstraint } from "./JsonRpcEngineV2.cjs";
2
+ import type { HandleOptions, JsonRpcMiddleware, MergedContextOf, MiddlewareConstraint } from "./JsonRpcEngineV2.cjs";
3
3
  import { JsonRpcEngineV2 } from "./JsonRpcEngineV2.cjs";
4
4
  type OnError = (error: unknown) => void;
5
- type Options<Middleware extends JsonRpcMiddleware> = {
5
+ type Options<Middleware extends MiddlewareConstraint> = {
6
6
  onError?: OnError;
7
7
  } & ({
8
8
  engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;
@@ -33,7 +33,7 @@ type Options<Middleware extends JsonRpcMiddleware> = {
33
33
  * }
34
34
  * ```
35
35
  */
36
- export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, ResultConstraint<any>, any> = JsonRpcMiddleware> {
36
+ export declare class JsonRpcServer<Middleware extends MiddlewareConstraint = JsonRpcMiddleware> {
37
37
  #private;
38
38
  /**
39
39
  * Construct a new JSON-RPC server.
@@ -59,9 +59,11 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
59
59
  * engine. The request will fail if the engine can only handle notifications.
60
60
  *
61
61
  * @param request - The request to handle.
62
+ * @param options - The options for the handle operation.
63
+ * @param options.context - The context to pass to the middleware.
62
64
  * @returns The JSON-RPC response.
63
65
  */
64
- handle(request: JsonRpcRequest): Promise<JsonRpcResponse>;
66
+ handle(request: JsonRpcRequest, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<JsonRpcResponse>;
65
67
  /**
66
68
  * Handle a JSON-RPC notification.
67
69
  *
@@ -72,8 +74,10 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
72
74
  * engine. The request will fail if the engine cannot handle notifications.
73
75
  *
74
76
  * @param notification - The notification to handle.
77
+ * @param options - The options for the handle operation.
78
+ * @param options.context - The context to pass to the middleware.
75
79
  */
76
- handle(notification: JsonRpcNotification): Promise<void>;
80
+ handle(notification: JsonRpcNotification, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<void>;
77
81
  /**
78
82
  * Handle an alleged JSON-RPC request or notification. Permits any plain
79
83
  * object with `{ method: string }`, so long as any present JSON-RPC 2.0
@@ -88,10 +92,12 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
88
92
  * response) is not of the type expected by the underlying engine.
89
93
  *
90
94
  * @param rawRequest - The raw request to handle.
95
+ * @param options - The options for the handle operation.
96
+ * @param options.context - The context to pass to the middleware.
91
97
  * @returns The JSON-RPC response, or `undefined` if the request is a
92
98
  * notification.
93
99
  */
94
- handle(rawRequest: unknown): Promise<JsonRpcResponse | void>;
100
+ handle(rawRequest: unknown, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<JsonRpcResponse | void>;
95
101
  }
96
102
  export {};
97
103
  //# sourceMappingURL=JsonRpcServer.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonRpcServer.d.cts","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAEnB,cAAc,EACd,eAAe,EACf,aAAa,EACd,wBAAwB;AAGzB,OAAO,KAAK,EACV,iBAAiB,EAGjB,gBAAgB,EACjB,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAIpD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAExC,KAAK,OAAO,CAAC,UAAU,SAAS,iBAAiB,IAAI;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/D,GACD;IACE,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACvC,CACJ,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAa,CACxB,UAAU,SAAS,iBAAiB,CAGlC,GAAG,EACH,gBAAgB,CAAC,GAAG,CAAC,EACrB,GAAG,CAEJ,GAAG,iBAAiB;;IASrB;;;;;;;;;;;;OAYG;gBACS,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;IAYxC;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAE/D;;;;;;;;;;OAUG;IACG,MAAM,CAAC,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9D;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAgEnE"}
1
+ {"version":3,"file":"JsonRpcServer.d.cts","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAEnB,cAAc,EACd,eAAe,EACf,aAAa,EACd,wBAAwB;AAGzB,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAErB,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAIpD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAExC,KAAK,OAAO,CAAC,UAAU,SAAS,oBAAoB,IAAI;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/D,GACD;IACE,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACvC,CACJ,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAa,CACxB,UAAU,SAAS,oBAAoB,GAAG,iBAAiB;;IAS3D;;;;;;;;;;;;OAYG;gBACS,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;IAYxC;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,eAAe,CAAC;IAE3B;;;;;;;;;;;;OAYG;IACG,MAAM,CACV,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;;;;;;;;;;;;;OAkBG;IACG,MAAM,CACV,UAAU,EAAE,OAAO,EACnB,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAmEnC"}
@@ -1,8 +1,8 @@
1
1
  import type { JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, NonEmptyArray } from "@metamask/utils";
2
- import type { JsonRpcMiddleware, ResultConstraint } from "./JsonRpcEngineV2.mjs";
2
+ import type { HandleOptions, JsonRpcMiddleware, MergedContextOf, MiddlewareConstraint } from "./JsonRpcEngineV2.mjs";
3
3
  import { JsonRpcEngineV2 } from "./JsonRpcEngineV2.mjs";
4
4
  type OnError = (error: unknown) => void;
5
- type Options<Middleware extends JsonRpcMiddleware> = {
5
+ type Options<Middleware extends MiddlewareConstraint> = {
6
6
  onError?: OnError;
7
7
  } & ({
8
8
  engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;
@@ -33,7 +33,7 @@ type Options<Middleware extends JsonRpcMiddleware> = {
33
33
  * }
34
34
  * ```
35
35
  */
36
- export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, ResultConstraint<any>, any> = JsonRpcMiddleware> {
36
+ export declare class JsonRpcServer<Middleware extends MiddlewareConstraint = JsonRpcMiddleware> {
37
37
  #private;
38
38
  /**
39
39
  * Construct a new JSON-RPC server.
@@ -59,9 +59,11 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
59
59
  * engine. The request will fail if the engine can only handle notifications.
60
60
  *
61
61
  * @param request - The request to handle.
62
+ * @param options - The options for the handle operation.
63
+ * @param options.context - The context to pass to the middleware.
62
64
  * @returns The JSON-RPC response.
63
65
  */
64
- handle(request: JsonRpcRequest): Promise<JsonRpcResponse>;
66
+ handle(request: JsonRpcRequest, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<JsonRpcResponse>;
65
67
  /**
66
68
  * Handle a JSON-RPC notification.
67
69
  *
@@ -72,8 +74,10 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
72
74
  * engine. The request will fail if the engine cannot handle notifications.
73
75
  *
74
76
  * @param notification - The notification to handle.
77
+ * @param options - The options for the handle operation.
78
+ * @param options.context - The context to pass to the middleware.
75
79
  */
76
- handle(notification: JsonRpcNotification): Promise<void>;
80
+ handle(notification: JsonRpcNotification, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<void>;
77
81
  /**
78
82
  * Handle an alleged JSON-RPC request or notification. Permits any plain
79
83
  * object with `{ method: string }`, so long as any present JSON-RPC 2.0
@@ -88,10 +92,12 @@ export declare class JsonRpcServer<Middleware extends JsonRpcMiddleware<any, Res
88
92
  * response) is not of the type expected by the underlying engine.
89
93
  *
90
94
  * @param rawRequest - The raw request to handle.
95
+ * @param options - The options for the handle operation.
96
+ * @param options.context - The context to pass to the middleware.
91
97
  * @returns The JSON-RPC response, or `undefined` if the request is a
92
98
  * notification.
93
99
  */
94
- handle(rawRequest: unknown): Promise<JsonRpcResponse | void>;
100
+ handle(rawRequest: unknown, options?: HandleOptions<MergedContextOf<Middleware>>): Promise<JsonRpcResponse | void>;
95
101
  }
96
102
  export {};
97
103
  //# sourceMappingURL=JsonRpcServer.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonRpcServer.d.mts","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAEnB,cAAc,EACd,eAAe,EACf,aAAa,EACd,wBAAwB;AAGzB,OAAO,KAAK,EACV,iBAAiB,EAGjB,gBAAgB,EACjB,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAIpD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAExC,KAAK,OAAO,CAAC,UAAU,SAAS,iBAAiB,IAAI;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/D,GACD;IACE,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACvC,CACJ,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAa,CACxB,UAAU,SAAS,iBAAiB,CAGlC,GAAG,EACH,gBAAgB,CAAC,GAAG,CAAC,EACrB,GAAG,CAEJ,GAAG,iBAAiB;;IASrB;;;;;;;;;;;;OAYG;gBACS,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;IAYxC;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAE/D;;;;;;;;;;OAUG;IACG,MAAM,CAAC,YAAY,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9D;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAgEnE"}
1
+ {"version":3,"file":"JsonRpcServer.d.mts","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EAEnB,cAAc,EACd,eAAe,EACf,aAAa,EACd,wBAAwB;AAGzB,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAErB,8BAA0B;AAC3B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAIpD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAExC,KAAK,OAAO,CAAC,UAAU,SAAS,oBAAoB,IAAI;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/D,GACD;IACE,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACvC,CACJ,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,aAAa,CACxB,UAAU,SAAS,oBAAoB,GAAG,iBAAiB;;IAS3D;;;;;;;;;;;;OAYG;gBACS,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;IAYxC;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,eAAe,CAAC;IAE3B;;;;;;;;;;;;OAYG;IACG,MAAM,CACV,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;;;;;;;;;;;;;OAkBG;IACG,MAAM,CACV,UAAU,EAAE,OAAO,EACnB,OAAO,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GACnD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAmEnC"}
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _JsonRpcServer_instances, _JsonRpcServer_engine, _JsonRpcServer_onError, _JsonRpcServer_coerceRequest;
12
+ var _a, _JsonRpcServer_engine, _JsonRpcServer_onError, _JsonRpcServer_coerceRequest;
13
13
  import { rpcErrors, serializeError } from "@metamask/rpc-errors";
14
14
  import { hasProperty, isObject } from "@metamask/utils";
15
15
  import { JsonRpcEngineV2 } from "./JsonRpcEngineV2.mjs";
@@ -54,7 +54,6 @@ export class JsonRpcServer {
54
54
  * `engine`.
55
55
  */
56
56
  constructor(options) {
57
- _JsonRpcServer_instances.add(this);
58
57
  _JsonRpcServer_engine.set(this, void 0);
59
58
  _JsonRpcServer_onError.set(this, void 0);
60
59
  __classPrivateFieldSet(this, _JsonRpcServer_onError, options.onError, "f");
@@ -67,16 +66,16 @@ export class JsonRpcServer {
67
66
  __classPrivateFieldSet(this, _JsonRpcServer_engine, JsonRpcEngineV2.create({ middleware: options.middleware }), "f");
68
67
  }
69
68
  }
70
- async handle(rawRequest) {
69
+ async handle(rawRequest, options) {
71
70
  // If rawRequest is not a notification, the originalId will be attached
72
71
  // to the response. We attach our own, trusted id in #coerceRequest()
73
72
  // while the request is being handled.
74
73
  const [originalId, isRequest] = getOriginalId(rawRequest);
75
74
  try {
76
- const request = __classPrivateFieldGet(this, _JsonRpcServer_instances, "m", _JsonRpcServer_coerceRequest).call(this, rawRequest, isRequest);
75
+ const request = __classPrivateFieldGet(_a, _a, "m", _JsonRpcServer_coerceRequest).call(_a, rawRequest, isRequest);
77
76
  // @ts-expect-error - The request may not be of the type expected by the engine,
78
77
  // and we intentionally allow this to happen.
79
- const result = await __classPrivateFieldGet(this, _JsonRpcServer_engine, "f").handle(request);
78
+ const result = await __classPrivateFieldGet(this, _JsonRpcServer_engine, "f").handle(request, options);
80
79
  if (result !== undefined) {
81
80
  return {
82
81
  jsonrpc,
@@ -103,7 +102,7 @@ export class JsonRpcServer {
103
102
  return undefined;
104
103
  }
105
104
  }
106
- _JsonRpcServer_engine = new WeakMap(), _JsonRpcServer_onError = new WeakMap(), _JsonRpcServer_instances = new WeakSet(), _JsonRpcServer_coerceRequest = function _JsonRpcServer_coerceRequest(rawRequest, isRequest) {
105
+ _a = JsonRpcServer, _JsonRpcServer_engine = new WeakMap(), _JsonRpcServer_onError = new WeakMap(), _JsonRpcServer_coerceRequest = function _JsonRpcServer_coerceRequest(rawRequest, isRequest) {
107
106
  if (!isMinimalRequest(rawRequest)) {
108
107
  throw rpcErrors.invalidRequest({
109
108
  data: {
@@ -1 +1 @@
1
- {"version":3,"file":"JsonRpcServer.mjs","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type {\n JsonRpcNotification,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n NonEmptyArray,\n} from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport type {\n JsonRpcMiddleware,\n MergedContextOf,\n RequestOf,\n ResultConstraint,\n} from './JsonRpcEngineV2';\nimport { JsonRpcEngineV2 } from './JsonRpcEngineV2';\nimport type { JsonRpcCall } from './utils';\nimport { getUniqueId } from '../getUniqueId';\n\ntype OnError = (error: unknown) => void;\n\ntype Options<Middleware extends JsonRpcMiddleware> = {\n onError?: OnError;\n} & (\n | {\n engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;\n }\n | {\n middleware: NonEmptyArray<Middleware>;\n }\n);\n\nconst jsonrpc = '2.0' as const;\n\n/**\n * A JSON-RPC server that handles requests and notifications.\n *\n * Essentially wraps a {@link JsonRpcEngineV2} in order to create a conformant\n * yet permissive JSON-RPC 2.0 server.\n *\n * Note that the server will accept both requests and notifications via {@link handle},\n * even if the underlying engine is only able to handle one or the other.\n *\n * @example\n * ```ts\n * const server = new JsonRpcServer({\n * engine,\n * onError,\n * });\n *\n * const response = await server.handle(request);\n * if ('result' in response) {\n * // Handle result\n * } else {\n * // Handle error\n * }\n * ```\n */\nexport class JsonRpcServer<\n Middleware extends JsonRpcMiddleware<\n // Non-polluting `any` constraint.\n /* eslint-disable @typescript-eslint/no-explicit-any */\n any,\n ResultConstraint<any>,\n any\n /* eslint-enable @typescript-eslint/no-explicit-any */\n > = JsonRpcMiddleware,\n> {\n readonly #engine: JsonRpcEngineV2<\n RequestOf<Middleware>,\n MergedContextOf<Middleware>\n >;\n\n readonly #onError?: OnError | undefined;\n\n /**\n * Construct a new JSON-RPC server.\n *\n * @param options - The options for the server.\n * @param options.onError - The callback to handle errors thrown by the\n * engine. Errors always result in a failed response object, containing a\n * JSON-RPC 2.0 serialized version of the original error. If you need to\n * access the original error, use the `onError` callback.\n * @param options.engine - The engine to use. Mutually exclusive with\n * `middleware`.\n * @param options.middleware - The middleware to use. Mutually exclusive with\n * `engine`.\n */\n constructor(options: Options<Middleware>) {\n this.#onError = options.onError;\n\n if (hasProperty(options, 'engine')) {\n // @ts-expect-error - hasProperty fails to narrow the type.\n this.#engine = options.engine;\n } else {\n // @ts-expect-error - TypeScript complains that engine is of the wrong type, but clearly it's not.\n this.#engine = JsonRpcEngineV2.create({ middleware: options.middleware });\n }\n }\n\n /**\n * Handle a JSON-RPC request.\n *\n * This method never throws. For requests, a response is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine can only handle notifications.\n *\n * @param request - The request to handle.\n * @returns The JSON-RPC response.\n */\n async handle(request: JsonRpcRequest): Promise<JsonRpcResponse>;\n\n /**\n * Handle a JSON-RPC notification.\n *\n * This method never throws. For notifications, `undefined` is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine cannot handle notifications.\n *\n * @param notification - The notification to handle.\n */\n async handle(notification: JsonRpcNotification): Promise<void>;\n\n /**\n * Handle an alleged JSON-RPC request or notification. Permits any plain\n * object with `{ method: string }`, so long as any present JSON-RPC 2.0\n * properties are valid. If the object has an `id` property, it will be\n * treated as a request, otherwise it will be treated as a notification.\n *\n * This method never throws. All errors are passed to the engine's\n * `onError` callback. A JSON-RPC response is always returned for requests,\n * and `undefined` is returned for notifications.\n *\n * **WARNING**: The request will fail if its coerced type (i.e. request or\n * response) is not of the type expected by the underlying engine.\n *\n * @param rawRequest - The raw request to handle.\n * @returns The JSON-RPC response, or `undefined` if the request is a\n * notification.\n */\n async handle(rawRequest: unknown): Promise<JsonRpcResponse | void>;\n\n async handle(rawRequest: unknown): Promise<JsonRpcResponse | void> {\n // If rawRequest is not a notification, the originalId will be attached\n // to the response. We attach our own, trusted id in #coerceRequest()\n // while the request is being handled.\n const [originalId, isRequest] = getOriginalId(rawRequest);\n\n try {\n const request = this.#coerceRequest(rawRequest, isRequest);\n // @ts-expect-error - The request may not be of the type expected by the engine,\n // and we intentionally allow this to happen.\n const result = await this.#engine.handle(request);\n\n if (result !== undefined) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n result,\n };\n }\n } catch (error) {\n this.#onError?.(error);\n\n if (isRequest) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n error: serializeError(error, {\n shouldIncludeStack: false,\n shouldPreserveMessage: true,\n }),\n };\n }\n }\n return undefined;\n }\n\n #coerceRequest(rawRequest: unknown, isRequest: boolean): JsonRpcCall {\n if (!isMinimalRequest(rawRequest)) {\n throw rpcErrors.invalidRequest({\n data: {\n request: rawRequest,\n },\n });\n }\n\n const request: JsonRpcCall = {\n jsonrpc,\n method: rawRequest.method,\n };\n\n if (hasProperty(rawRequest, 'params')) {\n request.params = rawRequest.params as JsonRpcParams;\n }\n\n if (isRequest) {\n (request as JsonRpcRequest).id = getUniqueId();\n }\n\n return request;\n }\n}\n\n/**\n * The most minimally conformant request object that we will accept.\n */\ntype MinimalRequest = {\n method: string;\n params?: JsonRpcParams;\n} & Record<string, unknown>;\n\n/**\n * Check if an unvalidated request is a minimal request.\n *\n * @param rawRequest - The raw request to check.\n * @returns `true` if the request is a {@link MinimalRequest}, `false` otherwise.\n */\nfunction isMinimalRequest(rawRequest: unknown): rawRequest is MinimalRequest {\n return (\n isObject(rawRequest) &&\n hasProperty(rawRequest, 'method') &&\n typeof rawRequest.method === 'string' &&\n hasValidParams(rawRequest)\n );\n}\n\n/**\n * Check if a request has valid params, i.e. an array or object.\n * The contents of the params are not inspected.\n *\n * @param rawRequest - The request to check.\n * @returns `true` if the request has valid params, `false` otherwise.\n */\nfunction hasValidParams(\n rawRequest: Record<string, unknown>,\n): rawRequest is { params?: JsonRpcParams } {\n if (hasProperty(rawRequest, 'params')) {\n return Array.isArray(rawRequest.params) || isObject(rawRequest.params);\n }\n return true;\n}\n\n/**\n * Get the original id from a request.\n *\n * @param rawRequest - The request to get the original id from.\n * @returns The original id and a boolean indicating if the request is a request\n * (as opposed to a notification).\n */\nfunction getOriginalId(rawRequest: unknown): [unknown, boolean] {\n if (isObject(rawRequest) && hasProperty(rawRequest, 'id')) {\n return [rawRequest.id, true];\n }\n return [undefined, false];\n}\n"]}
1
+ {"version":3,"file":"JsonRpcServer.mjs","sourceRoot":"","sources":["../../src/v2/JsonRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors, serializeError } from '@metamask/rpc-errors';\nimport type {\n JsonRpcNotification,\n JsonRpcParams,\n JsonRpcRequest,\n JsonRpcResponse,\n NonEmptyArray,\n} from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport type {\n HandleOptions,\n JsonRpcMiddleware,\n MergedContextOf,\n MiddlewareConstraint,\n RequestOf,\n} from './JsonRpcEngineV2';\nimport { JsonRpcEngineV2 } from './JsonRpcEngineV2';\nimport type { JsonRpcCall } from './utils';\nimport { getUniqueId } from '../getUniqueId';\n\ntype OnError = (error: unknown) => void;\n\ntype Options<Middleware extends MiddlewareConstraint> = {\n onError?: OnError;\n} & (\n | {\n engine: ReturnType<typeof JsonRpcEngineV2.create<Middleware>>;\n }\n | {\n middleware: NonEmptyArray<Middleware>;\n }\n);\n\nconst jsonrpc = '2.0' as const;\n\n/**\n * A JSON-RPC server that handles requests and notifications.\n *\n * Essentially wraps a {@link JsonRpcEngineV2} in order to create a conformant\n * yet permissive JSON-RPC 2.0 server.\n *\n * Note that the server will accept both requests and notifications via {@link handle},\n * even if the underlying engine is only able to handle one or the other.\n *\n * @example\n * ```ts\n * const server = new JsonRpcServer({\n * engine,\n * onError,\n * });\n *\n * const response = await server.handle(request);\n * if ('result' in response) {\n * // Handle result\n * } else {\n * // Handle error\n * }\n * ```\n */\nexport class JsonRpcServer<\n Middleware extends MiddlewareConstraint = JsonRpcMiddleware,\n> {\n readonly #engine: JsonRpcEngineV2<\n RequestOf<Middleware>,\n MergedContextOf<Middleware>\n >;\n\n readonly #onError?: OnError | undefined;\n\n /**\n * Construct a new JSON-RPC server.\n *\n * @param options - The options for the server.\n * @param options.onError - The callback to handle errors thrown by the\n * engine. Errors always result in a failed response object, containing a\n * JSON-RPC 2.0 serialized version of the original error. If you need to\n * access the original error, use the `onError` callback.\n * @param options.engine - The engine to use. Mutually exclusive with\n * `middleware`.\n * @param options.middleware - The middleware to use. Mutually exclusive with\n * `engine`.\n */\n constructor(options: Options<Middleware>) {\n this.#onError = options.onError;\n\n if (hasProperty(options, 'engine')) {\n // @ts-expect-error - hasProperty fails to narrow the type.\n this.#engine = options.engine;\n } else {\n // @ts-expect-error - TypeScript complains that engine is of the wrong type, but clearly it's not.\n this.#engine = JsonRpcEngineV2.create({ middleware: options.middleware });\n }\n }\n\n /**\n * Handle a JSON-RPC request.\n *\n * This method never throws. For requests, a response is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine can only handle notifications.\n *\n * @param request - The request to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n * @returns The JSON-RPC response.\n */\n async handle(\n request: JsonRpcRequest,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse>;\n\n /**\n * Handle a JSON-RPC notification.\n *\n * This method never throws. For notifications, `undefined` is always returned.\n * All errors are passed to the engine's `onError` callback.\n *\n * **WARNING**: This method is unaware of the request type of the underlying\n * engine. The request will fail if the engine cannot handle notifications.\n *\n * @param notification - The notification to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n */\n async handle(\n notification: JsonRpcNotification,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<void>;\n\n /**\n * Handle an alleged JSON-RPC request or notification. Permits any plain\n * object with `{ method: string }`, so long as any present JSON-RPC 2.0\n * properties are valid. If the object has an `id` property, it will be\n * treated as a request, otherwise it will be treated as a notification.\n *\n * This method never throws. All errors are passed to the engine's\n * `onError` callback. A JSON-RPC response is always returned for requests,\n * and `undefined` is returned for notifications.\n *\n * **WARNING**: The request will fail if its coerced type (i.e. request or\n * response) is not of the type expected by the underlying engine.\n *\n * @param rawRequest - The raw request to handle.\n * @param options - The options for the handle operation.\n * @param options.context - The context to pass to the middleware.\n * @returns The JSON-RPC response, or `undefined` if the request is a\n * notification.\n */\n async handle(\n rawRequest: unknown,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse | void>;\n\n async handle(\n rawRequest: unknown,\n options?: HandleOptions<MergedContextOf<Middleware>>,\n ): Promise<JsonRpcResponse | void> {\n // If rawRequest is not a notification, the originalId will be attached\n // to the response. We attach our own, trusted id in #coerceRequest()\n // while the request is being handled.\n const [originalId, isRequest] = getOriginalId(rawRequest);\n\n try {\n const request = JsonRpcServer.#coerceRequest(rawRequest, isRequest);\n // @ts-expect-error - The request may not be of the type expected by the engine,\n // and we intentionally allow this to happen.\n const result = await this.#engine.handle(request, options);\n\n if (result !== undefined) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n result,\n };\n }\n } catch (error) {\n this.#onError?.(error);\n\n if (isRequest) {\n return {\n jsonrpc,\n // @ts-expect-error - Reassign the original id, regardless of its type.\n id: originalId,\n error: serializeError(error, {\n shouldIncludeStack: false,\n shouldPreserveMessage: true,\n }),\n };\n }\n }\n return undefined;\n }\n\n static #coerceRequest(rawRequest: unknown, isRequest: boolean): JsonRpcCall {\n if (!isMinimalRequest(rawRequest)) {\n throw rpcErrors.invalidRequest({\n data: {\n request: rawRequest,\n },\n });\n }\n\n const request: JsonRpcCall = {\n jsonrpc,\n method: rawRequest.method,\n };\n\n if (hasProperty(rawRequest, 'params')) {\n request.params = rawRequest.params as JsonRpcParams;\n }\n\n if (isRequest) {\n (request as JsonRpcRequest).id = getUniqueId();\n }\n\n return request;\n }\n}\n\n/**\n * The most minimally conformant request object that we will accept.\n */\ntype MinimalRequest = {\n method: string;\n params?: JsonRpcParams;\n} & Record<string, unknown>;\n\n/**\n * Check if an unvalidated request is a minimal request.\n *\n * @param rawRequest - The raw request to check.\n * @returns `true` if the request is a {@link MinimalRequest}, `false` otherwise.\n */\nfunction isMinimalRequest(rawRequest: unknown): rawRequest is MinimalRequest {\n return (\n isObject(rawRequest) &&\n hasProperty(rawRequest, 'method') &&\n typeof rawRequest.method === 'string' &&\n hasValidParams(rawRequest)\n );\n}\n\n/**\n * Check if a request has valid params, i.e. an array or object.\n * The contents of the params are not inspected.\n *\n * @param rawRequest - The request to check.\n * @returns `true` if the request has valid params, `false` otherwise.\n */\nfunction hasValidParams(\n rawRequest: Record<string, unknown>,\n): rawRequest is { params?: JsonRpcParams } {\n if (hasProperty(rawRequest, 'params')) {\n return Array.isArray(rawRequest.params) || isObject(rawRequest.params);\n }\n return true;\n}\n\n/**\n * Get the original id from a request.\n *\n * @param rawRequest - The request to get the original id from.\n * @returns The original id and a boolean indicating if the request is a request\n * (as opposed to a notification).\n */\nfunction getOriginalId(rawRequest: unknown): [unknown, boolean] {\n if (isObject(rawRequest) && hasProperty(rawRequest, 'id')) {\n return [rawRequest.id, true];\n }\n return [undefined, false];\n}\n"]}
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
+ var _a;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.MiddlewareContext = void 0;
5
+ const utils_1 = require("@metamask/utils");
6
+ const MiddlewareContextSymbol = Symbol.for('json-rpc-engine#MiddlewareContext');
4
7
  /**
5
8
  * An context object for middleware that attempts to protect against accidental
6
9
  * modifications. Its interface is frozen.
@@ -26,8 +29,23 @@ exports.MiddlewareContext = void 0;
26
29
  * context.get('fizz'); // Type error
27
30
  */
28
31
  class MiddlewareContext extends Map {
32
+ /**
33
+ * Check if a value is a {@link MiddlewareContext} instance.
34
+ * Works across different package versions in the same realm.
35
+ *
36
+ * @param value - The value to check.
37
+ * @returns Whether the value is a {@link MiddlewareContext} instance.
38
+ */
39
+ static isInstance(value) {
40
+ return ((0, utils_1.isObject)(value) &&
41
+ MiddlewareContextSymbol in value &&
42
+ value[MiddlewareContextSymbol] === true);
43
+ }
29
44
  constructor(entries) {
30
- super(entries);
45
+ super(entries && isIterable(entries)
46
+ ? entries
47
+ : entriesFromKeyValues(entries ?? {}));
48
+ this[_a] = true;
31
49
  Object.freeze(this);
32
50
  }
33
51
  get(key) {
@@ -63,4 +81,27 @@ class MiddlewareContext extends Map {
63
81
  }
64
82
  }
65
83
  exports.MiddlewareContext = MiddlewareContext;
84
+ _a = MiddlewareContextSymbol;
85
+ /**
86
+ * {@link Iterable} type guard.
87
+ *
88
+ * @param value - The value to check.
89
+ * @returns Whether the value is an {@link Iterable}.
90
+ */
91
+ function isIterable(value) {
92
+ return Symbol.iterator in value;
93
+ }
94
+ /**
95
+ * Like Object.entries(), but includes symbol-keyed properties.
96
+ *
97
+ * @template KeyValues - The type of the keys and values in the object.
98
+ * @param keyValues - The object to convert.
99
+ * @returns The array of entries, including symbol-keyed properties.
100
+ */
101
+ function entriesFromKeyValues(keyValues) {
102
+ return Reflect.ownKeys(keyValues).map((key) => [
103
+ key,
104
+ keyValues[key],
105
+ ]);
106
+ }
66
107
  //# sourceMappingURL=MiddlewareContext.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MiddlewareContext.cjs","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAa,iBAEX,SAAQ,GAAgD;IACxD,YACE,OAA0E;QAE1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,GAAG,CAA4B,GAAM;QACnC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAA6B,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAA4B,GAAM;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SAC3D;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAiB,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,GAAG,CAA4B,GAAM,EAAE,KAAmB;QACxD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAClB,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;SAC1E;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA3CD,8CA2CC","sourcesContent":["import type { UnionToIntersection } from './utils';\n\n/**\n * An context object for middleware that attempts to protect against accidental\n * modifications. Its interface is frozen.\n *\n * Map keys may not be directly overridden with {@link set}. Instead, use\n * {@link delete} to remove a key and then {@link set} to add a new value.\n *\n * The override protections are circumvented when using e.g. `Reflect.set`, so\n * don't do that.\n *\n * @template KeyValues - The type of the keys and values in the context.\n * @example\n * // By default, the context permits any PropertyKey as a key.\n * const context = new MiddlewareContext();\n * context.set('foo', 'bar');\n * context.get('foo'); // 'bar'\n * context.get('fizz'); // undefined\n * @example\n * // By specifying an object type, the context permits only the keys of the object.\n * type Context = MiddlewareContext<{ foo: string }>;\n * const context = new Context([['foo', 'bar']]);\n * context.get('foo'); // 'bar'\n * context.get('fizz'); // Type error\n */\nexport class MiddlewareContext<\n KeyValues extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>,\n> extends Map<keyof KeyValues, KeyValues[keyof KeyValues]> {\n constructor(\n entries?: Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]>,\n ) {\n super(entries);\n Object.freeze(this);\n }\n\n get<K extends keyof KeyValues>(key: K): KeyValues[K] | undefined {\n return super.get(key) as KeyValues[K] | undefined;\n }\n\n /**\n * Get a value from the context. Throws if the key is not found.\n *\n * @param key - The key to get the value for.\n * @returns The value.\n */\n assertGet<K extends keyof KeyValues>(key: K): KeyValues[K] {\n if (!super.has(key)) {\n throw new Error(`Context key \"${String(key)}\" not found`);\n }\n return super.get(key) as KeyValues[K];\n }\n\n /**\n * Set a value in the context. Throws if the key already exists.\n * {@link delete} an existing key before setting it to a new value.\n *\n * @throws If the key already exists.\n * @param key - The key to set the value for.\n * @param value - The value to set.\n * @returns The context.\n */\n set<K extends keyof KeyValues>(key: K, value: KeyValues[K]): this {\n if (super.has(key)) {\n throw new Error(`MiddlewareContext key \"${String(key)}\" already exists`);\n }\n super.set(key, value);\n return this;\n }\n}\n\n/**\n * Infer the KeyValues type from a {@link MiddlewareContext}.\n */\ntype InferKeyValues<T> = T extends MiddlewareContext<infer U> ? U : never;\n\n/**\n * Simplifies an object type by \"merging\" its properties.\n *\n * - Expands intersections into a single object type.\n * - Forces mapped/conditional results to resolve into a readable shape.\n * - No runtime effect; purely a type-level normalization.\n *\n * @example\n * type A = { a: string } & { b: number };\n * type B = Simplify<A>; // { a: string; b: number }\n */\ntype Simplify<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;\n\n/**\n * Rejects record types that contain any `never`-valued property.\n *\n * If any property of `T` resolves to `never`, the result is `never`; otherwise it returns `T` unchanged.\n * Useful as a guard to ensure computed/merged record types didn't collapse any fields to `never`.\n *\n * @example\n * type A = ExcludeNever<{ a: string; b: never }>; // never\n * type B = ExcludeNever<{ a: string; b: number }>; // { a: string; b: number }\n */\ntype ExcludeNever<T extends Record<PropertyKey, unknown>> = {\n [K in keyof T]-?: [T[K]] extends [never] ? K : never;\n}[keyof T] extends never\n ? T\n : never;\n\n/**\n * Merge a union of {@link MiddlewareContext}s into a single {@link MiddlewareContext}\n * supertype.\n *\n * @param Contexts - The union of {@link MiddlewareContext}s to merge.\n * @returns The merged {@link MiddlewareContext} supertype.\n * @example\n * type A = MiddlewareContext<{ a: string }> | MiddlewareContext<{ b: number }>;\n * type B = MergeContexts<A>; // MiddlewareContext<{ a: string, b: number }>\n */\nexport type MergeContexts<Contexts extends ContextConstraint> =\n ExcludeNever<\n Simplify<UnionToIntersection<InferKeyValues<Contexts>>>\n > extends never\n ? never\n : MiddlewareContext<\n ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>>\n >;\n\n// Non-polluting `any` constraint.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ContextConstraint = MiddlewareContext<any>;\n\n/**\n * The empty context type, i.e. `MiddlewareContext<{}>`.\n */\n// The empty object type is literally an empty object in this context.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type EmptyContext = MiddlewareContext<{}>;\n"]}
1
+ {"version":3,"file":"MiddlewareContext.cjs","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":";;;;AAAA,2CAA2C;AAI3C,MAAM,uBAAuB,GAAG,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAa,iBAEX,SAAQ,GAAgD;IAGxD;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,KAAc;QAC9B,OAAO,CACL,IAAA,gBAAQ,EAAC,KAAK,CAAC;YACf,uBAAuB,IAAI,KAAK;YAChC,KAAK,CAAC,uBAAuB,CAAC,KAAK,IAAI,CACxC,CAAC;IACJ,CAAC;IAED,YACE,OAEa;QAEb,KAAK,CACH,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC;YAC5B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,oBAAoB,CAAC,OAAO,IAAI,EAAE,CAAC,CACxC,CAAC;QA1Ba,QAAyB,GAAG,IAAI,CAAC;QA2BhD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,GAAG,CAA4B,GAAM;QACnC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAA6B,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAA4B,GAAM;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SAC3D;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAiB,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,GAAG,CAA4B,GAAM,EAAE,KAAmB;QACxD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAClB,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;SAC1E;QACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAlED,8CAkEC;KA/DmB,uBAAuB;AAiE3C;;;;;GAKG;AACH,SAAS,UAAU,CACjB,KAAuD;IAEvD,OAAO,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAC3B,SAAoB;IAEpB,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAoB,EAAE,EAAE,CAAC;QAC9D,GAAG;QACH,SAAS,CAAC,GAAG,CAAC;KACf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { isObject } from '@metamask/utils';\n\nimport type { UnionToIntersection } from './utils';\n\nconst MiddlewareContextSymbol = Symbol.for('json-rpc-engine#MiddlewareContext');\n\n/**\n * An context object for middleware that attempts to protect against accidental\n * modifications. Its interface is frozen.\n *\n * Map keys may not be directly overridden with {@link set}. Instead, use\n * {@link delete} to remove a key and then {@link set} to add a new value.\n *\n * The override protections are circumvented when using e.g. `Reflect.set`, so\n * don't do that.\n *\n * @template KeyValues - The type of the keys and values in the context.\n * @example\n * // By default, the context permits any PropertyKey as a key.\n * const context = new MiddlewareContext();\n * context.set('foo', 'bar');\n * context.get('foo'); // 'bar'\n * context.get('fizz'); // undefined\n * @example\n * // By specifying an object type, the context permits only the keys of the object.\n * type Context = MiddlewareContext<{ foo: string }>;\n * const context = new Context([['foo', 'bar']]);\n * context.get('foo'); // 'bar'\n * context.get('fizz'); // Type error\n */\nexport class MiddlewareContext<\n KeyValues extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>,\n> extends Map<keyof KeyValues, KeyValues[keyof KeyValues]> {\n private readonly [MiddlewareContextSymbol] = true;\n\n /**\n * Check if a value is a {@link MiddlewareContext} instance.\n * Works across different package versions in the same realm.\n *\n * @param value - The value to check.\n * @returns Whether the value is a {@link MiddlewareContext} instance.\n */\n static isInstance(value: unknown): value is MiddlewareContext {\n return (\n isObject(value) &&\n MiddlewareContextSymbol in value &&\n value[MiddlewareContextSymbol] === true\n );\n }\n\n constructor(\n entries?:\n | Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]>\n | KeyValues,\n ) {\n super(\n entries && isIterable(entries)\n ? entries\n : entriesFromKeyValues(entries ?? {}),\n );\n Object.freeze(this);\n }\n\n get<K extends keyof KeyValues>(key: K): KeyValues[K] | undefined {\n return super.get(key) as KeyValues[K] | undefined;\n }\n\n /**\n * Get a value from the context. Throws if the key is not found.\n *\n * @param key - The key to get the value for.\n * @returns The value.\n */\n assertGet<K extends keyof KeyValues>(key: K): KeyValues[K] {\n if (!super.has(key)) {\n throw new Error(`Context key \"${String(key)}\" not found`);\n }\n return super.get(key) as KeyValues[K];\n }\n\n /**\n * Set a value in the context. Throws if the key already exists.\n * {@link delete} an existing key before setting it to a new value.\n *\n * @throws If the key already exists.\n * @param key - The key to set the value for.\n * @param value - The value to set.\n * @returns The context.\n */\n set<K extends keyof KeyValues>(key: K, value: KeyValues[K]): this {\n if (super.has(key)) {\n throw new Error(`MiddlewareContext key \"${String(key)}\" already exists`);\n }\n super.set(key, value);\n return this;\n }\n}\n\n/**\n * {@link Iterable} type guard.\n *\n * @param value - The value to check.\n * @returns Whether the value is an {@link Iterable}.\n */\nfunction isIterable(\n value: Iterable<unknown> | Record<PropertyKey, unknown>,\n): value is Iterable<unknown> {\n return Symbol.iterator in value;\n}\n\n/**\n * Like Object.entries(), but includes symbol-keyed properties.\n *\n * @template KeyValues - The type of the keys and values in the object.\n * @param keyValues - The object to convert.\n * @returns The array of entries, including symbol-keyed properties.\n */\nfunction entriesFromKeyValues<KeyValues extends Record<PropertyKey, unknown>>(\n keyValues: KeyValues,\n): [keyof KeyValues, KeyValues[keyof KeyValues]][] {\n return Reflect.ownKeys(keyValues).map((key: keyof KeyValues) => [\n key,\n keyValues[key],\n ]);\n}\n\n/**\n * Infer the KeyValues type from a {@link MiddlewareContext}.\n */\nexport type InferKeyValues<T> =\n T extends MiddlewareContext<infer U> ? U : never;\n\n/**\n * Simplifies an object type by \"merging\" its properties.\n *\n * - Expands intersections into a single object type.\n * - Forces mapped/conditional results to resolve into a readable shape.\n * - No runtime effect; purely a type-level normalization.\n *\n * @example\n * type A = { a: string } & { b: number };\n * type B = Simplify<A>; // { a: string; b: number }\n */\ntype Simplify<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;\n\n/**\n * Rejects record types that contain any `never`-valued property.\n *\n * If any property of `T` resolves to `never`, the result is `never`; otherwise it returns `T` unchanged.\n * Useful as a guard to ensure computed/merged record types didn't collapse any fields to `never`.\n *\n * @example\n * type A = ExcludeNever<{ a: string; b: never }>; // never\n * type B = ExcludeNever<{ a: string; b: number }>; // { a: string; b: number }\n */\ntype ExcludeNever<T extends Record<PropertyKey, unknown>> = {\n [K in keyof T]-?: [T[K]] extends [never] ? K : never;\n}[keyof T] extends never\n ? T\n : never;\n\n/**\n * Merge a union of {@link MiddlewareContext}s into a single {@link MiddlewareContext}\n * supertype.\n *\n * @param Contexts - The union of {@link MiddlewareContext}s to merge.\n * @returns The merged {@link MiddlewareContext} supertype.\n * @example\n * type A = MiddlewareContext<{ a: string }> | MiddlewareContext<{ b: number }>;\n * type B = MergeContexts<A>; // MiddlewareContext<{ a: string, b: number }>\n */\nexport type MergeContexts<Contexts extends ContextConstraint> =\n ExcludeNever<\n Simplify<UnionToIntersection<InferKeyValues<Contexts>>>\n > extends never\n ? never\n : MiddlewareContext<\n ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>>\n >;\n\n/**\n * A constraint for {@link MiddlewareContext} generic parameters.\n */\n// Non-polluting `any` constraint.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ContextConstraint = MiddlewareContext<any>;\n\n/**\n * The empty context type, i.e. `MiddlewareContext<{}>`.\n */\n// The empty object type is literally an empty object in this context.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type EmptyContext = MiddlewareContext<{}>;\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { UnionToIntersection } from "./utils.cjs";
2
+ declare const MiddlewareContextSymbol: unique symbol;
2
3
  /**
3
4
  * An context object for middleware that attempts to protect against accidental
4
5
  * modifications. Its interface is frozen.
@@ -24,7 +25,16 @@ import type { UnionToIntersection } from "./utils.cjs";
24
25
  * context.get('fizz'); // Type error
25
26
  */
26
27
  export declare class MiddlewareContext<KeyValues extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>> extends Map<keyof KeyValues, KeyValues[keyof KeyValues]> {
27
- constructor(entries?: Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]>);
28
+ private readonly [MiddlewareContextSymbol];
29
+ /**
30
+ * Check if a value is a {@link MiddlewareContext} instance.
31
+ * Works across different package versions in the same realm.
32
+ *
33
+ * @param value - The value to check.
34
+ * @returns Whether the value is a {@link MiddlewareContext} instance.
35
+ */
36
+ static isInstance(value: unknown): value is MiddlewareContext;
37
+ constructor(entries?: Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]> | KeyValues);
28
38
  get<K extends keyof KeyValues>(key: K): KeyValues[K] | undefined;
29
39
  /**
30
40
  * Get a value from the context. Throws if the key is not found.
@@ -47,7 +57,7 @@ export declare class MiddlewareContext<KeyValues extends Record<PropertyKey, unk
47
57
  /**
48
58
  * Infer the KeyValues type from a {@link MiddlewareContext}.
49
59
  */
50
- type InferKeyValues<T> = T extends MiddlewareContext<infer U> ? U : never;
60
+ export type InferKeyValues<T> = T extends MiddlewareContext<infer U> ? U : never;
51
61
  /**
52
62
  * Simplifies an object type by "merging" its properties.
53
63
  *
@@ -86,6 +96,9 @@ type ExcludeNever<T extends Record<PropertyKey, unknown>> = {
86
96
  * type B = MergeContexts<A>; // MiddlewareContext<{ a: string, b: number }>
87
97
  */
88
98
  export type MergeContexts<Contexts extends ContextConstraint> = ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>> extends never ? never : MiddlewareContext<ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>>>;
99
+ /**
100
+ * A constraint for {@link MiddlewareContext} generic parameters.
101
+ */
89
102
  export type ContextConstraint = MiddlewareContext<any>;
90
103
  /**
91
104
  * The empty context type, i.e. `MiddlewareContext<{}>`.
@@ -1 +1 @@
1
- {"version":3,"file":"MiddlewareContext.d.cts","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAgB;AAEnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAiB,CAC5B,SAAS,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAC7E,SAAQ,GAAG,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;gBAEtD,OAAO,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC;IAM5E,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS;IAIhE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAO1D;;;;;;;;OAQG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;CAOlE;AAED;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AAExE;;;;;;;;;GASG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK;CACrD,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GACpB,CAAC,GACD,KAAK,CAAC;AAEV;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,iBAAiB,IAC1D,YAAY,CACV,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxD,SAAS,KAAK,GACX,KAAK,GACL,iBAAiB,CACf,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,CAAC;AAIR,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAEvD;;GAEG;AAGH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"MiddlewareContext.d.cts","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAgB;AAEnD,QAAA,MAAM,uBAAuB,eAAkD,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAiB,CAC5B,SAAS,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAC7E,SAAQ,GAAG,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;IACxD,OAAO,CAAC,QAAQ,CAAC,CAAC,uBAAuB,CAAC,CAAQ;IAElD;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB;gBAS3D,OAAO,CAAC,EACJ,QAAQ,CAAC,SAAS,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,GAChE,SAAS;IAUf,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS;IAIhE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAO1D;;;;;;;;OAQG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;CAOlE;AA8BD;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAC1B,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AAExE;;;;;;;;;GASG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK;CACrD,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GACpB,CAAC,GACD,KAAK,CAAC;AAEV;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,iBAAiB,IAC1D,YAAY,CACV,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxD,SAAS,KAAK,GACX,KAAK,GACL,iBAAiB,CACf,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,CAAC;AAER;;GAEG;AAGH,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAEvD;;GAEG;AAGH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { UnionToIntersection } from "./utils.mjs";
2
+ declare const MiddlewareContextSymbol: unique symbol;
2
3
  /**
3
4
  * An context object for middleware that attempts to protect against accidental
4
5
  * modifications. Its interface is frozen.
@@ -24,7 +25,16 @@ import type { UnionToIntersection } from "./utils.mjs";
24
25
  * context.get('fizz'); // Type error
25
26
  */
26
27
  export declare class MiddlewareContext<KeyValues extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>> extends Map<keyof KeyValues, KeyValues[keyof KeyValues]> {
27
- constructor(entries?: Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]>);
28
+ private readonly [MiddlewareContextSymbol];
29
+ /**
30
+ * Check if a value is a {@link MiddlewareContext} instance.
31
+ * Works across different package versions in the same realm.
32
+ *
33
+ * @param value - The value to check.
34
+ * @returns Whether the value is a {@link MiddlewareContext} instance.
35
+ */
36
+ static isInstance(value: unknown): value is MiddlewareContext;
37
+ constructor(entries?: Iterable<readonly [keyof KeyValues, KeyValues[keyof KeyValues]]> | KeyValues);
28
38
  get<K extends keyof KeyValues>(key: K): KeyValues[K] | undefined;
29
39
  /**
30
40
  * Get a value from the context. Throws if the key is not found.
@@ -47,7 +57,7 @@ export declare class MiddlewareContext<KeyValues extends Record<PropertyKey, unk
47
57
  /**
48
58
  * Infer the KeyValues type from a {@link MiddlewareContext}.
49
59
  */
50
- type InferKeyValues<T> = T extends MiddlewareContext<infer U> ? U : never;
60
+ export type InferKeyValues<T> = T extends MiddlewareContext<infer U> ? U : never;
51
61
  /**
52
62
  * Simplifies an object type by "merging" its properties.
53
63
  *
@@ -86,6 +96,9 @@ type ExcludeNever<T extends Record<PropertyKey, unknown>> = {
86
96
  * type B = MergeContexts<A>; // MiddlewareContext<{ a: string, b: number }>
87
97
  */
88
98
  export type MergeContexts<Contexts extends ContextConstraint> = ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>> extends never ? never : MiddlewareContext<ExcludeNever<Simplify<UnionToIntersection<InferKeyValues<Contexts>>>>>;
99
+ /**
100
+ * A constraint for {@link MiddlewareContext} generic parameters.
101
+ */
89
102
  export type ContextConstraint = MiddlewareContext<any>;
90
103
  /**
91
104
  * The empty context type, i.e. `MiddlewareContext<{}>`.
@@ -1 +1 @@
1
- {"version":3,"file":"MiddlewareContext.d.mts","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAgB;AAEnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAiB,CAC5B,SAAS,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAC7E,SAAQ,GAAG,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;gBAEtD,OAAO,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC;IAM5E,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS;IAIhE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAO1D;;;;;;;;OAQG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;CAOlE;AAED;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AAExE;;;;;;;;;GASG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK;CACrD,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GACpB,CAAC,GACD,KAAK,CAAC;AAEV;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,iBAAiB,IAC1D,YAAY,CACV,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxD,SAAS,KAAK,GACX,KAAK,GACL,iBAAiB,CACf,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,CAAC;AAIR,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAEvD;;GAEG;AAGH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"MiddlewareContext.d.mts","sourceRoot":"","sources":["../../src/v2/MiddlewareContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAgB;AAEnD,QAAA,MAAM,uBAAuB,eAAkD,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAiB,CAC5B,SAAS,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAC7E,SAAQ,GAAG,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;IACxD,OAAO,CAAC,QAAQ,CAAC,CAAC,uBAAuB,CAAC,CAAQ;IAElD;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB;gBAS3D,OAAO,CAAC,EACJ,QAAQ,CAAC,SAAS,CAAC,MAAM,SAAS,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,GAChE,SAAS;IAUf,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS;IAIhE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAO1D;;;;;;;;OAQG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;CAOlE;AA8BD;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAC1B,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AAExE;;;;;;;;;GASG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK;CACrD,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GACpB,CAAC,GACD,KAAK,CAAC;AAEV;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,iBAAiB,IAC1D,YAAY,CACV,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CACxD,SAAS,KAAK,GACX,KAAK,GACL,iBAAiB,CACf,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACtE,CAAC;AAER;;GAEG;AAGH,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAEvD;;GAEG;AAGH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC"}
@@ -1,3 +1,6 @@
1
+ var _a;
2
+ import { isObject } from "@metamask/utils";
3
+ const MiddlewareContextSymbol = Symbol.for('json-rpc-engine#MiddlewareContext');
1
4
  /**
2
5
  * An context object for middleware that attempts to protect against accidental
3
6
  * modifications. Its interface is frozen.
@@ -23,8 +26,23 @@
23
26
  * context.get('fizz'); // Type error
24
27
  */
25
28
  export class MiddlewareContext extends Map {
29
+ /**
30
+ * Check if a value is a {@link MiddlewareContext} instance.
31
+ * Works across different package versions in the same realm.
32
+ *
33
+ * @param value - The value to check.
34
+ * @returns Whether the value is a {@link MiddlewareContext} instance.
35
+ */
36
+ static isInstance(value) {
37
+ return (isObject(value) &&
38
+ MiddlewareContextSymbol in value &&
39
+ value[MiddlewareContextSymbol] === true);
40
+ }
26
41
  constructor(entries) {
27
- super(entries);
42
+ super(entries && isIterable(entries)
43
+ ? entries
44
+ : entriesFromKeyValues(entries ?? {}));
45
+ this[_a] = true;
28
46
  Object.freeze(this);
29
47
  }
30
48
  get(key) {
@@ -59,4 +77,27 @@ export class MiddlewareContext extends Map {
59
77
  return this;
60
78
  }
61
79
  }
80
+ _a = MiddlewareContextSymbol;
81
+ /**
82
+ * {@link Iterable} type guard.
83
+ *
84
+ * @param value - The value to check.
85
+ * @returns Whether the value is an {@link Iterable}.
86
+ */
87
+ function isIterable(value) {
88
+ return Symbol.iterator in value;
89
+ }
90
+ /**
91
+ * Like Object.entries(), but includes symbol-keyed properties.
92
+ *
93
+ * @template KeyValues - The type of the keys and values in the object.
94
+ * @param keyValues - The object to convert.
95
+ * @returns The array of entries, including symbol-keyed properties.
96
+ */
97
+ function entriesFromKeyValues(keyValues) {
98
+ return Reflect.ownKeys(keyValues).map((key) => [
99
+ key,
100
+ keyValues[key],
101
+ ]);
102
+ }
62
103
  //# sourceMappingURL=MiddlewareContext.mjs.map