aveazul 0.1.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/LICENSE +17 -0
- package/README.md +87 -0
- package/lib/aveazul.js +356 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Joel Chen
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# AveAzul
|
|
2
|
+
|
|
3
|
+
AveAzul ("Blue Bird" in Spanish) is a Promise extension library that provides Bluebird-like utility methods built on top of native Promises. The name is a Spanish play on words referencing Bluebird.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 16 or higher
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Extends native Promise with Bluebird-like utility methods
|
|
12
|
+
- Built on top of the efficient `xaa` library for async operations
|
|
13
|
+
- Zero external runtime dependencies (other than `xaa`)
|
|
14
|
+
- TypeScript-friendly
|
|
15
|
+
- Familiar Bluebird-style API
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install aveazul
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
const AveAzul = require('aveazul');
|
|
27
|
+
|
|
28
|
+
// Create a new promise
|
|
29
|
+
const promise = new AveAzul((resolve, reject) => {
|
|
30
|
+
setTimeout(() => resolve('result'), 1000);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Use Bluebird-style methods
|
|
34
|
+
promise
|
|
35
|
+
.tap(value => console.log('Got:', value))
|
|
36
|
+
.delay(500)
|
|
37
|
+
.then(value => console.log('After delay:', value));
|
|
38
|
+
|
|
39
|
+
// Static helpers
|
|
40
|
+
AveAzul.delay(1000, 'hello')
|
|
41
|
+
.then(value => console.log(value));
|
|
42
|
+
|
|
43
|
+
// Array operations
|
|
44
|
+
AveAzul.resolve([1, 2, 3])
|
|
45
|
+
.map(x => x * 2)
|
|
46
|
+
.filter(x => x > 4)
|
|
47
|
+
.then(result => console.log(result)); // [6]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### Instance Methods
|
|
53
|
+
|
|
54
|
+
- `tap(fn)` - Execute side effects in a chain
|
|
55
|
+
- `filter(fn)` - Filter array elements
|
|
56
|
+
- `map(fn)` - Map array elements
|
|
57
|
+
- `return(value)` - Inject a value into the chain
|
|
58
|
+
- `each(fn)` - Iterate over array elements
|
|
59
|
+
- `delay(ms)` - Delay execution
|
|
60
|
+
- `timeout(ms, message?)` - Set operation timeout
|
|
61
|
+
- `try(fn)` - Wrap sync/async functions
|
|
62
|
+
- `props(obj)` - Handle object properties
|
|
63
|
+
- `reduce(fn, initialValue?)` - Reduce array
|
|
64
|
+
- `throw(reason)` - Return rejected promise
|
|
65
|
+
- `catchThrow(reason)` - Catch and throw new error
|
|
66
|
+
- `catchReturn(value)` - Catch and return value
|
|
67
|
+
- `get(propertyPath)` - Get nested property
|
|
68
|
+
|
|
69
|
+
### Static Methods
|
|
70
|
+
|
|
71
|
+
- `AveAzul.delay(ms, value?)` - Create delayed promise
|
|
72
|
+
- `AveAzul.map(array, fn)` - Map array elements
|
|
73
|
+
- `AveAzul.try(fn)` - Wrap function execution
|
|
74
|
+
- `AveAzul.props(obj)` - Handle object properties
|
|
75
|
+
- `AveAzul.defer()` - Create deferred promise
|
|
76
|
+
- `AveAzul.promisify(fn, options?)` - Promisify callback functions
|
|
77
|
+
- `AveAzul.each(items, fn)` - Iterate over items
|
|
78
|
+
- `AveAzul.reduce(array, fn, initialValue?)` - Reduce array
|
|
79
|
+
- `AveAzul.throw(reason)` - Create rejected promise
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
Apache 2.0
|
|
84
|
+
|
|
85
|
+
## Dependencies
|
|
86
|
+
|
|
87
|
+
- [xaa](https://github.com/jchip/xaa) - Efficient async/await helpers
|
package/lib/aveazul.js
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const xaa = require("xaa");
|
|
4
|
+
const { promisify: nodePromisify } = require("node:util");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* AveAzul ("Blue Bird" in Spanish) - Extended Promise class that provides Bluebird-like utility methods
|
|
8
|
+
* This implementation is inspired by and provides similar APIs to the Bluebird Promise library,
|
|
9
|
+
* but built on top of native Promises. The name is a Spanish play on words referencing Bluebird.
|
|
10
|
+
* @extends Promise
|
|
11
|
+
*/
|
|
12
|
+
class AveAzul extends Promise {
|
|
13
|
+
constructor(executor) {
|
|
14
|
+
super(executor);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Note: Per ECMAScript specification, when extending Promise, both .then() and static methods
|
|
19
|
+
* (resolve, reject, all, etc) must return instances of the derived class (AveAzul), so there's
|
|
20
|
+
* no need to explicitly wrap returns in new AveAzul(). This behavior is standard across all
|
|
21
|
+
* spec-compliant JS engines (V8, SpiderMonkey, JavaScriptCore, etc).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Bluebird-style tap() method that lets you perform side effects in a chain
|
|
26
|
+
* Similar to Bluebird's Promise.prototype.tap()
|
|
27
|
+
* @param {Function} fn - Function to execute with the resolved value
|
|
28
|
+
* @returns {Promise} Promise that resolves with the original value
|
|
29
|
+
*/
|
|
30
|
+
tap(fn) {
|
|
31
|
+
return this.then(value => {
|
|
32
|
+
fn(value);
|
|
33
|
+
return value;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Bluebird-style filter() method for array operations
|
|
39
|
+
* Similar to Bluebird's Promise.prototype.filter()
|
|
40
|
+
* @param {Function} fn - Filter function to apply to each element
|
|
41
|
+
* @returns {Promise} Promise that resolves with the filtered array
|
|
42
|
+
*/
|
|
43
|
+
filter(fn) {
|
|
44
|
+
return this.then(value => xaa.filter(value, fn));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Bluebird-style map() method for array operations
|
|
49
|
+
* Similar to Bluebird's Promise.prototype.map()
|
|
50
|
+
* @param {Function} fn - Map function to apply to each element
|
|
51
|
+
* @returns {Promise} Promise that resolves with the mapped array
|
|
52
|
+
*/
|
|
53
|
+
map(fn) {
|
|
54
|
+
return this.then(value => xaa.map(value, fn));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Bluebird-style return() method to inject a value into the chain
|
|
59
|
+
* Similar to Bluebird's Promise.prototype.return()
|
|
60
|
+
* @param {*} value - Value to return
|
|
61
|
+
* @returns {Promise} Promise that resolves with the new value
|
|
62
|
+
*/
|
|
63
|
+
return(value) {
|
|
64
|
+
return this.then(() => value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Bluebird-style each() method for array iteration
|
|
69
|
+
* Similar to Bluebird's Promise.prototype.each()
|
|
70
|
+
* @param {Function} fn - Function to execute for each element
|
|
71
|
+
* @returns {Promise} Promise that resolves when iteration is complete
|
|
72
|
+
*/
|
|
73
|
+
each(fn) {
|
|
74
|
+
return this.then(value => xaa.each(value, fn));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Bluebird-style delay() method
|
|
79
|
+
* @param {number} ms - Milliseconds to delay
|
|
80
|
+
* @returns {Promise} Promise that resolves after the delay
|
|
81
|
+
*/
|
|
82
|
+
delay(ms) {
|
|
83
|
+
return this.then(value => xaa.delay(ms, value));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Bluebird-style timeout() method
|
|
88
|
+
* @param {number} ms - Milliseconds before timeout
|
|
89
|
+
* @param {string} [message] - Optional error message
|
|
90
|
+
* @returns {Promise} Promise that rejects if timeout occurs
|
|
91
|
+
*/
|
|
92
|
+
timeout(ms, message = "Operation timed out") {
|
|
93
|
+
return new AveAzul((resolve, reject) => {
|
|
94
|
+
const timer = setTimeout(() => {
|
|
95
|
+
reject(new Error(message));
|
|
96
|
+
}, ms);
|
|
97
|
+
|
|
98
|
+
this.then(
|
|
99
|
+
value => {
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
resolve(value);
|
|
102
|
+
},
|
|
103
|
+
err => {
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
reject(err);
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Bluebird-style try() for wrapping sync/async functions
|
|
113
|
+
* @param {Function} fn - Function to execute
|
|
114
|
+
* @returns {Promise} Promise that resolves with the function's return value
|
|
115
|
+
*/
|
|
116
|
+
try(fn) {
|
|
117
|
+
return new AveAzul((resolve, reject) => {
|
|
118
|
+
try {
|
|
119
|
+
const result = fn();
|
|
120
|
+
if (result && typeof result.then === "function") {
|
|
121
|
+
result.then(resolve, reject);
|
|
122
|
+
} else {
|
|
123
|
+
resolve(result);
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
reject(err);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Bluebird-style props() for object properties
|
|
133
|
+
* @param {Object} obj - Object with promise values
|
|
134
|
+
* @returns {Promise} Promise that resolves with an object of resolved values
|
|
135
|
+
*/
|
|
136
|
+
props(obj) {
|
|
137
|
+
const keys = Object.keys(obj);
|
|
138
|
+
const values = keys.map(k => obj[k]);
|
|
139
|
+
|
|
140
|
+
return AveAzul.all(values).then(results => {
|
|
141
|
+
const resolved = {};
|
|
142
|
+
keys.forEach((k, i) => {
|
|
143
|
+
resolved[k] = results[i];
|
|
144
|
+
});
|
|
145
|
+
return resolved;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Bluebird-style catchIf() with predicate matching
|
|
151
|
+
* @param {Function|Error} predicate - Error class or predicate function
|
|
152
|
+
* @param {Function} fn - Handler function
|
|
153
|
+
* @returns {Promise} Promise with conditional catch handler
|
|
154
|
+
*/
|
|
155
|
+
catchIf(predicate, fn) {
|
|
156
|
+
return this.catch(err => {
|
|
157
|
+
if (
|
|
158
|
+
(typeof predicate === "function" && !predicate.prototype && predicate(err)) ||
|
|
159
|
+
(typeof predicate === "function" && predicate.prototype && err instanceof predicate)
|
|
160
|
+
) {
|
|
161
|
+
return fn(err);
|
|
162
|
+
}
|
|
163
|
+
throw err;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Bluebird-style tapCatch() for side effects on rejection
|
|
169
|
+
* @param {Function} fn - Function to execute on rejection
|
|
170
|
+
* @returns {Promise} Promise that maintains the rejection
|
|
171
|
+
*/
|
|
172
|
+
tapCatch(fn) {
|
|
173
|
+
return this.catch(err => {
|
|
174
|
+
fn(err);
|
|
175
|
+
throw err;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Bluebird-style reduce() method for array reduction
|
|
181
|
+
* Similar to Bluebird's Promise.prototype.reduce()
|
|
182
|
+
* @param {Function} fn - Reducer function to apply to each element
|
|
183
|
+
* @param {*} [initialValue] - Optional initial value
|
|
184
|
+
* @returns {Promise} Promise that resolves with the final reduced value
|
|
185
|
+
*/
|
|
186
|
+
reduce(fn, initialValue) {
|
|
187
|
+
return this.then(array => AveAzul.reduce(array, fn, initialValue));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Bluebird-style throw() that returns a rejected promise with the given reason
|
|
192
|
+
* @param {*} reason - Value to reject the promise with
|
|
193
|
+
* @returns {Promise} Promise that rejects with the given reason
|
|
194
|
+
*/
|
|
195
|
+
throw(reason) {
|
|
196
|
+
return AveAzul.reject(reason);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Bluebird-style catchThrow() that catches an error and throws a new one
|
|
201
|
+
* @param {*} reason - Value to reject the promise with
|
|
202
|
+
* @returns {Promise} Promise that rejects with the new reason
|
|
203
|
+
*/
|
|
204
|
+
catchThrow(reason) {
|
|
205
|
+
return this.catch(() => AveAzul.throw(reason));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Bluebird-style catchReturn() that catches an error and returns a value instead
|
|
210
|
+
* @param {*} value - Value to return
|
|
211
|
+
* @returns {Promise} Promise that resolves with the given value
|
|
212
|
+
*/
|
|
213
|
+
catchReturn(value) {
|
|
214
|
+
return this.catch(() => value);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Bluebird-style get() for retrieving a property value
|
|
219
|
+
* @param {string|number} propertyPath - Path to the property (can be nested using dot notation)
|
|
220
|
+
* @returns {Promise} Promise that resolves with the property value
|
|
221
|
+
*/
|
|
222
|
+
get(propertyPath) {
|
|
223
|
+
return this.then(value => {
|
|
224
|
+
if (value == null) {
|
|
225
|
+
throw new TypeError("Cannot read property '" + propertyPath + "' of " + value);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let result = value;
|
|
229
|
+
const props = String(propertyPath).split(".");
|
|
230
|
+
|
|
231
|
+
for (const prop of props) {
|
|
232
|
+
if (result == null) {
|
|
233
|
+
throw new TypeError("Cannot read property '" + prop + "' of " + result);
|
|
234
|
+
}
|
|
235
|
+
result = result[prop];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return result;
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Static helper methods
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Bluebird-style delay() that resolves after specified milliseconds
|
|
249
|
+
* @param {number} ms - Milliseconds to delay
|
|
250
|
+
* @param {*} [value] - Optional value to resolve with
|
|
251
|
+
* @returns {Promise} Promise that resolves after the delay
|
|
252
|
+
*/
|
|
253
|
+
AveAzul.delay = (ms, value) => {
|
|
254
|
+
if (value === undefined) {
|
|
255
|
+
return AveAzul.resolve(xaa.delay(ms));
|
|
256
|
+
}
|
|
257
|
+
return AveAzul.resolve(xaa.delay(ms, value));
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Bluebird-style map() for array operations
|
|
262
|
+
* @param {Array} value - Array to map over
|
|
263
|
+
* @param {Function} fn - Map function to apply to each element
|
|
264
|
+
* @returns {Promise} Promise that resolves with the mapped array
|
|
265
|
+
*/
|
|
266
|
+
AveAzul.map = (value, fn) => AveAzul.resolve(xaa.map(value, fn));
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Bluebird-style try() for wrapping sync/async functions
|
|
270
|
+
* @param {Function} fn - Function to execute
|
|
271
|
+
* @returns {Promise} Promise that resolves with the function's return value
|
|
272
|
+
*/
|
|
273
|
+
AveAzul.try = fn => AveAzul.resolve(xaa.wrap(fn));
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Bluebird-style props() for object properties
|
|
277
|
+
* @param {Object} obj - Object with promise values
|
|
278
|
+
* @returns {Promise} Promise that resolves with an object of resolved values
|
|
279
|
+
*/
|
|
280
|
+
AveAzul.props = obj => {
|
|
281
|
+
const keys = Object.keys(obj);
|
|
282
|
+
const values = keys.map(k => obj[k]);
|
|
283
|
+
|
|
284
|
+
return AveAzul.all(values).then(results => {
|
|
285
|
+
const resolved = {};
|
|
286
|
+
keys.forEach((k, i) => {
|
|
287
|
+
resolved[k] = results[i];
|
|
288
|
+
});
|
|
289
|
+
return resolved;
|
|
290
|
+
});
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Bluebird-style defer() for creating a deferred promise
|
|
295
|
+
* @returns {Object} Deferred object with promise, resolve, and reject methods
|
|
296
|
+
*/
|
|
297
|
+
AveAzul.defer = () => {
|
|
298
|
+
const deferred = xaa.makeDefer();
|
|
299
|
+
deferred.promise = AveAzul.resolve(deferred.promise);
|
|
300
|
+
return deferred;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Bluebird-style promisify() for converting callback-style functions to promises
|
|
305
|
+
* @param {Function} fn - Function to promisify
|
|
306
|
+
* @param {Object} [options] - Options object
|
|
307
|
+
* @param {Object} [options.context] - `this` context to bind the function to
|
|
308
|
+
* @returns {Function} Promisified function that returns an AveAzul promise
|
|
309
|
+
*/
|
|
310
|
+
AveAzul.promisify = (fn, options = {}) => {
|
|
311
|
+
const promisified = nodePromisify(fn);
|
|
312
|
+
if (options.context) {
|
|
313
|
+
return (...args) => AveAzul.resolve(promisified.apply(options.context, args));
|
|
314
|
+
}
|
|
315
|
+
return (...args) => AveAzul.resolve(promisified(...args));
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Bluebird-style each() for array iteration
|
|
320
|
+
* @param {Array} items - Array to iterate over
|
|
321
|
+
* @param {Function} fn - Iterator function to call for each item
|
|
322
|
+
* @returns {Promise} Promise that resolves when iteration is complete
|
|
323
|
+
*/
|
|
324
|
+
AveAzul.each = (items, fn) => AveAzul.resolve(xaa.each(items, fn));
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Bluebird-style reduce() for array reduction
|
|
328
|
+
* @param {Array} array - Array to reduce
|
|
329
|
+
* @param {Function} fn - Reducer function (value, item, index, length)
|
|
330
|
+
* @param {*} [initialValue] - Optional initial value
|
|
331
|
+
* @returns {Promise} Promise that resolves with the final reduced value
|
|
332
|
+
*/
|
|
333
|
+
AveAzul.reduce = (array, fn, initialValue) => {
|
|
334
|
+
const hasInitial = arguments.length > 2;
|
|
335
|
+
const len = array.length;
|
|
336
|
+
|
|
337
|
+
return AveAzul.resolve().then(async () => {
|
|
338
|
+
let value = hasInitial ? initialValue : array[0];
|
|
339
|
+
const start = hasInitial ? 0 : 1;
|
|
340
|
+
|
|
341
|
+
for (let i = start; i < len; i++) {
|
|
342
|
+
value = await fn(value, array[i], i, len);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return value;
|
|
346
|
+
});
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Bluebird-style throw() that returns a rejected promise with the given reason
|
|
351
|
+
* @param {*} reason - Value to reject the promise with
|
|
352
|
+
* @returns {Promise} Promise that rejects with the given reason
|
|
353
|
+
*/
|
|
354
|
+
AveAzul.throw = reason => AveAzul.reject(reason);
|
|
355
|
+
|
|
356
|
+
module.exports = AveAzul;
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aveazul",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Extend native Promise with bluebird like APIs",
|
|
5
|
+
"main": "lib/aveazul.js",
|
|
6
|
+
"homepage": "",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "jest test",
|
|
10
|
+
"test:watch": "jest test --watch",
|
|
11
|
+
"test:coverage": "jest test --coverage"
|
|
12
|
+
},
|
|
13
|
+
"author": "Joel Chen",
|
|
14
|
+
"files": [
|
|
15
|
+
"lib"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"promise",
|
|
19
|
+
"async",
|
|
20
|
+
"bluebird",
|
|
21
|
+
"nodejs"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": ""
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"xaa": "^1.7.3"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"jest": "^29.7.0"
|
|
32
|
+
}
|
|
33
|
+
}
|