Created
September 23, 2021 03:44
-
-
Save Kynako/3b7a8b2ddc49a91f2fa30790a22bd322 to your computer and use it in GitHub Desktop.
Generate classes that can use method chaining from built-in classes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
# Usage | |
const chainable = importModule('chainable') | |
// generate a class that can use method chaining. | |
const ChainableAlert = chainable('Alert') | |
// construct instance | |
const alert = new ChainableAlert() | |
.setTitle('Title') | |
.setMessage('Message') | |
.addAction('Action1') | |
.addAction('Action2') | |
.addCancelAction('CancelAction1') | |
.addDestructiveAction('DestructiveAction1') | |
await alert.present() | |
*/ | |
const INFO = { | |
'Alert': { | |
value: Alert, | |
voidReturnerNames: [ | |
'addAction', | |
'addCancelAction', | |
'addDestructiveAction' | |
], | |
writablePropNames: [ | |
'title', | |
'message' | |
] | |
}, | |
'Request': { | |
value: Request, | |
voidReturnerNames: [ | |
'addFileToMultipart', | |
'addFileDataToMultipart', | |
'addImageToMultipart', | |
'addParameterToMultipart' | |
], | |
writablePropNames: [ | |
'url', | |
'method', | |
'headers', | |
'body', | |
'timeoutInterval', | |
'onRedirect', | |
'allowInsecureRequest' | |
] | |
} | |
} | |
/* | |
* - lowerCamelCase -> UpperCamelCase | |
* - set `setProp(prop)` functon | |
* - make functions that return void return self | |
*/ | |
function lowerCamelToUpperCamel(string){ | |
const firstChar = string.slice(0, 1), | |
restChar = string.slice(-(string.length - 1)); | |
return [ firstChar.toUpperCase(), restChar ].join(''); | |
}; | |
/* | |
* set setProp(prop) | |
*/ | |
function setSetPropMethod(propName, Child, Parent){ | |
const methodName = 'set' + lowerCamelToUpperCamel(propName); | |
Child.prototype[methodName] = function (arg) { | |
this[propName] = arg; | |
return this; | |
}; | |
} | |
/* | |
* set selfReturnMethod | |
*/ | |
function setSelfReturnMethod(methodName, Child, Parent){ | |
Child.prototype[methodName] = function (...args){ | |
Parent.prototype[methodName].call(this, ...args); | |
return this; | |
}; | |
}; | |
/* | |
* main | |
*/ | |
function generateChainableClass(className) { | |
const targetClassInfo = INFO[className] | |
const { | |
value: BaseClass, | |
voidReturnerNames, | |
writablePropNames | |
} = targetClassInfo | |
// Inherits from BaseClass | |
const ChainableClass = class extends BaseClass { | |
constructor(...args) { | |
super(...args); | |
}; | |
static name = 'Chainable' + className; | |
}; | |
// list of methods that return void | |
// -> let these methods return this | |
voidReturnerNames.forEach(methodName => { | |
setSelfReturnMethod( | |
methodName, | |
ChainableClass, | |
BaseClass | |
); | |
}); | |
// list of properties that is writable | |
// -> `setTheProperty(theProperty) | |
writablePropNames.forEach(propName => { | |
setSetPropMethod( | |
propName, | |
ChainableClass, | |
BaseClass | |
); | |
}); | |
return ChainableClass; | |
} | |
module.exports = generateChainableClass; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment