Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active November 27, 2019 17:25
Show Gist options
  • Save burdiuz/f530f5d53f5a74e5155cd43cf060e808 to your computer and use it in GitHub Desktop.
Save burdiuz/f530f5d53f5a74e5155cd43cf060e808 to your computer and use it in GitHub Desktop.
Functions to copy properties between projects including read-only, non-enumerable and get/set

@actualwave/assign-own-props

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const { hasOwn } = require('@actualwave/has-own');
/*
Will throw error on trying to assign non-configurable property twice
*/
const assignOwnPropsUnsafe = (target, ...sources) => {
sources.forEach((source) => Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)));
return target;
};
const filterSources = (list) => list.filter((source) => source !== undefined && source !== null);
const filterDescriptor = (target, name) => !hasOwn(target, name);
const listPropertyNames = (descriptors) => Object.keys(descriptors);
/*
Allows to create special logic for assigining property descriptors by configuring
touchPropFn - alter every property descriptor
touchSourcesFn - access list of source objects before assigning properties
getDescriptors - function to retrieve property descriptors
filter - decides if property descriptor can be applied to a target
*/
const createAssignOwnProps = (
touchPropFn = (descriptor) => descriptor,
touchSourcesFn = filterSources,
getDescriptors = Object.getOwnPropertyDescriptors,
listNames = listPropertyNames,
filterProp = filterDescriptor,
) => (target, ...sources) => {
touchSourcesFn(sources).forEach((source) => {
const descriptors = getDescriptors(source);
listNames(descriptors).forEach((name) => {
if (filterProp(target, name)) {
Object.defineProperty(target, name, touchPropFn(descriptors[name], name, target));
}
});
});
return target;
};
const assignOwnProps = createAssignOwnProps();
/*
As you can see -- instead of re-assigning next descriptor for same property, I reversed array,
so last descriptor being used.
*/
const assignOwnPropsOverwrite = createAssignOwnProps(undefined, (list) => filterSources([...list]).reverse());
/*
Assign properties and alter each with properties from "sharedPart"
Make every property enumerable:
assignOwnPropsAlter(targetObj, { enumerable: true }, sourceObj1, sourceObj2);
Actually overwrite properties:
assignOwnPropsAlter(targetObj, { configurable: true }, sourceObj1, sourceObj2);
*/
const assignOwnPropsAlter = (() => {
let overwritePart;
const assignAndAlter = createAssignOwnProps((descriptor) => ({ ...descriptor, ...overwritePart }));
return (target, sharedPart, ...sources) => {
overwritePart = sharedPart;
return assignAndAlter(target, ...sources);
};
})();
exports.assignOwnPropsUnsafe = assignOwnPropsUnsafe;
exports.createAssignOwnProps = createAssignOwnProps;
exports.assignOwnProps = assignOwnProps;
exports.assignOwnPropsOverwrite = assignOwnPropsOverwrite;
exports.assignOwnPropsAlter = assignOwnPropsAlter;
exports.default = assignOwnProps;
{
"name": "@actualwave/assign-own-props",
"description": "Functions to copy properties between projects including read-only, non-enumerable and get/set",
"version": "0.0.1",
"main": "index.js",
"keywords": [
"object",
"property",
"assign",
"Object.assign",
"hasOwn",
"getOwnPropertyDescriptors",
"defineProperty",
"defineProperties",
"Object.keys"
],
"author": {
"name": "Oleg Galaburda",
"email": "[email protected]",
"url": "http://actualwave.com/"
},
"bugs": {
"url": "https://gist.github.com/burdiuz/f530f5d53f5a74e5155cd43cf060e808",
"email": "[email protected]"
},
"homepage": "https://gist.github.com/burdiuz/f530f5d53f5a74e5155cd43cf060e808",
"dependencies": {
"@actualwave/has-own": "0.0.1"
},
"license": "MIT"
}
import hasOwn from '@actualwave/has-own';
/*
Will throw error on trying to assign non-configurable property twice
*/
export const assignOwnPropsUnsafe = (target, ...sources) => {
sources.forEach((source) => Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)));
return target;
};
const filterSources = (list) => list.filter((source) => source !== undefined && source !== null);
const filterDescriptor = (target, name) => !hasOwn(target, name);
const listPropertyNames = (descriptors) => Object.keys(descriptors);
/*
Allows to create special logic for assigining property descriptors by configuring
touchPropFn - alter every property descriptor
touchSourcesFn - access list of source objects before assigning properties
getDescriptors - function to retrieve property descriptors
filter - decides if property descriptor can be applied to a target
*/
export const createAssignOwnProps = (
touchPropFn = (descriptor) => descriptor,
touchSourcesFn = filterSources,
getDescriptors = Object.getOwnPropertyDescriptors,
listNames = listPropertyNames,
filterProp = filterDescriptor,
) => (target, ...sources) => {
touchSourcesFn(sources).forEach((source) => {
const descriptors = getDescriptors(source);
listNames(descriptors).forEach((name) => {
if (filterProp(target, name)) {
Object.defineProperty(target, name, touchPropFn(descriptors[name], name, target));
}
});
});
return target;
};
export const assignOwnProps = createAssignOwnProps();
/*
As you can see -- instead of re-assigning next descriptor for same property, I reversed array,
so last descriptor being used.
*/
export const assignOwnPropsOverwrite = createAssignOwnProps(undefined, (list) => filterSources([...list]).reverse());
/*
Assign properties and alter each with properties from "sharedPart"
Make every property enumerable:
assignOwnPropsAlter(targetObj, { enumerable: true }, sourceObj1, sourceObj2);
Actually overwrite properties:
assignOwnPropsAlter(targetObj, { configurable: true }, sourceObj1, sourceObj2);
*/
export const assignOwnPropsAlter = (() => {
let overwritePart;
const assignAndAlter = createAssignOwnProps((descriptor) => ({ ...descriptor, ...overwritePart }));
return (target, sharedPart, ...sources) => {
overwritePart = sharedPart;
return assignAndAlter(target, ...sources);
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment