safe-wrapper 2.1.0 → 4.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,7 +5,9 @@
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
 
@@ -15,6 +17,7 @@ safe-wrapper is a lightweight utility for javascript that simplifies error handl
15
17
  - `error`: null if successful, else an error (or transformed object).
16
18
  - `result`: return value (sync) or resolved value (async) when successful, else null.
17
19
  - supports custom error transformation for advanced error handling.
20
+ - written in typescript with comprehensive type definitions, enabling full type inference support.
18
21
 
19
22
  ### Installation
20
23
 
@@ -24,7 +27,7 @@ npm install safe-wrapper
24
27
 
25
28
  ### Usage
26
29
 
27
- 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.
28
31
 
29
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.
30
33
 
@@ -79,10 +82,10 @@ const [error, result] = await safeAsync(args);
79
82
 
80
83
  we can specify multiple error types when wrapping a function, enabling safe to catch any of the specified errors.
81
84
 
82
- ```javascript
85
+ ```typescript
83
86
  import { safe } from 'safe-wrapper';
84
87
 
85
- const sync = (args) => {
88
+ const sync = (args: boolean): string => {
86
89
  if (args) {
87
90
  throw new TypeError('sync type error occurred');
88
91
  } else {
@@ -98,10 +101,12 @@ const [error, result] = safeSync(args);
98
101
 
99
102
  you can provide a custom error transformer function to modify how errors are handled:
100
103
 
101
- ```javascript
104
+ ```typescript
102
105
  import { safe } from 'safe-wrapper';
103
106
 
104
- const transformer = (error) => ({
107
+ type TransformedError = { code: string, message: string, timestamp: Date };
108
+
109
+ const transformer = (error: Error): TransformedError => ({
105
110
  code: error.name,
106
111
  message: error.message,
107
112
  timestamp: new Date()
@@ -114,17 +119,19 @@ const safeWithTransform = safe(
114
119
  );
115
120
 
116
121
  const [error, result] = safeWithTransform();
117
- // error will be: { code: 'Error', message: 'custom sync error', timestamp: Date }
122
+ // error will be of type TransformedError as: { code: 'Error', message: 'custom sync error', timestamp: Date }
118
123
  ```
119
124
 
120
125
  #### using asynchronous custom error transformer
121
126
 
122
127
  you can provide an asynchronous custom error transformer to modify how errors are handled.
123
128
 
124
- ```javascript
129
+ ```typescript
125
130
  import { safe } from 'safe-wrapper';
126
131
 
127
- const transformer = async (error) => {
132
+ type AsyncTransformedError = { code: string, message: string, timestamp: Date };
133
+
134
+ const transformer = async (error: Error): Promise<AsyncTransformedError> => {
128
135
  await report(error);
129
136
 
130
137
  return {
@@ -141,7 +148,7 @@ const safeWithTransform = safe(
141
148
  );
142
149
 
143
150
  const [error, result] = await safeWithTransform();
144
- // error will be: { code: 'Error', message: 'custom async error', timestamp: Date }
151
+ // error will be of type AsyncTransformedError as: { code: 'Error', message: 'custom async error', timestamp: Date }
145
152
  ```
146
153
 
147
154
  #### wrapping built-in functions
package/lib/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var f=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var l=(n,e)=>{for(var t in e)f(n,t,{get:e[t],enumerable:!0})},m=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let c of a(e))!h.call(n,c)&&c!==t&&f(n,c,{get:()=>e[c],enumerable:!(o=d(e,c))||o.enumerable});return n};var p=n=>m(f({},"__esModule",{value:!0}),n);var y={};l(y,{safe:()=>g});module.exports=p(y);var r=({error:n=null,data:e=null,result:t=void 0})=>[n,t!==void 0?t:e],s=n=>n instanceof Promise||typeof n?.then=="function",b=n=>(...e)=>{try{let t=n(...e);return s(t)?t.then(o=>r({error:o})).catch(o=>r({error:o})):r({error:t})}catch(t){return r({error:t})}},i=(n,e=[],t=void 0)=>{let o=!e.length||e.some(u=>n instanceof u),c=t!==void 0&&typeof t=="function";if(o)return c?b(t)(n):r({error:n});throw n},g=(n,e=[],t=void 0)=>(...o)=>{try{let c=n(...o);return s(c)?c.then(u=>r({data:u})).catch(u=>i(u,e,t)):r({result:c})}catch(c){return i(c,e,t)}};
1
+ "use strict";var y=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var c=(r,e)=>{for(var o in e)y(r,o,{get:e[o],enumerable:!0})},l=(r,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of i(e))!u.call(r,n)&&n!==o&&y(r,n,{get:()=>e[n],enumerable:!(s=a(e,n))||s.enumerable});return r};var m=r=>l(y({},"__esModule",{value:!0}),r);var P={};c(P,{safe:()=>R});module.exports=m(P);var p=({error:r,data:e})=>r?[r,null]:[null,e],E=r=>r instanceof Promise||r!==null&&typeof r=="object"&&"then"in r&&typeof r.then=="function",f=r=>e=>{let o=r(e);return E(o)?o.then(s=>p({error:s})):p({error:o})},T=(r,e=[],o)=>{let s=!e.length||e.some(t=>r instanceof t),n=o!==void 0&&typeof o=="function";if(s)return n?f(o)(r):p({error:r});throw r},R=(r,e=[],o)=>((...s)=>{try{let n=r(...s);return E(n)?n.then(t=>p({data:t})).catch(t=>T(t,e,o)):p({data:n})}catch(n){return T(n,e,o)}});0&&(module.exports={safe});
package/lib/index.d.ts CHANGED
@@ -1,13 +1,5 @@
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
- * @template R,
5
- * @template [T = Error]
6
- *
7
- * @param {(...args: any[]) => R} action - the function to be wrapped.
8
- * @param {Array<ErrorConstructor>} [types = []] - an optional array of error types to catch.
9
- * @param {(error: Error) => Promise<T> | T} [transformer] - an optional function to transform the error object.
10
- *
11
- * @returns {(...args: Parameters<typeof action>) => R extends Promise<infer U> ? Promise<[T, null] | [null, U]> : [T, null] | [null, R]} - a tuple where the first element is the error object, if available, or the transformed error object, if a transformer function is provided. the second element is the result of the action, if available.
12
- */
13
- export function safe<R, T = Error>(action: (...args: any[]) => R, types?: Array<ErrorConstructor>, transformer?: (error: Error) => Promise<T> | T): (...args: Parameters<typeof action>) => R extends Promise<infer U> ? Promise<[T, null] | [null, U]> : [T, null] | [null, R];
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
+ type ErrorConstructor = new (...args: any[]) => Error;
4
+ declare const safe: <ActionType extends (...args: any[]) => any, ErrorType = Error>(action: ActionType, types?: ErrorConstructor[], transformer?: (error: Error) => Promise<ErrorType> | ErrorType) => Safe<ActionType, ErrorType>;
5
+ export { safe };
package/lib/index.mjs CHANGED
@@ -1 +1 @@
1
- var r=({error:t=null,data:e=null,result:n=void 0})=>[t,n!==void 0?n:e],i=t=>t instanceof Promise||typeof t?.then=="function",s=t=>(...e)=>{try{let n=t(...e);return i(n)?n.then(c=>r({error:c})).catch(c=>r({error:c})):r({error:n})}catch(n){return r({error:n})}},f=(t,e=[],n=void 0)=>{let c=!e.length||e.some(u=>t instanceof u),o=n!==void 0&&typeof n=="function";if(c)return o?s(n)(t):r({error:t});throw t},d=(t,e=[],n=void 0)=>(...c)=>{try{let o=t(...c);return i(o)?o.then(u=>r({data:u})).catch(u=>f(u,e,n)):r({result:o})}catch(o){return f(o,e,n)}};export{d as safe};
1
+ var p=({error:r,data:o})=>r?[r,null]:[null,o],T=r=>r instanceof Promise||r!==null&&typeof r=="object"&&"then"in r&&typeof r.then=="function",E=r=>o=>{let e=r(o);return T(e)?e.then(s=>p({error:s})):p({error:e})},y=(r,o=[],e)=>{let s=!o.length||o.some(t=>r instanceof t),n=e!==void 0&&typeof e=="function";if(s)return n?E(e)(r):p({error:r});throw r},a=(r,o=[],e)=>((...s)=>{try{let n=r(...s);return T(n)?n.then(t=>p({data:t})).catch(t=>y(t,o,e)):p({data:n})}catch(n){return y(n,o,e)}});export{a as safe};
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "safe-wrapper",
3
- "version": "2.1.0",
4
- "description": "a js-util for safely wrapping synchronous and asynchronous functions to handle errors based on specified types.",
3
+ "version": "4.0.0",
4
+ "description": "a ts-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",
7
7
  "types": "lib/index.d.ts",
8
8
  "module": "lib/index.mjs",
9
9
  "scripts": {
10
- "build": "rm -rf lib && node esbuild.config.js",
11
- "ci": "npm install --clean-install && npm test && npm run build",
12
- "start": "node src/index.js",
13
- "test": "node --test"
10
+ "build": "rm -rf lib && tsx esbuild.config.ts",
11
+ "ci": "npm ci && npm test && npm run build",
12
+ "start": "tsx src/index.ts",
13
+ "test": "tsx test/*.test.ts"
14
14
  },
15
15
  "exports": {
16
16
  ".": {
@@ -37,7 +37,9 @@
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
+ "@types/node": "^25.1.0",
41
+ "esbuild": "^0.27.2",
42
+ "tsx": "^4.21.0",
43
+ "typescript": "^5.9.3"
42
44
  }
43
45
  }
package/2.0.1 DELETED
File without changes