Skip to content

Commit 7aa63b7

Browse files
authored
Add callable function to curry module (#161)
* implement callable with Proxy
1 parent 6c90614 commit 7aa63b7

File tree

7 files changed

+91
-3
lines changed

7 files changed

+91
-3
lines changed

Diff for: cdn/radash.esm.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,18 @@ const throttle = ({ interval }, func) => {
407407
};
408408
return throttled;
409409
};
410+
const callable = (obj, fn) => {
411+
const FUNC = () => {
412+
};
413+
return new Proxy(Object.assign(FUNC, obj), {
414+
get: (target, key) => target[key],
415+
set: (target, key, value) => {
416+
target[key] = value;
417+
return true;
418+
},
419+
apply: (target, self, args) => fn(Object.assign({}, target))(...args)
420+
});
421+
};
410422

411423
const toFloat = (value, defaultValue) => {
412424
const def = defaultValue === void 0 ? 0 : defaultValue;
@@ -766,4 +778,4 @@ const template = (str, data, regex = /\{\{(.+?)\}\}/g) => {
766778
}, str);
767779
};
768780

769-
export { alphabetical, boil, camel as camal, camel, capitalize, chain, clone, cluster, compose, counting, dash, debounce, defer, diff, draw, first, flat, fork, get, group, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isString, isSymbol, iterate, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, tryit as try, tryit, uid, unique, upperize, zip };
781+
export { alphabetical, boil, callable, camel as camal, camel, capitalize, chain, clone, cluster, compose, counting, dash, debounce, defer, diff, draw, first, flat, fork, get, group, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isString, isSymbol, iterate, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, tryit as try, tryit, uid, unique, upperize, zip };

Diff for: cdn/radash.js

+13
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,18 @@ var radash = (function (exports) {
410410
};
411411
return throttled;
412412
};
413+
const callable = (obj, fn) => {
414+
const FUNC = () => {
415+
};
416+
return new Proxy(Object.assign(FUNC, obj), {
417+
get: (target, key) => target[key],
418+
set: (target, key, value) => {
419+
target[key] = value;
420+
return true;
421+
},
422+
apply: (target, self, args) => fn(Object.assign({}, target))(...args)
423+
});
424+
};
413425

414426
const toFloat = (value, defaultValue) => {
415427
const def = defaultValue === void 0 ? 0 : defaultValue;
@@ -771,6 +783,7 @@ var radash = (function (exports) {
771783

772784
exports.alphabetical = alphabetical;
773785
exports.boil = boil;
786+
exports.callable = callable;
774787
exports.camal = camel;
775788
exports.camel = camel;
776789
exports.capitalize = capitalize;

Diff for: cdn/radash.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "radash",
3-
"version": "9.3.0",
3+
"version": "9.4.0",
44
"description": "Functional utility library - modern, simple, typed, powerful",
55
"main": "dist/cjs/index.cjs",
66
"module": "dist/esm/index.mjs",

Diff for: src/curry.ts

+37
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,40 @@ export const throttle = <TArgs extends any[]>(
128128
}
129129
return throttled as unknown as (...args: TArgs) => any
130130
}
131+
132+
/**
133+
* Make an object callable. Given an object and a function
134+
* the returned object will be a function with all the
135+
* objects properties.
136+
*
137+
* @example
138+
* ```typescript
139+
* const car = callable({
140+
* wheels: 2
141+
* }, self => () => {
142+
* return 'driving'
143+
* })
144+
*
145+
* car.wheels // => 2
146+
* car() // => 'driving'
147+
* ```
148+
*/
149+
export const callable = <
150+
TValue,
151+
TObj extends Record<string | number | symbol, TValue>,
152+
TFunc extends Function
153+
>(
154+
obj: TObj,
155+
fn: (self: TObj) => TFunc
156+
): TObj & TFunc => {
157+
/* istanbul ignore next */
158+
const FUNC = () => {}
159+
return new Proxy(Object.assign(FUNC, obj), {
160+
get: (target, key: string) => target[key],
161+
set: (target, key: string, value: any) => {
162+
;(target as any)[key] = value
163+
return true
164+
},
165+
apply: (target, self, args) => fn(Object.assign({}, target))(...args)
166+
}) as unknown as TObj & TFunc
167+
}

Diff for: src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export {
3939
} from './async'
4040
export type { AggregateError } from './async'
4141
export {
42+
callable,
4243
chain,
4344
compose,
4445
debounce,

Diff for: src/tests/curry.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,28 @@ describe('curry module', () => {
175175
})
176176
})
177177
})
178+
179+
describe('callable function', () => {
180+
test('makes object callable', async () => {
181+
const request = {
182+
source: 'client',
183+
body: 'ford',
184+
doors: 2
185+
}
186+
187+
const call = _.callable(request, self => (id: string) => ({ ...self, id }))
188+
189+
expect(call.source).toBe('client')
190+
expect(call.body).toBe('ford')
191+
expect(call.doors).toBe(2)
192+
const s = call('23')
193+
expect(s.doors).toBe(2)
194+
expect(s.id).toBe('23')
195+
196+
call.doors = 4
197+
expect(call.doors).toBe(4)
198+
const x = call('9')
199+
expect(x.doors).toBe(4)
200+
expect(x.id).toBe('9')
201+
})
202+
})

0 commit comments

Comments
 (0)