precedent 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.config/code-server/config.yaml +1 -1
  2. package/.config/configstore/update-notifier-npm.json +1 -1
  3. package/Dockerfile_LUXURYCode +69 -0
  4. package/dist/precedent.js +302 -307
  5. package/dist/precedent.min.js +29 -27
  6. package/dist/precedent.min.js.map +1 -1
  7. package/gulpfile.js +36 -15
  8. package/package.json +26 -12
  9. package/source/Precedent-Browser-Shim.js +5 -9
  10. package/source/StringParser.js +1 -1
  11. package/source/WordTree.js +7 -7
  12. package/test/Precedent_tests.js +106 -0
  13. package/test.js +1 -0
  14. package/.config/luxury-extras/.vscode/launch.json +0 -46
  15. package/.config/luxury-extras/Dockerfile +0 -32
  16. package/.config/luxury-extras/Dockerfile_LUXURYCode +0 -45
  17. package/.config/luxury-extras/MySQL/Dockerfile +0 -51
  18. package/.config/luxury-extras/MySQL/Dockerfile_LUXURYCODE +0 -65
  19. package/.config/luxury-extras/MySQL/MySQL-Laden-Entry.sh +0 -17
  20. package/.config/luxury-extras/MySQL/MySQL-Security.sql +0 -5
  21. package/.config/luxury-extras/model/ddl/BookStore.ddl +0 -66
  22. package/.config/luxury-extras/model/documentation/Dictionary.md +0 -18
  23. package/.config/luxury-extras/model/documentation/Model-Author.md +0 -20
  24. package/.config/luxury-extras/model/documentation/Model-Book.md +0 -26
  25. package/.config/luxury-extras/model/documentation/Model-BookAuthorJoin.md +0 -14
  26. package/.config/luxury-extras/model/documentation/Model-BookPrice.md +0 -25
  27. package/.config/luxury-extras/model/documentation/Model-Review.md +0 -22
  28. package/.config/luxury-extras/model/documentation/ModelChangeTracking.md +0 -17
  29. package/.config/luxury-extras/model/documentation/README.md +0 -1
  30. package/.config/luxury-extras/model/documentation/diagram/README.md +0 -1
  31. package/.config/luxury-extras/model/documentation/diagram/Stricture_Output.dot +0 -13
  32. package/.config/luxury-extras/model/documentation/diagram/Stricture_Output.png +0 -0
  33. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Author.json +0 -220
  34. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Book.json +0 -268
  35. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-BookAuthorJoin.json +0 -172
  36. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-BookPrice.json +0 -260
  37. package/.config/luxury-extras/model/json_schema_entities/BookStore-MeadowSchema-Review.json +0 -236
  38. package/.config/luxury-extras/model/json_schema_entities/README.md +0 -1
  39. package/.config/luxury-extras/model/json_schema_model/BookStore-Extended.json +0 -915
  40. package/.config/luxury-extras/model/json_schema_model/BookStore-PICT.json +0 -1
  41. package/.config/luxury-extras/model/json_schema_model/BookStore.json +0 -280
  42. package/.config/luxury-extras/model/json_schema_model/README.md +0 -1
  43. package/.config/luxury-extras/model/mysql_create/BookStore-CreateDatabase.mysql.sql +0 -116
  44. package/.config/luxury-extras/model/mysql_create/README.md +0 -1
  45. package/DockerfileLUXURYCode +0 -45
