safe-wrapper 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,14 +5,19 @@
5
5
  [![Build Status](https://github.com/mcking-07/safe-wrapper/workflows/publish/badge.svg)](https://github.com/mcking-07/safe-wrapper/actions)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/safe-wrapper.svg)](https://www.npmjs.com/package/safe-wrapper)
7
7
 
8
- safe-wrapper is a lightweight utility for javascript that simplifies error handling for both synchronous and asynchronous functions. inspired by the [safe assignment operator proposal](https://github.com/arthurfiorette/proposal-safe-assignment-operator), this utility allows for graceful error management by wrapping functions in a way that enables error handling without the need for explicit `try-catch` blocks.
8
+ safe-wrapper is a lightweight, typescript-first utility that simplifies error handling for both synchronous and asynchronous functions. inspired by the [safe assignment operator proposal](https://github.com/arthurfiorette/proposal-safe-assignment-operator), this utility allows for graceful error management by wrapping functions in a way that enables error handling without the need for explicit `try-catch` blocks.
9
+
10
+ in modern javascript and typescript, dealing with functions that might throw errors (especially in asynchronous operations or third-party libraries) often leads to repetitive boilerplate. safe-wrapper offers a cleaner and a more functional approach by reducing boilerplate, enabling full typescript support for type inference, and allowing for flexible error handling by letting you filter specific error types, or transform them into custom formats.
9
11
 
10
12
  ### Features
11
13
 
12
14
  - handles synchronous and asynchronous functions.
13
15
  - supports specifying error types to control which errors are caught and handled.
14
- - returns consistent responses in `[error, result]` format where error is null if no error occurred.
16
+ - returns a consistent response in `[error, result]` format,
17
+ - `error`: null if successful, else an error (or transformed object).
18
+ - `result`: return value (sync) or resolved value (async) when successful, else null.
15
19
  - supports custom error transformation for advanced error handling.
20
+ - written in typescript with comprehensive type definitions, enabling full type inference support.
16
21
 
17
22
  ### Installation
18
23
 
@@ -22,7 +27,7 @@ npm install safe-wrapper
22
27
 
23
28
  ### Usage
24
29
 
25
- import `safe` from `safe-wrapper` to use it with any function.
30
+ import `safe` from `safe-wrapper` to use it with any function. the types for `error` and `result` are automatically inferred.
26
31
 
27
32
  the `safe` function takes a target function (synchronous or asynchronous) and returns a function which handles errors and returns a response in a consistent way. the function returns an array `[error, result]`, where `error` is an instance of the specified error type or `null` if successful, and `result` is the result of the function when there is no error.
28
33
 
@@ -77,10 +82,10 @@ const [error, result] = await safeAsync(args);
77
82
 
78
83
  we can specify multiple error types when wrapping a function, enabling safe to catch any of the specified errors.
79
84
 
80
- ```javascript
85
+ ```typescript
81
86
  import { safe } from 'safe-wrapper';
82
87
 
83
- const sync = (args) => {
88
+ const sync = (args: boolean): string => {
84
89
  if (args) {
85
90
  throw new TypeError('sync type error occurred');
86
91
  } else {
@@ -92,27 +97,58 @@ const safeSync = safe(sync, [TypeError, RangeError]);
92
97
  const [error, result] = safeSync(args);
93
98
  ```
94
99
 
95
- #### using custom error transformer
100
+ #### using synchronous custom error transformer
96
101
 
97
102
  you can provide a custom error transformer function to modify how errors are handled:
98
103
 
99
- ```javascript
104
+ ```typescript
100
105
  import { safe } from 'safe-wrapper';
101
106
 
102
- const transformer = (error) => ({
107
+ type TransformedError = { code: string, message: string, timestamp: Date };
108
+
109
+ const transformer = (error: Error): TransformedError => ({
103
110
  code: error.name,
104
111
  message: error.message,
105
112
  timestamp: new Date()
106
113
  });
107
114
 
108
115
  const safeWithTransform = safe(
109
- () => { throw new Error('custom error'); },
116
+ () => { throw new Error('custom sync error'); },
110
117
  [Error],
111
118
  transformer
112
119
  );
113
120
 
114
121
  const [error, result] = safeWithTransform();
115
- // error will be: { code: 'Error', message: 'custom error', timestamp: Date }
122
+ // error will be of type TransformedError as: { code: 'Error', message: 'custom sync error', timestamp: Date }
123
+ ```
124
+
125
+ #### using asynchronous custom error transformer
126
+
127
+ you can provide an asynchronous custom error transformer to modify how errors are handled.
128
+
129
+ ```typescript
130
+ import { safe } from 'safe-wrapper';
131
+
132
+ type AsyncTransformedError = { code: string, message: string, timestamp: Date };
133
+
134
+ const transformer = async (error: Error): Promise<AsyncTransformedError> => {
135
+ await report(error);
136
+
137
+ return {
138
+ code: error.name,
139
+ message: error.message,
140
+ timestamp: new Date()
141
+ }
142
+ }
143
+
144
+ const safeWithTransform = safe(
145
+ async () => { throw new Error('custom async error'); },
146
+ [Error],
147
+ transformer
148
+ );
149
+
150
+ const [error, result] = await safeWithTransform();
151
+ // error will be of type AsyncTransformedError as: { code: 'Error', message: 'custom async error', timestamp: Date }
116
152
  ```
117
153
 
118
154
  #### wrapping built-in functions
@@ -138,4 +174,4 @@ const [error, result] = safe(Object.keys, [TypeError])(null);
138
174
  - transformer (function, optional): a function that takes an error object and returns a transformed version of it. if not provided, the original error is used.
139
175
  - returns `[error, result]`
140
176
  - error (error | null): the error object if error occurred, otherwise null. if an transformer is provided, this will be the transformed error.
141
- - result (any): the result of the action function if no error occurred, otherwise null.
177
+ - result (result | null): the result of the action function if no error occurred, otherwise null.
package/lib/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var s=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var h=(e,n)=>{for(var t in n)s(e,t,{get:n[t],enumerable:!0})},d=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let c of a(n))!l.call(e,c)&&c!==t&&s(e,c,{get:()=>n[c],enumerable:!(r=i(n,c))||r.enumerable});return e};var m=e=>d(s({},"__esModule",{value:!0}),e);var P={};h(P,{safe:()=>g});module.exports=m(P);var o=({error:e=null,data:n=null,result:t=null})=>[e,t||n],b=e=>(...n)=>{try{let t=e(...n);return t instanceof Promise?t.then(r=>o({error:r})).catch(r=>o({error:r})):o({error:t})}catch(t){return o({error:t})}},f=(e,n=[],t=void 0)=>{let r=!n.length||n.some(u=>e instanceof u),c=t!==void 0&&typeof t=="function";if(r)return c?b(t)(e):o({error:e});throw e},g=(e,n=[],t=void 0)=>(...r)=>{try{let c=e(...r);return c instanceof Promise?c.then(u=>o({data:u})).catch(u=>f(u,n,t)):o({result:c})}catch(c){return f(c,n,t)}};
1
+ "use strict";var T=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var i=(r,e)=>{for(var o in e)T(r,o,{get:e[o],enumerable:!0})},l=(r,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of u(e))!c.call(r,n)&&n!==o&&T(r,n,{get:()=>e[n],enumerable:!(s=E(e,n))||s.enumerable});return r};var m=r=>l(T({},"__esModule",{value:!0}),r);var d={};i(d,{safe:()=>R});module.exports=m(d);var t=({error:r,data:e})=>r?[r,null]:[null,e],a=r=>r instanceof Promise||typeof r=="object"&&r!==null&&typeof r.then=="function",f=r=>e=>{try{let o=r(e);return a(o)?o.then(s=>t({error:s})).catch(s=>t({error:s})):t({error:o})}catch(o){return t({error:o})}},y=(r,e=[],o)=>{let s=!e.length||e.some(p=>r instanceof p),n=o!==void 0&&typeof o=="function";if(s)return n?f(o)(r):t({error:r});throw r},R=(r,e=[],o)=>(...s)=>{try{let n=r(...s);return a(n)?n.then(p=>t({data:p})).catch(p=>y(p,e,o)):t({data:n})}catch(n){return y(n,e,o)}};0&&(module.exports={safe});
package/lib/index.d.ts CHANGED
@@ -1,9 +1,4 @@
1
- /**
2
- * safely executes a synchronous or asynchronous action, handles any errors that occur and returns the result in a consistent response structure.
3
- *
4
- * @param {Function} action - the function to be wrapped, which can either be synchronous or asynchronous.
5
- * @param {Array<ErrorConstructor>} [types = []] - an optional array of error types to check against.
6
- * @param {Function} [transformer = undefined] - an optional function to transform the error object.
7
- * @returns {Promise<[Error, null] | [null, any]> | [Error, null] | [null, any]} - a tuple where the first element is null, if the execution was successful, or an error object if an error occurred. the second element is the result of the action, if available.
8
- */
9
- export function safe(action: Function, types?: Array<ErrorConstructor>, transformer?: Function): Promise<[Error, null] | [null, any]> | [Error, null] | [null, any];
1
+ type Result<ResponseType, ErrorType> = [ErrorType, null] | [null, ResponseType];
2
+ type Safe<ActionType extends (...args: unknown[]) => unknown, ErrorType = Error> = ReturnType<ActionType> extends Promise<infer ResponseType> ? (...args: Parameters<ActionType>) => Promise<Result<ResponseType, ErrorType>> : (...args: Parameters<ActionType>) => Result<ReturnType<ActionType>, ErrorType>;
3
+ declare const safe: <ActionType extends (...args: unknown[]) => unknown, ErrorType = Error>(action: ActionType, types?: ErrorConstructor[], transformer?: (error: Error) => Promise<ErrorType> | ErrorType) => Safe<ActionType, ErrorType>;
4
+ export { safe };
package/lib/index.mjs CHANGED
@@ -1 +1 @@
1
- var o=({error:t=null,data:e=null,result:n=null})=>[t,n||e],f=t=>(...e)=>{try{let n=t(...e);return n instanceof Promise?n.then(c=>o({error:c})).catch(c=>o({error:c})):o({error:n})}catch(n){return o({error:n})}},s=(t,e=[],n=void 0)=>{let c=!e.length||e.some(u=>t instanceof u),r=n!==void 0&&typeof n=="function";if(c)return r?f(n)(t):o({error:t});throw t},i=(t,e=[],n=void 0)=>(...c)=>{try{let r=t(...c);return r instanceof Promise?r.then(u=>o({data:u})).catch(u=>s(u,e,n)):o({result:r})}catch(r){return s(r,e,n)}};export{i as safe};
1
+ var t=({error:r,data:o})=>r?[r,null]:[null,o],y=r=>r instanceof Promise||typeof r=="object"&&r!==null&&typeof r.then=="function",a=r=>o=>{try{let e=r(o);return y(e)?e.then(n=>t({error:n})).catch(n=>t({error:n})):t({error:e})}catch(e){return t({error:e})}},T=(r,o=[],e)=>{let n=!o.length||o.some(p=>r instanceof p),s=e!==void 0&&typeof e=="function";if(n)return s?a(e)(r):t({error:r});throw r},E=(r,o=[],e)=>(...n)=>{try{let s=r(...n);return y(s)?s.then(p=>t({data:p})).catch(p=>T(p,o,e)):t({data:s})}catch(s){return T(s,o,e)}};export{E as safe};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safe-wrapper",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "description": "a js-util for safely wrapping synchronous and asynchronous functions to handle errors based on specified types.",
5
5
  "type": "module",
6
6
  "main": "lib/index.cjs",
@@ -9,8 +9,8 @@
9
9
  "scripts": {
10
10
  "build": "rm -rf lib && node esbuild.config.js",
11
11
  "ci": "npm install --clean-install && npm test && npm run build",
12
- "start": "node src/index.js",
13
- "test": "node --test"
12
+ "start": "tsx src/index.ts",
13
+ "test": "tsx test/*.test.js"
14
14
  },
15
15
  "exports": {
16
16
  ".": {
@@ -37,7 +37,8 @@
37
37
  },
38
38
  "homepage": "https://github.com/mcking-07/safe-wrapper#readme",
39
39
  "devDependencies": {
40
- "esbuild": "^0.24.0",
41
- "typescript": "^5.6.3"
40
+ "esbuild": "^0.25.5",
41
+ "tsx": "^4.19.4",
42
+ "typescript": "^5.8.3"
42
43
  }
43
44
  }
package/2.0.0 DELETED
File without changes