@homer0/extend-promise 1.0.1

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 ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Leonardo Apiwan (@homer0)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # 💫 Extend promise
2
+
3
+ Extend a `Promise` by injecting custom properties using a `Proxy`. The custom properties will be available on the promise chain no matter how many `then`s, `catch`s or `finally`s are added.
4
+
5
+ ## 🍿 Usage
6
+
7
+ > If you are wondering why I built this, go to the [Motivation](#motivation) section.
8
+
9
+ - ⚙️ [Examples](#%EF%B8%8F-examples)
10
+ - 🤘 [Development](#-development)
11
+
12
+ ### ⚙️ Examples
13
+
14
+ > This function can be used with any kind of promises, but the example focuses on requests because, nowadays, they are the most common context for promises.
15
+
16
+ Let's say you have a function that makes a request and you want to be able to return a way to abort it at any point. You can use [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and
17
+ an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to do it, but you can't return just the promise, you need to return the controller, or at least its `abort` method:
18
+
19
+ ```js
20
+ const makeTheRequest = () => {
21
+ const controller = new AbortController();
22
+ const req = fetch('https://...', {
23
+ signal: controller.signal,
24
+ });
25
+
26
+ return { req, controller };
27
+ };
28
+ ```
29
+
30
+ It looks good, but if the function is called from a service or somewhere that is not the actual implementation, you'll need to keep track of both the `Promise` and the `controller`.
31
+
32
+ You could _monkey patch_ the `abort` method to the `Promise`:
33
+
34
+ ```js
35
+ const makeTheRequest = () => {
36
+ const controller = new AbortController();
37
+ const req = fetch('https://...', {
38
+ signal: controller.signal,
39
+ });
40
+ req.abort = controller.abort.bind(this);
41
+ return req;
42
+ };
43
+ ```
44
+
45
+ But there's a problem: the moment a `.then`/`.catch`/`.finally` is added to that `Promise`, a new one is generated, and the patch goes away.
46
+
47
+ This is where `extend-promise` can help you: Either the `controller` or the `abort` method can be added to the chain and the customization will be available no matter how many `.then`s are added:
48
+
49
+ ```js
50
+ import { extendPromise } from '@homer0/extend-promise';
51
+
52
+ const makeTheRequest = () => {
53
+ const controller = new AbortController();
54
+ const req = fetch('https://...', {
55
+ signal: controller.signal,
56
+ });
57
+
58
+ return extendPromise(req, {
59
+ abort: controller.abort.bind(this),
60
+ });
61
+ };
62
+ ```
63
+
64
+ And there you go! You can now receive the request `Promise` and abort it if needed:
65
+
66
+ ```js
67
+ // Make the request
68
+ const req = makeTheRequest()
69
+ .then((response) => response.json())
70
+ .catch((error) => {
71
+ if (error.name === 'AbortError') {
72
+ console.log('to late...');
73
+ }
74
+ ...
75
+ });
76
+
77
+ // Abort it if takes more than one second.
78
+ setTimeout(() => req.abort(), 1000);
79
+ ```
80
+
81
+ ### 🤘 Development
82
+
83
+ As this project is part of the `packages` monorepo, it requires Yarn, and some of the tooling, like ESLint and Husky, are installed on the root's `package.json`.
84
+
85
+ #### Yarn tasks
86
+
87
+ | Task | Description |
88
+ | ------- | -------------------- |
89
+ | `test` | Runs the unit tests. |
90
+ | `build` | Bundles the project. |
91
+
92
+ ## Motivation
93
+
94
+ This used to be part of the [`wootils`](https://www.npmjs.com/package/wootils) package, my personal lib of utilities, but I decided to extract them into individual packages, as part of the `packages` monorepo, and take the oportunity to migrate them to TypeScript.
95
+
96
+ Now, the example in this same `README` is the reason I built it: I wanted the `AbortController` to be available on the `Promise` chain.
@@ -0,0 +1,46 @@
1
+ // src/index.ts
2
+ var PromiseExtender = class {
3
+ promise;
4
+ constructor(promise, properties) {
5
+ this.promise = this.extend(promise, properties);
6
+ }
7
+ extend(promise, properties) {
8
+ if (!(promise instanceof Promise)) {
9
+ throw new Error("'promise' must be a valid Promise instance");
10
+ }
11
+ if (!properties || !Object.keys(properties).length) {
12
+ throw new Error("'properties' must be an object with at least one key");
13
+ }
14
+ const extended = new Proxy(promise, {
15
+ get: (target, name) => {
16
+ const targetKey = name;
17
+ if (typeof name === "string" && ["then", "catch", "finally"].includes(name) && name in target) {
18
+ const fn = target[targetKey];
19
+ return this.extendFunction(fn.bind(target), properties);
20
+ }
21
+ if (name in target) {
22
+ const possibleFn = target[targetKey];
23
+ if (typeof possibleFn["bind"] === "function") {
24
+ return possibleFn["bind"](target);
25
+ }
26
+ }
27
+ const key = name;
28
+ return properties[key];
29
+ }
30
+ });
31
+ return extended;
32
+ }
33
+ extendFunction(fn, properties) {
34
+ return new Proxy(fn, {
35
+ apply: (target, thisArg, args) => {
36
+ const value = target.bind(thisArg)(...args);
37
+ return this.extend(value, properties);
38
+ }
39
+ });
40
+ }
41
+ };
42
+ var extendPromise = (promise, properties) => new PromiseExtender(promise, properties).promise;
43
+ export {
44
+ extendPromise
45
+ };
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["type ExtractGeneric<Type> = Type extends Promise<infer X> ? X : never;\n\ntype ExtendedPromise<T extends Promise<unknown>, P, V = ExtractGeneric<T>> = Omit<\n T,\n 'then' | 'catch' | 'finally'\n> &\n P & {\n then: (...args: Parameters<T['then']>) => ExtendedPromise<Promise<V>, P>;\n catch: (...args: Parameters<T['catch']>) => ExtendedPromise<Promise<V>, P>;\n finally: (...args: Parameters<T['finally']>) => ExtendedPromise<Promise<V>, P>;\n };\ntype GenericFn = (...args: unknown[]) => unknown;\ntype ExtendedFn<F extends GenericFn, P> = F & P;\n\n/**\n * Helper class that creates a proxy for a {@link Promise} in order to add custom\n * properties.\n *\n * The only reason this class exists is so it can \"scope\" the necessary methods to extend\n * {@link Promise} and avoid workarounds in order to declare them, as they need to call\n * themselves recursively.\n */\nclass PromiseExtender<T extends Promise<unknown>, P extends Record<string, unknown>> {\n /**\n * The proxied promise.\n */\n readonly promise: ExtendedPromise<T, P>;\n /**\n * @param promise The promise to extend.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n */\n constructor(promise: T, properties: P) {\n this.promise = this.extend(promise, properties);\n }\n /**\n * The method that actually extends a promise: it creates a proxy of the promise in\n * order to intercept the getters so it can return the custom properties if requested,\n * and return new proxies when `then`, `catch` and `finally` are called; the reason new\n * proxies are created is because those methods return new promises, and without being\n * proxied, the custom properties would be lost.\n *\n * @param promise The promise to proxy.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n * @throws {Error} If `promise` is not a valid instance of {@link Promise}.\n * @throws {Error} If `properties` is not an object or if it doesn't have any\n * properties.\n */\n extend(promise: T, properties: P): ExtendedPromise<T, P> {\n if (!(promise instanceof Promise)) {\n throw new Error(\"'promise' must be a valid Promise instance\");\n }\n\n if (!properties || !Object.keys(properties).length) {\n throw new Error(\"'properties' must be an object with at least one key\");\n }\n\n const extended = new Proxy(promise, {\n /**\n * This is a trap for when something is trying to read/access a property for the\n * promise.\n * The function first validates if it's one of the functions\n * (`then`/`catch`/`finally`) in order to return a proxied function; then, if it's\n * another function (one that doesn't return another promise), it just calls the\n * original; finally, before doing a fallback to the original promise, it checks if\n * it's one of the custom properties that exented the promise.\n *\n * @param target The original promise.\n * @param name The name of the property.\n */\n get: (target, name) => {\n const targetKey = name as keyof typeof target;\n if (\n typeof name === 'string' &&\n ['then', 'catch', 'finally'].includes(name) &&\n name in target\n ) {\n const fn = target[targetKey] as unknown as GenericFn;\n return this.extendFunction(fn.bind(target), properties);\n }\n\n if (name in target) {\n const possibleFn = target[targetKey] as unknown as Record<string, unknown>;\n // eslint-disable-next-line dot-notation\n if (typeof possibleFn['bind'] === 'function') {\n // eslint-disable-next-line dot-notation\n return possibleFn['bind'](target);\n }\n }\n\n const key = name as keyof P;\n return properties[key];\n },\n });\n\n return extended as ExtendedPromise<T, P>;\n }\n /**\n * Creates a proxy for a promise function (`then`/`catch`/`finally`) so the returned\n * promise can also be extended.\n *\n * @param fn The promise function to proxy.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n */\n protected extendFunction<F extends GenericFn>(fn: F, properties: P): ExtendedFn<F, P> {\n return new Proxy(fn, {\n /**\n * This is a trap for when a function gets called (remember this gets used for\n * `then`/\n * `catch`/`finally`); it processes the result using the oringinal function and\n * since promise methods return a promise, instead of returning the original result,\n * it returns an _extended_ version of it.\n *\n * @param target The original function.\n * @param thisArg The promise the function belongs to.\n * @param args The list of arguments sent to the trap.\n */\n apply: (target, thisArg, args) => {\n const value = target.bind(thisArg)(...args);\n return this.extend(value as T, properties);\n },\n }) as ExtendedFn<F, P>;\n }\n}\n\n/**\n * Extends a {@link Promise} by injecting custom properties using a {@link Proxy}. The\n * custom properties will be available on the promise chain no matter how many `then`s,\n * `catch`s or `finally`s are added.\n *\n * @param promise The promise to extend.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n * @throws {Error} If `promise` is not a valid instance of {@link Promise}.\n * @throws {Error} If `properties` is not an object or if it doesn't have any\n * properties.\n */\nexport const extendPromise = <\n T extends Promise<unknown>,\n P extends Record<string, unknown>,\n>(\n promise: T,\n properties: P,\n): ExtendedPromise<T, P> => new PromiseExtender(promise, properties).promise;\n"],"mappings":";AAsBA,IAAM,kBAAN,MAAqF;AAAA,EAInF,AAAS;AAAA,EAMT,YAAY,SAAY,YAAe;AACrC,SAAK,UAAU,KAAK,OAAO,SAAS,UAAU;AAAA,EAChD;AAAA,EAeA,OAAO,SAAY,YAAsC;AACvD,QAAI,CAAE,oBAAmB,UAAU;AACjC,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,QAAI,CAAC,cAAc,CAAC,OAAO,KAAK,UAAU,EAAE,QAAQ;AAClD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAEA,UAAM,WAAW,IAAI,MAAM,SAAS;AAAA,MAalC,KAAK,CAAC,QAAQ,SAAS;AACrB,cAAM,YAAY;AAClB,YACE,OAAO,SAAS,YAChB,CAAC,QAAQ,SAAS,SAAS,EAAE,SAAS,IAAI,KAC1C,QAAQ,QACR;AACA,gBAAM,KAAK,OAAO;AAClB,iBAAO,KAAK,eAAe,GAAG,KAAK,MAAM,GAAG,UAAU;AAAA,QACxD;AAEA,YAAI,QAAQ,QAAQ;AAClB,gBAAM,aAAa,OAAO;AAE1B,cAAI,OAAO,WAAW,YAAY,YAAY;AAE5C,mBAAO,WAAW,QAAQ,MAAM;AAAA,UAClC;AAAA,QACF;AAEA,cAAM,MAAM;AACZ,eAAO,WAAW;AAAA,MACpB;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EASA,AAAU,eAAoC,IAAO,YAAiC;AACpF,WAAO,IAAI,MAAM,IAAI;AAAA,MAYnB,OAAO,CAAC,QAAQ,SAAS,SAAS;AAChC,cAAM,QAAQ,OAAO,KAAK,OAAO,EAAE,GAAG,IAAI;AAC1C,eAAO,KAAK,OAAO,OAAY,UAAU;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAcO,IAAM,gBAAgB,CAI3B,SACA,eAC0B,IAAI,gBAAgB,SAAS,UAAU,EAAE;","names":[]}
@@ -0,0 +1,21 @@
1
+ declare type ExtractGeneric<Type> = Type extends Promise<infer X> ? X : never;
2
+ declare type ExtendedPromise<T extends Promise<unknown>, P, V = ExtractGeneric<T>> = Omit<T, 'then' | 'catch' | 'finally'> & P & {
3
+ then: (...args: Parameters<T['then']>) => ExtendedPromise<Promise<V>, P>;
4
+ catch: (...args: Parameters<T['catch']>) => ExtendedPromise<Promise<V>, P>;
5
+ finally: (...args: Parameters<T['finally']>) => ExtendedPromise<Promise<V>, P>;
6
+ };
7
+ /**
8
+ * Extends a {@link Promise} by injecting custom properties using a {@link Proxy}. The
9
+ * custom properties will be available on the promise chain no matter how many `then`s,
10
+ * `catch`s or `finally`s are added.
11
+ *
12
+ * @param promise The promise to extend.
13
+ * @param properties A dictionary of custom properties to _inject_ in the promise
14
+ * chain.
15
+ * @throws {Error} If `promise` is not a valid instance of {@link Promise}.
16
+ * @throws {Error} If `properties` is not an object or if it doesn't have any
17
+ * properties.
18
+ */
19
+ declare const extendPromise: <T extends Promise<unknown>, P extends Record<string, unknown>>(promise: T, properties: P) => ExtendedPromise<T, P, ExtractGeneric<T>>;
20
+
21
+ export { extendPromise };
package/dist/index.js ADDED
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ extendPromise: () => extendPromise
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+ var PromiseExtender = class {
27
+ promise;
28
+ constructor(promise, properties) {
29
+ this.promise = this.extend(promise, properties);
30
+ }
31
+ extend(promise, properties) {
32
+ if (!(promise instanceof Promise)) {
33
+ throw new Error("'promise' must be a valid Promise instance");
34
+ }
35
+ if (!properties || !Object.keys(properties).length) {
36
+ throw new Error("'properties' must be an object with at least one key");
37
+ }
38
+ const extended = new Proxy(promise, {
39
+ get: (target, name) => {
40
+ const targetKey = name;
41
+ if (typeof name === "string" && ["then", "catch", "finally"].includes(name) && name in target) {
42
+ const fn = target[targetKey];
43
+ return this.extendFunction(fn.bind(target), properties);
44
+ }
45
+ if (name in target) {
46
+ const possibleFn = target[targetKey];
47
+ if (typeof possibleFn["bind"] === "function") {
48
+ return possibleFn["bind"](target);
49
+ }
50
+ }
51
+ const key = name;
52
+ return properties[key];
53
+ }
54
+ });
55
+ return extended;
56
+ }
57
+ extendFunction(fn, properties) {
58
+ return new Proxy(fn, {
59
+ apply: (target, thisArg, args) => {
60
+ const value = target.bind(thisArg)(...args);
61
+ return this.extend(value, properties);
62
+ }
63
+ });
64
+ }
65
+ };
66
+ var extendPromise = (promise, properties) => new PromiseExtender(promise, properties).promise;
67
+ // Annotate the CommonJS export names for ESM import in node:
68
+ 0 && (module.exports = {
69
+ extendPromise
70
+ });
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["type ExtractGeneric<Type> = Type extends Promise<infer X> ? X : never;\n\ntype ExtendedPromise<T extends Promise<unknown>, P, V = ExtractGeneric<T>> = Omit<\n T,\n 'then' | 'catch' | 'finally'\n> &\n P & {\n then: (...args: Parameters<T['then']>) => ExtendedPromise<Promise<V>, P>;\n catch: (...args: Parameters<T['catch']>) => ExtendedPromise<Promise<V>, P>;\n finally: (...args: Parameters<T['finally']>) => ExtendedPromise<Promise<V>, P>;\n };\ntype GenericFn = (...args: unknown[]) => unknown;\ntype ExtendedFn<F extends GenericFn, P> = F & P;\n\n/**\n * Helper class that creates a proxy for a {@link Promise} in order to add custom\n * properties.\n *\n * The only reason this class exists is so it can \"scope\" the necessary methods to extend\n * {@link Promise} and avoid workarounds in order to declare them, as they need to call\n * themselves recursively.\n */\nclass PromiseExtender<T extends Promise<unknown>, P extends Record<string, unknown>> {\n /**\n * The proxied promise.\n */\n readonly promise: ExtendedPromise<T, P>;\n /**\n * @param promise The promise to extend.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n */\n constructor(promise: T, properties: P) {\n this.promise = this.extend(promise, properties);\n }\n /**\n * The method that actually extends a promise: it creates a proxy of the promise in\n * order to intercept the getters so it can return the custom properties if requested,\n * and return new proxies when `then`, `catch` and `finally` are called; the reason new\n * proxies are created is because those methods return new promises, and without being\n * proxied, the custom properties would be lost.\n *\n * @param promise The promise to proxy.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n * @throws {Error} If `promise` is not a valid instance of {@link Promise}.\n * @throws {Error} If `properties` is not an object or if it doesn't have any\n * properties.\n */\n extend(promise: T, properties: P): ExtendedPromise<T, P> {\n if (!(promise instanceof Promise)) {\n throw new Error(\"'promise' must be a valid Promise instance\");\n }\n\n if (!properties || !Object.keys(properties).length) {\n throw new Error(\"'properties' must be an object with at least one key\");\n }\n\n const extended = new Proxy(promise, {\n /**\n * This is a trap for when something is trying to read/access a property for the\n * promise.\n * The function first validates if it's one of the functions\n * (`then`/`catch`/`finally`) in order to return a proxied function; then, if it's\n * another function (one that doesn't return another promise), it just calls the\n * original; finally, before doing a fallback to the original promise, it checks if\n * it's one of the custom properties that exented the promise.\n *\n * @param target The original promise.\n * @param name The name of the property.\n */\n get: (target, name) => {\n const targetKey = name as keyof typeof target;\n if (\n typeof name === 'string' &&\n ['then', 'catch', 'finally'].includes(name) &&\n name in target\n ) {\n const fn = target[targetKey] as unknown as GenericFn;\n return this.extendFunction(fn.bind(target), properties);\n }\n\n if (name in target) {\n const possibleFn = target[targetKey] as unknown as Record<string, unknown>;\n // eslint-disable-next-line dot-notation\n if (typeof possibleFn['bind'] === 'function') {\n // eslint-disable-next-line dot-notation\n return possibleFn['bind'](target);\n }\n }\n\n const key = name as keyof P;\n return properties[key];\n },\n });\n\n return extended as ExtendedPromise<T, P>;\n }\n /**\n * Creates a proxy for a promise function (`then`/`catch`/`finally`) so the returned\n * promise can also be extended.\n *\n * @param fn The promise function to proxy.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n */\n protected extendFunction<F extends GenericFn>(fn: F, properties: P): ExtendedFn<F, P> {\n return new Proxy(fn, {\n /**\n * This is a trap for when a function gets called (remember this gets used for\n * `then`/\n * `catch`/`finally`); it processes the result using the oringinal function and\n * since promise methods return a promise, instead of returning the original result,\n * it returns an _extended_ version of it.\n *\n * @param target The original function.\n * @param thisArg The promise the function belongs to.\n * @param args The list of arguments sent to the trap.\n */\n apply: (target, thisArg, args) => {\n const value = target.bind(thisArg)(...args);\n return this.extend(value as T, properties);\n },\n }) as ExtendedFn<F, P>;\n }\n}\n\n/**\n * Extends a {@link Promise} by injecting custom properties using a {@link Proxy}. The\n * custom properties will be available on the promise chain no matter how many `then`s,\n * `catch`s or `finally`s are added.\n *\n * @param promise The promise to extend.\n * @param properties A dictionary of custom properties to _inject_ in the promise\n * chain.\n * @throws {Error} If `promise` is not a valid instance of {@link Promise}.\n * @throws {Error} If `properties` is not an object or if it doesn't have any\n * properties.\n */\nexport const extendPromise = <\n T extends Promise<unknown>,\n P extends Record<string, unknown>,\n>(\n promise: T,\n properties: P,\n): ExtendedPromise<T, P> => new PromiseExtender(promise, properties).promise;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBA,IAAM,kBAAN,MAAqF;AAAA,EAInF,AAAS;AAAA,EAMT,YAAY,SAAY,YAAe;AACrC,SAAK,UAAU,KAAK,OAAO,SAAS,UAAU;AAAA,EAChD;AAAA,EAeA,OAAO,SAAY,YAAsC;AACvD,QAAI,CAAE,oBAAmB,UAAU;AACjC,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,QAAI,CAAC,cAAc,CAAC,OAAO,KAAK,UAAU,EAAE,QAAQ;AAClD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAEA,UAAM,WAAW,IAAI,MAAM,SAAS;AAAA,MAalC,KAAK,CAAC,QAAQ,SAAS;AACrB,cAAM,YAAY;AAClB,YACE,OAAO,SAAS,YAChB,CAAC,QAAQ,SAAS,SAAS,EAAE,SAAS,IAAI,KAC1C,QAAQ,QACR;AACA,gBAAM,KAAK,OAAO;AAClB,iBAAO,KAAK,eAAe,GAAG,KAAK,MAAM,GAAG,UAAU;AAAA,QACxD;AAEA,YAAI,QAAQ,QAAQ;AAClB,gBAAM,aAAa,OAAO;AAE1B,cAAI,OAAO,WAAW,YAAY,YAAY;AAE5C,mBAAO,WAAW,QAAQ,MAAM;AAAA,UAClC;AAAA,QACF;AAEA,cAAM,MAAM;AACZ,eAAO,WAAW;AAAA,MACpB;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EASA,AAAU,eAAoC,IAAO,YAAiC;AACpF,WAAO,IAAI,MAAM,IAAI;AAAA,MAYnB,OAAO,CAAC,QAAQ,SAAS,SAAS;AAChC,cAAM,QAAQ,OAAO,KAAK,OAAO,EAAE,GAAG,IAAI;AAC1C,eAAO,KAAK,OAAO,OAAY,UAAU;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAcO,IAAM,gBAAgB,CAI3B,SACA,eAC0B,IAAI,gBAAgB,SAAS,UAAU,EAAE;","names":[]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@homer0/extend-promise",
3
+ "description": "Extends a promise with custom properties",
4
+ "version": "1.0.1",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/homer0/packages.git",
8
+ "directory": "packages/public/extend-promise"
9
+ },
10
+ "author": "Leonardo Apiwan (@homer0) <me@homer0.com>",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "promise",
14
+ "custom",
15
+ "utility",
16
+ "wootils",
17
+ "javascript"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "files": [
23
+ "dist/"
24
+ ],
25
+ "devDependencies": {
26
+ "@types/jest": "^28.1.4",
27
+ "jest": "^28.1.2",
28
+ "ts-jest": "^28.0.5",
29
+ "tsup": "^6.1.3",
30
+ "typescript": "^4.7.4"
31
+ },
32
+ "engine-strict": true,
33
+ "engines": {
34
+ "node": ">=14"
35
+ },
36
+ "main": "./dist/index.js",
37
+ "module": "./dist/esm/index.js",
38
+ "types": "./dist/index.d.ts",
39
+ "scripts": {
40
+ "test": "jest -c ./.jestrc.js",
41
+ "types:check": "tsc --noEmit && tsc --noEmit --project ./tests/tsconfig.json",
42
+ "build": "tsup src/index.ts",
43
+ "prepublishOnly": "npm run build"
44
+ },
45
+ "gitHead": "835d84ced485240f90c9c9173b5fcb53346bf264"
46
+ }