test
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
mol
2024-07-06 22:23:31 +08:00
parent 08173d8497
commit 263cb5ef03
1663 changed files with 526884 additions and 0 deletions

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,17 @@
NOTICES AND INFORMATION
Do Not Translate or Localize
This software incorporates material from third parties. Microsoft makes certain
open source code available at https://3rdpartysource.microsoft.com, or you may
send a check or money order for US $5.00, including the product name, the open
source component name, and version number, to:
Source Code Compliance Team
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052
USA
Notwithstanding any other terms, you may reverse engineer this software to the
extent required to debug changes to any libraries licensed under the GNU Lesser
General Public License.

View File

@ -0,0 +1,124 @@
# Releases
## 1.1.9 (Mar 30th, 2023)
- #75 [Master] Fix npm pack and publish issues
- Additional fixes for #61 Exclude files from published package
## 1.1.8 (Feb 27th, 2023)
- #61 Exclude files from published package
- #65 Bump external library Sinon.JS to newer version which does not use eval
- #64 Internal Task 17133116: Add Policheck exclusion file
- #62 Add --no-sandbox to test runs
## 1.1.7 (Oct 11th, 2022)
- #55 Update and add legal compliance notices and license terms
- #56 Semmle warning help
- #57 [Bug] Corner case issue when extending the same "Class" name from different components
## 1.1.6 (May 4th, 2022)
- #50 [IE8] Fix in 1.1.5 only handles 2 levels of dynamically nested classes
## 1.1.5 (Apr 28th, 2022)
- #47 [IE8] The _checkPrototype always fails on IE in IE8 mode
## 1.1.4 (Jun 3rd, 2021)
- #36 v1.1.3 postinstall requires rush to be installed
## 1.1.3 (Jun 3rd, 2021)
There are no functional (code) differences between v1.1.2 and v1.1.3, both issues below are related to the build and packaging pipelines only.
- #33 Version 1.1.2 has extraneous dependencies such as findup-sync (Build Only)
- #34 Task 9901543: Remediate security vulnerabilities (Build only)
## 1.1.2 (Apr 16th, 2021)
- #31 [BUG] _checkPrototype function loops indefinitely when calling Invoke-WebRequest cmdlet against a docs.microsoft.com webpage
## 1.1.1 (Mar 10th, 2021)
### Changelog
- #28 [ES6] TypeError: xxx is not a function or TypeError: DynamicProto [XXXX] is not in class heirarchy of [Object]
- Added this RELEASES.md file
## 1.1.0 (Oct 14th, 2020)
### Changelog
- #24 [Feature Request] Performance optimization - ability to keep/set instance level function to avoid dynamic proxy lookup
## 1.0.1 (Sep 24th, 2020)
### Changelog
- #22 Add sideEffects field to package.json
## 1.0.0 and 0.5.3 (Jul 7th, 2020)
### Changelog
- Update version to major release based on stability
- #20 WARN @microsoft/dynamicproto-js@0.5.2 requires a peer of tslib@^1.9.3 but none was installed.
- Remove unused peerDependency for tslib
## 0.5.2 (Mar 24th, 2020)
### Changelog
- Fix issue causing long running script error on IE7/8
- #19 getBaseFuncs() usage of _getObjProto() is causing a long running script (it's broken) when running Internet explorer in 7/8 mode.
- #16 The dynamicRemove() rollup is not removing methods with default arguments or is using the spread operator
## 0.5.1 (Jan 14th, 2020)
### Changelog
- #14 postinstall script is causing consumption of the npm package to fail -- remove
- Enable the tagging and removal of stub methods during packaging #11
- Added rollup plugin to enable the removal of stub functions, required to enable declaration (*.d.ts) files to match the runtime resulting class definition.
- By using the rollup plugin this will remove the tagged stub functions during packaging with rollup.
## 0.5.0 (Jan 14th, 2020) - Pre-release
### Changelog
- #11 Enable the tagging and removal of stub methods during packaging
- Added rollup plugin to enable the removal of stub functions, required to enable declaration (*.d.ts) files to match the runtime resulting class definition.
- By using the rollup plugin this will remove the tagged stub functions during packaging with rollup.
## 0.2.0 (Nov 18th, 2019)
### Changelog
- Corrected the publishing and minification of the dist/esm module
## 0.1.0 (Nov 18th, 2019)
### Changelog
- Update NPM packaging and distribution packages
## 0.0.7 (Nov 15th, 2019)
### Changelog
- Fixes location of the typescript declaration in the root package.json
## 0.0.6 (Nov 15th, 2019)
### Changelog
- Initial working release
## 0.0.2 (Nov 12th, 2019)
### Changelog
- Initial publish release, merging code from internal repo's

View File

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

View File

@ -0,0 +1,548 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
define((function () { 'use strict';
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
return dynamicProto;
}));

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
define(function(){"use strict";var n,t="undefined",o="constructor",d="prototype",h="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",w="_dynInstChk",b=w,P="_dfOpts",r="_unknown_",e="__proto__",i="_dyn"+e,f="__dynProto$Gbl",u="_dynInstProto",I="useBaseInst",O="setInstFuncs",s=Object,m=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},C=t[f]||(t[f]={o:((n={})[O]=!0,n[I]=!0,n),n:1e3});function k(n,t){return n&&s[d].hasOwnProperty.call(n,t)}function F(n){return n&&(n===s[d]||n===Array[d])}function T(n){return F(n)||n===Function[d]}function $(n){if(n){if(m)return m(n);var t=n[e]||n[d]||(n[o]?n[o][d]:null),r=n[i]||t;k(n,i)||(delete n[u],r=n[i]=n[u]||n[i],n[u]=t)}return r}function D(n,t){var r=[];if(a)r=a(n);else for(var o in n)"string"==typeof o&&k(n,o)&&r.push(o);if(r&&0<r.length)for(var e=0;e<r.length;e++)t(r[e])}function j(n,t,r){return t!==o&&typeof n[t]===h&&(r||k(n,t))}function x(n){throw new TypeError("DynamicProto: "+n)}function A(n,t){for(var r=n.length-1;0<=r;r--)if(n[r]===t)return 1}function B(n,t){return k(n,d)?n.name||t||r:((n||{})[o]||{}).name||t||r}function E(n,o,t,r){k(n,d)||x("theClass is an invalid class definition.");var e,i,f,u,s,a,c=n[d],l=(function(n){if(!m)return 1;for(var t=[],r=$(o);r&&!T(r)&&!A(t,r);){if(r===n)return 1;t.push(r),r=$(r)}}(c)||x("["+B(n)+"] not in hierarchy of ["+B(o)+"]"),null),n=(k(c,g)?l=c[g]:(l="_dynCls$"+B(n,"_")+"$"+C.n,C.n++,c[g]=l),E[P]),y=!!n[I],p=(y&&r&&r[I]!==undefined&&(y=!!r[I]),i={},D(e=o,function(n){!i[n]&&j(e,n,!1)&&(i[n]=e[n])}),i),y=(t(o,function(n,t,r,i){function o(n,t,r){var o,e=t[r];return e[_]&&i&&!1!==(o=n[v]||{})[b]&&(e=(o[t[g]]||{})[r]||e),function(){return e.apply(n,arguments)}}for(var e={},f=(D(r,function(n){e[n]=o(t,r,n)}),$(n)),u=[];f&&!T(f)&&!A(u,f);)D(f,function(n){!e[n]&&j(f,n,!m)&&(e[n]=o(t,f,n))}),u.push(f),f=$(f);return e}(c,o,p,y)),!!m&&!!n[O]);f=c,t=l,u=o,s=p,n=0!=(y&&r?!!r[O]:y),F(f)||(c=u[v]=u[v]||{},a=c[t]=c[t]||{},!1!==c[b]&&(c[b]=!!n),D(u,function(n){var r,o,e;j(u,n,!1)&&u[n]!==s[n]&&(a[n]=u[n],delete u[n],k(f,n)&&(!f[n]||f[n][_])||(f[n]=(r=f,o=n,(e=function(){var n,t;return(function(n,t,r,o){var e=null;if(n&&k(r,g)){var i=n[v]||{};if((e=(i[r[g]]||{})[t])||x("Missing ["+t+"] "+h),!e[w]&&!1!==i[b]){for(var f=!k(n,t),u=$(n),s=[];f&&u&&!T(u)&&!A(s,u);){var a=u[t];if(a){f=a===o;break}s.push(u),u=$(u)}try{f&&(n[t]=e),e[w]=1}catch(c){i[b]=!1}}}return e}(this,o,r,e)||(typeof(t=(t=r[n=o])===e?$(r)[n]:t)!==h&&x("["+n+"] is not a "+h),t)).apply(this,arguments)})[_]=1,e)))}))}return E[P]=C.o,E});

View File

@ -0,0 +1,546 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
'use strict';
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
module.exports = dynamicProto;

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
"use strict";var n,t="undefined",o="constructor",d="prototype",h="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",w="_dynInstChk",b=w,P="_dfOpts",r="_unknown_",e="__proto__",i="_dyn"+e,u="__dynProto$Gbl",f="_dynInstProto",m="useBaseInst",I="setInstFuncs",s=Object,O=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},C=t[u]||(t[u]={o:((n={})[I]=!0,n[m]=!0,n),n:1e3});function k(n,t){return n&&s[d].hasOwnProperty.call(n,t)}function F(n){return n&&(n===s[d]||n===Array[d])}function T(n){return F(n)||n===Function[d]}function $(n){if(n){if(O)return O(n);var t=n[e]||n[d]||(n[o]?n[o][d]:null),r=n[i]||t;k(n,i)||(delete n[f],r=n[i]=n[f]||n[i],n[f]=t)}return r}function x(n,t){var r=[];if(a)r=a(n);else for(var o in n)"string"==typeof o&&k(n,o)&&r.push(o);if(r&&0<r.length)for(var e=0;e<r.length;e++)t(r[e])}function D(n,t,r){return t!==o&&typeof n[t]===h&&(r||k(n,t))}function j(n){throw new TypeError("DynamicProto: "+n)}function A(n,t){for(var r=n.length-1;0<=r;r--)if(n[r]===t)return 1}function B(n,t){return k(n,d)?n.name||t||r:((n||{})[o]||{}).name||t||r}function E(n,o,t,r){k(n,d)||j("theClass is an invalid class definition.");var e,i,u,f,s,a,c=n[d],l=(function(n){if(!O)return 1;for(var t=[],r=$(o);r&&!T(r)&&!A(t,r);){if(r===n)return 1;t.push(r),r=$(r)}}(c)||j("["+B(n)+"] not in hierarchy of ["+B(o)+"]"),null),n=(k(c,g)?l=c[g]:(l="_dynCls$"+B(n,"_")+"$"+C.n,C.n++,c[g]=l),E[P]),y=!!n[m],p=(y&&r&&r[m]!==undefined&&(y=!!r[m]),i={},x(e=o,function(n){!i[n]&&D(e,n,!1)&&(i[n]=e[n])}),i),y=(t(o,function(n,t,r,i){function o(n,t,r){var o,e=t[r];return e[_]&&i&&!1!==(o=n[v]||{})[b]&&(e=(o[t[g]]||{})[r]||e),function(){return e.apply(n,arguments)}}for(var e={},u=(x(r,function(n){e[n]=o(t,r,n)}),$(n)),f=[];u&&!T(u)&&!A(f,u);)x(u,function(n){!e[n]&&D(u,n,!O)&&(e[n]=o(t,u,n))}),f.push(u),u=$(u);return e}(c,o,p,y)),!!O&&!!n[I]);u=c,t=l,f=o,s=p,n=0!=(y&&r?!!r[I]:y),F(u)||(c=f[v]=f[v]||{},a=c[t]=c[t]||{},!1!==c[b]&&(c[b]=!!n),x(f,function(n){var r,o,e;D(f,n,!1)&&f[n]!==s[n]&&(a[n]=f[n],delete f[n],k(u,n)&&(!u[n]||u[n][_])||(u[n]=(r=u,o=n,(e=function(){var n,t;return(function(n,t,r,o){var e=null;if(n&&k(r,g)){var i=n[v]||{};if((e=(i[r[g]]||{})[t])||j("Missing ["+t+"] "+h),!e[w]&&!1!==i[b]){for(var u=!k(n,t),f=$(n),s=[];u&&f&&!T(f)&&!A(s,f);){var a=f[t];if(a){u=a===o;break}s.push(f),f=$(f)}try{u&&(n[t]=e),e[w]=1}catch(c){i[b]=!1}}}return e}(this,o,r,e)||(typeof(t=(t=r[n=o])===e?$(r)[n]:t)!==h&&j("["+n+"] is not a "+h),t)).apply(this,arguments)})[_]=1,e)))}))}E[P]=C.o,module.exports=E;

View File

@ -0,0 +1,544 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
export { dynamicProto as default };

View File

@ -0,0 +1,544 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
export { dynamicProto as default };

View File

@ -0,0 +1,550 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
this.Microsoft = this.Microsoft || {};
this.Microsoft["DynamicProto-JS"] = (function () {
'use strict';
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
return dynamicProto;
})();

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
this.Microsoft=this.Microsoft||{},this.Microsoft["DynamicProto-JS"]=function(){"use strict";var n,t="undefined",o="constructor",h="prototype",d="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",w="_dynInstChk",P=w,b="_dfOpts",r="_unknown_",i="__proto__",e="_dyn"+i,f="__dynProto$Gbl",u="_dynInstProto",m="useBaseInst",I="setInstFuncs",s=Object,O=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},C=t[f]||(t[f]={o:((n={})[I]=!0,n[m]=!0,n),n:1e3});function M(n,t){return n&&s[h].hasOwnProperty.call(n,t)}function k(n){return n&&(n===s[h]||n===Array[h])}function D(n){return k(n)||n===Function[h]}function F(n){if(n){if(O)return O(n);var t=n[i]||n[h]||(n[o]?n[o][h]:null),r=n[e]||t;M(n,e)||(delete n[u],r=n[e]=n[u]||n[e],n[u]=t)}return r}function T(n,t){var r=[];if(a)r=a(n);else for(var o in n)"string"==typeof o&&M(n,o)&&r.push(o);if(r&&0<r.length)for(var i=0;i<r.length;i++)t(r[i])}function $(n,t,r){return t!==o&&typeof n[t]===d&&(r||M(n,t))}function j(n){throw new TypeError("DynamicProto: "+n)}function x(n,t){for(var r=n.length-1;0<=r;r--)if(n[r]===t)return 1}function A(n,t){return M(n,h)?n.name||t||r:((n||{})[o]||{}).name||t||r}function B(n,o,t,r){M(n,h)||j("theClass is an invalid class definition.");var i,e,f,u,s,a,c=n[h],l=(function(n){if(!O)return 1;for(var t=[],r=F(o);r&&!D(r)&&!x(t,r);){if(r===n)return 1;t.push(r),r=F(r)}}(c)||j("["+A(n)+"] not in hierarchy of ["+A(o)+"]"),null),n=(M(c,g)?l=c[g]:(l="_dynCls$"+A(n,"_")+"$"+C.n,C.n++,c[g]=l),B[b]),y=!!n[m],p=(y&&r&&r[m]!==undefined&&(y=!!r[m]),e={},T(i=o,function(n){!e[n]&&$(i,n,!1)&&(e[n]=i[n])}),e),y=(t(o,function(n,t,r,e){function o(n,t,r){var o,i=t[r];return i[_]&&e&&!1!==(o=n[v]||{})[P]&&(i=(o[t[g]]||{})[r]||i),function(){return i.apply(n,arguments)}}for(var i={},f=(T(r,function(n){i[n]=o(t,r,n)}),F(n)),u=[];f&&!D(f)&&!x(u,f);)T(f,function(n){!i[n]&&$(f,n,!O)&&(i[n]=o(t,f,n))}),u.push(f),f=F(f);return i}(c,o,p,y)),!!O&&!!n[I]);f=c,t=l,u=o,s=p,n=0!=(y&&r?!!r[I]:y),k(f)||(c=u[v]=u[v]||{},a=c[t]=c[t]||{},!1!==c[P]&&(c[P]=!!n),T(u,function(n){var r,o,i;$(u,n,!1)&&u[n]!==s[n]&&(a[n]=u[n],delete u[n],M(f,n)&&(!f[n]||f[n][_])||(f[n]=(r=f,o=n,(i=function(){var n,t;return(function(n,t,r,o){var i=null;if(n&&M(r,g)){var e=n[v]||{};if((i=(e[r[g]]||{})[t])||j("Missing ["+t+"] "+d),!i[w]&&!1!==e[P]){for(var f=!M(n,t),u=F(n),s=[];f&&u&&!D(u)&&!x(s,u);){var a=u[t];if(a){f=a===o;break}s.push(u),u=F(u)}try{f&&(n[t]=i),i[w]=1}catch(c){e[P]=!1}}}return i}(this,o,r,i)||(typeof(t=(t=r[n=o])===i?F(r)[n]:t)!==d&&j("["+n+"] is not a "+d),t)).apply(this,arguments)})[_]=1,i)))}))}return B[b]=C.o,B}();

View File