@@ -1,37 +1,39 @@
1
1
  !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Precedent=t()}}((function(){return function t(e,r,n){function a(s,f){if(!r[s]){if(!e[s]){var o="function"==typeof require&&require;if(!f&&o)return o(s,!0);if(u)return u(s,!0);var i=new Error("Cannot find module '"+s+"'");throw i.code="MODULE_NOT_FOUND",i}var P=r[s]={exports:{}};e[s][0].call(P.exports,(function(t){return a(e[s][1][t]||t)}),P,P.exports,t,e,r,n)}return r[s].exports}for(var u="function"==typeof require&&require,s=0;s<n.length;s++)a(n[s]);return a}({1:[function(t,e,r){
2
2
  /**
3
- * @license MIT
4
- * @author <steven@velozo.com>
5
- */
3
+ * Simple browser shim loader - assign the npm module to a window global automatically
4
+ *
5
+ * @license MIT
6
+ * @author <steven@velozo.com>
7
+ */
6
8
  var n=t("./Precedent.js");"object"!=typeof window||window.hasOwnProperty("Precedent")||(window.Precedent=n),e.exports=n},{"./Precedent.js":2}],2:[function(t,e,r){
7
9
  /**
8
- * Precedent Meta-Templating
9
- *
10
- * @license MIT
11
- *
12
- * @author Steven Velozo <steven@velozo.com>
13
- *
14
- * @description Process text streams, parsing out meta-template expressions.
15
- */
10
+ * Precedent Meta-Templating
11
+ *
12
+ * @license MIT
13
+ *
14
+ * @author Steven Velozo <steven@velozo.com>
15
+ *
16
+ * @description Process text streams, parsing out meta-template expressions.
17
+ */
16
18
  var n=t("./WordTree.js"),a=t("./StringParser.js");e.exports=class{constructor(){this.WordTree=new n,this.StringParser=new a,this.ParseTree=this.WordTree.ParseTree}addPattern(t,e,r){return this.WordTree.addPattern(t,e,r)}parseString(t){return this.StringParser.parseString(t,this.ParseTree)}}},{"./StringParser.js":3,"./WordTree.js":4}],3:[function(t,e,r){e.exports=
17
19
  /**
18
- * String Parser
19
- *
20
- * @license MIT
21
- *
22
- * @author Steven Velozo <steven@velozo.com>
23
- *
24
- * @description Parse a string, properly processing each matched token in the word tree.
25
- */
20
+ * String Parser
21
+ *
22
+ * @license MIT
23
+ *
24
+ * @author Steven Velozo <steven@velozo.com>
25
+ *
26
+ * @description Parse a string, properly processing each matched token in the word tree.
27
+ */
26
28
  class{constructor(){}newParserState(t){return{ParseTree:t,Output:"",OutputBuffer:"",Pattern:!1,PatternMatch:!1,PatternMatchOutputBuffer:""}}assignNode(t,e){e.PatternMatch=t,e.PatternMatch.hasOwnProperty("PatternEnd")&&(e.Pattern=e.PatternMatch)}appendOutputBuffer(t,e){e.OutputBuffer+=t}flushOutputBuffer(t){t.Output+=t.OutputBuffer,t.OutputBuffer=""}checkPatternEnd(t){t.OutputBuffer.length>=t.Pattern.PatternEnd.length+t.Pattern.PatternStart.length&&t.OutputBuffer.substr(-t.Pattern.PatternEnd.length)===t.Pattern.PatternEnd&&(t.OutputBuffer=t.Pattern.Parse(t.OutputBuffer.substr(t.Pattern.PatternStart.length,t.OutputBuffer.length-(t.Pattern.PatternStart.length+t.Pattern.PatternEnd.length))),this.flushOutputBuffer(t),t.Pattern=!1,t.PatternMatch=!1)}parseCharacter(t,e){!e.PatternMatch&&e.ParseTree.hasOwnProperty(t)?(this.assignNode(e.ParseTree[t],e),this.appendOutputBuffer(t,e)):e.PatternMatch?(e.PatternMatch.hasOwnProperty(t)&&this.assignNode(e.PatternMatch[t],e),this.appendOutputBuffer(t,e),e.Pattern&&this.checkPatternEnd(e)):e.Output+=t}parseString(t,e){let r=this.newParserState(e);for(var n=0;n<t.length;n++)this.parseCharacter(t[n],r);return this.flushOutputBuffer(r),r.Output}}},{}],4:[function(t,e,r){e.exports=
27
29
  /**
28
- * Word Tree
29
- *
30
- * @license MIT
31
- *
32
- * @author Steven Velozo <steven@velozo.com>
33
- *
34
- * @description Create a tree (directed graph) of Javascript objects, one character per object.
35
- */
30
+ * Word Tree
31
+ *
32
+ * @license MIT
33
+ *
34
+ * @author Steven Velozo <steven@velozo.com>
35
+ *
36
+ * @description Create a tree (directed graph) of Javascript objects, one character per object.
37
+ */
36
38
  class{constructor(){this.ParseTree={}}addChild(t,e,r){return r>e.length?t:(t.hasOwnProperty(e[r])||(t[e[r]]={}),t[e[r]])}addPattern(t,e,r){if(t.length<1)return!1;let n=this.ParseTree;for(var a=0;a<t.length;a++)n=this.addChild(n,t,a);return n.PatternStart=t,n.PatternEnd="string"==typeof e&&e.length>0?e:t,n.Parse="function"==typeof r?r:"string"==typeof r?()=>r:t=>t,!0}}},{}]},{},[1])(1)}));
