New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

toucan-js

Package Overview
Dependencies
Maintainers
0
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

toucan-js - npm Package Compare versions

Comparing version

to
4.1.0

dist/integrations/zod/integration.d.ts

179

dist/index.cjs.js

@@ -154,4 +154,4 @@ 'use strict';

const DEFAULT_LIMIT = 5;
const linkedErrorsIntegration = core.defineIntegration((options = { limit: DEFAULT_LIMIT }) => {
const DEFAULT_LIMIT$1 = 5;
const linkedErrorsIntegration = core.defineIntegration((options = { limit: DEFAULT_LIMIT$1 }) => {
return {

@@ -394,2 +394,172 @@ name: 'LinkedErrors',

/**
* Define an integration function that can be used to create an integration instance.
* Note that this by design hides the implementation details of the integration, as they are considered internal.
*
* Inlined from https://github.com/getsentry/sentry-javascript/blob/develop/packages/core/src/integration.ts#L165
*/
function defineIntegration(fn) {
return fn;
}
// Adapted from: https://github.com/getsentry/sentry-javascript/blob/develop/packages/core/src/integrations/zoderrors.ts
const INTEGRATION_NAME = 'ZodErrors';
const DEFAULT_LIMIT = 10;
function originalExceptionIsZodError(originalException) {
return (utils.isError(originalException) &&
originalException.name === 'ZodError' &&
Array.isArray(originalException.errors));
}
/**
* Formats child objects or arrays to a string
* that is preserved when sent to Sentry.
*
* Without this, we end up with something like this in Sentry:
*
* [
* [Object],
* [Object],
* [Object],
* [Object]
* ]
*/
function flattenIssue(issue) {
return {
...issue,
path: 'path' in issue && Array.isArray(issue.path)
? issue.path.join('.')
: undefined,
keys: 'keys' in issue ? JSON.stringify(issue.keys) : undefined,
unionErrors: 'unionErrors' in issue ? JSON.stringify(issue.unionErrors) : undefined,
};
}
/**
* Takes ZodError issue path array and returns a flattened version as a string.
* This makes it easier to display paths within a Sentry error message.
*
* Array indexes are normalized to reduce duplicate entries
*
* @param path ZodError issue path
* @returns flattened path
*
* @example
* flattenIssuePath([0, 'foo', 1, 'bar']) // -> '<array>.foo.<array>.bar'
*/
function flattenIssuePath(path) {
return path
.map((p) => {
if (typeof p === 'number') {
return '<array>';
}
else {
return p;
}
})
.join('.');
}
/**
* Zod error message is a stringified version of ZodError.issues
* This doesn't display well in the Sentry UI. Replace it with something shorter.
*/
function formatIssueMessage(zodError) {
const errorKeyMap = new Set();
for (const iss of zodError.issues) {
const issuePath = flattenIssuePath(iss.path);
if (issuePath.length > 0) {
errorKeyMap.add(issuePath);
}
}
const errorKeys = Array.from(errorKeyMap);
if (errorKeys.length === 0) {
// If there are no keys, then we're likely validating the root
// variable rather than a key within an object. This attempts
// to extract what type it was that failed to validate.
// For example, z.string().parse(123) would return "string" here.
let rootExpectedType = 'variable';
if (zodError.issues.length > 0) {
const iss = zodError.issues[0];
if ('expected' in iss && typeof iss.expected === 'string') {
rootExpectedType = iss.expected;
}
}
return `Failed to validate ${rootExpectedType}`;
}
return `Failed to validate keys: ${utils.truncate(errorKeys.join(', '), 100)}`;
}
/**
* Applies ZodError issues to an event context and replaces the error message
*/
function applyZodErrorsToEvent(limit, event, saveAttachments, hint) {
if (event.exception === undefined ||
event.exception.values === undefined ||
hint === undefined ||
hint.originalException === undefined ||
!originalExceptionIsZodError(hint.originalException) ||
hint.originalException.issues.length === 0) {
return event;
}
try {
const flattenedIssues = hint.originalException.errors.map(flattenIssue);
if (saveAttachments === true) {
// Add an attachment with all issues (no limits), as well as the default
// flatten format to see if it's preferred over our custom flatten format.
if (!Array.isArray(hint.attachments)) {
hint.attachments = [];
}
hint.attachments.push({
filename: 'zod_issues.json',
data: JSON.stringify({
issueDetails: hint.originalException.flatten(flattenIssue),
}),
});
}
return {
...event,
exception: {
...event.exception,
values: [
{
...event.exception.values[0],
value: formatIssueMessage(hint.originalException),
},
...event.exception.values.slice(1),
],
},
extra: {
...event.extra,
'zoderror.issues': flattenedIssues.slice(0, limit),
},
};
}
catch (e) {
// Hopefully we never throw errors here, but record it
// with the event just in case.
return {
...event,
extra: {
...event.extra,
'zoderrors sentry integration parse error': {
message: `an exception was thrown while processing ZodError within applyZodErrorsToEvent()`,
error: e instanceof Error
? `${e.name}: ${e.message}\n${e.stack}`
: 'unknown',
},
},
};
}
}
/**
* Sentry integration to process Zod errors, making them easier to work with in Sentry.
*/
const zodErrorsIntegration = defineIntegration((options = {}) => {
const limit = options.limit ?? DEFAULT_LIMIT;
return {
name: INTEGRATION_NAME,
processEvent(originalEvent, hint) {
const processedEvent = applyZodErrorsToEvent(limit, originalEvent, options.saveAttachments, hint);
return processedEvent;
},
};
});
/**
* Installs integrations on the current scope.

@@ -452,6 +622,6 @@ *

name: 'npm:' + 'toucan-js',
version: '4.0.0',
version: '4.1.0',
},
],
version: '4.0.0',
version: '4.1.0',
};

@@ -611,2 +781,3 @@ super(options);

linkedErrorsIntegration(),
zodErrorsIntegration(),
]),

@@ -613,0 +784,0 @@ ];

@@ -1,3 +0,3 @@

import { GLOBAL_OBJ, isError, isPlainObject, extractExceptionKeysForMessage, normalizeToSize, addExceptionTypeValue, addExceptionMechanism, isInstanceOf, resolvedSyncPromise, createStackParser, nodeStackLineParser, basename, rejectedSyncPromise, stackParserFromStackParserOptions } from '@sentry/utils';
import { defineIntegration, ServerRuntimeClient, createTransport, Scope, getIntegrationsToSetup } from '@sentry/core';
import { GLOBAL_OBJ, isError, isPlainObject, extractExceptionKeysForMessage, normalizeToSize, addExceptionTypeValue, addExceptionMechanism, isInstanceOf, truncate, resolvedSyncPromise, createStackParser, nodeStackLineParser, basename, rejectedSyncPromise, stackParserFromStackParserOptions } from '@sentry/utils';
import { defineIntegration as defineIntegration$1, ServerRuntimeClient, createTransport, Scope, getIntegrationsToSetup } from '@sentry/core';
export { dedupeIntegration, extraErrorDataIntegration, rewriteFramesIntegration, sessionTimingIntegration } from '@sentry/core';

@@ -153,4 +153,4 @@

const DEFAULT_LIMIT = 5;
const linkedErrorsIntegration = defineIntegration((options = { limit: DEFAULT_LIMIT }) => {
const DEFAULT_LIMIT$1 = 5;
const linkedErrorsIntegration = defineIntegration$1((options = { limit: DEFAULT_LIMIT$1 }) => {
return {

@@ -188,3 +188,3 @@ name: 'LinkedErrors',

};
const requestDataIntegration = defineIntegration((userOptions = {}) => {
const requestDataIntegration = defineIntegration$1((userOptions = {}) => {
const options = { ...defaultRequestDataOptions, ...userOptions };

@@ -394,2 +394,172 @@ return {

/**
* Define an integration function that can be used to create an integration instance.
* Note that this by design hides the implementation details of the integration, as they are considered internal.
*
* Inlined from https://github.com/getsentry/sentry-javascript/blob/develop/packages/core/src/integration.ts#L165
*/
function defineIntegration(fn) {
return fn;
}
// Adapted from: https://github.com/getsentry/sentry-javascript/blob/develop/packages/core/src/integrations/zoderrors.ts
const INTEGRATION_NAME = 'ZodErrors';
const DEFAULT_LIMIT = 10;
function originalExceptionIsZodError(originalException) {
return (isError(originalException) &&
originalException.name === 'ZodError' &&
Array.isArray(originalException.errors));
}
/**
* Formats child objects or arrays to a string
* that is preserved when sent to Sentry.
*
* Without this, we end up with something like this in Sentry:
*
* [
* [Object],
* [Object],
* [Object],
* [Object]
* ]
*/
function flattenIssue(issue) {
return {
...issue,
path: 'path' in issue && Array.isArray(issue.path)
? issue.path.join('.')
: undefined,
keys: 'keys' in issue ? JSON.stringify(issue.keys) : undefined,
unionErrors: 'unionErrors' in issue ? JSON.stringify(issue.unionErrors) : undefined,
};
}
/**
* Takes ZodError issue path array and returns a flattened version as a string.
* This makes it easier to display paths within a Sentry error message.
*
* Array indexes are normalized to reduce duplicate entries
*
* @param path ZodError issue path
* @returns flattened path
*
* @example
* flattenIssuePath([0, 'foo', 1, 'bar']) // -> '<array>.foo.<array>.bar'
*/
function flattenIssuePath(path) {
return path
.map((p) => {
if (typeof p === 'number') {
return '<array>';
}
else {
return p;
}
})
.join('.');
}
/**
* Zod error message is a stringified version of ZodError.issues
* This doesn't display well in the Sentry UI. Replace it with something shorter.
*/
function formatIssueMessage(zodError) {
const errorKeyMap = new Set();
for (const iss of zodError.issues) {
const issuePath = flattenIssuePath(iss.path);
if (issuePath.length > 0) {
errorKeyMap.add(issuePath);
}
}
const errorKeys = Array.from(errorKeyMap);
if (errorKeys.length === 0) {
// If there are no keys, then we're likely validating the root
// variable rather than a key within an object. This attempts
// to extract what type it was that failed to validate.
// For example, z.string().parse(123) would return "string" here.
let rootExpectedType = 'variable';
if (zodError.issues.length > 0) {
const iss = zodError.issues[0];
if ('expected' in iss && typeof iss.expected === 'string') {
rootExpectedType = iss.expected;
}
}
return `Failed to validate ${rootExpectedType}`;
}
return `Failed to validate keys: ${truncate(errorKeys.join(', '), 100)}`;
}
/**
* Applies ZodError issues to an event context and replaces the error message
*/
function applyZodErrorsToEvent(limit, event, saveAttachments, hint) {
if (event.exception === undefined ||
event.exception.values === undefined ||
hint === undefined ||
hint.originalException === undefined ||
!originalExceptionIsZodError(hint.originalException) ||
hint.originalException.issues.length === 0) {
return event;
}
try {
const flattenedIssues = hint.originalException.errors.map(flattenIssue);
if (saveAttachments === true) {
// Add an attachment with all issues (no limits), as well as the default
// flatten format to see if it's preferred over our custom flatten format.
if (!Array.isArray(hint.attachments)) {
hint.attachments = [];
}
hint.attachments.push({
filename: 'zod_issues.json',
data: JSON.stringify({
issueDetails: hint.originalException.flatten(flattenIssue),
}),
});
}
return {
...event,
exception: {
...event.exception,
values: [
{
...event.exception.values[0],
value: formatIssueMessage(hint.originalException),
},
...event.exception.values.slice(1),
],
},
extra: {
...event.extra,
'zoderror.issues': flattenedIssues.slice(0, limit),
},
};
}
catch (e) {
// Hopefully we never throw errors here, but record it
// with the event just in case.
return {
...event,
extra: {
...event.extra,
'zoderrors sentry integration parse error': {
message: `an exception was thrown while processing ZodError within applyZodErrorsToEvent()`,
error: e instanceof Error
? `${e.name}: ${e.message}\n${e.stack}`
: 'unknown',
},
},
};
}
}
/**
* Sentry integration to process Zod errors, making them easier to work with in Sentry.
*/
const zodErrorsIntegration = defineIntegration((options = {}) => {
const limit = options.limit ?? DEFAULT_LIMIT;
return {
name: INTEGRATION_NAME,
processEvent(originalEvent, hint) {
const processedEvent = applyZodErrorsToEvent(limit, originalEvent, options.saveAttachments, hint);
return processedEvent;
},
};
});
/**
* Installs integrations on the current scope.

@@ -452,6 +622,6 @@ *

name: 'npm:' + 'toucan-js',
version: '4.0.0',
version: '4.1.0',
},
],
version: '4.0.0',
version: '4.1.0',
};

@@ -611,2 +781,3 @@ super(options);

linkedErrorsIntegration(),
zodErrorsIntegration(),
]),

@@ -613,0 +784,0 @@ ];

export * from './linkedErrors';
export * from './requestData';
export { zodErrorsIntegration } from './zod/zoderrors';
export { dedupeIntegration, extraErrorDataIntegration, rewriteFramesIntegration, sessionTimingIntegration, } from '@sentry/core';
//# sourceMappingURL=index.d.ts.map

6

package.json
{
"name": "toucan-js",
"sideEffects": false,
"version": "4.0.0",
"version": "4.1.0",
"description": "Cloudflare Workers client for Sentry",

@@ -37,3 +37,3 @@ "main": "dist/index.cjs.js",

"devDependencies": {
"@rollup/plugin-commonjs": "25.0.3",
"@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.1.0",

@@ -48,3 +48,3 @@ "@rollup/plugin-replace": "5.0.2",

"jest": "29.6.1",
"miniflare": "2.14.0",
"miniflare": "3.20240701.0",
"jest-environment-miniflare": "2.10.0",

@@ -51,0 +51,0 @@ "ts-jest": "29.1.1",

@@ -63,2 +63,3 @@ <p align="center">

- [requestDataIntegration](src/integrations/requestData.ts)
- [zodErrorsIntegration](src/integrations/zod/zoderrors.ts)

@@ -65,0 +66,0 @@ ### Custom integration example:

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet