push neon reactor

This commit is contained in:
2026-07-12 15:11:38 +02:00
parent 172e72dbcd
commit aeab5f7820
9597 changed files with 2407488 additions and 0 deletions
@@ -0,0 +1,563 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var _a;
import { getGlobal, objCreate, objHasOwnProperty, throwTypeError } from "@nevware21/ts-utils";
/**
* 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';
/**
* Name used to cache base prototype function sources on the class prototype to avoid
* re-walking the prototype chain on every instance creation.
* @ignore
*/
var DynBaseProtoFuncs = '_dynBaseFuncs';
/**
* 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;
/**
* Prefix used for per-instance resolved function cache keys stored in the instFuncTable
* @ignore
*/
var DynResolvedCachePrefix = '_dyn_r$';
/**
* 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"];
// 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 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 (!objHasOwnProperty(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" && objHasOwnProperty(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 || objHasOwnProperty(target, funcName)) && funcName !== str__Proto && funcName !== Prototype);
}
/**
* Helper to throw a TypeError exception
* @param message the message
* @ignore
*/
function _throwTypeError(message) {
throwTypeError("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 = objCreate(null);
// 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;
}
/**
* Caches and returns a mapping of base prototype function names to their source prototype objects.
* This avoids re-walking the prototype chain on every instance creation, reducing construction
* cost from O(M*D) to O(M) for subsequent instances (M = methods, D = depth).
* @param classProto The current class prototype to look up base functions for
* @ignore
*/
function _getBaseProtoFuncs(classProto) {
if (objHasOwnProperty(classProto, DynBaseProtoFuncs)) {
return classProto[DynBaseProtoFuncs];
}
var baseFuncSources = objCreate(null);
var baseProto = _getObjProto(classProto);
var visited = [];
// Walk the entire prototype chain once and record which proto owns each function
while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
_forEachProp(baseProto, function (name) {
if (!baseFuncSources[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
baseFuncSources[name] = baseProto;
}
});
visited.push(baseProto);
baseProto = _getObjProto(baseProto);
}
classProto[DynBaseProtoFuncs] = baseFuncSources;
return baseFuncSources;
}
/**
* 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 = objCreate(null);
_forEachProp(instFuncs, function (name) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
});
// Use cached prototype chain function sources to avoid O(M*D) walk per instance
var baseFuncSources = _getBaseProtoFuncs(classProto);
for (var name_2 in baseFuncSources) {
if (!baseFuncs[name_2]) {
// Create an instance callback for passing the base function to the caller
baseFuncs[name_2] = _instFuncProxy(thisTarget, baseFuncSources[name_2], name_2);
}
}
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 && objHasOwnProperty(proto, DynClassName)) {
var instFuncTable = target[DynInstFuncTable] || objCreate(null);
instFunc = (instFuncTable[proto[DynClassName]] || objCreate(null))[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 = !objHasOwnProperty(target, funcName);
// Only perform the prototype chain walk if canAddInst is still viable
if (canAddInst) {
// 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 (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) {
// Pre-compute a cache key for storing the resolved instance function directly in the
// instFuncTable (which is per-instance and NOT frozen even when the instance is).
// This avoids repeated _getInstFunc lookups when the shortcut optimization cannot be applied.
var cacheKey = DynResolvedCachePrefix + className + "." + funcName;
var dynProtoProxy = function () {
// Fast path: check the per-instance resolved cache to avoid _getInstFunc overhead on repeated calls
var instFuncTable = this[DynInstFuncTable];
var instFunc = instFuncTable ? instFuncTable[cacheKey] : undefined;
if (!instFunc) {
// Use the instance or prototype function
instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
// Cache the resolved function for subsequent calls from this instance.
// instFuncTable is created with objCreate(null) during construction and is not frozen
// even when the instance itself is frozen (Object.freeze is shallow).
if (instFuncTable) {
instFuncTable[cacheKey] = instFunc;
}
}
// 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_1 = target[DynInstFuncTable] = target[DynInstFuncTable] || objCreate(null);
if (!_isObjectOrArrayPrototype(instFuncTable_1)) {
var instFuncs_1 = instFuncTable_1[className] = (instFuncTable_1[className] || objCreate(null)); // 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_1[DynAllowInstChkTag] !== false) {
instFuncTable_1[DynAllowInstChkTag] = !!setInstanceFunc;
}
if (!_isObjectOrArrayPrototype(instFuncs_1)) {
_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];
// Invalidate any cached resolved function for this entry so stale
// values are not returned after re-registration via dynamicProto
delete instFuncTable_1[DynResolvedCachePrefix + className + "." + name];
// Add a dynamic proto if one doesn't exist or if a prototype function exists and it's not a dynamic one
if (!objHasOwnProperty(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 (objHasOwnProperty(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
*/
export default function dynamicProto(theClass, target, delegateFunc, options) {
// Make sure that the passed theClass argument looks correct
if (!objHasOwnProperty(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 (objHasOwnProperty(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;
//# sourceMappingURL=DynamicProto.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,73 @@
{
"name": "@microsoft/dynamicproto-js",
"author": "Microsoft Application Insights Team",
"version": "2.0.5",
"description": "Microsoft Dynamic Proto Utility",
"keywords": [
"javascript",
"dynamic prototype",
"microsoft",
"typescript",
"inheritence",
"minification",
"application insights",
"rollup"
],
"main": "./dist/es5/node/dynamicproto-js.js",
"module": "./dist-es5/DynamicProto.js",
"types": "./types/DynamicProto.d.ts",
"directories": {
"doc": "./docs"
},
"scripts": {
"clean": "grunt clean",
"build": "npm run build:esm && npm run build:bundle && npm run lint",
"build:esm": "grunt dynamicproto",
"build:bundle": "rollup -c rollup.config.js --bundleConfigAsCjs",
"rebuild": "npm run build",
"test": "grunt dynamicprototest",
"lint": "grunt lint"
},
"repository": {
"type": "git",
"url": "git+https://github.com/microsoft/DynamicProto-JS.git"
},
"bugs": {
"url": "https://github.com/microsoft/DynamicProto-JS/issues"
},
"homepage": "https://github.com/microsoft/DynamicProto-JS#readme",
"license": "MIT",
"sideEffects": false,
"dependencies": {
"@nevware21/ts-utils": ">= 0.14.0 < 2.x"
},
"devDependencies": {
"@microsoft/applicationinsights-rollup-es3" : "^1.0.1",
"@microsoft/dynamicproto-rollup": "1.0.0",
"grunt": "^1.6.1",
"grunt-cli": "^1.5.0",
"grunt-contrib-qunit": "^4.0.0",
"grunt-contrib-uglify": "^5.2.1",
"grunt-run": "^0.8.1",
"@nevware21/grunt-ts-plugin": "^0.5.2",
"@nevware21/grunt-eslint-ts": "^0.5.2",
"@typescript-eslint/eslint-plugin": "^5.46.1",
"@typescript-eslint/parser": "^5.46.1",
"@types/node": "18.19.121",
"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",
"typescript": "^4.9.5",
"typedoc": "^0.26.6",
"rollup-plugin-copy": "^3.4.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-minify-es": "^1.1.1",
"rollup": "^3.20.0",
"uglify-js": "^3.13.7"
}
}
@@ -0,0 +1,173 @@
import MagicString from 'magic-string';
;
function escape(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
function isSourceMapEnabled(options) {
if (options) {
return options.sourceMap !== false && options.sourcemap !== false;
}
return false;
}
// Need to mock this rather than rely on JavaScript String.prototype.padEnd() as it doesn't always
// exists in the build / test infrastructure
function padEnd(input, len, fill) {
var value = input || "";
while (value.length < len) {
value += fill;
}
if (value.length > len) {
value = value.substring(0, len);
}
return value;
}
function isNullOrWhitespace(value) {
if (value) {
return value.replace(/\s/g, "").length < 1;
}
return true;
}
/**
* Simple Rush plugin to remove code that is wrapped between specific comments, this is used to
* remove the boilerplate code require by typescript to define methods as prototype level while
* using @ms-dynamicProto project to support minification. This can also be used to remove "debug"
* functions from the production code.
*/
export default function dynamicRemove(options) {
if (options === void 0) { options = {}; }
var token = (options || {}).tagname || "@DynamicProtoStub";
var replaceValue = (options || {}).comment || "// Removed Stub for %function%.";
var tokenGroups = [4, 10, 13];
var funcNameGroup = 6;
// Because of the test infrastructure (PhamtonJS) the RegEx can't use the "s" flag (gis vs gi) or named groups
var pattern = new RegExp("([\\t ]*\\/\\*\\*((?!\\*\\/)(.|\\r|\\n))*\\*\\/[\\s]*)*(\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*(\\r\\n|\\n\\r|\\r|\\n))*[\\t ]*([\\w]*\\.prototype(\\.|\\[\\\"|\\[\\')[\\w]*(\\\"\\]|\\'\\])?)[\\t ]*=[\\t ]*function[\\t ]*\\([^\\{]*\\{[^\\/\\}\\{]*(\\{[^\\}]*\\}[^\\/\\}\\{]*)*(\\/[\\*\\/][\\t ]*" + escape(token) + "[^\\*\\r\\n]*(\\*\\/)?(\\r\\n|\\n\\r|\\r|\\n))*[^\\}]*\\};([\\t ]*\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*)*", 'gi');
function formatError(token, code, pos, id) {
var lines = code.split(/(?:\r\n|\n\r|\r|\n)/);
var lineNumber = 0;
var count = pos;
while (count > 0) {
lineNumber++;
count = code.lastIndexOf("\n", count - 1);
}
var column = 0;
var lineStart = code.lastIndexOf("\n", pos);
if (lineStart != -1) {
column = (pos - lineStart);
}
else {
column = pos + 1;
}
var message = "Invalid (Unremoved) token [" + token + "] found on line [" + lineNumber + "], column [" + column + "], position [" + pos + "] - " + (id || "") + "\n";
var marker = padEnd("", token.length, "^");
var line = lineNumber - 6;
if (line > 0) {
message += " ...\n";
}
count = 0;
while (count < 10 && line < lines.length - 1) {
count++;
if (line >= 0) {
var number = padEnd("" + (line + 1), 4, " ");
message += number + ":" + lines[line] + "\n";
if (line == lineNumber - 1) {
message += padEnd("", column + 4, " ") + marker + "\n";
}
}
line++;
}
if (line < lines.length - 1) {
message += " ...\n";
}
var match;
var matchCount = 0;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
if (matchCount == 0) {
message += "\nMatch checks\n";
}
matchCount++;
if (match[0].length > 0) {
message += "Match " + matchCount + " tag Groups for " + (funcName || "") + "\n";
message += "--=( Complete Matched Content )=--\n";
message += match[0];
message += "\n--------------------------------\n";
for (var lp = 1; lp < match.length; lp++) {
if (match[lp]) {
message += "" + lp + ": " + (match[lp] || "").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
if ((match[lp] || "").indexOf(token) != -1) {
message += " <- Contains tag";
}
message += "\n";
}
}
message += "\n";
}
}
}
return message;
}
function replaceToken(code, theString) {
var result = false;
var match;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
// Only remove matches that contain a tag and function
var hasToken = false;
for (var lp = 0; lp < tokenGroups.length; lp++) {
if ((match[tokenGroups[lp]] || "").indexOf(token) != -1) {
hasToken = true;
break;
}
}
if (hasToken) {
result = true;
var start = match.index;
var newValue = replaceValue.replace("%function%", funcName);
theString.overwrite(start, start + match[0].length, newValue);
}
}
}
return result;
}
function checkResult(result, id) {
if (result) {
var pos = result.indexOf(token);
if (pos != -1) {
throw new Error(formatError(token, result, pos, id));
}
}
}
function doTransform(code, id) {
var theString = new MagicString(code);
if (!replaceToken(code, theString)) {
return null;
}
var result = { code: theString.toString() };
if (isSourceMapEnabled(options)) {
result.map = theString.generateMap({ hires: true });
}
return result;
}
function doTransformAndCheck(code, id) {
var result = doTransform(code, id);
if (result) {
// Do a final check of the string
checkResult(result.code, id);
}
else {
// Check that the raw input doesn't include the tag
checkResult(code, id);
}
return result;
}
return {
name: 'dynamicRemove',
renderChunk: function (code, chunk) {
return doTransformAndCheck(code, chunk.filename);
},
transform: doTransformAndCheck
};
}
//# sourceMappingURL=removeDynamic.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,988 @@
/*!
* Microsoft Dynamic Proto Rollup Utility, 1.0.0
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function encode(decoded) {
var sourceFileIndex = 0;
var sourceCodeLine = 0;
var sourceCodeColumn = 0;
var nameIndex = 0;
var mappings = '';
for (var i = 0; i < decoded.length; i++) {
var line = decoded[i];
if (i > 0)
mappings += ';';
if (line.length === 0)
continue;
var generatedCodeColumn = 0;
var lineMappings = [];
for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
var segment = line_1[_i];
var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
generatedCodeColumn = segment[0];
if (segment.length > 1) {
segmentMappings +=
encodeInteger(segment[1] - sourceFileIndex) +
encodeInteger(segment[2] - sourceCodeLine) +
encodeInteger(segment[3] - sourceCodeColumn);
sourceFileIndex = segment[1];
sourceCodeLine = segment[2];
sourceCodeColumn = segment[3];
}
if (segment.length === 5) {
segmentMappings += encodeInteger(segment[4] - nameIndex);
nameIndex = segment[4];
}
lineMappings.push(segmentMappings);
}
mappings += lineMappings.join(',');
}
return mappings;
}
function encodeInteger(num) {
var result = '';
num = num < 0 ? (-num << 1) | 1 : num << 1;
do {
var clamped = num & 31;
num >>>= 5;
if (num > 0) {
clamped |= 32;
}
result += chars[clamped];
} while (num > 0);
return result;
}
var BitSet = function BitSet(arg) {
this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
};
BitSet.prototype.add = function add (n) {
this.bits[n >> 5] |= 1 << (n & 31);
};
BitSet.prototype.has = function has (n) {
return !!(this.bits[n >> 5] & (1 << (n & 31)));
};
var Chunk = function Chunk(start, end, content) {
this.start = start;
this.end = end;
this.original = content;
this.intro = '';
this.outro = '';
this.content = content;
this.storeName = false;
this.edited = false;
Object.defineProperties(this, {
previous: { writable: true, value: null },
next: { writable: true, value: null },
});
};
Chunk.prototype.appendLeft = function appendLeft (content) {
this.outro += content;
};
Chunk.prototype.appendRight = function appendRight (content) {
this.intro = this.intro + content;
};
Chunk.prototype.clone = function clone () {
var chunk = new Chunk(this.start, this.end, this.original);
chunk.intro = this.intro;
chunk.outro = this.outro;
chunk.content = this.content;
chunk.storeName = this.storeName;
chunk.edited = this.edited;
return chunk;
};
Chunk.prototype.contains = function contains (index) {
return this.start < index && index < this.end;
};
Chunk.prototype.eachNext = function eachNext (fn) {
var chunk = this;
while (chunk) {
fn(chunk);
chunk = chunk.next;
}
};
Chunk.prototype.eachPrevious = function eachPrevious (fn) {
var chunk = this;
while (chunk) {
fn(chunk);
chunk = chunk.previous;
}
};
Chunk.prototype.edit = function edit (content, storeName, contentOnly) {
this.content = content;
if (!contentOnly) {
this.intro = '';
this.outro = '';
}
this.storeName = storeName;
this.edited = true;
return this;
};
Chunk.prototype.prependLeft = function prependLeft (content) {
this.outro = content + this.outro;
};
Chunk.prototype.prependRight = function prependRight (content) {
this.intro = content + this.intro;
};
Chunk.prototype.split = function split (index) {
var sliceIndex = index - this.start;
var originalBefore = this.original.slice(0, sliceIndex);
var originalAfter = this.original.slice(sliceIndex);
this.original = originalBefore;
var newChunk = new Chunk(index, this.end, originalAfter);
newChunk.outro = this.outro;
this.outro = '';
this.end = index;
if (this.edited) {
newChunk.edit('', false);
this.content = '';
} else {
this.content = originalBefore;
}
newChunk.next = this.next;
if (newChunk.next) { newChunk.next.previous = newChunk; }
newChunk.previous = this;
this.next = newChunk;
return newChunk;
};
Chunk.prototype.toString = function toString () {
return this.intro + this.content + this.outro;
};
Chunk.prototype.trimEnd = function trimEnd (rx) {
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
var trimmed = this.content.replace(rx, '');
if (trimmed.length) {
if (trimmed !== this.content) {
this.split(this.start + trimmed.length).edit('', undefined, true);
}
return true;
} else {
this.edit('', undefined, true);
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
}
};
Chunk.prototype.trimStart = function trimStart (rx) {
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
var trimmed = this.content.replace(rx, '');
if (trimmed.length) {
if (trimmed !== this.content) {
this.split(this.end - trimmed.length);
this.edit('', undefined, true);
}
return true;
} else {
this.edit('', undefined, true);
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
}
};
var btoa = function () {
throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
};
if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
btoa = function (str) { return window.btoa(unescape(encodeURIComponent(str))); };
} else if (typeof Buffer === 'function') {
btoa = function (str) { return Buffer.from(str, 'utf-8').toString('base64'); };
}
var SourceMap = function SourceMap(properties) {
this.version = 3;
this.file = properties.file;
this.sources = properties.sources;
this.sourcesContent = properties.sourcesContent;
this.names = properties.names;
this.mappings = encode(properties.mappings);
};
SourceMap.prototype.toString = function toString () {
return JSON.stringify(this);
};
SourceMap.prototype.toUrl = function toUrl () {
return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
};
function guessIndent(code) {
var lines = code.split('\n');
var tabbed = lines.filter(function (line) { return /^\t+/.test(line); });
var spaced = lines.filter(function (line) { return /^ {2,}/.test(line); });
if (tabbed.length === 0 && spaced.length === 0) {
return null;
}
if (tabbed.length >= spaced.length) {
return '\t';
}
var min = spaced.reduce(function (previous, current) {
var numSpaces = /^ +/.exec(current)[0].length;
return Math.min(numSpaces, previous);
}, Infinity);
return new Array(min + 1).join(' ');
}
function getRelativePath(from, to) {
var fromParts = from.split(/[/\\]/);
var toParts = to.split(/[/\\]/);
fromParts.pop();
while (fromParts[0] === toParts[0]) {
fromParts.shift();
toParts.shift();
}
if (fromParts.length) {
var i = fromParts.length;
while (i--) { fromParts[i] = '..'; }
}
return fromParts.concat(toParts).join('/');
}
var toString = Object.prototype.toString;
function isObject(thing) {
return toString.call(thing) === '[object Object]';
}
function getLocator(source) {
var originalLines = source.split('\n');
var lineOffsets = [];
for (var i = 0, pos = 0; i < originalLines.length; i++) {
lineOffsets.push(pos);
pos += originalLines[i].length + 1;
}
return function locate(index) {
var i = 0;
var j = lineOffsets.length;
while (i < j) {
var m = (i + j) >> 1;
if (index < lineOffsets[m]) {
j = m;
} else {
i = m + 1;
}
}
var line = i - 1;
var column = index - lineOffsets[line];
return { line: line, column: column };
};
}
var Mappings = function Mappings(hires) {
this.hires = hires;
this.generatedCodeLine = 0;
this.generatedCodeColumn = 0;
this.raw = [];
this.rawSegments = this.raw[this.generatedCodeLine] = [];
this.pending = null;
};
Mappings.prototype.addEdit = function addEdit (sourceIndex, content, loc, nameIndex) {
if (content.length) {
var segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
if (nameIndex >= 0) {
segment.push(nameIndex);
}
this.rawSegments.push(segment);
} else if (this.pending) {
this.rawSegments.push(this.pending);
}
this.advance(content);
this.pending = null;
};
Mappings.prototype.addUneditedChunk = function addUneditedChunk (sourceIndex, chunk, original, loc, sourcemapLocations) {
var originalCharIndex = chunk.start;
var first = true;
while (originalCharIndex < chunk.end) {
if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
this.rawSegments.push([this.generatedCodeColumn, sourceIndex, loc.line, loc.column]);
}
if (original[originalCharIndex] === '\n') {
loc.line += 1;
loc.column = 0;
this.generatedCodeLine += 1;
this.raw[this.generatedCodeLine] = this.rawSegments = [];
this.generatedCodeColumn = 0;
first = true;
} else {
loc.column += 1;
this.generatedCodeColumn += 1;
first = false;
}
originalCharIndex += 1;
}
this.pending = null;
};
Mappings.prototype.advance = function advance (str) {
if (!str) { return; }
var lines = str.split('\n');
if (lines.length > 1) {
for (var i = 0; i < lines.length - 1; i++) {
this.generatedCodeLine++;
this.raw[this.generatedCodeLine] = this.rawSegments = [];
}
this.generatedCodeColumn = 0;
}
this.generatedCodeColumn += lines[lines.length - 1].length;
};
var n = '\n';
var warned = {
insertLeft: false,
insertRight: false,
storeName: false,
};
var MagicString = function MagicString(string, options) {
if ( options === void 0 ) options = {};
var chunk = new Chunk(0, string.length, string);
Object.defineProperties(this, {
original: { writable: true, value: string },
outro: { writable: true, value: '' },
intro: { writable: true, value: '' },
firstChunk: { writable: true, value: chunk },
lastChunk: { writable: true, value: chunk },
lastSearchedChunk: { writable: true, value: chunk },
byStart: { writable: true, value: {} },
byEnd: { writable: true, value: {} },
filename: { writable: true, value: options.filename },
indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
sourcemapLocations: { writable: true, value: new BitSet() },
storedNames: { writable: true, value: {} },
indentStr: { writable: true, value: guessIndent(string) },
});
this.byStart[0] = chunk;
this.byEnd[string.length] = chunk;
};
MagicString.prototype.addSourcemapLocation = function addSourcemapLocation (char) {
this.sourcemapLocations.add(char);
};
MagicString.prototype.append = function append (content) {
if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
this.outro += content;
return this;
};
MagicString.prototype.appendLeft = function appendLeft (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byEnd[index];
if (chunk) {
chunk.appendLeft(content);
} else {
this.intro += content;
}
return this;
};
MagicString.prototype.appendRight = function appendRight (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byStart[index];
if (chunk) {
chunk.appendRight(content);
} else {
this.outro += content;
}
return this;
};
MagicString.prototype.clone = function clone () {
var cloned = new MagicString(this.original, { filename: this.filename });
var originalChunk = this.firstChunk;
var clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());
while (originalChunk) {
cloned.byStart[clonedChunk.start] = clonedChunk;
cloned.byEnd[clonedChunk.end] = clonedChunk;
var nextOriginalChunk = originalChunk.next;
var nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
if (nextClonedChunk) {
clonedChunk.next = nextClonedChunk;
nextClonedChunk.previous = clonedChunk;
clonedChunk = nextClonedChunk;
}
originalChunk = nextOriginalChunk;
}
cloned.lastChunk = clonedChunk;
if (this.indentExclusionRanges) {
cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
}
cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
cloned.intro = this.intro;
cloned.outro = this.outro;
return cloned;
};
MagicString.prototype.generateDecodedMap = function generateDecodedMap (options) {
var this$1$1 = this;
options = options || {};
var sourceIndex = 0;
var names = Object.keys(this.storedNames);
var mappings = new Mappings(options.hires);
var locate = getLocator(this.original);
if (this.intro) {
mappings.advance(this.intro);
}
this.firstChunk.eachNext(function (chunk) {
var loc = locate(chunk.start);
if (chunk.intro.length) { mappings.advance(chunk.intro); }
if (chunk.edited) {
mappings.addEdit(
sourceIndex,
chunk.content,
loc,
chunk.storeName ? names.indexOf(chunk.original) : -1
);
} else {
mappings.addUneditedChunk(sourceIndex, chunk, this$1$1.original, loc, this$1$1.sourcemapLocations);
}
if (chunk.outro.length) { mappings.advance(chunk.outro); }
});
return {
file: options.file ? options.file.split(/[/\\]/).pop() : null,
sources: [options.source ? getRelativePath(options.file || '', options.source) : null],
sourcesContent: options.includeContent ? [this.original] : [null],
names: names,
mappings: mappings.raw,
};
};
MagicString.prototype.generateMap = function generateMap (options) {
return new SourceMap(this.generateDecodedMap(options));
};
MagicString.prototype.getIndentString = function getIndentString () {
return this.indentStr === null ? '\t' : this.indentStr;
};
MagicString.prototype.indent = function indent (indentStr, options) {
var pattern = /^[^\r\n]/gm;
if (isObject(indentStr)) {
options = indentStr;
indentStr = undefined;
}
indentStr = indentStr !== undefined ? indentStr : this.indentStr || '\t';
if (indentStr === '') { return this; }
options = options || {};
var isExcluded = {};
if (options.exclude) {
var exclusions =
typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
exclusions.forEach(function (exclusion) {
for (var i = exclusion[0]; i < exclusion[1]; i += 1) {
isExcluded[i] = true;
}
});
}
var shouldIndentNextCharacter = options.indentStart !== false;
var replacer = function (match) {
if (shouldIndentNextCharacter) { return ("" + indentStr + match); }
shouldIndentNextCharacter = true;
return match;
};
this.intro = this.intro.replace(pattern, replacer);
var charIndex = 0;
var chunk = this.firstChunk;
while (chunk) {
var end = chunk.end;
if (chunk.edited) {
if (!isExcluded[charIndex]) {
chunk.content = chunk.content.replace(pattern, replacer);
if (chunk.content.length) {
shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
}
}
} else {
charIndex = chunk.start;
while (charIndex < end) {
if (!isExcluded[charIndex]) {
var char = this.original[charIndex];
if (char === '\n') {
shouldIndentNextCharacter = true;
} else if (char !== '\r' && shouldIndentNextCharacter) {
shouldIndentNextCharacter = false;
if (charIndex === chunk.start) {
chunk.prependRight(indentStr);
} else {
this._splitChunk(chunk, charIndex);
chunk = chunk.next;
chunk.prependRight(indentStr);
}
}
}
charIndex += 1;
}
}
charIndex = chunk.end;
chunk = chunk.next;
}
this.outro = this.outro.replace(pattern, replacer);
return this;
};
MagicString.prototype.insert = function insert () {
throw new Error(
'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)'
);
};
MagicString.prototype.insertLeft = function insertLeft (index, content) {
if (!warned.insertLeft) {
console.warn(
'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'
);
warned.insertLeft = true;
}
return this.appendLeft(index, content);
};
MagicString.prototype.insertRight = function insertRight (index, content) {
if (!warned.insertRight) {
console.warn(
'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'
);
warned.insertRight = true;
}
return this.prependRight(index, content);
};
MagicString.prototype.move = function move (start, end, index) {
if (index >= start && index <= end) { throw new Error('Cannot move a selection inside itself'); }
this._split(start);
this._split(end);
this._split(index);
var first = this.byStart[start];
var last = this.byEnd[end];
var oldLeft = first.previous;
var oldRight = last.next;
var newRight = this.byStart[index];
if (!newRight && last === this.lastChunk) { return this; }
var newLeft = newRight ? newRight.previous : this.lastChunk;
if (oldLeft) { oldLeft.next = oldRight; }
if (oldRight) { oldRight.previous = oldLeft; }
if (newLeft) { newLeft.next = first; }
if (newRight) { newRight.previous = last; }
if (!first.previous) { this.firstChunk = last.next; }
if (!last.next) {
this.lastChunk = first.previous;
this.lastChunk.next = null;
}
first.previous = newLeft;
last.next = newRight || null;
if (!newLeft) { this.firstChunk = first; }
if (!newRight) { this.lastChunk = last; }
return this;
};
MagicString.prototype.overwrite = function overwrite (start, end, content, options) {
if (typeof content !== 'string') { throw new TypeError('replacement content must be a string'); }
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
if (end > this.original.length) { throw new Error('end is out of bounds'); }
if (start === end)
{ throw new Error(
'Cannot overwrite a zero-length range use appendLeft or prependRight instead'
); }
this._split(start);
this._split(end);
if (options === true) {
if (!warned.storeName) {
console.warn(
'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'
);
warned.storeName = true;
}
options = { storeName: true };
}
var storeName = options !== undefined ? options.storeName : false;
var contentOnly = options !== undefined ? options.contentOnly : false;
if (storeName) {
var original = this.original.slice(start, end);
Object.defineProperty(this.storedNames, original, { writable: true, value: true, enumerable: true });
}
var first = this.byStart[start];
var last = this.byEnd[end];
if (first) {
var chunk = first;
while (chunk !== last) {
if (chunk.next !== this.byStart[chunk.end]) {
throw new Error('Cannot overwrite across a split point');
}
chunk = chunk.next;
chunk.edit('', false);
}
first.edit(content, storeName, contentOnly);
} else {
var newChunk = new Chunk(start, end, '').edit(content, storeName);
last.next = newChunk;
newChunk.previous = last;
}
return this;
};
MagicString.prototype.prepend = function prepend (content) {
if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
this.intro = content + this.intro;
return this;
};
MagicString.prototype.prependLeft = function prependLeft (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byEnd[index];
if (chunk) {
chunk.prependLeft(content);
} else {
this.intro = content + this.intro;
}
return this;
};
MagicString.prototype.prependRight = function prependRight (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byStart[index];
if (chunk) {
chunk.prependRight(content);
} else {
this.outro = content + this.outro;
}
return this;
};
MagicString.prototype.remove = function remove (start, end) {
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
if (start === end) { return this; }
if (start < 0 || end > this.original.length) { throw new Error('Character is out of bounds'); }
if (start > end) { throw new Error('end must be greater than start'); }
this._split(start);
this._split(end);
var chunk = this.byStart[start];
while (chunk) {
chunk.intro = '';
chunk.outro = '';
chunk.edit('');
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
}
return this;
};
MagicString.prototype.lastChar = function lastChar () {
if (this.outro.length) { return this.outro[this.outro.length - 1]; }
var chunk = this.lastChunk;
do {
if (chunk.outro.length) { return chunk.outro[chunk.outro.length - 1]; }
if (chunk.content.length) { return chunk.content[chunk.content.length - 1]; }
if (chunk.intro.length) { return chunk.intro[chunk.intro.length - 1]; }
} while ((chunk = chunk.previous));
if (this.intro.length) { return this.intro[this.intro.length - 1]; }
return '';
};
MagicString.prototype.lastLine = function lastLine () {
var lineIndex = this.outro.lastIndexOf(n);
if (lineIndex !== -1) { return this.outro.substr(lineIndex + 1); }
var lineStr = this.outro;
var chunk = this.lastChunk;
do {
if (chunk.outro.length > 0) {
lineIndex = chunk.outro.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.outro.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.outro + lineStr;
}
if (chunk.content.length > 0) {
lineIndex = chunk.content.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.content.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.content + lineStr;
}
if (chunk.intro.length > 0) {
lineIndex = chunk.intro.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.intro.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.intro + lineStr;
}
} while ((chunk = chunk.previous));
lineIndex = this.intro.lastIndexOf(n);
if (lineIndex !== -1) { return this.intro.substr(lineIndex + 1) + lineStr; }
return this.intro + lineStr;
};
MagicString.prototype.slice = function slice (start, end) {
if ( start === void 0 ) start = 0;
if ( end === void 0 ) end = this.original.length;
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
var result = '';
var chunk = this.firstChunk;
while (chunk && (chunk.start > start || chunk.end <= start)) {
if (chunk.start < end && chunk.end >= end) {
return result;
}
chunk = chunk.next;
}
if (chunk && chunk.edited && chunk.start !== start)
{ throw new Error(("Cannot use replaced character " + start + " as slice start anchor.")); }
var startChunk = chunk;
while (chunk) {
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
result += chunk.intro;
}
var containsEnd = chunk.start < end && chunk.end >= end;
if (containsEnd && chunk.edited && chunk.end !== end)
{ throw new Error(("Cannot use replaced character " + end + " as slice end anchor.")); }
var sliceStart = startChunk === chunk ? start - chunk.start : 0;
var sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
result += chunk.content.slice(sliceStart, sliceEnd);
if (chunk.outro && (!containsEnd || chunk.end === end)) {
result += chunk.outro;
}
if (containsEnd) {
break;
}
chunk = chunk.next;
}
return result;
};
MagicString.prototype.snip = function snip (start, end) {
var clone = this.clone();
clone.remove(0, start);
clone.remove(end, clone.original.length);
return clone;
};
MagicString.prototype._split = function _split (index) {
if (this.byStart[index] || this.byEnd[index]) { return; }
var chunk = this.lastSearchedChunk;
var searchForward = index > chunk.end;
while (chunk) {
if (chunk.contains(index)) { return this._splitChunk(chunk, index); }
chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
}
};
MagicString.prototype._splitChunk = function _splitChunk (chunk, index) {
if (chunk.edited && chunk.content.length) {
var loc = getLocator(this.original)(index);
throw new Error(
("Cannot split a chunk that has already been edited (" + (loc.line) + ":" + (loc.column) + " \"" + (chunk.original) + "\")")
);
}
var newChunk = chunk.split(index);
this.byEnd[index] = chunk;
this.byStart[index] = newChunk;
this.byEnd[newChunk.end] = newChunk;
if (chunk === this.lastChunk) { this.lastChunk = newChunk; }
this.lastSearchedChunk = chunk;
return true;
};
MagicString.prototype.toString = function toString () {
var str = this.intro;
var chunk = this.firstChunk;
while (chunk) {
str += chunk.toString();
chunk = chunk.next;
}
return str + this.outro;
};
MagicString.prototype.isEmpty = function isEmpty () {
var chunk = this.firstChunk;
do {
if (
(chunk.intro.length && chunk.intro.trim()) ||
(chunk.content.length && chunk.content.trim()) ||
(chunk.outro.length && chunk.outro.trim())
)
{ return false; }
} while ((chunk = chunk.next));
return true;
};
MagicString.prototype.length = function length () {
var chunk = this.firstChunk;
var length = 0;
do {
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
} while ((chunk = chunk.next));
return length;
};
MagicString.prototype.trimLines = function trimLines () {
return this.trim('[\\r\\n]');
};
MagicString.prototype.trim = function trim (charType) {
return this.trimStart(charType).trimEnd(charType);
};
MagicString.prototype.trimEndAborted = function trimEndAborted (charType) {
var rx = new RegExp((charType || '\\s') + '+$');
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
var chunk = this.lastChunk;
do {
var end = chunk.end;
var aborted = chunk.trimEnd(rx);
if (chunk.end !== end) {
if (this.lastChunk === chunk) {
this.lastChunk = chunk.next;
}
this.byEnd[chunk.end] = chunk;
this.byStart[chunk.next.start] = chunk.next;
this.byEnd[chunk.next.end] = chunk.next;
}
if (aborted) { return true; }
chunk = chunk.previous;
} while (chunk);
return false;
};
MagicString.prototype.trimEnd = function trimEnd (charType) {
this.trimEndAborted(charType);
return this;
};
MagicString.prototype.trimStartAborted = function trimStartAborted (charType) {
var rx = new RegExp('^' + (charType || '\\s') + '+');
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
var chunk = this.firstChunk;
do {
var end = chunk.end;
var aborted = chunk.trimStart(rx);
if (chunk.end !== end) {
if (chunk === this.lastChunk) { this.lastChunk = chunk.next; }
this.byEnd[chunk.end] = chunk;
this.byStart[chunk.next.start] = chunk.next;
this.byEnd[chunk.next.end] = chunk.next;
}
if (aborted) { return true; }
chunk = chunk.next;
} while (chunk);
return false;
};
MagicString.prototype.trimStart = function trimStart (charType) {
this.trimStartAborted(charType);
return this;
};
function escape(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
function isSourceMapEnabled(options) {
if (options) {
return options.sourceMap !== false && options.sourcemap !== false;
}
return false;
}
function padEnd(input, len, fill) {
var value = input || "";
while (value.length < len) {
value += fill;
}
if (value.length > len) {
value = value.substring(0, len);
}
return value;
}
function isNullOrWhitespace(value) {
if (value) {
return value.replace(/\s/g, "").length < 1;
}
return true;
}
function dynamicRemove(options) {
if (options === void 0) { options = {}; }
var token = (options || {}).tagname || "@DynamicProtoStub";
var replaceValue = (options || {}).comment || "// Removed Stub for %function%.";
var tokenGroups = [4, 10, 13];
var funcNameGroup = 6;
var pattern = new RegExp("([\\t ]*\\/\\*\\*((?!\\*\\/)(.|\\r|\\n))*\\*\\/[\\s]*)*(\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*(\\r\\n|\\n\\r|\\r|\\n))*[\\t ]*([\\w]*\\.prototype(\\.|\\[\\\"|\\[\\')[\\w]*(\\\"\\]|\\'\\])?)[\\t ]*=[\\t ]*function[\\t ]*\\([^\\{]*\\{[^\\/\\}\\{]*(\\{[^\\}]*\\}[^\\/\\}\\{]*)*(\\/[\\*\\/][\\t ]*" + escape(token) + "[^\\*\\r\\n]*(\\*\\/)?(\\r\\n|\\n\\r|\\r|\\n))*[^\\}]*\\};([\\t ]*\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*)*", 'gi');
function formatError(token, code, pos, id) {
var lines = code.split(/(?:\r\n|\n\r|\r|\n)/);
var lineNumber = 0;
var count = pos;
while (count > 0) {
lineNumber++;
count = code.lastIndexOf("\n", count - 1);
}
var column = 0;
var lineStart = code.lastIndexOf("\n", pos);
if (lineStart != -1) {
column = (pos - lineStart);
}
else {
column = pos + 1;
}
var message = "Invalid (Unremoved) token [" + token + "] found on line [" + lineNumber + "], column [" + column + "], position [" + pos + "] - " + (id || "") + "\n";
var marker = padEnd("", token.length, "^");
var line = lineNumber - 6;
if (line > 0) {
message += " ...\n";
}
count = 0;
while (count < 10 && line < lines.length - 1) {
count++;
if (line >= 0) {
var number = padEnd("" + (line + 1), 4, " ");
message += number + ":" + lines[line] + "\n";
if (line == lineNumber - 1) {
message += padEnd("", column + 4, " ") + marker + "\n";
}
}
line++;
}
if (line < lines.length - 1) {
message += " ...\n";
}
var match;
var matchCount = 0;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
if (matchCount == 0) {
message += "\nMatch checks\n";
}
matchCount++;
if (match[0].length > 0) {
message += "Match " + matchCount + " tag Groups for " + (funcName || "") + "\n";
message += "--=( Complete Matched Content )=--\n";
message += match[0];
message += "\n--------------------------------\n";
for (var lp = 1; lp < match.length; lp++) {
if (match[lp]) {
message += "" + lp + ": " + (match[lp] || "").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
if ((match[lp] || "").indexOf(token) != -1) {
message += " <- Contains tag";
}
message += "\n";
}
}
message += "\n";
}
}
}
return message;
}
function replaceToken(code, theString) {
var result = false;
var match;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
var hasToken = false;
for (var lp = 0; lp < tokenGroups.length; lp++) {
if ((match[tokenGroups[lp]] || "").indexOf(token) != -1) {
hasToken = true;
break;
}
}
if (hasToken) {
result = true;
var start = match.index;
var newValue = replaceValue.replace("%function%", funcName);
theString.overwrite(start, start + match[0].length, newValue);
}
}
}
return result;
}
function checkResult(result, id) {
if (result) {
var pos = result.indexOf(token);
if (pos != -1) {
throw new Error(formatError(token, result, pos, id));
}
}
}
function doTransform(code, id) {
var theString = new MagicString(code);
if (!replaceToken(code, theString)) {
return null;
}
var result = { code: theString.toString() };
if (isSourceMapEnabled(options)) {
result.map = theString.generateMap({ hires: true });
}
return result;
}
function doTransformAndCheck(code, id) {
var result = doTransform(code);
if (result) {
checkResult(result.code, id);
}
else {
checkResult(code, id);
}
return result;
}
return {
name: 'dynamicRemove',
renderChunk: function (code, chunk) {
return doTransformAndCheck(code, chunk.filename);
},
transform: doTransformAndCheck
};
}
export { dynamicRemove as default };
@@ -0,0 +1,996 @@
/*!
* Microsoft Dynamic Proto Rollup Utility, 1.0.0
* 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-Rollup"] = factory()));
})(this, (function () { 'use strict';
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function encode(decoded) {
var sourceFileIndex = 0;
var sourceCodeLine = 0;
var sourceCodeColumn = 0;
var nameIndex = 0;
var mappings = '';
for (var i = 0; i < decoded.length; i++) {
var line = decoded[i];
if (i > 0)
mappings += ';';
if (line.length === 0)
continue;
var generatedCodeColumn = 0;
var lineMappings = [];
for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
var segment = line_1[_i];
var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
generatedCodeColumn = segment[0];
if (segment.length > 1) {
segmentMappings +=
encodeInteger(segment[1] - sourceFileIndex) +
encodeInteger(segment[2] - sourceCodeLine) +
encodeInteger(segment[3] - sourceCodeColumn);
sourceFileIndex = segment[1];
sourceCodeLine = segment[2];
sourceCodeColumn = segment[3];
}
if (segment.length === 5) {
segmentMappings += encodeInteger(segment[4] - nameIndex);
nameIndex = segment[4];
}
lineMappings.push(segmentMappings);
}
mappings += lineMappings.join(',');
}
return mappings;
}
function encodeInteger(num) {
var result = '';
num = num < 0 ? (-num << 1) | 1 : num << 1;
do {
var clamped = num & 31;
num >>>= 5;
if (num > 0) {
clamped |= 32;
}
result += chars[clamped];
} while (num > 0);
return result;
}
var BitSet = function BitSet(arg) {
this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
};
BitSet.prototype.add = function add (n) {
this.bits[n >> 5] |= 1 << (n & 31);
};
BitSet.prototype.has = function has (n) {
return !!(this.bits[n >> 5] & (1 << (n & 31)));
};
var Chunk = function Chunk(start, end, content) {
this.start = start;
this.end = end;
this.original = content;
this.intro = '';
this.outro = '';
this.content = content;
this.storeName = false;
this.edited = false;
Object.defineProperties(this, {
previous: { writable: true, value: null },
next: { writable: true, value: null },
});
};
Chunk.prototype.appendLeft = function appendLeft (content) {
this.outro += content;
};
Chunk.prototype.appendRight = function appendRight (content) {
this.intro = this.intro + content;
};
Chunk.prototype.clone = function clone () {
var chunk = new Chunk(this.start, this.end, this.original);
chunk.intro = this.intro;
chunk.outro = this.outro;
chunk.content = this.content;
chunk.storeName = this.storeName;
chunk.edited = this.edited;
return chunk;
};
Chunk.prototype.contains = function contains (index) {
return this.start < index && index < this.end;
};
Chunk.prototype.eachNext = function eachNext (fn) {
var chunk = this;
while (chunk) {
fn(chunk);
chunk = chunk.next;
}
};
Chunk.prototype.eachPrevious = function eachPrevious (fn) {
var chunk = this;
while (chunk) {
fn(chunk);
chunk = chunk.previous;
}
};
Chunk.prototype.edit = function edit (content, storeName, contentOnly) {
this.content = content;
if (!contentOnly) {
this.intro = '';
this.outro = '';
}
this.storeName = storeName;
this.edited = true;
return this;
};
Chunk.prototype.prependLeft = function prependLeft (content) {
this.outro = content + this.outro;
};
Chunk.prototype.prependRight = function prependRight (content) {
this.intro = content + this.intro;
};
Chunk.prototype.split = function split (index) {
var sliceIndex = index - this.start;
var originalBefore = this.original.slice(0, sliceIndex);
var originalAfter = this.original.slice(sliceIndex);
this.original = originalBefore;
var newChunk = new Chunk(index, this.end, originalAfter);
newChunk.outro = this.outro;
this.outro = '';
this.end = index;
if (this.edited) {
newChunk.edit('', false);
this.content = '';
} else {
this.content = originalBefore;
}
newChunk.next = this.next;
if (newChunk.next) { newChunk.next.previous = newChunk; }
newChunk.previous = this;
this.next = newChunk;
return newChunk;
};
Chunk.prototype.toString = function toString () {
return this.intro + this.content + this.outro;
};
Chunk.prototype.trimEnd = function trimEnd (rx) {
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
var trimmed = this.content.replace(rx, '');
if (trimmed.length) {
if (trimmed !== this.content) {
this.split(this.start + trimmed.length).edit('', undefined, true);
}
return true;
} else {
this.edit('', undefined, true);
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
}
};
Chunk.prototype.trimStart = function trimStart (rx) {
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
var trimmed = this.content.replace(rx, '');
if (trimmed.length) {
if (trimmed !== this.content) {
this.split(this.end - trimmed.length);
this.edit('', undefined, true);
}
return true;
} else {
this.edit('', undefined, true);
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
}
};
var btoa = function () {
throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
};
if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
btoa = function (str) { return window.btoa(unescape(encodeURIComponent(str))); };
} else if (typeof Buffer === 'function') {
btoa = function (str) { return Buffer.from(str, 'utf-8').toString('base64'); };
}
var SourceMap = function SourceMap(properties) {
this.version = 3;
this.file = properties.file;
this.sources = properties.sources;
this.sourcesContent = properties.sourcesContent;
this.names = properties.names;
this.mappings = encode(properties.mappings);
};
SourceMap.prototype.toString = function toString () {
return JSON.stringify(this);
};
SourceMap.prototype.toUrl = function toUrl () {
return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
};
function guessIndent(code) {
var lines = code.split('\n');
var tabbed = lines.filter(function (line) { return /^\t+/.test(line); });
var spaced = lines.filter(function (line) { return /^ {2,}/.test(line); });
if (tabbed.length === 0 && spaced.length === 0) {
return null;
}
if (tabbed.length >= spaced.length) {
return '\t';
}
var min = spaced.reduce(function (previous, current) {
var numSpaces = /^ +/.exec(current)[0].length;
return Math.min(numSpaces, previous);
}, Infinity);
return new Array(min + 1).join(' ');
}
function getRelativePath(from, to) {
var fromParts = from.split(/[/\\]/);
var toParts = to.split(/[/\\]/);
fromParts.pop();
while (fromParts[0] === toParts[0]) {
fromParts.shift();
toParts.shift();
}
if (fromParts.length) {
var i = fromParts.length;
while (i--) { fromParts[i] = '..'; }
}
return fromParts.concat(toParts).join('/');
}
var toString = Object.prototype.toString;
function isObject(thing) {
return toString.call(thing) === '[object Object]';
}
function getLocator(source) {
var originalLines = source.split('\n');
var lineOffsets = [];
for (var i = 0, pos = 0; i < originalLines.length; i++) {
lineOffsets.push(pos);
pos += originalLines[i].length + 1;
}
return function locate(index) {
var i = 0;
var j = lineOffsets.length;
while (i < j) {
var m = (i + j) >> 1;
if (index < lineOffsets[m]) {
j = m;
} else {
i = m + 1;
}
}
var line = i - 1;
var column = index - lineOffsets[line];
return { line: line, column: column };
};
}
var Mappings = function Mappings(hires) {
this.hires = hires;
this.generatedCodeLine = 0;
this.generatedCodeColumn = 0;
this.raw = [];
this.rawSegments = this.raw[this.generatedCodeLine] = [];
this.pending = null;
};
Mappings.prototype.addEdit = function addEdit (sourceIndex, content, loc, nameIndex) {
if (content.length) {
var segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
if (nameIndex >= 0) {
segment.push(nameIndex);
}
this.rawSegments.push(segment);
} else if (this.pending) {
this.rawSegments.push(this.pending);
}
this.advance(content);
this.pending = null;
};
Mappings.prototype.addUneditedChunk = function addUneditedChunk (sourceIndex, chunk, original, loc, sourcemapLocations) {
var originalCharIndex = chunk.start;
var first = true;
while (originalCharIndex < chunk.end) {
if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
this.rawSegments.push([this.generatedCodeColumn, sourceIndex, loc.line, loc.column]);
}
if (original[originalCharIndex] === '\n') {
loc.line += 1;
loc.column = 0;
this.generatedCodeLine += 1;
this.raw[this.generatedCodeLine] = this.rawSegments = [];
this.generatedCodeColumn = 0;
first = true;
} else {
loc.column += 1;
this.generatedCodeColumn += 1;
first = false;
}
originalCharIndex += 1;
}
this.pending = null;
};
Mappings.prototype.advance = function advance (str) {
if (!str) { return; }
var lines = str.split('\n');
if (lines.length > 1) {
for (var i = 0; i < lines.length - 1; i++) {
this.generatedCodeLine++;
this.raw[this.generatedCodeLine] = this.rawSegments = [];
}
this.generatedCodeColumn = 0;
}
this.generatedCodeColumn += lines[lines.length - 1].length;
};
var n = '\n';
var warned = {
insertLeft: false,
insertRight: false,
storeName: false,
};
var MagicString = function MagicString(string, options) {
if ( options === void 0 ) options = {};
var chunk = new Chunk(0, string.length, string);
Object.defineProperties(this, {
original: { writable: true, value: string },
outro: { writable: true, value: '' },
intro: { writable: true, value: '' },
firstChunk: { writable: true, value: chunk },
lastChunk: { writable: true, value: chunk },
lastSearchedChunk: { writable: true, value: chunk },
byStart: { writable: true, value: {} },
byEnd: { writable: true, value: {} },
filename: { writable: true, value: options.filename },
indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
sourcemapLocations: { writable: true, value: new BitSet() },
storedNames: { writable: true, value: {} },
indentStr: { writable: true, value: guessIndent(string) },
});
this.byStart[0] = chunk;
this.byEnd[string.length] = chunk;
};
MagicString.prototype.addSourcemapLocation = function addSourcemapLocation (char) {
this.sourcemapLocations.add(char);
};
MagicString.prototype.append = function append (content) {
if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
this.outro += content;
return this;
};
MagicString.prototype.appendLeft = function appendLeft (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byEnd[index];
if (chunk) {
chunk.appendLeft(content);
} else {
this.intro += content;
}
return this;
};
MagicString.prototype.appendRight = function appendRight (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byStart[index];
if (chunk) {
chunk.appendRight(content);
} else {
this.outro += content;
}
return this;
};
MagicString.prototype.clone = function clone () {
var cloned = new MagicString(this.original, { filename: this.filename });
var originalChunk = this.firstChunk;
var clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());
while (originalChunk) {
cloned.byStart[clonedChunk.start] = clonedChunk;
cloned.byEnd[clonedChunk.end] = clonedChunk;
var nextOriginalChunk = originalChunk.next;
var nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
if (nextClonedChunk) {
clonedChunk.next = nextClonedChunk;
nextClonedChunk.previous = clonedChunk;
clonedChunk = nextClonedChunk;
}
originalChunk = nextOriginalChunk;
}
cloned.lastChunk = clonedChunk;
if (this.indentExclusionRanges) {
cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
}
cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
cloned.intro = this.intro;
cloned.outro = this.outro;
return cloned;
};
MagicString.prototype.generateDecodedMap = function generateDecodedMap (options) {
var this$1$1 = this;
options = options || {};
var sourceIndex = 0;
var names = Object.keys(this.storedNames);
var mappings = new Mappings(options.hires);
var locate = getLocator(this.original);
if (this.intro) {
mappings.advance(this.intro);
}
this.firstChunk.eachNext(function (chunk) {
var loc = locate(chunk.start);
if (chunk.intro.length) { mappings.advance(chunk.intro); }
if (chunk.edited) {
mappings.addEdit(
sourceIndex,
chunk.content,
loc,
chunk.storeName ? names.indexOf(chunk.original) : -1
);
} else {
mappings.addUneditedChunk(sourceIndex, chunk, this$1$1.original, loc, this$1$1.sourcemapLocations);
}
if (chunk.outro.length) { mappings.advance(chunk.outro); }
});
return {
file: options.file ? options.file.split(/[/\\]/).pop() : null,
sources: [options.source ? getRelativePath(options.file || '', options.source) : null],
sourcesContent: options.includeContent ? [this.original] : [null],
names: names,
mappings: mappings.raw,
};
};
MagicString.prototype.generateMap = function generateMap (options) {
return new SourceMap(this.generateDecodedMap(options));
};
MagicString.prototype.getIndentString = function getIndentString () {
return this.indentStr === null ? '\t' : this.indentStr;
};
MagicString.prototype.indent = function indent (indentStr, options) {
var pattern = /^[^\r\n]/gm;
if (isObject(indentStr)) {
options = indentStr;
indentStr = undefined;
}
indentStr = indentStr !== undefined ? indentStr : this.indentStr || '\t';
if (indentStr === '') { return this; }
options = options || {};
var isExcluded = {};
if (options.exclude) {
var exclusions =
typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
exclusions.forEach(function (exclusion) {
for (var i = exclusion[0]; i < exclusion[1]; i += 1) {
isExcluded[i] = true;
}
});
}
var shouldIndentNextCharacter = options.indentStart !== false;
var replacer = function (match) {
if (shouldIndentNextCharacter) { return ("" + indentStr + match); }
shouldIndentNextCharacter = true;
return match;
};
this.intro = this.intro.replace(pattern, replacer);
var charIndex = 0;
var chunk = this.firstChunk;
while (chunk) {
var end = chunk.end;
if (chunk.edited) {
if (!isExcluded[charIndex]) {
chunk.content = chunk.content.replace(pattern, replacer);
if (chunk.content.length) {
shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
}
}
} else {
charIndex = chunk.start;
while (charIndex < end) {
if (!isExcluded[charIndex]) {
var char = this.original[charIndex];
if (char === '\n') {
shouldIndentNextCharacter = true;
} else if (char !== '\r' && shouldIndentNextCharacter) {
shouldIndentNextCharacter = false;
if (charIndex === chunk.start) {
chunk.prependRight(indentStr);
} else {
this._splitChunk(chunk, charIndex);
chunk = chunk.next;
chunk.prependRight(indentStr);
}
}
}
charIndex += 1;
}
}
charIndex = chunk.end;
chunk = chunk.next;
}
this.outro = this.outro.replace(pattern, replacer);
return this;
};
MagicString.prototype.insert = function insert () {
throw new Error(
'magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)'
);
};
MagicString.prototype.insertLeft = function insertLeft (index, content) {
if (!warned.insertLeft) {
console.warn(
'magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'
);
warned.insertLeft = true;
}
return this.appendLeft(index, content);
};
MagicString.prototype.insertRight = function insertRight (index, content) {
if (!warned.insertRight) {
console.warn(
'magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'
);
warned.insertRight = true;
}
return this.prependRight(index, content);
};
MagicString.prototype.move = function move (start, end, index) {
if (index >= start && index <= end) { throw new Error('Cannot move a selection inside itself'); }
this._split(start);
this._split(end);
this._split(index);
var first = this.byStart[start];
var last = this.byEnd[end];
var oldLeft = first.previous;
var oldRight = last.next;
var newRight = this.byStart[index];
if (!newRight && last === this.lastChunk) { return this; }
var newLeft = newRight ? newRight.previous : this.lastChunk;
if (oldLeft) { oldLeft.next = oldRight; }
if (oldRight) { oldRight.previous = oldLeft; }
if (newLeft) { newLeft.next = first; }
if (newRight) { newRight.previous = last; }
if (!first.previous) { this.firstChunk = last.next; }
if (!last.next) {
this.lastChunk = first.previous;
this.lastChunk.next = null;
}
first.previous = newLeft;
last.next = newRight || null;
if (!newLeft) { this.firstChunk = first; }
if (!newRight) { this.lastChunk = last; }
return this;
};
MagicString.prototype.overwrite = function overwrite (start, end, content, options) {
if (typeof content !== 'string') { throw new TypeError('replacement content must be a string'); }
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
if (end > this.original.length) { throw new Error('end is out of bounds'); }
if (start === end)
{ throw new Error(
'Cannot overwrite a zero-length range use appendLeft or prependRight instead'
); }
this._split(start);
this._split(end);
if (options === true) {
if (!warned.storeName) {
console.warn(
'The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'
);
warned.storeName = true;
}
options = { storeName: true };
}
var storeName = options !== undefined ? options.storeName : false;
var contentOnly = options !== undefined ? options.contentOnly : false;
if (storeName) {
var original = this.original.slice(start, end);
Object.defineProperty(this.storedNames, original, { writable: true, value: true, enumerable: true });
}
var first = this.byStart[start];
var last = this.byEnd[end];
if (first) {
var chunk = first;
while (chunk !== last) {
if (chunk.next !== this.byStart[chunk.end]) {
throw new Error('Cannot overwrite across a split point');
}
chunk = chunk.next;
chunk.edit('', false);
}
first.edit(content, storeName, contentOnly);
} else {
var newChunk = new Chunk(start, end, '').edit(content, storeName);
last.next = newChunk;
newChunk.previous = last;
}
return this;
};
MagicString.prototype.prepend = function prepend (content) {
if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
this.intro = content + this.intro;
return this;
};
MagicString.prototype.prependLeft = function prependLeft (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byEnd[index];
if (chunk) {
chunk.prependLeft(content);
} else {
this.intro = content + this.intro;
}
return this;
};
MagicString.prototype.prependRight = function prependRight (index, content) {
if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
this._split(index);
var chunk = this.byStart[index];
if (chunk) {
chunk.prependRight(content);
} else {
this.outro = content + this.outro;
}
return this;
};
MagicString.prototype.remove = function remove (start, end) {
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
if (start === end) { return this; }
if (start < 0 || end > this.original.length) { throw new Error('Character is out of bounds'); }
if (start > end) { throw new Error('end must be greater than start'); }
this._split(start);
this._split(end);
var chunk = this.byStart[start];
while (chunk) {
chunk.intro = '';
chunk.outro = '';
chunk.edit('');
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
}
return this;
};
MagicString.prototype.lastChar = function lastChar () {
if (this.outro.length) { return this.outro[this.outro.length - 1]; }
var chunk = this.lastChunk;
do {
if (chunk.outro.length) { return chunk.outro[chunk.outro.length - 1]; }
if (chunk.content.length) { return chunk.content[chunk.content.length - 1]; }
if (chunk.intro.length) { return chunk.intro[chunk.intro.length - 1]; }
} while ((chunk = chunk.previous));
if (this.intro.length) { return this.intro[this.intro.length - 1]; }
return '';
};
MagicString.prototype.lastLine = function lastLine () {
var lineIndex = this.outro.lastIndexOf(n);
if (lineIndex !== -1) { return this.outro.substr(lineIndex + 1); }
var lineStr = this.outro;
var chunk = this.lastChunk;
do {
if (chunk.outro.length > 0) {
lineIndex = chunk.outro.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.outro.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.outro + lineStr;
}
if (chunk.content.length > 0) {
lineIndex = chunk.content.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.content.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.content + lineStr;
}
if (chunk.intro.length > 0) {
lineIndex = chunk.intro.lastIndexOf(n);
if (lineIndex !== -1) { return chunk.intro.substr(lineIndex + 1) + lineStr; }
lineStr = chunk.intro + lineStr;
}
} while ((chunk = chunk.previous));
lineIndex = this.intro.lastIndexOf(n);
if (lineIndex !== -1) { return this.intro.substr(lineIndex + 1) + lineStr; }
return this.intro + lineStr;
};
MagicString.prototype.slice = function slice (start, end) {
if ( start === void 0 ) start = 0;
if ( end === void 0 ) end = this.original.length;
while (start < 0) { start += this.original.length; }
while (end < 0) { end += this.original.length; }
var result = '';
var chunk = this.firstChunk;
while (chunk && (chunk.start > start || chunk.end <= start)) {
if (chunk.start < end && chunk.end >= end) {
return result;
}
chunk = chunk.next;
}
if (chunk && chunk.edited && chunk.start !== start)
{ throw new Error(("Cannot use replaced character " + start + " as slice start anchor.")); }
var startChunk = chunk;
while (chunk) {
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
result += chunk.intro;
}
var containsEnd = chunk.start < end && chunk.end >= end;
if (containsEnd && chunk.edited && chunk.end !== end)
{ throw new Error(("Cannot use replaced character " + end + " as slice end anchor.")); }
var sliceStart = startChunk === chunk ? start - chunk.start : 0;
var sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
result += chunk.content.slice(sliceStart, sliceEnd);
if (chunk.outro && (!containsEnd || chunk.end === end)) {
result += chunk.outro;
}
if (containsEnd) {
break;
}
chunk = chunk.next;
}
return result;
};
MagicString.prototype.snip = function snip (start, end) {
var clone = this.clone();
clone.remove(0, start);
clone.remove(end, clone.original.length);
return clone;
};
MagicString.prototype._split = function _split (index) {
if (this.byStart[index] || this.byEnd[index]) { return; }
var chunk = this.lastSearchedChunk;
var searchForward = index > chunk.end;
while (chunk) {
if (chunk.contains(index)) { return this._splitChunk(chunk, index); }
chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
}
};
MagicString.prototype._splitChunk = function _splitChunk (chunk, index) {
if (chunk.edited && chunk.content.length) {
var loc = getLocator(this.original)(index);
throw new Error(
("Cannot split a chunk that has already been edited (" + (loc.line) + ":" + (loc.column) + " \"" + (chunk.original) + "\")")
);
}
var newChunk = chunk.split(index);
this.byEnd[index] = chunk;
this.byStart[index] = newChunk;
this.byEnd[newChunk.end] = newChunk;
if (chunk === this.lastChunk) { this.lastChunk = newChunk; }
this.lastSearchedChunk = chunk;
return true;
};
MagicString.prototype.toString = function toString () {
var str = this.intro;
var chunk = this.firstChunk;
while (chunk) {
str += chunk.toString();
chunk = chunk.next;
}
return str + this.outro;
};
MagicString.prototype.isEmpty = function isEmpty () {
var chunk = this.firstChunk;
do {
if (
(chunk.intro.length && chunk.intro.trim()) ||
(chunk.content.length && chunk.content.trim()) ||
(chunk.outro.length && chunk.outro.trim())
)
{ return false; }
} while ((chunk = chunk.next));
return true;
};
MagicString.prototype.length = function length () {
var chunk = this.firstChunk;
var length = 0;
do {
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
} while ((chunk = chunk.next));
return length;
};
MagicString.prototype.trimLines = function trimLines () {
return this.trim('[\\r\\n]');
};
MagicString.prototype.trim = function trim (charType) {
return this.trimStart(charType).trimEnd(charType);
};
MagicString.prototype.trimEndAborted = function trimEndAborted (charType) {
var rx = new RegExp((charType || '\\s') + '+$');
this.outro = this.outro.replace(rx, '');
if (this.outro.length) { return true; }
var chunk = this.lastChunk;
do {
var end = chunk.end;
var aborted = chunk.trimEnd(rx);
if (chunk.end !== end) {
if (this.lastChunk === chunk) {
this.lastChunk = chunk.next;
}
this.byEnd[chunk.end] = chunk;
this.byStart[chunk.next.start] = chunk.next;
this.byEnd[chunk.next.end] = chunk.next;
}
if (aborted) { return true; }
chunk = chunk.previous;
} while (chunk);
return false;
};
MagicString.prototype.trimEnd = function trimEnd (charType) {
this.trimEndAborted(charType);
return this;
};
MagicString.prototype.trimStartAborted = function trimStartAborted (charType) {
var rx = new RegExp('^' + (charType || '\\s') + '+');
this.intro = this.intro.replace(rx, '');
if (this.intro.length) { return true; }
var chunk = this.firstChunk;
do {
var end = chunk.end;
var aborted = chunk.trimStart(rx);
if (chunk.end !== end) {
if (chunk === this.lastChunk) { this.lastChunk = chunk.next; }
this.byEnd[chunk.end] = chunk;
this.byStart[chunk.next.start] = chunk.next;
this.byEnd[chunk.next.end] = chunk.next;
}
if (aborted) { return true; }
chunk = chunk.next;
} while (chunk);
return false;
};
MagicString.prototype.trimStart = function trimStart (charType) {
this.trimStartAborted(charType);
return this;
};
function escape(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
function isSourceMapEnabled(options) {
if (options) {
return options.sourceMap !== false && options.sourcemap !== false;
}
return false;
}
function padEnd(input, len, fill) {
var value = input || "";
while (value.length < len) {
value += fill;
}
if (value.length > len) {
value = value.substring(0, len);
}
return value;
}
function isNullOrWhitespace(value) {
if (value) {
return value.replace(/\s/g, "").length < 1;
}
return true;
}
function dynamicRemove(options) {
if (options === void 0) { options = {}; }
var token = (options || {}).tagname || "@DynamicProtoStub";
var replaceValue = (options || {}).comment || "// Removed Stub for %function%.";
var tokenGroups = [4, 10, 13];
var funcNameGroup = 6;
var pattern = new RegExp("([\\t ]*\\/\\*\\*((?!\\*\\/)(.|\\r|\\n))*\\*\\/[\\s]*)*(\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*(\\r\\n|\\n\\r|\\r|\\n))*[\\t ]*([\\w]*\\.prototype(\\.|\\[\\\"|\\[\\')[\\w]*(\\\"\\]|\\'\\])?)[\\t ]*=[\\t ]*function[\\t ]*\\([^\\{]*\\{[^\\/\\}\\{]*(\\{[^\\}]*\\}[^\\/\\}\\{]*)*(\\/[\\*\\/][\\t ]*" + escape(token) + "[^\\*\\r\\n]*(\\*\\/)?(\\r\\n|\\n\\r|\\r|\\n))*[^\\}]*\\};([\\t ]*\\/\\/[\\t ]*" + escape(token) + "[^\\r\\n]*)*", 'gi');
function formatError(token, code, pos, id) {
var lines = code.split(/(?:\r\n|\n\r|\r|\n)/);
var lineNumber = 0;
var count = pos;
while (count > 0) {
lineNumber++;
count = code.lastIndexOf("\n", count - 1);
}
var column = 0;
var lineStart = code.lastIndexOf("\n", pos);
if (lineStart != -1) {
column = (pos - lineStart);
}
else {
column = pos + 1;
}
var message = "Invalid (Unremoved) token [" + token + "] found on line [" + lineNumber + "], column [" + column + "], position [" + pos + "] - " + (id || "") + "\n";
var marker = padEnd("", token.length, "^");
var line = lineNumber - 6;
if (line > 0) {
message += " ...\n";
}
count = 0;
while (count < 10 && line < lines.length - 1) {
count++;
if (line >= 0) {
var number = padEnd("" + (line + 1), 4, " ");
message += number + ":" + lines[line] + "\n";
if (line == lineNumber - 1) {
message += padEnd("", column + 4, " ") + marker + "\n";
}
}
line++;
}
if (line < lines.length - 1) {
message += " ...\n";
}
var match;
var matchCount = 0;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
if (matchCount == 0) {
message += "\nMatch checks\n";
}
matchCount++;
if (match[0].length > 0) {
message += "Match " + matchCount + " tag Groups for " + (funcName || "") + "\n";
message += "--=( Complete Matched Content )=--\n";
message += match[0];
message += "\n--------------------------------\n";
for (var lp = 1; lp < match.length; lp++) {
if (match[lp]) {
message += "" + lp + ": " + (match[lp] || "").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
if ((match[lp] || "").indexOf(token) != -1) {
message += " <- Contains tag";
}
message += "\n";
}
}
message += "\n";
}
}
}
return message;
}
function replaceToken(code, theString) {
var result = false;
var match;
while ((match = pattern.exec(code))) {
var funcName = match[funcNameGroup];
if (!isNullOrWhitespace(funcName)) {
var hasToken = false;
for (var lp = 0; lp < tokenGroups.length; lp++) {
if ((match[tokenGroups[lp]] || "").indexOf(token) != -1) {
hasToken = true;
break;
}
}
if (hasToken) {
result = true;
var start = match.index;
var newValue = replaceValue.replace("%function%", funcName);
theString.overwrite(start, start + match[0].length, newValue);
}
}
}
return result;
}
function checkResult(result, id) {
if (result) {
var pos = result.indexOf(token);
if (pos != -1) {
throw new Error(formatError(token, result, pos, id));
}
}
}
function doTransform(code, id) {
var theString = new MagicString(code);
if (!replaceToken(code, theString)) {
return null;
}
var result = { code: theString.toString() };
if (isSourceMapEnabled(options)) {
result.map = theString.generateMap({ hires: true });
}
return result;
}
function doTransformAndCheck(code, id) {
var result = doTransform(code);
if (result) {
checkResult(result.code, id);
}
else {
checkResult(code, id);
}
return result;
}
return {
name: 'dynamicRemove',
renderChunk: function (code, chunk) {
return doTransformAndCheck(code, chunk.filename);
},
transform: doTransformAndCheck
};
}
return dynamicRemove;
}));
@@ -0,0 +1,62 @@
{
"name": "@microsoft/dynamicproto-rollup",
"description": "Microsoft Dynamic Proto Utility Rollup",
"version": "1.0.0",
"keywords": [
"javascript",
"dynamic prototype",
"microsoft",
"typescript",
"inheritence",
"minification",
"application insights"
],
"main": "dist/node/removedynamic.js",
"module": "dist-es5/removeDynamic.js",
"types": "types/removeDynamic.d.ts",
"directories": {},
"scripts": {
"clean": "grunt clean",
"build": "npm run build:esm && npm run build:bundle",
"build:esm": "grunt rollup",
"build:bundle": "rollup -c rollup.config.js --bundleConfigAsCjs",
"rebuild": "npm run build && copyfiles package.json ../lib/tools/rollup"
},
"repository": {
"type": "git",
"url": "git+https://github.com/microsoft/DynamicProto-JS.git"
},
"author": "Microsoft Application Insights Team",
"license": "MIT",
"bugs": {
"url": "https://github.com/microsoft/DynamicProto-JS/issues"
},
"homepage": "https://github.com/microsoft/DynamicProto-JS#readme",
"overrides": {
"minimatch": ">=3.1.2"
},
"dependencies": {
"@nevware21/ts-utils": ">= 0.14.0 < 2.x"
},
"devDependencies": {
"@types/glob": "^7.1.3",
"grunt": "^1.6.1",
"grunt-cli": "^1.5.0",
"grunt-contrib-qunit": "^4.0.0",
"grunt-contrib-uglify": "^5.2.1",
"grunt-contrib-connect": "^5.0.0",
"grunt-run": "^0.8.1",
"@nevware21/grunt-ts-plugin": "^0.5.2",
"typedoc": "^0.26.6",
"typescript": "^4.9.5",
"rollup-plugin-copy": "^3.4.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-replace": "^5.0.2",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-minify-es": "^1.1.1",
"rollup": "^3.20.0",
"magic-string": "^0.25.5",
"copyfiles": "^2.4.1"
}
}
@@ -0,0 +1,16 @@
export interface IDynamicProtoRollupOptions {
tagname?: string;
comment?: string;
sourcemap?: boolean;
}
/**
* Simple Rush plugin to remove code that is wrapped between specific comments, this is used to
* remove the boilerplate code require by typescript to define methods as prototype level while
* using @ms-dynamicProto project to support minification. This can also be used to remove "debug"
* functions from the production code.
*/
export default function dynamicRemove(options?: IDynamicProtoRollupOptions): {
name: string;
renderChunk(code: string, chunk: any): any;
transform: (code: string, id: string) => any;
};
@@ -0,0 +1,77 @@
/**
* Interface to define additional configuration options to control how the dynamic prototype functions operate.
*/
export interface IDynamicProtoOpts {
/**
* Should the dynamic prototype attempt to set an instance function for instances that do not already have an
* function of the same name or have been extended by a class with a (non-dynamic proto) prototype function.
*/
setInstFuncs: boolean;
/**
* When looking for base (super) functions if it finds a dynamic proto instances can it use the instance functions
* and bypass the prototype lookups. Defaults to true.
*/
useBaseInst?: boolean;
}
/**
* The delegate signature for the function used as the callback for dynamicProto()
* @typeparam DPType This is the generic type of the class, used to keep intellisense valid for the proxy instance, even
* though it is only a proxy that only contains the functions
* @param theTarget This is the real "this" of the current target object
* @param baseFuncProxy The is a proxy object which ONLY contains this function that existed on the "this" instance before
* calling dynamicProto, it does NOT contain properties of this. This is basically equivalent to using the "super" keyword.
*/
export type DynamicProtoDelegate<DPType> = (theTarget: DPType, baseFuncProxy?: DPType) => void;
/**
* 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
*/
export default function dynamicProto<DPType, DPCls>(theClass: DPCls, target: DPType, delegateFunc: DynamicProtoDelegate<DPType>, options?: IDynamicProtoOpts): void;