37
39
  //# sourceMappingURL=precedent.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["node_modules/browser-pack/_prelude.js","source/Precedent-Browser-Shim.js","precedent.min.js","source/Precedent.js","source/StringParser.js","source/WordTree.js"],"names":["f","exports","module","define","amd","window","global","self","this","Precedent","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","libPrecedent","hasOwnProperty","libWordTree","libStringParser","constructor","WordTree","StringParser","ParseTree","addPattern","pPatternStart","pPatternEnd","pParser","parseString","pString","newParserState","pParseTree","Output","OutputBuffer","Pattern","PatternMatch","PatternMatchOutputBuffer","assignNode","pNode","pParserState","appendOutputBuffer","pCharacter","flushOutputBuffer","checkPatternEnd","PatternEnd","PatternStart","substr","Parse","parseCharacter","tmpParserState","addChild","pTree","pPattern","pIndex","tmpLeaf","pData"],"mappings":"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","file":"precedent.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()","/**\n* @license MIT\n* @author <steven@velozo.com>\n*/\n\n/**\n* Precedent browser shim loader\n*/\n\n// Load the precedent module into the browser global automatically.\nvar libPrecedent = require('./Precedent.js');\n\nif ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))\n{\n\twindow.Precedent = libPrecedent;\n}\n\nmodule.exports = libPrecedent;",null,"/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n","/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t ParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n","/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (pIndex > pPattern.length)\n\t\t\treturn pTree;\n\t\t\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n"]}
