From 333eb4123f969523f086976b523d6e7a4e5c025a Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 22 Jan 2025 17:52:13 +0100 Subject: [PATCH 1/2] fix(parser): API Gateway Envelopes handle non-JSON --- packages/parser/src/envelopes/apigw.ts | 38 +++-- packages/parser/src/envelopes/apigwv2.ts | 42 +++-- .../parser/tests/unit/envelopes/apigw.test.ts | 155 ++++++++++-------- .../tests/unit/envelopes/apigwv2.test.ts | 152 +++++++++-------- .../parser/tests/unit/schema/apigw.test.ts | 24 +-- .../parser/tests/unit/schema/apigwv2.test.ts | 18 +- 6 files changed, 228 insertions(+), 201 deletions(-) diff --git a/packages/parser/src/envelopes/apigw.ts b/packages/parser/src/envelopes/apigw.ts index 86f716b234..2ff9d3b8ab 100644 --- a/packages/parser/src/envelopes/apigw.ts +++ b/packages/parser/src/envelopes/apigw.ts @@ -2,7 +2,7 @@ import type { ZodSchema, z } from 'zod'; import { ParseError } from '../errors.js'; import { APIGatewayProxyEventSchema } from '../schemas/apigw.js'; import type { ParsedResult } from '../types/parser.js'; -import { Envelope, envelopeDiscriminator } from './envelope.js'; +import { envelopeDiscriminator } from './envelope.js'; /** * API Gateway envelope to extract data within body key @@ -14,36 +14,38 @@ export const ApiGatewayEnvelope = { */ [envelopeDiscriminator]: 'object' as const, parse(data: unknown, schema: T): z.infer { - return Envelope.parse(APIGatewayProxyEventSchema.parse(data).body, schema); + try { + return APIGatewayProxyEventSchema.extend({ + body: schema, + }).parse(data).body; + } catch (error) { + throw new ParseError('Failed to parse API Gateway body', { + cause: error as Error, + }); + } }, safeParse( data: unknown, schema: T ): ParsedResult> { - const parsedEnvelope = APIGatewayProxyEventSchema.safeParse(data); - if (!parsedEnvelope.success) { - return { - success: false, - error: new ParseError('Failed to parse ApiGatewayEnvelope', { - cause: parsedEnvelope.error, - }), - originalEvent: data, - }; - } - - const parsedBody = Envelope.safeParse(parsedEnvelope.data.body, schema); + const result = APIGatewayProxyEventSchema.extend({ + body: schema, + }).safeParse(data); - if (!parsedBody.success) { + if (!result.success) { return { success: false, - error: new ParseError('Failed to parse ApiGatewayEnvelope body', { - cause: parsedBody.error, + error: new ParseError('Failed to parse API Gateway body', { + cause: result.error, }), originalEvent: data, }; } - return parsedBody; + return { + success: true, + data: result.data.body, + }; }, }; diff --git a/packages/parser/src/envelopes/apigwv2.ts b/packages/parser/src/envelopes/apigwv2.ts index 45c80f0727..486fb74593 100644 --- a/packages/parser/src/envelopes/apigwv2.ts +++ b/packages/parser/src/envelopes/apigwv2.ts @@ -2,7 +2,7 @@ import type { ZodSchema, z } from 'zod'; import { ParseError } from '../errors.js'; import { APIGatewayProxyEventV2Schema } from '../schemas/apigwv2.js'; import type { ParsedResult } from '../types/index.js'; -import { Envelope, envelopeDiscriminator } from './envelope.js'; +import { envelopeDiscriminator } from './envelope.js'; /** * API Gateway V2 envelope to extract data within body key @@ -14,40 +14,38 @@ export const ApiGatewayV2Envelope = { */ [envelopeDiscriminator]: 'object' as const, parse(data: unknown, schema: T): z.infer { - return Envelope.parse( - APIGatewayProxyEventV2Schema.parse(data).body, - schema - ); + try { + return APIGatewayProxyEventV2Schema.extend({ + body: schema, + }).parse(data).body; + } catch (error) { + throw new ParseError('Failed to parse API Gateway HTTP body', { + cause: error as Error, + }); + } }, safeParse( data: unknown, schema: T ): ParsedResult> { - const parsedEnvelope = APIGatewayProxyEventV2Schema.safeParse(data); - if (!parsedEnvelope.success) { - return { - success: false, - error: new ParseError('Failed to parse API Gateway V2 envelope', { - cause: parsedEnvelope.error, - }), - originalEvent: data, - }; - } - - const parsedBody = Envelope.safeParse(parsedEnvelope.data.body, schema); + const result = APIGatewayProxyEventV2Schema.extend({ + body: schema, + }).safeParse(data); - if (!parsedBody.success) { + if (!result.success) { return { success: false, - error: new ParseError('Failed to parse API Gateway V2 envelope body', { - cause: parsedBody.error, + error: new ParseError('Failed to parse API Gateway HTTP body', { + cause: result.error, }), originalEvent: data, }; } - // use type assertion to avoid type check, we know it's success here - return parsedBody; + return { + success: true, + data: result.data.body, + }; }, }; diff --git a/packages/parser/tests/unit/envelopes/apigw.test.ts b/packages/parser/tests/unit/envelopes/apigw.test.ts index f50ffb9174..b298e1eec4 100644 --- a/packages/parser/tests/unit/envelopes/apigw.test.ts +++ b/packages/parser/tests/unit/envelopes/apigw.test.ts @@ -1,123 +1,134 @@ import { describe, expect, it } from 'vitest'; -import { ZodError } from 'zod'; +import { ZodError, z } from 'zod'; import { ApiGatewayEnvelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; +import { JSONStringified } from '../../../src/helpers.js'; import type { APIGatewayProxyEvent } from '../../../src/types/schema.js'; -import { TestSchema, getTestEvent } from '../schema/utils.js'; - -describe('API Gateway REST Envelope', () => { - const eventsPath = 'apigw-rest'; - const eventPrototype = getTestEvent({ - eventsPath, +import { getTestEvent, omit } from '../schema/utils.js'; + +describe('Envelope: API Gateway REST', () => { + const schema = z + .object({ + message: z.string(), + }) + .strict(); + const baseEvent = getTestEvent({ + eventsPath: 'apigw-rest', filename: 'no-auth', }); describe('Method: parse', () => { - it('should throw if the payload does not match the schema', () => { - // Prepare - const event = { ...eventPrototype }; - event.body = JSON.stringify({ name: 'foo' }); - - // Act & Assess - expect(() => ApiGatewayEnvelope.parse(event, TestSchema)).toThrow( - ParseError - ); - }); - - it('should throw if the body is null', () => { + it('throws if the payload does not match the schema', () => { // Prepare - const event = { ...eventPrototype }; - event.body = null; + const event = structuredClone(baseEvent); // Act & Assess - expect(() => ApiGatewayEnvelope.parse(event, TestSchema)).toThrow( - ParseError + expect(() => ApiGatewayEnvelope.parse(event, schema)).toThrow( + expect.objectContaining({ + message: expect.stringContaining('Failed to parse API Gateway body'), + cause: expect.objectContaining({ + issues: [ + { + code: 'invalid_type', + expected: 'object', + received: 'null', + path: ['body'], + message: 'Expected object, received null', + }, + ], + }), + }) ); }); - it('should parse and return the inner schema in an envelope', () => { + it('parses an API Gateway REST event with plain text', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = structuredClone(baseEvent); + event.body = 'hello world'; // Act - const parsedEvent = ApiGatewayEnvelope.parse(event, TestSchema); + const result = ApiGatewayEnvelope.parse(event, z.string()); // Assess - expect(parsedEvent).toEqual(payload); + expect(result).toEqual('hello world'); }); - }); - describe('Method: safeParse', () => { - it('should not throw if the payload does not match the schema', () => { + it('parses an API Gateway REST event with JSON-stringified body', () => { // Prepare - const event = { ...eventPrototype }; - event.body = JSON.stringify({ name: 'foo' }); + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ message: 'hello world' }); // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.parse(event, JSONStringified(schema)); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, - }); - - if (!parseResult.success && parseResult.error) { - expect(parseResult.error.cause).toBeInstanceOf(ZodError); - } + expect(result).toStrictEqual({ message: 'hello world' }); }); - it('should not throw if the body is null', () => { + it('parses an API Gateway REST event with binary body', () => { // Prepare - const event = { ...eventPrototype }; - event.body = null; + const event = structuredClone(baseEvent); + event.body = 'aGVsbG8gd29ybGQ='; // base64 encoded 'hello world' + // @ts-expect-error - we know the headers exist + event.headers['content-type'] = 'application/octet-stream'; + event.isBase64Encoded = true; // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.parse(event, z.string()); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, - }); - - if (!parseResult.success && parseResult.error) { - expect(parseResult.error.cause).toBeInstanceOf(ZodError); - } + expect(result).toEqual('aGVsbG8gd29ybGQ='); }); + }); - it('should not throw if the event is invalid', () => { + describe('Method: safeParse', () => { + it('parses an API Gateway REST event', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ message: 'hello world' }); // Act - const parseResult = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.safeParse( + event, + JSONStringified(schema) + ); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, + expect(result).toEqual({ + success: true, + data: { message: 'hello world' }, }); }); - it('should parse and return the inner schema in an envelope', () => { + it('returns an error if the event is not a valid API Gateway REST event', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = omit(['path'], structuredClone(baseEvent)); // Act - const parsedEvent = ApiGatewayEnvelope.safeParse(event, TestSchema); + const result = ApiGatewayEnvelope.safeParse(event, schema); // Assess - expect(parsedEvent).toEqual({ - success: true, - data: payload, + expect(result).toEqual({ + success: false, + error: new ParseError('Failed to parse API Gateway body', { + cause: new ZodError([ + { + code: 'invalid_type', + expected: 'string', + received: 'undefined', + path: ['path'], + message: 'Required', + }, + { + code: 'invalid_type', + expected: 'object', + received: 'null', + path: ['body'], + message: 'Expected object, received null', + }, + ]), + }), + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/envelopes/apigwv2.test.ts b/packages/parser/tests/unit/envelopes/apigwv2.test.ts index 8c96c7cdc3..edf1b9de3b 100644 --- a/packages/parser/tests/unit/envelopes/apigwv2.test.ts +++ b/packages/parser/tests/unit/envelopes/apigwv2.test.ts @@ -1,119 +1,135 @@ import { describe, expect, it } from 'vitest'; -import { ZodError } from 'zod'; +import { ZodError, z } from 'zod'; import { ApiGatewayV2Envelope } from '../../../src/envelopes/index.js'; import { ParseError } from '../../../src/errors.js'; +import { JSONStringified } from '../../../src/helpers.js'; import type { APIGatewayProxyEventV2 } from '../../../src/types/schema.js'; -import { TestSchema, getTestEvent } from '../schema/utils.js'; - -describe('API Gateway HTTP Envelope', () => { - const eventsPath = 'apigw-http'; - const eventPrototype = getTestEvent({ - eventsPath, +import { getTestEvent, omit } from '../schema/utils.js'; + +describe('Envelope: API Gateway HTTP', () => { + const schema = z + .object({ + message: z.string(), + }) + .strict(); + const baseEvent = getTestEvent({ + eventsPath: 'apigw-http', filename: 'no-auth', }); describe('Method: parse', () => { - it('should throw if the payload does not match the schema', () => { - // Prepare - const event = { ...eventPrototype }; - event.body = JSON.stringify({ name: 'foo' }); - - // Act & Assess - expect(() => ApiGatewayV2Envelope.parse(event, TestSchema)).toThrow( - ParseError - ); - }); - - it('should throw if the body is undefined', () => { + it('throws if the payload does not match the schema', () => { // Prepare - const event = { ...eventPrototype }; - event.body = undefined; + const event = structuredClone(baseEvent); // Act & Assess - expect(() => ApiGatewayV2Envelope.parse(event, TestSchema)).toThrow( - ParseError + expect(() => ApiGatewayV2Envelope.parse(event, schema)).toThrow( + expect.objectContaining({ + message: expect.stringContaining( + 'Failed to parse API Gateway HTTP body' + ), + cause: expect.objectContaining({ + issues: [ + { + code: 'invalid_type', + expected: 'object', + received: 'undefined', + path: ['body'], + message: 'Required', + }, + ], + }), + }) ); }); - it('should parse and return the inner schema in an envelope', () => { + it('parses an API Gateway HTTP event with plain text', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = structuredClone(baseEvent); + event.body = 'hello world'; // Act - const parsedEvent = ApiGatewayV2Envelope.parse(event, TestSchema); + const result = ApiGatewayV2Envelope.parse(event, z.string()); // Assess - expect(parsedEvent).toEqual(payload); + expect(result).toEqual('hello world'); }); - }); - describe('Method: safeParse', () => { - it('should not throw if the payload does not match the schema', () => { + it('parses an API Gateway HTTP event with JSON-stringified body', () => { // Prepare - const event = { ...eventPrototype }; - event.body = JSON.stringify({ name: 'foo' }); + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ message: 'hello world' }); // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const result = ApiGatewayV2Envelope.parse(event, JSONStringified(schema)); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, - }); - - if (!parseResult.success && parseResult.error) { - expect(parseResult.error.cause).toBeInstanceOf(ZodError); - } + expect(result).toStrictEqual({ message: 'hello world' }); }); - it('should not throw if the body is undefined', () => { + it('parses an API Gateway HTTP event with binary body', () => { // Prepare - const event = { ...eventPrototype }; - event.body = undefined; + const event = structuredClone(baseEvent); + event.body = 'aGVsbG8gd29ybGQ='; // base64 encoded 'hello world' + event.headers['content-type'] = 'application/octet-stream'; + event.isBase64Encoded = true; // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const result = ApiGatewayV2Envelope.parse(event, z.string()); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, - }); + expect(result).toEqual('aGVsbG8gd29ybGQ='); }); + }); - it('should not throw if the event is invalid', () => { + describe('Method: safeParse', () => { + it('parses an API Gateway HTTP event', () => { // Prepare - const event = getTestEvent({ eventsPath, filename: 'invalid' }); + const event = structuredClone(baseEvent); + event.body = JSON.stringify({ message: 'hello world' }); // Act - const parseResult = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const result = ApiGatewayV2Envelope.safeParse( + event, + JSONStringified(schema) + ); // Assess - expect(parseResult).toEqual({ - success: false, - error: expect.any(ParseError), - originalEvent: event, + expect(result).toEqual({ + success: true, + data: { message: 'hello world' }, }); }); - it('should parse and return the inner schema in an envelope', () => { + it('returns an error if the event is not a valid API Gateway HTTP event', () => { // Prepare - const event = { ...eventPrototype }; - const payload = { name: 'foo', age: 42 }; - event.body = JSON.stringify(payload); + const event = omit(['rawPath'], structuredClone(baseEvent)); // Act - const parsedEvent = ApiGatewayV2Envelope.safeParse(event, TestSchema); + const result = ApiGatewayV2Envelope.safeParse(event, schema); // Assess - expect(parsedEvent).toEqual({ - success: true, - data: payload, + expect(result).toEqual({ + success: false, + error: new ParseError('Failed to parse API Gateway HTTP body', { + cause: new ZodError([ + { + code: 'invalid_type', + expected: 'string', + received: 'undefined', + path: ['rawPath'], + message: 'Required', + }, + { + code: 'invalid_type', + expected: 'object', + received: 'undefined', + path: ['body'], + message: 'Required', + }, + ]), + }), + originalEvent: event, }); }); }); diff --git a/packages/parser/tests/unit/schema/apigw.test.ts b/packages/parser/tests/unit/schema/apigw.test.ts index fa205b532b..b9bedbcaec 100644 --- a/packages/parser/tests/unit/schema/apigw.test.ts +++ b/packages/parser/tests/unit/schema/apigw.test.ts @@ -6,11 +6,11 @@ import { } from '../../../src/schemas/index.js'; import { getTestEvent } from './utils.js'; -describe('API Gateway REST Schemas', () => { +describe('Schema: API Gateway REST', () => { const eventsPath = 'apigw-rest'; describe('APIGatewayProxyEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -18,7 +18,7 @@ describe('API Gateway REST Schemas', () => { expect(() => APIGatewayProxyEventSchema.parse(event)).toThrow(); }); - it('should parse an event with no authorizer', () => { + it('parses an event with no authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'no-auth' }); @@ -29,7 +29,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a lambda authorizer', () => { + it('parses an event with a lambda authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -43,7 +43,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a JWT authorizer', () => { + it('parses an event with a JWT authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -57,7 +57,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with an IAM authorizer', () => { + it('parses an event with an IAM authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -71,7 +71,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event sent by the AWS console test UI', () => { + it('parses an event sent by the AWS console test UI', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -85,7 +85,7 @@ describe('API Gateway REST Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event sent as a part of a websocket API', () => { + it('parses an event sent as a part of a websocket API', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -101,7 +101,7 @@ describe('API Gateway REST Schemas', () => { }); describe('APIGatewayRequestAuthorizerEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -111,7 +111,7 @@ describe('API Gateway REST Schemas', () => { ).toThrow(); }); - it('should parse the authorizer event', () => { + it('parses the authorizer event', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -127,7 +127,7 @@ describe('API Gateway REST Schemas', () => { }); describe('APIGatewayTokenAuthorizerEventSchema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -135,7 +135,7 @@ describe('API Gateway REST Schemas', () => { expect(() => APIGatewayTokenAuthorizerEventSchema.parse(event)).toThrow(); }); - it('should parse the event', () => { + it('parses the event', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'authorizer-token' }); diff --git a/packages/parser/tests/unit/schema/apigwv2.test.ts b/packages/parser/tests/unit/schema/apigwv2.test.ts index 916b20e2f8..b0dfe1e551 100644 --- a/packages/parser/tests/unit/schema/apigwv2.test.ts +++ b/packages/parser/tests/unit/schema/apigwv2.test.ts @@ -8,11 +8,11 @@ import { import type { APIGatewayProxyEventV2 } from '../../../src/types/schema.js'; import { getTestEvent } from './utils.js'; -describe('API Gateway HTTP (v2) Schemas', () => { +describe('Schema: API Gateway HTTP (v2)', () => { const eventsPath = 'apigw-http'; describe('APIGatewayProxyEventV2Schema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -20,7 +20,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(() => APIGatewayProxyEventV2Schema.parse(event)).toThrow(); }); - it('should parse an event with no authorizer', () => { + it('parses an event with no authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'no-auth' }); @@ -31,7 +31,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a lambda authorizer', () => { + it('parses an event with a lambda authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -45,7 +45,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with a JWT authorizer', () => { + it('parses an event with a JWT authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -59,7 +59,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse an event with an IAM authorizer', () => { + it('parses an event with an IAM authorizer', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -75,7 +75,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { }); describe('APIGatewayRequestAuthorizerEventV2Schema', () => { - it('should throw when the event is invalid', () => { + it('throws when the event is invalid', () => { // Prepare const event = getTestEvent({ eventsPath, filename: 'invalid' }); @@ -85,7 +85,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { ).toThrow(); }); - it('should parse the authorizer event', () => { + it('parses the authorizer event', () => { // Prepare const event = getTestEvent({ eventsPath, @@ -99,7 +99,7 @@ describe('API Gateway HTTP (v2) Schemas', () => { expect(parsedEvent).toEqual(event); }); - it('should parse the authorizer event with null identitySource', () => { + it('parses the authorizer event with null identitySource', () => { // Prepare const event = getTestEvent({ eventsPath, From 39cc89e3f907ea11da12d04b9160f9af34db8f6d Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 22 Jan 2025 17:53:33 +0100 Subject: [PATCH 2/2] chore: remove Envelope from coverage --- packages/parser/src/envelopes/envelope.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/parser/src/envelopes/envelope.ts b/packages/parser/src/envelopes/envelope.ts index 85cdef225f..312dc022ec 100644 --- a/packages/parser/src/envelopes/envelope.ts +++ b/packages/parser/src/envelopes/envelope.ts @@ -2,6 +2,7 @@ import type { ZodSchema, z } from 'zod'; import { ParseError } from '../errors.js'; import type { ParsedResult } from '../types/parser.js'; +/* v8 ignore start */ const Envelope = { /** * Abstract function to parse the content of the envelope using provided schema. @@ -35,7 +36,10 @@ const Envelope = { * @param input * @param schema */ - safeParse(input: unknown, schema: T): ParsedResult> { + safeParse( + input: unknown, + schema: T + ): ParsedResult> { try { if (typeof input !== 'object' && typeof input !== 'string') { return { @@ -75,3 +79,4 @@ const Envelope = { const envelopeDiscriminator = Symbol.for('returnType'); export { Envelope, envelopeDiscriminator }; +/* v8 ignore stop */