@ -0,0 +1,552 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.Microsoft = global.Microsoft || {}, global.Microsoft["DynamicProto-JS"] = factory()));
})(this, (function () { 'use strict';
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
return dynamicProto;
}));

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var n=this,t=function(){"use strict";var n,t="undefined",r="constructor",d="prototype",h="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",b="_dynInstChk",w=b,m="_dfOpts",o="_unknown_",e="__proto__",i="_dyn"+e,f="__dynProto$Gbl",u="_dynInstProto",P="useBaseInst",I="setInstFuncs",s=Object,O=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},T=t[f]||(t[f]={o:((n={})[I]=!0,n[P]=!0,n),n:1e3});function C(n,t){return n&&s[d].hasOwnProperty.call(n,t)}function M(n){return n&&(n===s[d]||n===Array[d])}function k(n){return M(n)||n===Function[d]}function x(n){if(n){if(O)return O(n);var t=n[e]||n[d]||(n[r]?n[r][d]:null),o=n[i]||t;C(n,i)||(delete n[u],o=n[i]=n[u]||n[i],n[u]=t)}return o}function D(n,t){var o=[];if(a)o=a(n);else for(var r in n)"string"==typeof r&&C(n,r)&&o.push(r);if(o&&0<o.length)for(var e=0;e<o.length;e++)t(o[e])}function F(n,t,o){return t!==r&&typeof n[t]===h&&(o||C(n,t))}function $(n){throw new TypeError("DynamicProto: "+n)}function j(n,t){for(var o=n.length-1;0<=o;o--)if(n[o]===t)return 1}function A(n,t){return C(n,d)?n.name||t||o:((n||{})[r]||{}).name||t||o}function B(n,r,t,o){C(n,d)||$("theClass is an invalid class definition.");var e,i,f,u,s,a,c=n[d],l=(function(n){if(!O)return 1;for(var t=[],o=x(r);o&&!k(o)&&!j(t,o);){if(o===n)return 1;t.push(o),o=x(o)}}(c)||$("["+A(n)+"] not in hierarchy of ["+A(r)+"]"),null),n=(C(c,g)?l=c[g]:(l="_dynCls$"+A(n,"_")+"$"+T.n,T.n++,c[g]=l),B[m]),y=!!n[P],p=(y&&o&&o[P]!==undefined&&(y=!!o[P]),i={},D(e=r,function(n){!i[n]&&F(e,n,!1)&&(i[n]=e[n])}),i),y=(t(r,function(n,t,o,i){function r(n,t,o){var r,e=t[o];return e[_]&&i&&!1!==(r=n[v]||{})[w]&&(e=(r[t[g]]||{})[o]||e),function(){return e.apply(n,arguments)}}for(var e={},f=(D(o,function(n){e[n]=r(t,o,n)}),x(n)),u=[];f&&!k(f)&&!j(u,f);)D(f,function(n){!e[n]&&F(f,n,!O)&&(e[n]=r(t,f,n))}),u.push(f),f=x(f);return e}(c,r,p,y)),!!O&&!!n[I]);f=c,t=l,u=r,s=p,n=0!=(y&&o?!!o[I]:y),M(f)||(c=u[v]=u[v]||{},a=c[t]=c[t]||{},!1!==c[w]&&(c[w]=!!n),D(u,function(n){var o,r,e;F(u,n,!1)&&u[n]!==s[n]&&(a[n]=u[n],delete u[n],C(f,n)&&(!f[n]||f[n][_])||(f[n]=(o=f,r=n,(e=function(){var n,t;return(function(n,t,o,r){var e=null;if(n&&C(o,g)){var i=n[v]||{};if((e=(i[o[g]]||{})[t])||$("Missing ["+t+"] "+h),!e[b]&&!1!==i[w]){for(var f=!C(n,t),u=x(n),s=[];f&&u&&!k(u)&&!j(s,u);){var a=u[t];if(a){f=a===r;break}s.push(u),u=x(u)}try{f&&(n[t]=e),e[b]=1}catch(c){i[w]=!1}}}return e}(this,r,o,e)||(typeof(t=(t=o[n=r])===e?x(o)[n]:t)!==h&&$("["+n+"] is not a "+h),t)).apply(this,arguments)})[_]=1,e)))}))}return B[m]=T.o,B};"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((n="undefined"!=typeof globalThis?globalThis:n||self).Microsoft=n.Microsoft||{},n.Microsoft["DynamicProto-JS"]=t());

View File

@ -0,0 +1,553 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
System.register('Microsoft.DynamicProto-JS', [], (function (exports) {
'use strict';
return {
execute: (function () {
exports('default', dynamicProto);
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
})
};
}));

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
System.register("Microsoft.DynamicProto-JS",[],function(c){"use strict";return{execute:function(){c("default",B);var n,t="undefined",o="constructor",d="prototype",h="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",w="_dynCls$",P="_dynInstChk",b=P,m="_dfOpts",r="_unknown_",e="__proto__",i="_dyn"+e,u="__dynProto$Gbl",f="_dynInstProto",I="useBaseInst",O="setInstFuncs",s=Object,C=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},k=t[u]||(t[u]={o:((n={})[O]=!0,n[I]=!0,n),n:1e3});function D(n,t){return n&&s[d].hasOwnProperty.call(n,t)}function F(n){return n&&(n===s[d]||n===Array[d])}function T(n){return F(n)||n===Function[d]}function $(n){if(n){if(C)return C(n);var t=n[e]||n[d]||(n[o]?n[o][d]:null),r=n[i]||t;D(n,i)||(delete n[f],r=n[i]=n[f]||n[i],n[f]=t)}return r}function x(n,t){var r=[];if(a)r=a(n);else for(var o in n)"string"==typeof o&&D(n,o)&&r.push(o);if(r&&0<r.length)for(var e=0;e<r.length;e++)t(r[e])}function M(n,t,r){return t!==o&&typeof n[t]===h&&(r||D(n,t))}function S(n){throw new TypeError("DynamicProto: "+n)}function j(n,t){for(var r=n.length-1;0<=r;r--)if(n[r]===t)return 1}function A(n,t){return D(n,d)?n.name||t||r:((n||{})[o]||{}).name||t||r}function B(n,o,t,r){D(n,d)||S("theClass is an invalid class definition.");var e,i,u,f,s,a,c=n[d],l=(function(n){if(!C)return 1;for(var t=[],r=$(o);r&&!T(r)&&!j(t,r);){if(r===n)return 1;t.push(r),r=$(r)}}(c)||S("["+A(n)+"] not in hierarchy of ["+A(o)+"]"),null),n=(D(c,g)?l=c[g]:(l=w+A(n,"_")+"$"+k.n,k.n++,c[g]=l),B[m]),y=!!n[I],p=(y&&r&&r[I]!==undefined&&(y=!!r[I]),i={},x(e=o,function(n){!i[n]&&M(e,n,!1)&&(i[n]=e[n])}),i),y=(t(o,function(n,t,r,i){function o(n,t,r){var o,e=t[r];return e[_]&&i&&!1!==(o=n[v]||{})[b]&&(e=(o[t[g]]||{})[r]||e),function(){return e.apply(n,arguments)}}for(var e={},u=(x(r,function(n){e[n]=o(t,r,n)}),$(n)),f=[];u&&!T(u)&&!j(f,u);)x(u,function(n){!e[n]&&M(u,n,!C)&&(e[n]=o(t,u,n))}),f.push(u),u=$(u);return e}(c,o,p,y)),!!C&&!!n[O]);u=c,t=l,f=o,s=p,n=0!=(y&&r?!!r[O]:y),F(u)||(c=f[v]=f[v]||{},a=c[t]=c[t]||{},!1!==c[b]&&(c[b]=!!n),x(f,function(n){var r,o,e;M(f,n,!1)&&f[n]!==s[n]&&(a[n]=f[n],delete f[n],D(u,n)&&(!u[n]||u[n][_])||(u[n]=(r=u,o=n,(e=function(){var n,t;return(function(n,t,r,o){var e=null;if(n&&D(r,g)){var i=n[v]||{};if((e=(i[r[g]]||{})[t])||S("Missing ["+t+"] "+h),!e[P]&&!1!==i[b]){for(var u=!D(n,t),f=$(n),s=[];u&&f&&!T(f)&&!j(s,f);){var a=f[t];if(a){u=a===o;break}s.push(f),f=$(f)}try{u&&(n[t]=e),e[P]=1}catch(c){i[b]=!1}}}return e}(this,o,r,e)||(typeof(t=(t=r[n=o])===e?$(r)[n]:t)!==h&&S("["+n+"] is not a "+h),t)).apply(this,arguments)})[_]=1,e)))}))}B[m]=k.o}}});

