@metamask/utils
Version:
Various JavaScript/TypeScript utilities of wide relevance to the MetaMask codebase
1 lines • 28.2 kB
Source Map (JSON)
{"version":3,"file":"json.mjs","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n any,\n array,\n coerce,\n create,\n define,\n integer,\n is,\n literal,\n nullable,\n number,\n object as superstructObject,\n optional,\n record,\n string,\n union,\n unknown,\n Struct,\n refine,\n} from '@metamask/superstruct';\nimport type {\n Context,\n Infer,\n ObjectSchema,\n Simplify,\n Optionalize,\n} from '@metamask/superstruct';\n\nimport type { AssertionErrorConstructor } from './assert';\nimport { assertStruct } from './assert';\nimport { hasProperty } from './misc';\n\n/**\n * Any JSON-compatible value.\n */\nexport type Json =\n | null\n | boolean\n | number\n | string\n | Json[]\n | { [prop: string]: Json };\n\n/**\n * A helper type to make properties with `undefined` in their type optional, but\n * not `undefined` itself.\n *\n * @deprecated Use `ObjectType` and/or `ExactOptionalize` from `@metamask/superstruct@>=3.2.0` instead.\n * @example\n * ```ts\n * type Foo = ObjectOptional<{ foo: string | undefined }>;\n * // Foo is equivalent to { foo?: string }\n * ```\n */\nexport type ObjectOptional<Schema extends Record<string, unknown>> = {\n [Key in keyof Schema as Schema[Key] extends ExactOptionalGuard\n ? Key\n : never]?: Schema[Key] extends ExactOptionalGuard & infer Original\n ? Original\n : never;\n} & {\n [Key in keyof Schema as Schema[Key] extends ExactOptionalGuard\n ? never\n : Key]: Schema[Key];\n};\n\n/**\n * An object type with support for exact optionals. This is used by the `object`\n * struct. This uses the {@link ObjectOptional} helper to make properties with\n * `undefined` in their type optional, but not `undefined` itself.\n *\n * @deprecated Use `ObjectType` from `@metamask/superstruct@>=3.2.0` instead.\n */\nexport type ObjectType<Schema extends ObjectSchema> = Simplify<\n ObjectOptional<\n Optionalize<{\n [Key in keyof Schema]: Infer<Schema[Key]>;\n }>\n >\n>;\n\n/**\n * A struct to check if the given value is a valid object, with support for\n * {@link exactOptional} types.\n *\n * @deprecated Use `exactOptional` and `object` from `@metamask/superstruct@>=3.2.0` instead.\n * @param schema - The schema of the object.\n * @returns A struct to check if the given value is an object.\n */\nexport const object = <Schema extends ObjectSchema>(\n schema: Schema,\n): Struct<ObjectType<Schema>> =>\n // The type is slightly different from a regular object struct, because we\n // want to make properties with `undefined` in their type optional, but not\n // `undefined` itself. This means that we need a type cast.\n superstructObject(schema) as unknown as Struct<ObjectType<Schema>>;\n\ndeclare const exactOptionalSymbol: unique symbol;\ntype ExactOptionalGuard = {\n _exactOptionalGuard?: typeof exactOptionalSymbol;\n};\n\n/**\n * Check the last field of a path is present.\n *\n * @param context - The context to check.\n * @param context.path - The path to check.\n * @param context.branch - The branch to check.\n * @returns Whether the last field of a path is present.\n */\nfunction hasOptional({ path, branch }: Context): boolean {\n const field = path[path.length - 1];\n return hasProperty(branch[branch.length - 2], field);\n}\n\n/**\n * A struct which allows the property of an object to be absent, or to be present\n * as long as it's valid and not set to `undefined`.\n *\n * This struct should be used in conjunction with the {@link object} from this\n * library, to get proper type inference.\n *\n * @deprecated Use `exactOptional` and `object` from `@metamask/superstruct@>=3.2.0` instead.\n * @param struct - The struct to check the value against, if present.\n * @returns A struct to check if the given value is valid, or not present.\n * @example\n * ```ts\n * const struct = object({\n * foo: exactOptional(string()),\n * bar: exactOptional(number()),\n * baz: optional(boolean()),\n * qux: unknown(),\n * });\n *\n * type Type = Infer<typeof struct>;\n * // Type is equivalent to:\n * // {\n * // foo?: string;\n * // bar?: number;\n * // baz?: boolean | undefined;\n * // qux: unknown;\n * // }\n * ```\n */\nexport function exactOptional<Type, Schema>(\n struct: Struct<Type, Schema>,\n): Struct<Type & ExactOptionalGuard, Schema> {\n return new Struct<Type & ExactOptionalGuard, Schema>({\n ...struct,\n\n type: `optional ${struct.type}`,\n validator: (value, context) =>\n !hasOptional(context) || struct.validator(value, context),\n\n refiner: (value, context) =>\n !hasOptional(context) || struct.refiner(value as Type, context),\n });\n}\n\n/**\n * Validate an unknown input to be valid JSON.\n *\n * Useful for constructing JSON structs.\n *\n * @param json - An unknown value.\n * @returns True if the value is valid JSON, otherwise false.\n */\nfunction validateJson(json: unknown): boolean {\n if (json === null || typeof json === 'boolean' || typeof json === 'string') {\n return true;\n }\n\n if (typeof json === 'number' && Number.isFinite(json)) {\n return true;\n }\n\n if (typeof json === 'object') {\n let every = true;\n if (Array.isArray(json)) {\n // Ignoring linting error since for-of is significantly slower than a normal for-loop\n // and performance is important in this specific function.\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < json.length; i++) {\n if (!validateJson(json[i])) {\n every = false;\n break;\n }\n }\n return every;\n }\n\n const entries = Object.entries(json);\n // Ignoring linting errors since for-of is significantly slower than a normal for-loop\n // and performance is important in this specific function.\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < entries.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (typeof entries[i]![0] !== 'string' || !validateJson(entries[i]![1])) {\n every = false;\n break;\n }\n }\n return every;\n }\n\n return false;\n}\n\n/**\n * A struct to check if the given value is a valid JSON-serializable value.\n *\n * Note that this struct is unsafe. For safe validation, use {@link JsonStruct}.\n */\nexport const UnsafeJsonStruct: Struct<Json> = define('JSON', (json) =>\n validateJson(json),\n);\n\n/**\n * A struct to check if the given value is a valid JSON-serializable value.\n *\n * This struct sanitizes the value before validating it, so that it is safe to\n * use with untrusted input.\n */\nexport const JsonStruct = coerce(\n UnsafeJsonStruct,\n refine(any(), 'JSON', (value) => is(value, UnsafeJsonStruct)),\n (value) =>\n JSON.parse(\n JSON.stringify(value, (propKey, propValue) => {\n // Strip __proto__ and constructor properties to prevent prototype pollution.\n if (propKey === '__proto__' || propKey === 'constructor') {\n return undefined;\n }\n return propValue;\n }),\n ),\n);\n\n/**\n * Check if the given value is a valid {@link Json} value, i.e., a value that is\n * serializable to JSON.\n *\n * @param value - The value to check.\n * @returns Whether the value is a valid {@link Json} value.\n */\nexport function isValidJson(value: unknown): value is Json {\n try {\n getSafeJson(value);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate and return sanitized JSON.\n *\n * Note:\n * This function uses sanitized JsonStruct for validation\n * that applies stringify and then parse of a value provided\n * to ensure that there are no getters which can have side effects\n * that can cause security issues.\n *\n * @param value - JSON structure to be processed.\n * @returns Sanitized JSON structure.\n */\nexport function getSafeJson<Type extends Json = Json>(value: unknown): Type {\n return create(value, JsonStruct) as Type;\n}\n\n/**\n * Get the size of a JSON value in bytes. This also validates the value.\n *\n * @param value - The JSON value to get the size of.\n * @returns The size of the JSON value in bytes.\n */\nexport function getJsonSize(value: unknown): number {\n assertStruct(value, JsonStruct, 'Invalid JSON value');\n\n const json = JSON.stringify(value);\n return new TextEncoder().encode(json).byteLength;\n}\n\n/**\n * The string '2.0'.\n */\nexport const jsonrpc2 = '2.0' as const;\nexport const JsonRpcVersionStruct = literal(jsonrpc2);\n\n/**\n * A String specifying the version of the JSON-RPC protocol.\n * MUST be exactly \"2.0\".\n */\nexport type JsonRpcVersion2 = typeof jsonrpc2;\n\nexport const JsonRpcIdStruct = nullable(union([number(), string()]));\n\n/**\n * An identifier established by the Client that MUST contain a String, Number,\n * or NULL value if included. If it is not included it is assumed to be a\n * notification. The value SHOULD normally not be Null and Numbers SHOULD\n * NOT contain fractional parts.\n */\nexport type JsonRpcId = Infer<typeof JsonRpcIdStruct>;\n\nexport const JsonRpcErrorStruct = object({\n code: integer(),\n message: string(),\n data: exactOptional(JsonStruct),\n stack: exactOptional(string()),\n});\n\n/**\n * Mark a certain key of a type as optional.\n */\nexport type OptionalField<\n Type extends Record<string, unknown>,\n Key extends keyof Type,\n> = Omit<Type, Key> & Partial<Pick<Type, Key>>;\n\n/**\n * A JSON-RPC error object.\n *\n * Note that TypeScript infers `unknown | undefined` as `unknown`, meaning that\n * the `data` field is not optional. To make it optional, we use the\n * `OptionalField` helper, to explicitly make it optional.\n */\nexport type JsonRpcError = OptionalField<\n Infer<typeof JsonRpcErrorStruct>,\n 'data'\n>;\n\nexport const JsonRpcParamsStruct: Struct<Json[] | Record<string, Json>, null> =\n union([record(string(), JsonStruct), array(JsonStruct)]);\n\nexport type JsonRpcParams = Json[] | Record<string, Json>;\n\nexport const JsonRpcRequestStruct = object({\n id: JsonRpcIdStruct,\n jsonrpc: JsonRpcVersionStruct,\n method: string(),\n params: exactOptional(JsonRpcParamsStruct),\n});\n\nexport type InferWithParams<\n Type extends Struct<any>,\n Params extends JsonRpcParams,\n> = Infer<Type> & {\n params?: Params;\n};\n\n/**\n * A JSON-RPC request object.\n */\nexport type JsonRpcRequest<Params extends JsonRpcParams = JsonRpcParams> =\n InferWithParams<typeof JsonRpcRequestStruct, Params>;\n\nexport const JsonRpcNotificationStruct = object({\n jsonrpc: JsonRpcVersionStruct,\n method: string(),\n params: exactOptional(JsonRpcParamsStruct),\n});\n\n/**\n * A JSON-RPC notification object.\n */\nexport type JsonRpcNotification<Params extends JsonRpcParams = JsonRpcParams> =\n InferWithParams<typeof JsonRpcNotificationStruct, Params>;\n\n/**\n * Check if the given value is a valid {@link JsonRpcNotification} object.\n *\n * @param value - The value to check.\n * @returns Whether the given value is a valid {@link JsonRpcNotification}\n * object.\n */\nexport function isJsonRpcNotification(\n value: unknown,\n): value is JsonRpcNotification {\n return is(value, JsonRpcNotificationStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcNotification} object.\n *\n * @param value - The value to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcNotification} object.\n */\nexport function assertIsJsonRpcNotification(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcNotification {\n assertStruct(\n value,\n JsonRpcNotificationStruct,\n 'Invalid JSON-RPC notification',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given value is a valid {@link JsonRpcRequest} object.\n *\n * @param value - The value to check.\n * @returns Whether the given value is a valid {@link JsonRpcRequest} object.\n */\nexport function isJsonRpcRequest(value: unknown): value is JsonRpcRequest {\n return is(value, JsonRpcRequestStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcRequest} object.\n *\n * @param value - The JSON-RPC request or notification to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcRequest} object.\n */\nexport function assertIsJsonRpcRequest(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcRequest {\n assertStruct(\n value,\n JsonRpcRequestStruct,\n 'Invalid JSON-RPC request',\n ErrorWrapper,\n );\n}\n\nexport const PendingJsonRpcResponseStruct = superstructObject({\n id: JsonRpcIdStruct,\n jsonrpc: JsonRpcVersionStruct,\n result: optional(unknown()),\n error: optional(JsonRpcErrorStruct),\n});\n\n/**\n * A JSON-RPC response object that has not yet been resolved.\n */\nexport type PendingJsonRpcResponse<Result extends Json = Json> = Omit<\n Infer<typeof PendingJsonRpcResponseStruct>,\n 'result'\n> & {\n result?: Result;\n};\n\nexport const JsonRpcSuccessStruct = object({\n id: JsonRpcIdStruct,\n jsonrpc: JsonRpcVersionStruct,\n result: JsonStruct,\n});\n\n/**\n * A successful JSON-RPC response object.\n */\nexport type JsonRpcSuccess<Result extends Json = Json> = Omit<\n Infer<typeof JsonRpcSuccessStruct>,\n 'result'\n> & {\n result: Result;\n};\n\nexport const JsonRpcFailureStruct = object({\n id: JsonRpcIdStruct,\n jsonrpc: JsonRpcVersionStruct,\n error: JsonRpcErrorStruct as Struct<JsonRpcError>,\n});\n\n/**\n * A failed JSON-RPC response object.\n */\nexport type JsonRpcFailure = Infer<typeof JsonRpcFailureStruct>;\n\nexport const JsonRpcResponseStruct = union([\n JsonRpcSuccessStruct,\n JsonRpcFailureStruct,\n]);\n\n/**\n * A JSON-RPC response object. Must be checked to determine whether it's a\n * success or failure.\n *\n * @template Result - The type of the result.\n */\nexport type JsonRpcResponse<Result extends Json = Json> =\n | JsonRpcSuccess<Result>\n | JsonRpcFailure;\n\n/**\n * Type guard to check whether specified JSON-RPC response is a\n * {@link PendingJsonRpcResponse}.\n *\n * @param response - The JSON-RPC response to check.\n * @returns Whether the specified JSON-RPC response is pending.\n */\nexport function isPendingJsonRpcResponse(\n response: unknown,\n): response is PendingJsonRpcResponse {\n return is(response, PendingJsonRpcResponseStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link PendingJsonRpcResponse} object.\n *\n * @param response - The JSON-RPC response to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link PendingJsonRpcResponse}\n * object.\n */\nexport function assertIsPendingJsonRpcResponse(\n response: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts response is PendingJsonRpcResponse {\n assertStruct(\n response,\n PendingJsonRpcResponseStruct,\n 'Invalid pending JSON-RPC response',\n ErrorWrapper,\n );\n}\n\n/**\n * Type guard to check if a value is a {@link JsonRpcResponse}.\n *\n * @param response - The object to check.\n * @returns Whether the object is a JsonRpcResponse.\n */\nexport function isJsonRpcResponse(\n response: unknown,\n): response is JsonRpcResponse {\n return is(response, JsonRpcResponseStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcResponse} object.\n *\n * @param value - The value to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcResponse} object.\n */\nexport function assertIsJsonRpcResponse(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcResponse {\n assertStruct(\n value,\n JsonRpcResponseStruct,\n 'Invalid JSON-RPC response',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given value is a valid {@link JsonRpcSuccess} object.\n *\n * @param value - The value to check.\n * @returns Whether the given value is a valid {@link JsonRpcSuccess} object.\n */\nexport function isJsonRpcSuccess(value: unknown): value is JsonRpcSuccess {\n return is(value, JsonRpcSuccessStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcSuccess} object.\n *\n * @param value - The value to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcSuccess} object.\n */\nexport function assertIsJsonRpcSuccess(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcSuccess {\n assertStruct(\n value,\n JsonRpcSuccessStruct,\n 'Invalid JSON-RPC success response',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given value is a valid {@link JsonRpcFailure} object.\n *\n * @param value - The value to check.\n * @returns Whether the given value is a valid {@link JsonRpcFailure} object.\n */\nexport function isJsonRpcFailure(value: unknown): value is JsonRpcFailure {\n return is(value, JsonRpcFailureStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcFailure} object.\n *\n * @param value - The value to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcFailure} object.\n */\nexport function assertIsJsonRpcFailure(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcFailure {\n assertStruct(\n value,\n JsonRpcFailureStruct,\n 'Invalid JSON-RPC failure response',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given value is a valid {@link JsonRpcError} object.\n *\n * @param value - The value to check.\n * @returns Whether the given value is a valid {@link JsonRpcError} object.\n */\nexport function isJsonRpcError(value: unknown): value is JsonRpcError {\n return is(value, JsonRpcErrorStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link JsonRpcError} object.\n *\n * @param value - The value to check.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the given value is not a valid {@link JsonRpcError} object.\n */\nexport function assertIsJsonRpcError(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is JsonRpcError {\n assertStruct(\n value,\n JsonRpcErrorStruct,\n 'Invalid JSON-RPC error',\n ErrorWrapper,\n );\n}\n\ntype JsonRpcValidatorOptions = {\n permitEmptyString?: boolean;\n permitFractions?: boolean;\n permitNull?: boolean;\n};\n\n/**\n * Gets a function for validating JSON-RPC request / response `id` values.\n *\n * By manipulating the options of this factory, you can control the behavior\n * of the resulting validator for some edge cases. This is useful because e.g.\n * `null` should sometimes but not always be permitted.\n *\n * Note that the empty string (`''`) is always permitted by the JSON-RPC\n * specification, but that kind of sucks and you may want to forbid it in some\n * instances anyway.\n *\n * For more details, see the\n * [JSON-RPC Specification](https://www.jsonrpc.org/specification).\n *\n * @param options - An options object.\n * @param options.permitEmptyString - Whether the empty string (i.e. `''`)\n * should be treated as a valid ID. Default: `true`\n * @param options.permitFractions - Whether fractional numbers (e.g. `1.2`)\n * should be treated as valid IDs. Default: `false`\n * @param options.permitNull - Whether `null` should be treated as a valid ID.\n * Default: `true`\n * @returns The JSON-RPC ID validator function.\n */\nexport function getJsonRpcIdValidator(options?: JsonRpcValidatorOptions) {\n const { permitEmptyString, permitFractions, permitNull } = {\n permitEmptyString: true,\n permitFractions: false,\n permitNull: true,\n ...options,\n };\n\n /**\n * Type guard for {@link JsonRpcId}.\n *\n * @param id - The JSON-RPC ID value to check.\n * @returns Whether the given ID is valid per the options given to the\n * factory.\n */\n const isValidJsonRpcId = (id: unknown): id is JsonRpcId => {\n return Boolean(\n (typeof id === 'number' && (permitFractions || Number.isInteger(id))) ||\n (typeof id === 'string' && (permitEmptyString || id.length > 0)) ||\n (permitNull && id === null),\n );\n };\n\n return isValidJsonRpcId;\n}\n"]}