UNPKG

class-privacy

Version:

Simple way to define private members on ES6 classes, keep their code clean.

1 lines 6.24 kB
{"version":3,"sources":["../lib/index.js"],"names":["defaultOptions","decide","revealIsProxy","referenceClass","IS_PROXY","CLASS","check","value","expected","proto","Object","getPrototypeOf","constructor","constructorName","name","expectedName","TypeError","createFactory","ClassDefinition","options","Function","factoryOptions","assign","factory","invocationArgs","instance","handler","get","target","property","member","type","includeMember","bind","Proxy"],"mappings":"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","sourcesContent":["/**\n * @type {decide} defaults to a function always returning true\n * @type {revealIsProxy} defaults to false\n * @type {referenceClass} defaults to false\n */\nconst defaultOptions = {}\ndefaultOptions.decide = () => true\ndefaultOptions.revealIsProxy = false\ndefaultOptions.referenceClass = false\n\nconst IS_PROXY = 'isProxy'\nconst CLASS = 'class'\n\n/**\n * @private checks for a prototype constructor to match an expected value\n */\nconst check = (value, expected) => {\n const proto = value && Object.getPrototypeOf(value)\n const constructor = proto && proto.constructor\n if (constructor !== expected) {\n const constructorName = constructor && constructor.name\n const expectedName = expected && expected.name\n throw new TypeError(`Expected ${expectedName}, got ${constructorName}.`)\n }\n}\n\n/**\n * Creates a factory function that produces proxies to instances of a {class} definition, based on\n * @param ClassDefinition\n * @param options.decide {function} A function that checks the instance's given {key} and {value} of a property and\n * returns true, if the property is public or false if private.\n * @param options.revealIsProxy {boolean} if true it allows external code to ask for {isProxy} which then returns true\n * @param options.referenceClass {boolean} if true it allows external code to ask for {class} which then returns\n * the referenced original class definition but never the instance\n * @returns {function} A factory function to produce proxies to an instance\n */\nconst createFactory = (ClassDefinition, options = defaultOptions) => {\n check(ClassDefinition, Function)\n check(options, Object)\n\n // we flat-merge the options with the default options\n // to ensure that there are no options missing and the factory\n // doesn't crash at runtime, for example because an options has\n // been explicitly set to null\n const factoryOptions = Object.assign({}, defaultOptions, options)\n const decide = factoryOptions.decide || defaultOptions.decide\n const referenceClass = factoryOptions.referenceClass || defaultOptions.referenceClass\n const revealIsProxy = factoryOptions.revealIsProxy || defaultOptions.revealIsProxy\n\n /**\n * Creates an instance of the given ClassDefinition\n * @param invocationArgs arguments of arbitrary length, determined by ClassDefinition\n * @return {proxy}\n */\n const factory = (...invocationArgs) => {\n const instance = new ClassDefinition(...invocationArgs)\n const handler = {\n get: function (target, property /*, receiver */) {\n // get proxy by symbol\n if (revealIsProxy && property === IS_PROXY) {\n return true\n }\n\n // get class by symbol\n if (referenceClass && property === CLASS) {\n return ClassDefinition\n }\n\n // skip any request to unowned properties\n // using 'in' as a good trade-off between validity and performance\n if (!(property in instance)) {\n return\n }\n\n // skip members, that don't pass the test,\n // let developer decide how to design tests\n const member = instance[property]\n const type = typeof member\n const includeMember = decide(property, type, ClassDefinition)\n\n if (!includeMember) {\n return\n }\n\n // bind functions to the instance to avoid unintended\n // blocking the member function's internals\n if (type === 'function') {\n return member.bind(instance)\n } else {\n return member\n }\n }\n }\n\n return new Proxy({}, handler)\n }\n return factory\n}\n\nexport default createFactory\n"],"file":"index.js"}