View File

@ -0,0 +1,552 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.Microsoft = global.Microsoft || {}, global.Microsoft["DynamicProto-JS"] = factory()));
})(this, (function () { 'use strict';
var _a;
var UNDEFINED = "undefined";
/**
* Constant string defined to support minimization
* @ignore
*/
var Constructor = 'constructor';
/**
* Constant string defined to support minimization
* @ignore
*/
var Prototype = 'prototype';
/**
* Constant string defined to support minimization
* @ignore
*/
var strFunction = 'function';
/**
* Used to define the name of the instance function lookup table
* @ignore
*/
var DynInstFuncTable = '_dynInstFuncs';
/**
* Name used to tag the dynamic prototype function
* @ignore
*/
var DynProxyTag = '_isDynProxy';
/**
* Name added to a prototype to define the dynamic prototype "class" name used to lookup the function table
* @ignore
*/
var DynClassName = '_dynClass';
/**
* Prefix added to the classname to avoid any name clashes with other instance level properties
* @ignore
*/
var DynClassNamePrefix = '_dynCls$';
/**
* A tag which is used to check if we have already to attempted to set the instance function if one is not present
* @ignore
*/
var DynInstChkTag = '_dynInstChk';
/**
* A tag which is used to check if we are allows to try and set an instance function is one is not present. Using the same
* tag name as the function level but a different const name for readability only.
*/
var DynAllowInstChkTag = DynInstChkTag;
/**
* The global (imported) instances where the global performance options are stored
*/
var DynProtoDefaultOptions = '_dfOpts';
/**
* Value used as the name of a class when it cannot be determined
* @ignore
*/
var UnknownValue = '_unknown_';
/**
* Constant string defined to support minimization
* @ignore
*/
var str__Proto = "__proto__";
/**
* The polyfill version of __proto__ so that it doesn't cause issues for anyone not expecting it to exist
*/
var DynProtoBaseProto = "_dyn" + str__Proto;
/**
* Runtime Global holder for dynamicProto settings
*/
var DynProtoGlobalSettings = "__dynProto$Gbl";
/**
* Track the current prototype for IE8 as you can't look back to get the prototype
*/
var DynProtoCurrent = "_dynInstProto";
/**
* Constant string defined to support minimization
* @ignore
*/
var strUseBaseInst = 'useBaseInst';
/**
* Constant string defined to support minimization
* @ignore
*/
var strSetInstFuncs = 'setInstFuncs';
var Obj = Object;
/**
* Pre-lookup to check if we are running on a modern browser (i.e. not IE8)
* @ignore
*/
var _objGetPrototypeOf = Obj["getPrototypeOf"];
/**
* Pre-lookup to check for the existence of this function
*/
var _objGetOwnProps = Obj["getOwnPropertyNames"];
/**
* Gets the runtime global reference
* @returns
*/
function _getGlobal() {
var result;
if (typeof globalThis !== UNDEFINED) {
result = globalThis;
}
if (!result && typeof self !== UNDEFINED) {
result = self;
}
if (!result && typeof window !== UNDEFINED) {
result = window;
}
if (!result && typeof global !== UNDEFINED) {
result = global;
}
return result || {};
}
// Since 1.1.7 moving these to the runtime global to work around mixed version and module issues
// See Issue https://github.com/microsoft/DynamicProto-JS/issues/57 for details
var _gbl = _getGlobal();
var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
o: (_a = {},
_a[strSetInstFuncs] = true,
_a[strUseBaseInst] = true,
_a),
n: 1000 // Start new global index @ 1000 so we "fix" some cases when mixed with 1.1.6 or earlier
});
/**
* Helper to check if the object contains a property of the name
* @ignore
*/
function _hasOwnProperty(obj, prop) {
return obj && Obj[Prototype].hasOwnProperty.call(obj, prop);
}
/**
* Helper used to check whether the target is an Object prototype or Array prototype
* @ignore
*/
function _isObjectOrArrayPrototype(target) {
return target && (target === Obj[Prototype] || target === Array[Prototype]);
}
/**
* Helper used to check whether the target is an Object prototype, Array prototype or Function prototype
* @ignore
*/
function _isObjectArrayOrFunctionPrototype(target) {
return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
}
/**
* Helper used to get the prototype of the target object as getPrototypeOf is not available in an ES3 environment.
* @ignore
*/
function _getObjProto(target) {
var newProto;
if (target) {
// This method doesn't exist in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
return _objGetPrototypeOf(target);
}
var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
// Using the pre-calculated value as IE8 doesn't support looking up the prototype of a prototype and thus fails for more than 1 base class
newProto = target[DynProtoBaseProto] || curProto;
if (!_hasOwnProperty(target, DynProtoBaseProto)) {
// As this prototype doesn't have this property then this is from an inherited class so newProto is the base to return so save it
// so we can look it up value (which for a multiple hierarchy dynamicProto will be the base class)
delete target[DynProtoCurrent]; // Delete any current value allocated to this instance so we pick up the value from prototype hierarchy
newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
target[DynProtoCurrent] = curProto;
}
}
return newProto;
}
/**
* Helper to get the properties of an object, including none enumerable ones as functions on a prototype in ES6
* are not enumerable.
* @param target
*/
function _forEachProp(target, func) {
var props = [];
if (_objGetOwnProps) {
props = _objGetOwnProps(target);
}
else {
for (var name_1 in target) {
if (typeof name_1 === "string" && _hasOwnProperty(target, name_1)) {
props.push(name_1);
}
}
}
if (props && props.length > 0) {
for (var lp = 0; lp < props.length; lp++) {
func(props[lp]);
}
}
}
/**
* Helper function to check whether the provided function name is a potential candidate for dynamic
* callback and prototype generation.
* @param target The target object, may be a prototype or class object
* @param funcName The function name
* @param skipOwn Skips the check for own property
* @ignore
*/
function _isDynamicCandidate(target, funcName, skipOwn) {
return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || _hasOwnProperty(target, funcName)));
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throw new TypeError("DynamicProto: " + message);
}
/**
* Returns a collection of the instance functions that are defined directly on the thisTarget object, it does
* not return any inherited functions
* @param thisTarget The object to get the instance functions from
* @ignore
*/
function _getInstanceFuncs(thisTarget) {
// Get the base proto
var instFuncs = {};
// Save any existing instance functions
_forEachProp(thisTarget, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
// Create an instance callback for passing the base function to the caller
instFuncs[name] = thisTarget[name];
}
});
return instFuncs;
}
/**
* Returns whether the value is included in the array
* @param values The array of values
* @param value The value
*/
function _hasVisited(values, value) {
for (var lp = values.length - 1; lp >= 0; lp--) {
if (values[lp] === value) {
return true;
}
}
return false;
}
/**
* Returns an object that contains callback functions for all "base/super" functions, this is used to "save"
* enabling calling super.xxx() functions without requiring that the base "class" has defined a prototype references
* @param target The current instance
* @ignore
*/
function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
function _instFuncProxy(target, funcHost, funcName) {
var theFunc = funcHost[funcName];
if (theFunc[DynProxyTag] && useBaseInst) {
// grab and reuse the hosted looking function (if available) otherwise the original passed function
var instFuncTable = target[DynInstFuncTable] || {};
if (instFuncTable[DynAllowInstChkTag] !== false) {
theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
}
}
return function () {
// eslint-disable-next-line prefer-rest-params
return theFunc.apply(target, arguments);
};
}
// Start creating a new baseFuncs by creating proxies for the instance functions (as they may get replaced)
var baseFuncs = {};
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Get the base prototype functions
var baseProto = _getObjProto(classProto);
var visited = [];
// Don't include base object functions for Object, Array or Function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
// look for prototype functions
_forEachProp(baseProto, function (name) {
// Don't include any dynamic prototype instances - as we only want the real functions
// For IE 7/8 the prototype lookup doesn't provide the full chain so we need to bypass the
// hasOwnProperty check we get all of the methods, main difference is that IE7/8 doesn't return
// the Object prototype methods while bypassing the check
if (!baseFuncs[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, baseProto, name);
}
});
// We need to find all possible functions that might be overloaded by walking the entire prototype chain
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
return baseFuncs;
}
function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
var instFunc = null;
// We need to check whether the class name is defined directly on this prototype otherwise
// it will walk the proto chain and return any parent proto classname.
if (target && _hasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || {};
instFunc = (instFuncTable[proto[DynClassName]] || {})[funcName];
if (!instFunc) {
// Avoid stack overflow from recursive calling the same function
_throwTypeError("Missing [" + funcName + "] " + strFunction);
}
// We have the instance function, lets check it we can speed up further calls
// by adding the instance function back directly on the instance (avoiding the dynamic func lookup)
if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
// If the instance already has an instance function we can't replace it
var canAddInst = !_hasOwnProperty(target, funcName);
// Get current prototype
var objProto = _getObjProto(target);
var visited = [];
// Lookup the function starting at the top (instance level prototype) and traverse down, if the first matching function
// if nothing is found or if the first hit is a dynamic proto instance then we can safely add an instance shortcut
while (canAddInst && objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
var protoFunc = objProto[funcName];
if (protoFunc) {
canAddInst = (protoFunc === currentDynProtoProxy);
break;
}
// We need to find all possible initial functions to ensure that we don't bypass a valid override function
visited.push(objProto);
objProto = _getObjProto(objProto);
}
try {
if (canAddInst) {
// This instance doesn't have an instance func and the class hierarchy does have a higher level prototype version
// so it's safe to directly assign for any subsequent calls (for better performance)
target[funcName] = instFunc;
}
// Block further attempts to set the instance function for any
instFunc[DynInstChkTag] = 1;
}
catch (e) {
// Don't crash if the object is readonly or the runtime doesn't allow changing this
// And set a flag so we don't try again for any function
instFuncTable[DynAllowInstChkTag] = false;
}
}
}
return instFunc;
}
function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
var protoFunc = proto[funcName];
// Check that the prototype function is not a self reference -- try to avoid stack overflow!
if (protoFunc === currentDynProtoProxy) {
// It is so lookup the base prototype
protoFunc = _getObjProto(proto)[funcName];
}
if (typeof protoFunc !== strFunction) {
_throwTypeError("[" + funcName + "] is not a " + strFunction);
}
return protoFunc;
}
/**
* Add the required dynamic prototype methods to the the class prototype
* @param proto - The class prototype
* @param className - The instance classname
* @param target - The target instance
* @param baseInstFuncs - The base instance functions
* @param setInstanceFunc - Flag to allow prototype function to reset the instance function if one does not exist
* @ignore
*/
function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
function _createDynamicPrototype(proto, funcName) {
var dynProtoProxy = function () {
// Use the instance or prototype function
var instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// eslint-disable-next-line prefer-rest-params
return instFunc.apply(this, arguments);
};
// Tag this function as a proxy to support replacing dynamic proxy elements (primary use case is for unit testing
// via which can dynamically replace the prototype function reference)
dynProtoProxy[DynProxyTag] = 1;
return dynProtoProxy;
}
if (!_isObjectOrArrayPrototype(proto)) {
var instFuncTable = target[DynInstFuncTable] = target[DynInstFuncTable] || {};
var instFuncs_1 = instFuncTable[className] = (instFuncTable[className] || {}); // fetch and assign if as it may not exist yet
// Set whether we are allow to lookup instances, if someone has set to false then do not re-enable
if (instFuncTable[DynAllowInstChkTag] !== false) {
instFuncTable[DynAllowInstChkTag] = !!setInstanceFunc;
}
_forEachProp(target, function (name) {
// Only add overridden functions
if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
// Save the instance Function to the lookup table and remove it from the instance as it's not a dynamic proto function
instFuncs_1[name] = target[name];
delete target[name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!_hasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
proto[name] = _createDynamicPrototype(proto, name);
}
}
});
}
}
/**
* Checks whether the passed prototype object appears to be correct by walking the prototype hierarchy of the instance
* @param classProto The class prototype instance
* @param thisTarget The current instance that will be checked whether the passed prototype instance is in the hierarchy
* @ignore
*/
function _checkPrototype(classProto, thisTarget) {
// This method doesn't existing in older browsers (e.g. IE8)
if (_objGetPrototypeOf) {
// As this is primarily a coding time check, don't bother checking if running in IE8 or lower
var visited = [];
var thisProto = _getObjProto(thisTarget);
while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
if (thisProto === classProto) {
return true;
}
// This avoids the caller from needing to check whether it's direct base class implements the function or not
// by walking the entire chain it simplifies the usage and issues from upgrading any of the base classes.
visited.push(thisProto);
thisProto = _getObjProto(thisProto);
}
return false;
}
// If objGetPrototypeOf doesn't exist then just assume everything is ok.
return true;
}
/**
* Gets the current prototype name using the ES6 name if available otherwise falling back to a use unknown as the name.
* It's not critical for this to return a name, it's used to decorate the generated unique name for easier debugging only.
* @param target
* @param unknownValue
* @ignore
*/
function _getObjName(target, unknownValue) {
if (_hasOwnProperty(target, Prototype)) {
// Look like a prototype
return target.name || unknownValue || UnknownValue;
}
return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
}
/**
* Helper function when creating dynamic (inline) functions for classes, this helper performs the following tasks :-
* - Saves references to all defined base class functions
* - Calls the delegateFunc with the current target (this) and a base object reference that can be used to call all "super" functions.
* - Will populate the class prototype for all overridden functions to support class extension that call the prototype instance.
* Callers should use this helper when declaring all function within the constructor of a class, as mentioned above the delegateFunc is
* passed both the target "this" and an object that can be used to call any base (super) functions, using this based object in place of
* super.XXX() (which gets expanded to _super.prototype.XXX()) provides a better minification outcome and also ensures the correct "this"
* context is maintained as TypeScript creates incorrect references using super.XXXX() for dynamically defined functions i.e. Functions
* defined in the constructor or some other function (rather than declared as complete typescript functions).
* ### Usage
* ```typescript
* import dynamicProto from "@microsoft/dynamicproto-js";
* class ExampleClass extends BaseClass {
* constructor() {
* dynamicProto(ExampleClass, this, (_self, base) => {
* // This will define a function that will be converted to a prototype function
* _self.newFunc = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* ...
* }
* }
* // This will define a function that will be converted to a prototype function
* _self.myFunction = () => {
* // Access any "this" instance property
* if (_self.someProperty) {
* // Call the base version of the function that we are overriding
* base.myFunction();
* }
* ...
* }
* _self.initialize = () => {
* ...
* }
* // Warnings: While the following will work as _self is simply a reference to
* // this, if anyone overrides myFunction() the overridden will be called first
* // as the normal JavaScript method resolution will occur and the defined
* // _self.initialize() function is actually gets removed from the instance and
* // a proxy prototype version is created to reference the created method.
* _self.initialize();
* });
* }
* }
* ```
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid
* @typeparam DPCls The type that contains the prototype of the current class
* @param theClass - This is the current class instance which contains the prototype for the current class
* @param target - The current "this" (target) reference, when the class has been extended this.prototype will not be the 'theClass' value.
* @param delegateFunc - The callback function (closure) that will create the dynamic function
* @param options - Additional options to configure how the dynamic prototype operates
*/
function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!_hasOwnProperty(theClass, Prototype)) {
_throwTypeError("theClass is an invalid class definition.");
}
// Quick check to make sure that the passed theClass argument looks correct (this is a common copy/paste error)
var classProto = theClass[Prototype];
if (!_checkPrototype(classProto, target)) {
_throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
}
var className = null;
if (_hasOwnProperty(classProto, DynClassName)) {
// Only grab the class name if it's defined on this prototype (i.e. don't walk the prototype chain)
className = classProto[DynClassName];
}
else {
// As not all browser support name on the prototype creating a unique dynamic one if we have not already
// assigned one, so we can use a simple string as the lookup rather than an object for the dynamic instance
// function table lookup.
className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
_gblInst.n++;
classProto[DynClassName] = className;
}
var perfOptions = dynamicProto[DynProtoDefaultOptions];
var useBaseInst = !!perfOptions[strUseBaseInst];
if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
useBaseInst = !!options[strUseBaseInst];
}
// Get the current instance functions
var instFuncs = _getInstanceFuncs(target);
// Get all of the functions for any base instance (before they are potentially overridden)
var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
// Execute the delegate passing in both the current target "this" and "base" function references
// Note casting the same type as we don't actually have the base class here and this will provide some intellisense support
delegateFunc(target, baseFuncs);
// Don't allow setting instance functions for older IE instances
var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
if (setInstanceFunc && options) {
setInstanceFunc = !!options[strSetInstFuncs];
}
// Populate the Prototype for any overridden instance functions
_populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
}
/**
* Exposes the default global options to allow global configuration, if the global values are disabled these will override
* any passed values. This is primarily exposed to support unit-testing without the need for individual classes to expose
* their internal usage of dynamic proto.
*/
dynamicProto[DynProtoDefaultOptions] = _gblInst.o;
return dynamicProto;
}));

