chain-simple 1.3.2 → 2.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/built/{index.d.ts → cjs/index.d.ts} +5 -4
- package/built/{index.js → cjs/index.js} +37 -34
- package/built/esm/index.d.ts +51 -0
- package/built/esm/index.js +174 -0
- package/built/esm/logger.d.ts +4 -0
- package/built/esm/logger.js +7 -0
- package/lib/index.ts +40 -32
- package/package.json +15 -7
- package/readme.md +5 -5
- package/tsconfig.esm.json +18 -0
- package/tsconfig.json +6 -7
- /package/built/{logger.d.ts → cjs/logger.d.ts} +0 -0
- /package/built/{logger.js → cjs/logger.js} +0 -0
|
@@ -5,6 +5,7 @@ export type TChainable<T extends Record<string, TFn>> = {
|
|
|
5
5
|
};
|
|
6
6
|
type TConfig = {
|
|
7
7
|
getEntity?: string;
|
|
8
|
+
extendOnly?: boolean;
|
|
8
9
|
extendProxed?: (propName: any) => {
|
|
9
10
|
[k: string]: any;
|
|
10
11
|
} | ((item: any) => {
|
|
@@ -16,7 +17,7 @@ type TConfig = {
|
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
19
|
* @example
|
|
19
|
-
* const {
|
|
20
|
+
* const {chainProps} = require('chain-simple');
|
|
20
21
|
* const obj = {
|
|
21
22
|
* async method1() {
|
|
22
23
|
* return Promise.resolve(1).then(value => {
|
|
@@ -37,7 +38,7 @@ type TConfig = {
|
|
|
37
38
|
* });
|
|
38
39
|
* },
|
|
39
40
|
* };
|
|
40
|
-
* const chainableObj =
|
|
41
|
+
* const chainableObj = chainProps(obj);
|
|
41
42
|
* obj.method1().method3().then((val) => console.log(val))
|
|
42
43
|
*
|
|
43
44
|
*
|
|
@@ -45,6 +46,6 @@ type TConfig = {
|
|
|
45
46
|
* @param {{getEntity: string}} [config] config to describe how to get original not project object
|
|
46
47
|
* @returns {object} object with chainable properties
|
|
47
48
|
*/
|
|
48
|
-
declare function
|
|
49
|
+
declare function chainProps(item: any, config?: TConfig): any;
|
|
49
50
|
declare function makeConstructorInstancePropertiesChainable(constructorFunction: any, config?: TConfig): any;
|
|
50
|
-
export {
|
|
51
|
+
export { chainProps, makeConstructorInstancePropertiesChainable };
|
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.chainProps = chainProps;
|
|
4
|
+
exports.makeConstructorInstancePropertiesChainable = makeConstructorInstancePropertiesChainable;
|
|
4
5
|
const sat_utils_1 = require("sat-utils");
|
|
5
6
|
const logger_1 = require("./logger");
|
|
6
7
|
logger_1.logger.setLogLevel(process.env.CHAIN_SIMPLE_LOG_LEVEL);
|
|
8
|
+
function extendProxed(target, propName, receiver, config) {
|
|
9
|
+
if ((0, sat_utils_1.isObject)(config) && (0, sat_utils_1.isFunction)(config.extendProxed) && (0, sat_utils_1.isUndefined)(Reflect.get(target, propName, receiver))) {
|
|
10
|
+
try {
|
|
11
|
+
const extension = config.extendProxed(propName);
|
|
12
|
+
if ((0, sat_utils_1.isObject)(extension)) {
|
|
13
|
+
Object.assign(target, extension);
|
|
14
|
+
}
|
|
15
|
+
else if ((0, sat_utils_1.isFunction)(extension)) {
|
|
16
|
+
const result = extension(target);
|
|
17
|
+
Object.assign(target, result);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.error(error);
|
|
22
|
+
}
|
|
23
|
+
return target;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
7
26
|
/**
|
|
8
27
|
* @example
|
|
9
|
-
* const {
|
|
28
|
+
* const {chainProps} = require('chain-simple');
|
|
10
29
|
* const obj = {
|
|
11
30
|
* async method1() {
|
|
12
31
|
* return Promise.resolve(1).then(value => {
|
|
@@ -27,7 +46,7 @@ logger_1.logger.setLogLevel(process.env.CHAIN_SIMPLE_LOG_LEVEL);
|
|
|
27
46
|
* });
|
|
28
47
|
* },
|
|
29
48
|
* };
|
|
30
|
-
* const chainableObj =
|
|
49
|
+
* const chainableObj = chainProps(obj);
|
|
31
50
|
* obj.method1().method3().then((val) => console.log(val))
|
|
32
51
|
*
|
|
33
52
|
*
|
|
@@ -35,7 +54,7 @@ logger_1.logger.setLogLevel(process.env.CHAIN_SIMPLE_LOG_LEVEL);
|
|
|
35
54
|
* @param {{getEntity: string}} [config] config to describe how to get original not project object
|
|
36
55
|
* @returns {object} object with chainable properties
|
|
37
56
|
*/
|
|
38
|
-
function
|
|
57
|
+
function chainProps(item, config) {
|
|
39
58
|
const promiseCallableProps = ['then', 'catch', 'finally'];
|
|
40
59
|
const propsList = [];
|
|
41
60
|
if ((0, sat_utils_1.isObject)(config) && config.getEntityPropList) {
|
|
@@ -47,23 +66,27 @@ function makePropertiesChainable(item, config) {
|
|
|
47
66
|
: config.getEntityPropList));
|
|
48
67
|
}
|
|
49
68
|
if (!(0, sat_utils_1.canBeProxed)(item)) {
|
|
50
|
-
throw new TypeError('
|
|
69
|
+
throw new TypeError('chainProps(): first argument should be an entity that can be proxed');
|
|
51
70
|
}
|
|
52
71
|
if (!(0, sat_utils_1.isUndefined)(config) && !(0, sat_utils_1.isObject)(config)) {
|
|
53
|
-
throw new TypeError('
|
|
72
|
+
throw new TypeError('chainProps(): second argument should be an object');
|
|
54
73
|
}
|
|
74
|
+
const _config = { ...config };
|
|
55
75
|
let proxifiedResult = item;
|
|
56
76
|
const proxed = new Proxy(item, {
|
|
57
77
|
get(_t, p, r) {
|
|
58
|
-
var _a;
|
|
59
78
|
if (propsList.length && propsList.includes(p)) {
|
|
60
|
-
const propValue =
|
|
79
|
+
const propValue = Reflect.getOwnPropertyDescriptor(item, p)?.value;
|
|
61
80
|
if ((0, sat_utils_1.isFunction)(propValue) || (0, sat_utils_1.isAsyncFunction)(propValue)) {
|
|
62
81
|
return item[p].bind(item);
|
|
63
82
|
}
|
|
64
83
|
return item[p];
|
|
65
84
|
}
|
|
66
|
-
if (
|
|
85
|
+
if (_config.extendOnly) {
|
|
86
|
+
extendProxed(item, p, r, config);
|
|
87
|
+
return item[p];
|
|
88
|
+
}
|
|
89
|
+
if (_config.getEntity === p) {
|
|
67
90
|
return item;
|
|
68
91
|
}
|
|
69
92
|
if (p === Symbol.toStringTag) {
|
|
@@ -79,24 +102,8 @@ function makePropertiesChainable(item, config) {
|
|
|
79
102
|
return proxifiedResult;
|
|
80
103
|
};
|
|
81
104
|
}
|
|
82
|
-
if (!promiseCallableProps.includes(p)
|
|
83
|
-
(
|
|
84
|
-
(0, sat_utils_1.isObject)(config) &&
|
|
85
|
-
(0, sat_utils_1.isFunction)(config.extendProxed)) {
|
|
86
|
-
try {
|
|
87
|
-
const extension = config.extendProxed(p);
|
|
88
|
-
if ((0, sat_utils_1.isObject)(extension)) {
|
|
89
|
-
Object.assign(item, extension);
|
|
90
|
-
}
|
|
91
|
-
else if ((0, sat_utils_1.isFunction)(extension)) {
|
|
92
|
-
// @ts-ignore
|
|
93
|
-
const result = extension(item);
|
|
94
|
-
Object.assign(item, result);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
console.error(error);
|
|
99
|
-
}
|
|
105
|
+
if (!promiseCallableProps.includes(p)) {
|
|
106
|
+
extendProxed(item, p, r, config);
|
|
100
107
|
}
|
|
101
108
|
const isCallable = (0, sat_utils_1.isFunction)(Reflect.get(item, p, r)) || (0, sat_utils_1.isAsyncFunction)(Reflect.get(item, p, r));
|
|
102
109
|
if (!isCallable && !(0, sat_utils_1.isPromise)(proxifiedResult) && item[p] && !proxifiedResult[p]) {
|
|
@@ -109,12 +116,10 @@ function makePropertiesChainable(item, config) {
|
|
|
109
116
|
logger_1.logger.chainer(`[CHAIN_SIMPLE]: ${String(p)} is called with args: `, ...arguments);
|
|
110
117
|
if ((0, sat_utils_1.isPromise)(proxifiedResult)) {
|
|
111
118
|
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is a promise`);
|
|
112
|
-
proxifiedResult = proxifiedResult
|
|
113
|
-
.then(function (r) {
|
|
119
|
+
proxifiedResult = proxifiedResult.then(function (r) {
|
|
114
120
|
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, r);
|
|
115
121
|
return item[p].call(item, ...arguments_);
|
|
116
|
-
})
|
|
117
|
-
.catch(e => console.log(e));
|
|
122
|
+
});
|
|
118
123
|
}
|
|
119
124
|
else {
|
|
120
125
|
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is not a promise`);
|
|
@@ -155,17 +160,15 @@ function makePropertiesChainable(item, config) {
|
|
|
155
160
|
});
|
|
156
161
|
return proxed;
|
|
157
162
|
}
|
|
158
|
-
exports.makePropertiesChainable = makePropertiesChainable;
|
|
159
163
|
function handlerConstructor(config) {
|
|
160
164
|
return {
|
|
161
165
|
construct(target, args) {
|
|
162
166
|
const item = new target(...args);
|
|
163
|
-
return
|
|
167
|
+
return chainProps(item, config);
|
|
164
168
|
},
|
|
165
169
|
};
|
|
166
170
|
}
|
|
167
171
|
function makeConstructorInstancePropertiesChainable(constructorFunction, config) {
|
|
168
172
|
return new Proxy(constructorFunction, handlerConstructor(config));
|
|
169
173
|
}
|
|
170
|
-
exports.makeConstructorInstancePropertiesChainable = makeConstructorInstancePropertiesChainable;
|
|
171
174
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type TFn = (...args: any) => any;
|
|
2
|
+
type TReplaceReturnType<T extends TFn, TNewReturnType> = (...args: Parameters<T>) => TNewReturnType;
|
|
3
|
+
export type TChainable<T extends Record<string, TFn>> = {
|
|
4
|
+
[K in keyof T]: TReplaceReturnType<T[K], ReturnType<T[K]> & TChainable<T>>;
|
|
5
|
+
};
|
|
6
|
+
type TConfig = {
|
|
7
|
+
getEntity?: string;
|
|
8
|
+
extendOnly?: boolean;
|
|
9
|
+
extendProxed?: (propName: any) => {
|
|
10
|
+
[k: string]: any;
|
|
11
|
+
} | ((item: any) => {
|
|
12
|
+
[k: string]: any;
|
|
13
|
+
});
|
|
14
|
+
getEntityPropList?: string[] | {
|
|
15
|
+
[k: string]: any;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @example
|
|
20
|
+
* const {chainProps} = require('chain-simple');
|
|
21
|
+
* const obj = {
|
|
22
|
+
* async method1() {
|
|
23
|
+
* return Promise.resolve(1).then(value => {
|
|
24
|
+
* console.log('method1', value);
|
|
25
|
+
* return value;
|
|
26
|
+
* });
|
|
27
|
+
* },
|
|
28
|
+
* async method2() {
|
|
29
|
+
* return Promise.resolve(2).then(value => {
|
|
30
|
+
* console.log('method2', value);
|
|
31
|
+
* return value;
|
|
32
|
+
* });
|
|
33
|
+
* },
|
|
34
|
+
* async method3() {
|
|
35
|
+
* return Promise.resolve(3).then(value => {
|
|
36
|
+
* console.log('method3', value);
|
|
37
|
+
* return value;
|
|
38
|
+
* });
|
|
39
|
+
* },
|
|
40
|
+
* };
|
|
41
|
+
* const chainableObj = chainProps(obj);
|
|
42
|
+
* obj.method1().method3().then((val) => console.log(val))
|
|
43
|
+
*
|
|
44
|
+
*
|
|
45
|
+
* @param {!object} item
|
|
46
|
+
* @param {{getEntity: string}} [config] config to describe how to get original not project object
|
|
47
|
+
* @returns {object} object with chainable properties
|
|
48
|
+
*/
|
|
49
|
+
declare function chainProps(item: any, config?: TConfig): any;
|
|
50
|
+
declare function makeConstructorInstancePropertiesChainable(constructorFunction: any, config?: TConfig): any;
|
|
51
|
+
export { chainProps, makeConstructorInstancePropertiesChainable };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.chainProps = chainProps;
|
|
4
|
+
exports.makeConstructorInstancePropertiesChainable = makeConstructorInstancePropertiesChainable;
|
|
5
|
+
const sat_utils_1 = require("sat-utils");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
logger_1.logger.setLogLevel(process.env.CHAIN_SIMPLE_LOG_LEVEL);
|
|
8
|
+
function extendProxed(target, propName, receiver, config) {
|
|
9
|
+
if ((0, sat_utils_1.isObject)(config) && (0, sat_utils_1.isFunction)(config.extendProxed) && (0, sat_utils_1.isUndefined)(Reflect.get(target, propName, receiver))) {
|
|
10
|
+
try {
|
|
11
|
+
const extension = config.extendProxed(propName);
|
|
12
|
+
if ((0, sat_utils_1.isObject)(extension)) {
|
|
13
|
+
Object.assign(target, extension);
|
|
14
|
+
}
|
|
15
|
+
else if ((0, sat_utils_1.isFunction)(extension)) {
|
|
16
|
+
const result = extension(target);
|
|
17
|
+
Object.assign(target, result);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.error(error);
|
|
22
|
+
}
|
|
23
|
+
return target;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @example
|
|
28
|
+
* const {chainProps} = require('chain-simple');
|
|
29
|
+
* const obj = {
|
|
30
|
+
* async method1() {
|
|
31
|
+
* return Promise.resolve(1).then(value => {
|
|
32
|
+
* console.log('method1', value);
|
|
33
|
+
* return value;
|
|
34
|
+
* });
|
|
35
|
+
* },
|
|
36
|
+
* async method2() {
|
|
37
|
+
* return Promise.resolve(2).then(value => {
|
|
38
|
+
* console.log('method2', value);
|
|
39
|
+
* return value;
|
|
40
|
+
* });
|
|
41
|
+
* },
|
|
42
|
+
* async method3() {
|
|
43
|
+
* return Promise.resolve(3).then(value => {
|
|
44
|
+
* console.log('method3', value);
|
|
45
|
+
* return value;
|
|
46
|
+
* });
|
|
47
|
+
* },
|
|
48
|
+
* };
|
|
49
|
+
* const chainableObj = chainProps(obj);
|
|
50
|
+
* obj.method1().method3().then((val) => console.log(val))
|
|
51
|
+
*
|
|
52
|
+
*
|
|
53
|
+
* @param {!object} item
|
|
54
|
+
* @param {{getEntity: string}} [config] config to describe how to get original not project object
|
|
55
|
+
* @returns {object} object with chainable properties
|
|
56
|
+
*/
|
|
57
|
+
function chainProps(item, config) {
|
|
58
|
+
const promiseCallableProps = ['then', 'catch', 'finally'];
|
|
59
|
+
const propsList = [];
|
|
60
|
+
if ((0, sat_utils_1.isObject)(config) && config.getEntityPropList) {
|
|
61
|
+
if (!(0, sat_utils_1.isObject)(config.getEntityPropList) && !(0, sat_utils_1.isArray)(config.getEntityPropList)) {
|
|
62
|
+
throw new TypeError('config "getEntityPropList" should be an array or an object');
|
|
63
|
+
}
|
|
64
|
+
propsList.push(...((0, sat_utils_1.isObject)(config.getEntityPropList)
|
|
65
|
+
? Object.keys(config.getEntityPropList)
|
|
66
|
+
: config.getEntityPropList));
|
|
67
|
+
}
|
|
68
|
+
if (!(0, sat_utils_1.canBeProxed)(item)) {
|
|
69
|
+
throw new TypeError('chainProps(): first argument should be an entity that can be proxed');
|
|
70
|
+
}
|
|
71
|
+
if (!(0, sat_utils_1.isUndefined)(config) && !(0, sat_utils_1.isObject)(config)) {
|
|
72
|
+
throw new TypeError('chainProps(): second argument should be an object');
|
|
73
|
+
}
|
|
74
|
+
const _config = { ...config };
|
|
75
|
+
let proxifiedResult = item;
|
|
76
|
+
const proxed = new Proxy(item, {
|
|
77
|
+
get(_t, p, r) {
|
|
78
|
+
if (propsList.length && propsList.includes(p)) {
|
|
79
|
+
const propValue = Reflect.getOwnPropertyDescriptor(item, p)?.value;
|
|
80
|
+
if ((0, sat_utils_1.isFunction)(propValue) || (0, sat_utils_1.isAsyncFunction)(propValue)) {
|
|
81
|
+
return item[p].bind(item);
|
|
82
|
+
}
|
|
83
|
+
return item[p];
|
|
84
|
+
}
|
|
85
|
+
if (_config.extendOnly) {
|
|
86
|
+
extendProxed(item, p, r, config);
|
|
87
|
+
return item[p];
|
|
88
|
+
}
|
|
89
|
+
if (_config.getEntity === p) {
|
|
90
|
+
return item;
|
|
91
|
+
}
|
|
92
|
+
if (p === Symbol.toStringTag) {
|
|
93
|
+
return proxifiedResult[Symbol.toStringTag];
|
|
94
|
+
}
|
|
95
|
+
if (p === 'toString') {
|
|
96
|
+
return function (...args) {
|
|
97
|
+
return proxifiedResult.toString(...args);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (p === 'toJSON') {
|
|
101
|
+
return function () {
|
|
102
|
+
return proxifiedResult;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (!promiseCallableProps.includes(p)) {
|
|
106
|
+
extendProxed(item, p, r, config);
|
|
107
|
+
}
|
|
108
|
+
const isCallable = (0, sat_utils_1.isFunction)(Reflect.get(item, p, r)) || (0, sat_utils_1.isAsyncFunction)(Reflect.get(item, p, r));
|
|
109
|
+
if (!isCallable && !(0, sat_utils_1.isPromise)(proxifiedResult) && item[p] && !proxifiedResult[p]) {
|
|
110
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: ${String(p)} is not a callable.`);
|
|
111
|
+
return item[p];
|
|
112
|
+
}
|
|
113
|
+
else if (isCallable) {
|
|
114
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: ${String(p)} is a callable.`);
|
|
115
|
+
return function (...arguments_) {
|
|
116
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: ${String(p)} is called with args: `, ...arguments);
|
|
117
|
+
if ((0, sat_utils_1.isPromise)(proxifiedResult)) {
|
|
118
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is a promise`);
|
|
119
|
+
proxifiedResult = proxifiedResult.then(function (r) {
|
|
120
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, r);
|
|
121
|
+
return item[p].call(item, ...arguments_);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is not a promise`);
|
|
126
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, proxifiedResult);
|
|
127
|
+
proxifiedResult = item[p].call(item, ...arguments_);
|
|
128
|
+
}
|
|
129
|
+
return proxed;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
else if (promiseCallableProps.includes(p) && (0, sat_utils_1.isPromise)(proxifiedResult)) {
|
|
133
|
+
logger_1.logger.chainer(`[CHAIN_SIMPLE]: previous call result is a promise and next call is a promise method call`);
|
|
134
|
+
if (!(0, sat_utils_1.isPromise)(proxifiedResult)) {
|
|
135
|
+
return proxifiedResult;
|
|
136
|
+
}
|
|
137
|
+
return function (onRes, onRej) {
|
|
138
|
+
const promised = proxifiedResult;
|
|
139
|
+
proxifiedResult = item;
|
|
140
|
+
return promised[p].call(promised, onRes, onRej);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
else if (proxifiedResult[p]) {
|
|
144
|
+
return proxifiedResult[p];
|
|
145
|
+
}
|
|
146
|
+
if (!(p in item) && p in proxifiedResult) {
|
|
147
|
+
return proxifiedResult[p];
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
/** @info base */
|
|
151
|
+
getPrototypeOf(_t) {
|
|
152
|
+
return Object.getPrototypeOf(proxifiedResult);
|
|
153
|
+
},
|
|
154
|
+
ownKeys(_t) {
|
|
155
|
+
return Object.getOwnPropertyNames(proxifiedResult);
|
|
156
|
+
},
|
|
157
|
+
getOwnPropertyDescriptor(_t, p) {
|
|
158
|
+
return Object.getOwnPropertyDescriptor(proxifiedResult, p);
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
return proxed;
|
|
162
|
+
}
|
|
163
|
+
function handlerConstructor(config) {
|
|
164
|
+
return {
|
|
165
|
+
construct(target, args) {
|
|
166
|
+
const item = new target(...args);
|
|
167
|
+
return chainProps(item, config);
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function makeConstructorInstancePropertiesChainable(constructorFunction, config) {
|
|
172
|
+
return new Proxy(constructorFunction, handlerConstructor(config));
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logger = void 0;
|
|
4
|
+
const sat_utils_1 = require("sat-utils");
|
|
5
|
+
const logger = (0, sat_utils_1.createLogger)().addCustomLevel('chainer', 'CHAIN_LOG', 'CHAIN_LOG', 'info', 'BgBlue', 'BgWhite');
|
|
6
|
+
exports.logger = logger;
|
|
7
|
+
//# sourceMappingURL=logger.js.map
|
package/lib/index.ts
CHANGED
|
@@ -14,13 +14,32 @@ export type TChainable<T extends Record<string, TFn>> = {
|
|
|
14
14
|
|
|
15
15
|
type TConfig = {
|
|
16
16
|
getEntity?: string;
|
|
17
|
+
extendOnly?: boolean;
|
|
17
18
|
extendProxed?: (propName) => { [k: string]: any } | ((item: any) => { [k: string]: any });
|
|
18
19
|
getEntityPropList?: string[] | { [k: string]: any };
|
|
19
20
|
};
|
|
20
21
|
|
|
22
|
+
function extendProxed(target, propName: string | symbol, receiver: any, config: TConfig) {
|
|
23
|
+
if (isObject(config) && isFunction(config.extendProxed) && isUndefined(Reflect.get(target, propName, receiver))) {
|
|
24
|
+
try {
|
|
25
|
+
const extension = config.extendProxed(propName);
|
|
26
|
+
if (isObject(extension)) {
|
|
27
|
+
Object.assign(target, extension);
|
|
28
|
+
} else if (isFunction(extension)) {
|
|
29
|
+
const result = (extension as TConfig['extendProxed'])(target);
|
|
30
|
+
Object.assign(target, result);
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error(error);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return target;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
21
40
|
/**
|
|
22
41
|
* @example
|
|
23
|
-
* const {
|
|
42
|
+
* const {chainProps} = require('chain-simple');
|
|
24
43
|
* const obj = {
|
|
25
44
|
* async method1() {
|
|
26
45
|
* return Promise.resolve(1).then(value => {
|
|
@@ -41,7 +60,7 @@ type TConfig = {
|
|
|
41
60
|
* });
|
|
42
61
|
* },
|
|
43
62
|
* };
|
|
44
|
-
* const chainableObj =
|
|
63
|
+
* const chainableObj = chainProps(obj);
|
|
45
64
|
* obj.method1().method3().then((val) => console.log(val))
|
|
46
65
|
*
|
|
47
66
|
*
|
|
@@ -49,7 +68,7 @@ type TConfig = {
|
|
|
49
68
|
* @param {{getEntity: string}} [config] config to describe how to get original not project object
|
|
50
69
|
* @returns {object} object with chainable properties
|
|
51
70
|
*/
|
|
52
|
-
function
|
|
71
|
+
function chainProps(item, config?: TConfig) {
|
|
53
72
|
const promiseCallableProps: any[] = ['then', 'catch', 'finally'];
|
|
54
73
|
const propsList = [];
|
|
55
74
|
|
|
@@ -66,12 +85,13 @@ function makePropertiesChainable(item, config?: TConfig) {
|
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
if (!canBeProxed(item)) {
|
|
69
|
-
throw new TypeError('
|
|
88
|
+
throw new TypeError('chainProps(): first argument should be an entity that can be proxed');
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
if (!isUndefined(config) && !isObject(config)) {
|
|
73
|
-
throw new TypeError('
|
|
92
|
+
throw new TypeError('chainProps(): second argument should be an object');
|
|
74
93
|
}
|
|
94
|
+
const _config = { ...config };
|
|
75
95
|
|
|
76
96
|
let proxifiedResult = item;
|
|
77
97
|
const proxed = new Proxy(item, {
|
|
@@ -84,7 +104,13 @@ function makePropertiesChainable(item, config?: TConfig) {
|
|
|
84
104
|
return item[p];
|
|
85
105
|
}
|
|
86
106
|
|
|
87
|
-
if (
|
|
107
|
+
if (_config.extendOnly) {
|
|
108
|
+
extendProxed(item, p, r, config);
|
|
109
|
+
|
|
110
|
+
return item[p];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (_config.getEntity === p) {
|
|
88
114
|
return item;
|
|
89
115
|
}
|
|
90
116
|
|
|
@@ -104,24 +130,8 @@ function makePropertiesChainable(item, config?: TConfig) {
|
|
|
104
130
|
};
|
|
105
131
|
}
|
|
106
132
|
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
isUndefined(Reflect.get(item, p, r)) &&
|
|
110
|
-
isObject(config) &&
|
|
111
|
-
isFunction(config.extendProxed)
|
|
112
|
-
) {
|
|
113
|
-
try {
|
|
114
|
-
const extension = config.extendProxed(p);
|
|
115
|
-
if (isObject(extension)) {
|
|
116
|
-
Object.assign(item, extension);
|
|
117
|
-
} else if (isFunction(extension)) {
|
|
118
|
-
// @ts-ignore
|
|
119
|
-
const result = extension(item);
|
|
120
|
-
Object.assign(item, result);
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error(error);
|
|
124
|
-
}
|
|
133
|
+
if (!promiseCallableProps.includes(p)) {
|
|
134
|
+
extendProxed(item, p, r, config);
|
|
125
135
|
}
|
|
126
136
|
|
|
127
137
|
const isCallable = isFunction(Reflect.get(item, p, r)) || isAsyncFunction(Reflect.get(item, p, r));
|
|
@@ -138,13 +148,11 @@ function makePropertiesChainable(item, config?: TConfig) {
|
|
|
138
148
|
|
|
139
149
|
if (isPromise(proxifiedResult)) {
|
|
140
150
|
logger.chainer(`[CHAIN_SIMPLE]: previous call result is a promise`);
|
|
141
|
-
proxifiedResult = proxifiedResult
|
|
142
|
-
.
|
|
143
|
-
logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, r);
|
|
151
|
+
proxifiedResult = proxifiedResult.then(function (r) {
|
|
152
|
+
logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, r);
|
|
144
153
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
.catch(e => console.log(e));
|
|
154
|
+
return item[p].call(item, ...arguments_);
|
|
155
|
+
});
|
|
148
156
|
} else {
|
|
149
157
|
logger.chainer(`[CHAIN_SIMPLE]: previous call result is not a promise`);
|
|
150
158
|
logger.chainer(`[CHAIN_SIMPLE]: previous call result is: `, proxifiedResult);
|
|
@@ -193,7 +201,7 @@ function handlerConstructor(config) {
|
|
|
193
201
|
return {
|
|
194
202
|
construct(target, args) {
|
|
195
203
|
const item = new target(...args);
|
|
196
|
-
return
|
|
204
|
+
return chainProps(item, config);
|
|
197
205
|
},
|
|
198
206
|
};
|
|
199
207
|
}
|
|
@@ -202,4 +210,4 @@ function makeConstructorInstancePropertiesChainable(constructorFunction, config?
|
|
|
202
210
|
return new Proxy(constructorFunction, handlerConstructor(config));
|
|
203
211
|
}
|
|
204
212
|
|
|
205
|
-
export {
|
|
213
|
+
export { chainProps, makeConstructorInstancePropertiesChainable };
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chain-simple",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Main purpose of this package is - provide simple way to build chain between any item methods",
|
|
5
|
-
"main": "built/index.js",
|
|
5
|
+
"main": "./built/cjs/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"require": "./built/cjs/index.js",
|
|
9
|
+
"import": "./built/esm/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
6
12
|
"directories": {
|
|
7
13
|
"example": "examples",
|
|
8
14
|
"lib": "lib"
|
|
@@ -12,7 +18,9 @@
|
|
|
12
18
|
"test:verbose": "LOG_LEVEL=VERBOSE mocha ./specs/**/*.spec.ts --require ts-node/register --timeout 30000",
|
|
13
19
|
"test:watch": "mocha ./specs/**/*.spec.ts --require ts-node/register --timeout 30000 --watch",
|
|
14
20
|
"lint": "eslint --ext .ts ./",
|
|
15
|
-
"tsc": "
|
|
21
|
+
"tsc:cjs": "tsc -p tsconfig.json",
|
|
22
|
+
"tsc:esm": "tsc -p tsconfig.esm.json",
|
|
23
|
+
"tsc": "rm -rf ./built && npm run tsc:cjs && npm run tsc:esm",
|
|
16
24
|
"prepublish": "npm run tsc"
|
|
17
25
|
},
|
|
18
26
|
"keywords": [
|
|
@@ -38,7 +46,6 @@
|
|
|
38
46
|
"homepage": "https://github.com/Simple-Automation-Testing/chain-simple#readme",
|
|
39
47
|
"devDependencies": {
|
|
40
48
|
"@types/mocha": "^8.2.0",
|
|
41
|
-
"@types/node": "^14.14.17",
|
|
42
49
|
"@typescript-eslint/eslint-plugin": "^4.11.1",
|
|
43
50
|
"@typescript-eslint/parser": "^4.11.1",
|
|
44
51
|
"assertior": "0.0.23",
|
|
@@ -48,13 +55,14 @@
|
|
|
48
55
|
"eslint-plugin-mocha": "^8.0.0",
|
|
49
56
|
"mocha": "^8.2.1",
|
|
50
57
|
"prettier": "^2.6.2",
|
|
51
|
-
"ts-node": "^10.9.
|
|
52
|
-
"typescript": "^
|
|
58
|
+
"ts-node": "^10.9.2",
|
|
59
|
+
"typescript": "^5.8.3"
|
|
53
60
|
},
|
|
54
61
|
"engines": {
|
|
55
|
-
"node": ">=
|
|
62
|
+
"node": ">=20.9.0"
|
|
56
63
|
},
|
|
57
64
|
"dependencies": {
|
|
58
65
|
"sat-utils": "1.9.0"
|
|
59
66
|
}
|
|
60
67
|
}
|
|
68
|
+
|
package/readme.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
The purpose of this library is - build simple and flexible chainable call of the object` methods
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
|
-
import {
|
|
8
|
+
import { chainProps } from 'chain-simple';
|
|
9
9
|
import type { TChainable } from 'chain-simple';
|
|
10
10
|
|
|
11
11
|
const obj = {
|
|
@@ -29,7 +29,7 @@ const obj = {
|
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
const chainableObj: TChainable<typeof obj> =
|
|
32
|
+
const chainableObj: TChainable<typeof obj> = chainProps(obj);
|
|
33
33
|
|
|
34
34
|
chainableObj
|
|
35
35
|
.method1()
|
|
@@ -38,7 +38,7 @@ chainableObj
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
```js
|
|
41
|
-
const {
|
|
41
|
+
const { chainProps } = require('chain-simple');
|
|
42
42
|
|
|
43
43
|
const obj = {
|
|
44
44
|
async method1() {
|
|
@@ -61,10 +61,10 @@ const obj = {
|
|
|
61
61
|
},
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
const chainableObj: TChainable<typeof obj> =
|
|
64
|
+
const chainableObj: TChainable<typeof obj> = chainProps(obj);
|
|
65
65
|
|
|
66
66
|
chainableObj
|
|
67
67
|
.method1()
|
|
68
68
|
.method3()
|
|
69
69
|
.then(val => console.log(val)); // method1 1 \n method3 3 \n 3
|
|
70
|
-
```
|
|
70
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "NodeNext",
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"sourceMap": true,
|
|
6
|
+
"outDir": "built/esm",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"experimentalDecorators": true,
|
|
9
|
+
"allowJs": true
|
|
10
|
+
},
|
|
11
|
+
"exclude": [
|
|
12
|
+
"node_modules",
|
|
13
|
+
"built",
|
|
14
|
+
"specs",
|
|
15
|
+
"example",
|
|
16
|
+
"playground.*"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"module": "commonjs",
|
|
4
|
-
"target": "
|
|
4
|
+
"target": "es2020",
|
|
5
5
|
"sourceMap": true,
|
|
6
|
-
"outDir": "built",
|
|
6
|
+
"outDir": "built/cjs",
|
|
7
7
|
"declaration": true,
|
|
8
|
-
"experimentalDecorators": true
|
|
8
|
+
"experimentalDecorators": true,
|
|
9
|
+
"allowJs": true
|
|
9
10
|
},
|
|
10
|
-
"include": [
|
|
11
|
-
"lib"
|
|
12
|
-
],
|
|
13
11
|
"exclude": [
|
|
14
12
|
"node_modules",
|
|
15
13
|
"built",
|
|
16
14
|
"specs",
|
|
17
|
-
"example"
|
|
15
|
+
"example",
|
|
16
|
+
"playground.*"
|
|
18
17
|
]
|
|
19
18
|
}
|
|
File without changes
|
|
File without changes
|