1
+ {"version":3,"sources":["node_modules/browser-pack/_prelude.js","source/Precedent-Browser-Shim.js","precedent.min.js","source/Precedent.js","source/StringParser.js","source/WordTree.js"],"names":["f","exports","module","define","amd","window","global","self","this","Precedent","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","libNPMModuleWrapper","hasOwnProperty","libWordTree","libStringParser","constructor","WordTree","StringParser","ParseTree","addPattern","pPatternStart","pPatternEnd","pParser","parseString","pString","newParserState","pParseTree","Output","OutputBuffer","Pattern","PatternMatch","PatternMatchOutputBuffer","assignNode","pNode","pParserState","appendOutputBuffer","pCharacter","flushOutputBuffer","checkPatternEnd","PatternEnd","PatternStart","substr","Parse","parseCharacter","tmpParserState","addChild","pTree","pPattern","pIndex","tmpLeaf","pData"],"mappings":"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","file":"precedent.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()","/**\n* Simple browser shim loader - assign the npm module to a window global automatically\n*\n* @license MIT\n* @author <steven@velozo.com>\n*/\nvar libNPMModuleWrapper = require('./Precedent.js');\n\nif ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))\n{\n\twindow.Precedent = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;","(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Precedent = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){\n/**\n* Simple browser shim loader - assign the npm module to a window global automatically\n*\n* @license MIT\n* @author <steven@velozo.com>\n*/\nvar libNPMModuleWrapper = require('./Precedent.js');\n\nif ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))\n{\n\twindow.Precedent = libNPMModuleWrapper;\n}\n\nmodule.exports = libNPMModuleWrapper;\n},{\"./Precedent.js\":2}],2:[function(require,module,exports){\n/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n\n},{\"./StringParser.js\":3,\"./WordTree.js\":4}],3:[function(require,module,exports){\n/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n\n},{}],4:[function(require,module,exports){\n/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (pIndex > pPattern.length)\n\t\t\treturn pTree;\n\t\t\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n\n},{}]},{},[1])(1)\n});\n\n","/**\n* Precedent Meta-Templating\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Process text streams, parsing out meta-template expressions.\n*/\nvar libWordTree = require(`./WordTree.js`);\nvar libStringParser = require(`./StringParser.js`);\n\nclass Precedent\n{\n\t/**\n\t * Precedent Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.WordTree = new libWordTree();\n\t\t\n\t\tthis.StringParser = new libStringParser();\n\n\t\tthis.ParseTree = this.WordTree.ParseTree;\n\t}\n\t\n\t/**\n\t * Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern(pPatternStart, pPatternEnd, pParser)\n\t{\n\t\treturn this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);\n\t}\n\t\n\t/**\n\t * Parse a string with the existing parse tree\n\t * @method parseString\n\t * @param {string} pString - The string to parse\n\t * @return {string} The result from the parser\n\t */\n\tparseString(pString)\n\t{\n\t\treturn this.StringParser.parseString(pString, this.ParseTree);\n\t}\n}\n\nmodule.exports = Precedent;\n","/**\n* String Parser\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Parse a string, properly processing each matched token in the word tree.\n*/\n\nclass StringParser\n{\n\t/**\n\t * StringParser Constructor\n\t */\n\tconstructor()\n\t{\n\t}\n\t\n\t/**\n\t * Create a fresh parsing state object to work with.\n\t * @method newParserState\n\t * @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)\n\t * @return {Object} A new parser state object for running a character parser on\n\t * @private\n\t */\n\tnewParserState (pParseTree)\n\t{\n\t\treturn (\n\t\t{\n\t\t\tParseTree: pParseTree,\n\n\t\t\tOutput: '',\n\t\t\tOutputBuffer: '',\n\n\t\t\tPattern: false,\n\n\t\t\tPatternMatch: false,\n\t\t\tPatternMatchOutputBuffer: ''\n\t\t});\n\t}\n\t\t\n\t/**\n\t * Assign a node of the parser tree to be the next potential match.\n\t * If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).\n\t * @method assignNode\n\t * @param {Object} pNode - A node on the parse tree to assign\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tassignNode (pNode, pParserState)\n\t{\n\t\tpParserState.PatternMatch = pNode;\n\n\t\t// If the pattern has a END we can assume it has a parse function...\n\t\tif (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))\n\t\t{\n\t\t\t// ... this is the legitimate start of a pattern.\n\t\t\tpParserState.Pattern = pParserState.PatternMatch;\n\t\t}\n\t}\n\t\n\t/**\n\t * Append a character to the output buffer in the parser state.\n\t * This output buffer is used when a potential match is being explored, or a match is being explored.\n\t * @method appendOutputBuffer\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tappendOutputBuffer (pCharacter, pParserState)\n\t{\n\t\tpParserState.OutputBuffer += pCharacter;\n\t}\n\t\n\t/**\n\t * Flush the output buffer to the output and clear it.\n\t * @method flushOutputBuffer\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tflushOutputBuffer (pParserState)\n\t{\n\t\tpParserState.Output += pParserState.OutputBuffer;\n\t\tpParserState.OutputBuffer = '';\n\t}\n\n\t\n\t/**\n\t * Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.\n\t * @method checkPatternEnd\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tcheckPatternEnd (pParserState)\n\t{\n\t\tif ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) && \n\t\t\t(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))\n\t\t{\n\t\t\t// ... this is the end of a pattern, cut off the end tag and parse it.\n\t\t\t// Trim the start and end tags off the output buffer now\n\t\t\tpParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)));\n\t\t\t// Flush the output buffer.\n\t\t\tthis.flushOutputBuffer(pParserState);\n\t\t\t// End pattern mode\n\t\t\tpParserState.Pattern = false;\n\t\t\tpParserState.PatternMatch = false;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a character in the buffer.\n\t * @method parseCharacter\n\t * @param {string} pCharacter - The character to append\n\t * @param {Object} pParserState - The state object for the current parsing task\n\t * @private\n\t */\n\tparseCharacter (pCharacter, pParserState)\n\t{\n\t\t// (1) If we aren't in a pattern match, and we aren't potentially matching, and this may be the start of a new pattern....\n\t\tif (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))\n\t\t{\n\t\t\t// ... assign the node as the matched node.\n\t\t\tthis.assignNode(pParserState.ParseTree[pCharacter], pParserState);\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t}\n\t\t// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)\n\t\telse if (pParserState.PatternMatch)\n\t\t{\n\t\t\t// If the pattern has a subpattern with this key\n\t\t\tif (pParserState.PatternMatch.hasOwnProperty(pCharacter))\n\t\t\t{\n\t\t\t\t// Continue matching patterns.\n\t\t\t\tthis.assignNode(pParserState.PatternMatch[pCharacter], pParserState);\n\t\t\t}\n\t\t\tthis.appendOutputBuffer(pCharacter, pParserState);\n\t\t\tif (pParserState.Pattern)\n\t\t\t{\n\t\t\t\t// ... Check if this is the end of the pattern (if we are matching a valid pattern)...\n\t\t\t\tthis.checkPatternEnd(pParserState);\n\t\t\t}\n\t\t}\n\t\t// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....\n\t\telse\n\t\t{\n\t\t\tpParserState.Output += pCharacter;\n\t\t}\n\t}\n\t\n\t/**\n\t * Parse a string for matches, and process any template segments that occur.\n\t * @method parseString\n\t * @param {string} pString - The string to parse.\n\t * @param {Object} pParseTree - The parse tree to begin parsing from (usually root)\n\t */\n\tparseString (pString, pParseTree)\n\t{\n\t\tlet tmpParserState = this.newParserState(pParseTree);\n\n\t\tfor (var i = 0; i < pString.length; i++)\n\t\t{\n\t\t\t// TODO: This is not fast.\n\t\t\tthis.parseCharacter(pString[i], tmpParserState);\n\t\t}\n\t\t\n\t\tthis.flushOutputBuffer(tmpParserState);\n\t\t\n\t\treturn tmpParserState.Output;\n\t}\n}\n\nmodule.exports = StringParser;\n","/**\n* Word Tree\n*\n* @license MIT\n*\n* @author Steven Velozo <steven@velozo.com>\n*\n* @description Create a tree (directed graph) of Javascript objects, one character per object.\n*/\n\nclass WordTree\n{\n\t/**\n\t * WordTree Constructor\n\t */\n\tconstructor()\n\t{\n\t\tthis.ParseTree = {};\n\t}\n\t\n\t/** \n\t * Add a child character to a Parse Tree node\n\t * @method addChild\n\t * @param {Object} pTree - A parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @returns {Object} The resulting leaf node that was added (or found)\n\t * @private\n\t */\n\taddChild (pTree, pPattern, pIndex)\n\t{\n\t\tif (pIndex > pPattern.length)\n\t\t\treturn pTree;\n\t\t\n\t\tif (!pTree.hasOwnProperty(pPattern[pIndex]))\n\t\t\tpTree[pPattern[pIndex]] = {};\n\t\t\n\t\treturn pTree[pPattern[pIndex]];\n\t}\n\t\n\t/** Add a Pattern to the Parse Tree\n\t * @method addPattern\n\t * @param {Object} pTree - A node on the parse tree to push the characters into\n\t * @param {string} pPattern - The string to add to the tree\n\t * @param {number} pIndex - callback function\n\t * @return {bool} True if adding the pattern was successful\n\t */\n\taddPattern (pPatternStart, pPatternEnd, pParser)\n\t{\n\t\tif (pPatternStart.length < 1)\n\t\t\treturn false;\n\n\t\tlet tmpLeaf = this.ParseTree;\n\n\t\t// Add the tree of leaves iteratively\n\t\tfor (var i = 0; i < pPatternStart.length; i++)\n\t\t\ttmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);\n\n\t\ttmpLeaf.PatternStart = pPatternStart;\n\t\ttmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;\n\t\ttmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser : \n\t\t\t\t\t\t(typeof(pParser) === 'string') ? () => { return pParser; } :\n\t\t\t\t\t\t(pData) => { return pData; };\n\n\t\treturn true;\n\t}\n}\n\nmodule.exports = WordTree;\n"]}
package/gulpfile.js CHANGED
@@ -1,62 +1,83 @@
1
1
  'use strict';
2
2
 
3
+ // We aren't abstracting this yet but here's the ... "Config"
4
+ const _CONFIG = (
5
+ {
6
+ // The input source file that should be passed to browserify:
7
+ // (if you need to auto-instantiate an object, for instance)
8
+ EntrypointInputSourceFile: `${__dirname}/source/Precedent-Browser-Shim.js`,
9
+
10
+ // The name of the packaged object to be passed to browserify:
11
+ // (browserify sets this to global scope and window.SOMEOBJECTNAMEHERE where SOMEOBJECTNAMEHERE is the string below)
12
+ LibraryObjectName: `Precedent`,
13
+
14
+ // The folder to write the library files and maps out to:
15
+ LibraryOutputFolder: `${__dirname}/dist/`,
16
+
17
+ // The name of the unminified version of the packaged library, for easy debugging:
18
+ LibraryUniminifiedFileName: `precedent.js`,
19
+
20
+ // The name of the minified version of the packaged library, for production release:
21
+ LibraryMinifiedFileName: `precedent.min.js`
22
+ });
23
+
24
+ // ---> Boilerplate Browser Uglification and Packaging <--- \\
25
+
3
26
  const libBrowserify = require('browserify');
4
27
  const libGulp = require('gulp');
5
28
 
6
29
  const libVinylSourceStream = require('vinyl-source-stream');
7
30
  const libVinylBuffer = require('vinyl-buffer');
8
31
 
9
- const libTerser = require('gulp-terser');
10
- const libBuble = require('gulp-buble');
11
32
  const libSourcemaps = require('gulp-sourcemaps');
12
33
  const libGulpUtil = require('gulp-util');
34
+ const libBabel = require('gulp-babel');
35
+ const libTerser = require('gulp-terser');
13
36
 
14
37
  // Build the module for the browser
15
- // This gulp task is taken from the gulp recipe repository:
16
- // https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md
17
38
  libGulp.task('minified',
18
39
  () => {
19
40
  // set up the custom browserify instance for this task
20
41
  var tmpBrowserify = libBrowserify(
21
42
  {
22
- entries: './source/Precedent-Browser-Shim.js',
23
- standalone: 'Precedent',
43
+ entries: _CONFIG.EntrypointInputSourceFile,
44
+ standalone: _CONFIG.LibraryObjectName,
24
45
  debug: true
25
46
  });
26
47
 
27
48
  return tmpBrowserify.bundle()
28
- .pipe(libVinylSourceStream('precedent.min.js'))
49
+ .pipe(libVinylSourceStream(_CONFIG.LibraryMinifiedFileName))
29
50
  .pipe(libVinylBuffer())
30
51
  .pipe(libSourcemaps.init({loadMaps: true}))
31
52
  // Add transformation tasks to the pipeline here.
53
+ .pipe(libBabel())
32
54
  .pipe(libTerser())
33
55
  .on('error', libGulpUtil.log)
34
56
  .pipe(libSourcemaps.write('./'))
35
- .pipe(libGulp.dest('./dist/'));
57
+ .pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
36
58
  });
37
59
 
38
60
  // Build the module for the browser
39
- // This gulp task is taken from the gulp recipe repository:
40
- // https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md
41
61
  libGulp.task('debug',
42
62
  () => {
43
63
  // set up the custom browserify instance for this task
44
64
  var tmpBrowserify = libBrowserify(
45
65
  {
46
- entries: './source/Precedent-Browser-Shim.js',
47
- standalone: 'Precedent',
66
+ entries: _CONFIG.EntrypointInputSourceFile,
67
+ standalone: _CONFIG.LibraryObjectName,
48
68
  debug: true
49
69
  });
50
70
 
51
71
  return tmpBrowserify.bundle()
52
- .pipe(libVinylSourceStream('precedent.js'))
72
+ .pipe(libVinylSourceStream(_CONFIG.LibraryUniminifiedFileName))
53
73
  .pipe(libVinylBuffer())
74
+ .pipe(libBabel())
54
75
  .on('error', libGulpUtil.log)
55
- .pipe(libGulp.dest('./dist/'));
76
+ .pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
56
77
  });
57
78
 
58
79
  libGulp.task
59
80
  (
60
81
  'build',
61
82
  libGulp.series('debug', 'minified')
62
- );
83
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "precedent",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Precedent Meta-Templating",
5
5
  "main": "source/Precedent.js",
6
6
  "bin": {
@@ -8,8 +8,11 @@
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node source/Precedent.js",
11
- "coverage": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
12
- "test": "./node_modules/mocha/bin/_mocha -u tdd -R spec"
11
+ "coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
12
+ "test": "./node_modules/.bin/mocha -u tdd -R spec",
13
+ "docker-dev-build-image": "docker build ./ -f Dockerfile_LUXURYCode -t retold/precedent:local",
14
+ "docker-dev-run": "docker run -it -d --name precedent-dev -p 127.0.0.1:12340:8080 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/precedent\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/precedent:local",
15
+ "build": "./node_modules/.bin/gulp build"
13
16
  },
14
17
  "repository": {
15
18
  "type": "git",
@@ -23,22 +26,33 @@
23
26
  "bugs": {
24
27
  "url": "https://github.com/stevenvelozo/precedent/issues"
25
28
  },
29
+ "mocha": {
30
+ "diff": true,
31
+ "extension": [
32
+ "js"
33
+ ],
34
+ "package": "./package.json",
35
+ "reporter": "spec",
36
+ "slow": "75",
37
+ "timeout": "5000",
38
+ "ui": "tdd",
39
+ "watch-files": [
40
+ "source/**/*.js",
41
+ "test/**/*.js"
42
+ ],
43
+ "watch-ignore": [
44
+ "lib/vendor"
45
+ ]
46
+ },
26
47
  "devDependencies": {
27
- "@babel/core": "^7.17.9",
28
- "@babel/preset-env": "^7.16.11",
29
- "@testing-library/dom": "^8.13.0",
30
- "async": "^3.2.3",
31
48
  "browserify": "^17.0.0",
32
- "chai": "4.3.6",
49
+ "chai": "4.3.7",
33
50
  "gulp": "^4.0.2",
34
51
  "gulp-babel": "^8.0.0",
35
- "gulp-buble": "^0.9.0",
36
52
  "gulp-sourcemaps": "^3.0.0",
37
53
  "gulp-terser": "^2.1.0",
38
54
  "gulp-util": "^3.0.8",
39
- "jsdom": "^19.0.0",
40
- "mocha": "9.2.2",
41
- "npm-check-updates": "^12.5.9",
55
+ "mocha": "10.2.0",
42
56
  "nyc": "^15.1.0",
43
57
  "vinyl-buffer": "^1.0.1",
44
58
  "vinyl-source-stream": "^2.0.0"
@@ -1,18 +1,14 @@
1
1
  /**
2
+ * Simple browser shim loader - assign the npm module to a window global automatically
3
+ *
2
4
  * @license MIT
3
5
  * @author <steven@velozo.com>
4
6
  */
5
-
6
- /**
7
- * Precedent browser shim loader
8
- */
9
-
10
- // Load the precedent module into the browser global automatically.
11
- var libPrecedent = require('./Precedent.js');
7
+ var libNPMModuleWrapper = require('./Precedent.js');
12
8
 
13
9
  if ((typeof(window) == 'object') && (!window.hasOwnProperty('Precedent')))
14
10
  {
15
- window.Precedent = libPrecedent;
11
+ window.Precedent = libNPMModuleWrapper;
16
12
  }
17
13
 
18
- module.exports = libPrecedent;
14
+ module.exports = libNPMModuleWrapper;
@@ -28,7 +28,7 @@ class StringParser
28
28
  {
29
29
  return (
30
30
  {
31
- ParseTree: pParseTree,
31
+ ParseTree: pParseTree,
32
32
 
33
33
  Output: '',
34
34
  OutputBuffer: '',
@@ -23,15 +23,12 @@ class WordTree
23
23
  * @method addChild
24
24
  * @param {Object} pTree - A parse tree to push the characters into
25
25
  * @param {string} pPattern - The string to add to the tree
26
- * @param {number} pIndex - callback function
26
+ * @param {number} pIndex - The index of the character in the pattern
27
27
  * @returns {Object} The resulting leaf node that was added (or found)
28
28
  * @private
29
29
  */
30
30
  addChild (pTree, pPattern, pIndex)
31
31
  {
32
- if (pIndex > pPattern.length)
33
- return pTree;
34
-
35
32
  if (!pTree.hasOwnProperty(pPattern[pIndex]))
36
33
  pTree[pPattern[pIndex]] = {};
37
34
 
@@ -40,9 +37,9 @@ class WordTree
40
37
 
41
38
  /** Add a Pattern to the Parse Tree
42
39
  * @method addPattern
43
- * @param {Object} pTree - A node on the parse tree to push the characters into
44
- * @param {string} pPattern - The string to add to the tree
45
- * @param {number} pIndex - callback function
40
+ * @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
41
+ * @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
42
+ * @param {number} pParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
46
43
  * @return {bool} True if adding the pattern was successful
47
44
  */
48
45
  addPattern (pPatternStart, pPatternEnd, pParser)
@@ -50,6 +47,9 @@ class WordTree
50
47
  if (pPatternStart.length < 1)
51
48
  return false;
52
49
 
50
+ if ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))
51
+ return false;
52
+
53
53
  let tmpLeaf = this.ParseTree;
54
54
 
55
55
  // Add the tree of leaves iteratively
@@ -121,6 +121,28 @@ suite
121
121
  }
122
122
  );
123
123
  test
124
+ (
125
+ 'Bad pattern start parameter...',
126
+ (fDone) =>
127
+ {
128
+ var testPrecedent = loadPrecedentModule();
129
+ configPrecedent(testPrecedent);
130
+ Expect(testPrecedent.addPattern('', '>', 'SHORTEST_MATCH')).to.equal(false);
131
+ fDone();
132
+ }
133
+ );
134
+ test
135
+ (
136
+ 'Bad pattern end parameter...',
137
+ (fDone) =>
138
+ {
139
+ var testPrecedent = loadPrecedentModule();
140
+ configPrecedent(testPrecedent);
141
+ Expect(testPrecedent.addPattern('<', '', 'SHORTEST_MATCH')).to.equal(false);
142
+ fDone();
143
+ }
144
+ );
145
+ test
124
146
  (
125
147
  'Identifier fallback...',
126
148
  (fDone) =>
@@ -147,6 +169,90 @@ suite
147
169
  'Match this MEDIUM_MATCH and this SHORTEST_MATCH please.'
148
170
  ];
149
171
 
172
+ var tmpResult = '';
173
+ // Test every pair in TestStrings
174
+ for (var i = 0; i < tmpTestStrings.length; i+=2)
175
+ {
176
+ tmpResult = testPrecedent.parseString(tmpTestStrings[i]);
177
+ Expect(tmpResult).to.equal(tmpTestStrings[i+1]);
178
+ }
179
+ fDone();
180
+ }
181
+ );
182
+ test
183
+ (
184
+ 'Config magic example...',
185
+ (fDone) =>
186
+ {
187
+ // Use case is take a string with the following template expressions and translate them into the value from the environment variable if a default isn't passed in:
188
+ // 'Expressions like ${VariableWithDefault|DefaultValue} have a Default value after the pipe; others like ${VariableWithoutDefault} expressions do not have a Default value after the pipe. but should be processed properly.',
189
+ // 'Expressions like DefaultValue have a Default value after the pipe; others like VariableWithoutDefault expressions do not have a Default value after the pipe. but should be processed properly.',
190
+
191
+ // The usual case is just expressions in the string, but composability is fine.
192
+
193
+ var testPrecedent = new libPrecedent();
194
+
195
+ testPrecedent.addPattern('${', '}',
196
+ (pTemplateValue)=>
197
+ {
198
+ let tmpTemplateValue = pTemplateValue.trim();
199
+
200
+ let tmpSeparatorIndex = tmpTemplateValue.indexOf('|');
201
+
202
+ // If there is no pipe, the default value will end up being whatever the variable name is.
203
+ let tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);
204
+
205
+ let tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;
206
+
207
+ if (process.env.hasOwnProperty(tmpEnvironmentVariableName))
208
+ {
209
+ return process.env[tmpEnvironmentVariableName];
210
+ }
211
+ else
212
+ {
213
+ return tmpDefaultValue;
214
+ }
215
+ });
216
+
217
+ var tmpTestStrings = [
218
+ 'Expressions like ${VariableWithDefault|DefaultValue} have a Default value after the pipe; others like ${VariableWithoutDefault} expressions do not have a Default value after the pipe. but should be processed properly.',
219
+ 'Expressions like DefaultValue have a Default value after the pipe; others like VariableWithoutDefault expressions do not have a Default value after the pipe. but should be processed properly.',
220
+
221
+ '${PATH}',
222
+ process.env.PATH,
223
+
224
+ 'AAA ${PATH}',
225
+ 'AAA '+process.env.PATH,
226
+
227
+ ' ${PATH} AAA ${PATH}',
228
+ ' '+process.env.PATH+' AAA '+process.env.PATH,
229
+
230
+ 'AAA ${PATH} BBB',
231
+ 'AAA '+process.env.PATH+' BBB',
232
+
233
+ 'AAA ${PATH} } BBB',
234
+ 'AAA '+process.env.PATH+' } BBB',
235
+
236
+ 'AAA ${ ${PATH} BBB',
237
+ // Two start parameters isn't okay ---
238
+ // ...it passes the pattern processor the following (without quotes):
239
+ // " ${PATH"
240
+ // Which is not going to match an environment variable. With the second
241
+ 'AAA ${PATH BBB',
242
+
243
+ '${PATH|Malarky Default Value} ZZZ',
244
+ process.env.PATH+' ZZZ',
245
+
246
+ '${THISISNOTANENVIRONMENTVARIABLE|Real Default Value} ZZZed',
247
+ 'Real Default Value ZZZed',
248
+
249
+ '${ THISISNOTANENVIRONMENTVARIABLETRIMMED|Real Trimmed Default Value } ZZZed',
250
+ 'Real Trimmed Default Value ZZZed',
251
+
252
+ '${PATH} BBB',
253
+ process.env.PATH+' BBB'
254
+ ];
255
+
150
256
  var tmpResult = '';
151
257
  // Test every pair in TestStrings
152
258
  for (var i = 0; i < tmpTestStrings.length; i+=2)
package/test.js ADDED
@@ -0,0 +1 @@
1
+ console.log(JSON.stringify(process.env, null, 4));
@@ -1,46 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "name": "Launch Debug Harness",
9
- "type": "pwa-node",
10
- "request": "launch",
11
- "outputCapture": "std",
12
- "skipFiles": [
13
- "<node_internals>/**"
14
- ],
15
- "program": "${workspaceFolder}/debug/Harness.js",
16
- "presentation": {
17
- "hidden": false,
18
- "group": "",
19
- "order": 1
20
- }
21
- },
22
- {
23
- "name": "Mocha Tests",
24
- "args": [
25
- "-u",
26
- "tdd",
27
- "--timeout",
28
- "999999",
29
- "--colors",
30
- "${workspaceFolder}/test"
31
- ],
32
- "internalConsoleOptions": "openOnSessionStart",
33
- "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
34
- "request": "launch",
35
- "skipFiles": [
36
- "<node_internals>/**"
37
- ],
38
- "type": "pwa-node",
39
- "presentation": {
40
- "hidden": false,
41
- "group": "",
42
- "order": 2
43
- }
44
- }
45
- ]
46
- }
@@ -1,32 +0,0 @@
1
- # Use the codercom/code-server image
2
- FROM codercom/code-server:latest
3
- MAINTAINER steven velozo
4
-
5
- VOLUME /home/coder/.config
6
- VOLUME /home/coder/.vscode
7
-
8
- RUN echo "...installing debian dependencies..."
9
- RUN sudo apt update
10
- RUN sudo apt install vim curl tmux -y
11
-
12
- RUN echo "Building development image..."
13
-
14
-
15
- RUN echo "...mapping library specific volumes..."
16
- # Volume mappings for code
17
- VOLUME /home/coder/YOURLIBRARYNAMEHERE
18
- # VOLUME /home/coder/YOURLIBRARYNAMEHERE/node_modules
19
-
20
- SHELL ["/bin/bash", "-c"]
21
- USER coder
22
-
23
- RUN echo "...installing node version manager..."
24
- # Because there is a .bashrc chicken/egg problem, we will create one here to simulate logging in. This is not great.
25
- RUN touch ~/.bashrc && chmod +x ~/.bashrc
26
- RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
27
-
28
- RUN echo "...installing node version 14 as the default..."
29
- RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm install 14
30
- RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 14
31
-
32
- WORKDIR /home/coder/YOURLIBRARYNAMEHERE