View File

@ -0,0 +1,5 @@
/*!
* Microsoft Dynamic Proto Utility, 1.1.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var n=this,t=function(){"use strict";var n,t="undefined",r="constructor",d="prototype",h="function",v="_dynInstFuncs",_="_isDynProxy",g="_dynClass",b="_dynInstChk",w=b,m="_dfOpts",o="_unknown_",e="__proto__",i="_dyn"+e,f="__dynProto$Gbl",u="_dynInstProto",P="useBaseInst",I="setInstFuncs",s=Object,O=s.getPrototypeOf,a=s.getOwnPropertyNames,t=(n=(n=(n=(n=typeof globalThis!=t?globalThis:n)||typeof self==t?n:self)||typeof window==t?n:window)||typeof global==t?n:global)||{},T=t[f]||(t[f]={o:((n={})[I]=!0,n[P]=!0,n),n:1e3});function C(n,t){return n&&s[d].hasOwnProperty.call(n,t)}function M(n){return n&&(n===s[d]||n===Array[d])}function k(n){return M(n)||n===Function[d]}function x(n){if(n){if(O)return O(n);var t=n[e]||n[d]||(n[r]?n[r][d]:null),o=n[i]||t;C(n,i)||(delete n[u],o=n[i]=n[u]||n[i],n[u]=t)}return o}function D(n,t){var o=[];if(a)o=a(n);else for(var r in n)"string"==typeof r&&C(n,r)&&o.push(r);if(o&&0<o.length)for(var e=0;e<o.length;e++)t(o[e])}function F(n,t,o){return t!==r&&typeof n[t]===h&&(o||C(n,t))}function $(n){throw new TypeError("DynamicProto: "+n)}function j(n,t){for(var o=n.length-1;0<=o;o--)if(n[o]===t)return 1}function A(n,t){return C(n,d)?n.name||t||o:((n||{})[r]||{}).name||t||o}function B(n,r,t,o){C(n,d)||$("theClass is an invalid class definition.");var e,i,f,u,s,a,c=n[d],l=(function(n){if(!O)return 1;for(var t=[],o=x(r);o&&!k(o)&&!j(t,o);){if(o===n)return 1;t.push(o),o=x(o)}}(c)||$("["+A(n)+"] not in hierarchy of ["+A(r)+"]"),null),n=(C(c,g)?l=c[g]:(l="_dynCls$"+A(n,"_")+"$"+T.n,T.n++,c[g]=l),B[m]),y=!!n[P],p=(y&&o&&o[P]!==undefined&&(y=!!o[P]),i={},D(e=r,function(n){!i[n]&&F(e,n,!1)&&(i[n]=e[n])}),i),y=(t(r,function(n,t,o,i){function r(n,t,o){var r,e=t[o];return e[_]&&i&&!1!==(r=n[v]||{})[w]&&(e=(r[t[g]]||{})[o]||e),function(){return e.apply(n,arguments)}}for(var e={},f=(D(o,function(n){e[n]=r(t,o,n)}),x(n)),u=[];f&&!k(f)&&!j(u,f);)D(f,function(n){!e[n]&&F(f,n,!O)&&(e[n]=r(t,f,n))}),u.push(f),f=x(f);return e}(c,r,p,y)),!!O&&!!n[I]);f=c,t=l,u=r,s=p,n=0!=(y&&o?!!o[I]:y),M(f)||(c=u[v]=u[v]||{},a=c[t]=c[t]||{},!1!==c[w]&&(c[w]=!!n),D(u,function(n){var o,r,e;F(u,n,!1)&&u[n]!==s[n]&&(a[n]=u[n],delete u[n],C(f,n)&&(!f[n]||f[n][_])||(f[n]=(o=f,r=n,(e=function(){var n,t;return(function(n,t,o,r){var e=null;if(n&&C(o,g)){var i=n[v]||{};if((e=(i[o[g]]||{})[t])||$("Missing ["+t+"] "+h),!e[b]&&!1!==i[w]){for(var f=!C(n,t),u=x(n),s=[];f&&u&&!k(u)&&!j(s,u);){var a=u[t];if(a){f=a===r;break}s.push(u),u=x(u)}try{f&&(n[t]=e),e[b]=1}catch(c){i[w]=!1}}}return e}(this,r,o,e)||(typeof(t=(t=o[n=r])===e?x(o)[n]:t)!==h&&$("["+n+"] is not a "+h),t)).apply(this,arguments)})[_]=1,e)))}))}return B[m]=T.o,B};"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((n="undefined"!=typeof globalThis?globalThis:n||self).Microsoft=n.Microsoft||{},n.Microsoft["DynamicProto-JS"]=t());

View File

@ -0,0 +1,69 @@
{
"name": "@microsoft/dynamicproto-js",
"description": "Microsoft Dynamic Proto Utility",
"version": "1.1.9",
"keywords": [
"javascript",
"dynamic prototype",
"microsoft",
"typescript",
"inheritence",
"minification",
"application insights"
],
"main": "./lib/dist/node/dynamicproto-js.js",
"module": "./lib/dist/esm/dynamicproto-js.js",
"types": "./lib/types/dynamicproto-js.d.ts",
"directories": {
"doc": "lib/docs"
},
"scripts": {
"ci-install": "node common/scripts/install-run-rush.js check && node common/scripts/install-run-rush.js update",
"build": "node common/scripts/install-run-rush.js rebuild && npm run docs",
"test": "grunt dynamicprototest",
"rollup": "grunt rollup",
"rupdate": "node common/scripts/install-run-rush.js update --recheck --purge --full",
"docs": "typedoc",
"fullClean": "git clean -xdf && npm install && rush update --recheck --purge --full",
"fullCleanBuild": "npm run fullClean && npm run build",
"npm_pack": "npm pack",
"npm_publish": "node ./tools/release-tools/npm_publish.js ."
},
"repository": {
"type": "git",
"url": "git+https://github.com/microsoft/DynamicProto-JS.git"
},
"author": "Microsoft Application Insights Team",
"sideEffects": false,
"license": "MIT",
"bugs": {
"url": "https://github.com/microsoft/DynamicProto-JS/issues"
},
"homepage": "https://github.com/microsoft/DynamicProto-JS#readme",
"dependencies": {},
"devDependencies": {
"@microsoft/rush": "5.82.1",
"@nevware21/grunt-ts-plugin": "^0.3.0",
"@nevware21/grunt-eslint-ts": "^0.1.0",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"eslint": "^7.29.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-security": "^1.4.0",
"grunt": "^1.5.3",
"grunt-cli": "^1.4.3",
"grunt-contrib-qunit": "^4.0.0",
"grunt-contrib-uglify": "^5.0.1",
"grunt-run": "^0.8.1",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-replace": "^2.3.3",
"rollup-plugin-cleanup": "3.2.1",
"rollup": "^2.32.0",
"typedoc": "^0.23.25",
"typescript": "^4.9.5",
"copyfiles": "^2.4.1"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff