fable 3.0.45 → 3.0.47
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.
- package/.browserslistrc +1 -1
- package/.config/configstore/update-notifier-npm.json +1 -1
- package/.config/vscode-sqltools/runningInfo.json +1 -1
- package/Dockerfile_LUXURYCode +4 -5
- package/dist/fable.compatible.js +277 -4005
- package/dist/fable.compatible.min.js +18 -30
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +208 -3936
- package/dist/fable.min.js +18 -30
- package/dist/fable.min.js.map +1 -1
- package/gulpfile-config.json +2 -2
- package/package.json +7 -7
- package/retold-harness/bookstore-serve-api.js +41 -0
- package/retold-harness/configuration-bookstore-serve-api.js +30 -0
- package/retold-harness/model/manual_scripts/MySQL-Laden-Entry.sh +17 -0
- package/retold-harness/model/manual_scripts/my.cnf +4 -0
- package/retold-harness/model/sql_create/BookStore-DeleteAndRepopulateTables.sql +194 -0
- package/retold-harness/model/sql_create/MySQL-Security.sql +5 -0
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-StringParser.js +281 -0
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-WordTree.js +97 -0
- package/source/services/Fable-Service-MetaTemplate.js +20 -6
- package/source/services/Fable-Service-Operation-DefaultSettings.js +1 -1
- package/source/services/Fable-Service-Operation.js +4 -11
- package/test/MetaTemplating_tests.js +241 -29
- package/test/RestClient_test.js +1 -1
- package/retold-harness/Bookstore-Import-Books.sh +0 -4
- package/retold-harness/bookstore-configuration.json +0 -28
- package/retold-harness/bookstore-import-books-run.js +0 -9
- package/retold-harness/bookstore-import-books.js +0 -214
- package/retold-harness/bookstore-serve-meadow-endpoint-apis-IPC.js +0 -137
- package/retold-harness/bookstore-serve-meadow-endpoint-apis-run.js +0 -6
- package/retold-harness/bookstore-serve-meadow-endpoint-apis.js +0 -129
- package/retold-harness/data/books.csv +0 -10001
- package/retold-harness/model/json_schema/README.md +0 -1
- package/retold-harness/package.json +0 -22
- package/retold-harness/test_old/Tests.js +0 -3243
- package/retold-harness/test_old/untitled.js +0 -88
- /package/retold-harness/{MySQL-Laden-Entry.sh → docker_scripts/MySQL-Laden-Entry.sh} +0 -0
- /package/retold-harness/model/{json_schema/BookStore-Extended.json → Model-Extended.json} +0 -0
- /package/retold-harness/model/{json_schema/BookStore-PICT.json → Model-PICT.json} +0 -0
- /package/retold-harness/model/{json_schema/BookStore.json → Model.json} +0 -0
- /package/retold-harness/{bookstore-api-endpoint-exercises.paw → model/bookstore-api-endpoint-exercises.paw} +0 -0
- /package/retold-harness/{MySQL-Security.sql → model/manual_scripts/MySQL-Security.sql} +0 -0
- /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Author.json → meadow/Model-MeadowSchema-Author.json} +0 -0
- /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Book.json → meadow/Model-MeadowSchema-Book.json} +0 -0
- /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json → meadow/Model-MeadowSchema-BookAuthorJoin.json} +0 -0
- /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-BookPrice.json → meadow/Model-MeadowSchema-BookPrice.json} +0 -0
- /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Review.json → meadow/Model-MeadowSchema-Review.json} +0 -0
- /package/retold-harness/model/{meadow_schema → meadow}/README.md +0 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetaTemplate String Parser
|
|
3
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
4
|
+
* @description Parse a string, properly processing each matched token in the word tree.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
class StringParser
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* StringParser Constructor
|
|
11
|
+
*/
|
|
12
|
+
constructor(fEachLimit)
|
|
13
|
+
{
|
|
14
|
+
this.eachLimit = fEachLimit;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a fresh parsing state object to work with.
|
|
19
|
+
* @method newParserState
|
|
20
|
+
* @param {Object} pParseTree - A node on the parse tree to begin parsing from (usually root)
|
|
21
|
+
* @return {Object} A new parser state object for running a character parser on
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
newParserState (pParseTree)
|
|
25
|
+
{
|
|
26
|
+
return (
|
|
27
|
+
{
|
|
28
|
+
ParseTree: pParseTree,
|
|
29
|
+
|
|
30
|
+
Asynchronous: false,
|
|
31
|
+
|
|
32
|
+
Output: '',
|
|
33
|
+
OutputBuffer: '',
|
|
34
|
+
|
|
35
|
+
Pattern: false,
|
|
36
|
+
|
|
37
|
+
PatternMatch: false,
|
|
38
|
+
PatternMatchOutputBuffer: ''
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Assign a node of the parser tree to be the next potential match.
|
|
44
|
+
* If the node has a PatternEnd property, it is a valid match and supercedes the last valid match (or becomes the initial match).
|
|
45
|
+
* @method assignNode
|
|
46
|
+
* @param {Object} pNode - A node on the parse tree to assign
|
|
47
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
assignNode (pNode, pParserState)
|
|
51
|
+
{
|
|
52
|
+
pParserState.PatternMatch = pNode;
|
|
53
|
+
|
|
54
|
+
// If the pattern has a END we can assume it has a parse function...
|
|
55
|
+
if (pParserState.PatternMatch.hasOwnProperty('PatternEnd'))
|
|
56
|
+
{
|
|
57
|
+
// ... this is the legitimate start of a pattern.
|
|
58
|
+
pParserState.Pattern = pParserState.PatternMatch;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Append a character to the output buffer in the parser state.
|
|
64
|
+
* This output buffer is used when a potential match is being explored, or a match is being explored.
|
|
65
|
+
* @method appendOutputBuffer
|
|
66
|
+
* @param {string} pCharacter - The character to append
|
|
67
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
appendOutputBuffer (pCharacter, pParserState)
|
|
71
|
+
{
|
|
72
|
+
pParserState.OutputBuffer += pCharacter;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Flush the output buffer to the output and clear it.
|
|
77
|
+
* @method flushOutputBuffer
|
|
78
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
flushOutputBuffer (pParserState)
|
|
82
|
+
{
|
|
83
|
+
pParserState.Output += pParserState.OutputBuffer;
|
|
84
|
+
pParserState.OutputBuffer = '';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Check if the pattern has ended. If it has, properly flush the buffer and start looking for new patterns.
|
|
89
|
+
* @method checkPatternEnd
|
|
90
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
checkPatternEnd (pParserState, pData)
|
|
94
|
+
{
|
|
95
|
+
if ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) &&
|
|
96
|
+
(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))
|
|
97
|
+
{
|
|
98
|
+
// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
99
|
+
// Trim the start and end tags off the output buffer now
|
|
100
|
+
if (pParserState.Pattern.isAsync)
|
|
101
|
+
{
|
|
102
|
+
console.log(`Precedent ERROR: Async template detected for pattern ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd} but the template engine is being run in non-async mode.`);
|
|
103
|
+
this.OutputBuffer = '';
|
|
104
|
+
// Flush the output buffer.
|
|
105
|
+
this.flushOutputBuffer(pParserState);
|
|
106
|
+
// End pattern mode
|
|
107
|
+
pParserState.Pattern = false;
|
|
108
|
+
pParserState.PatternMatch = false;
|
|
109
|
+
}
|
|
110
|
+
else
|
|
111
|
+
{
|
|
112
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)), pData);
|
|
113
|
+
// Flush the output buffer.
|
|
114
|
+
this.flushOutputBuffer(pParserState);
|
|
115
|
+
// End pattern mode
|
|
116
|
+
pParserState.Pattern = false;
|
|
117
|
+
pParserState.PatternMatch = false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
checkPatternEndAsync (pParserState, pData, fCallback)
|
|
123
|
+
{
|
|
124
|
+
if ((pParserState.OutputBuffer.length >= pParserState.Pattern.PatternEnd.length+pParserState.Pattern.PatternStart.length) &&
|
|
125
|
+
(pParserState.OutputBuffer.substr(-pParserState.Pattern.PatternEnd.length) === pParserState.Pattern.PatternEnd))
|
|
126
|
+
{
|
|
127
|
+
// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
128
|
+
// Trim the start and end tags off the output buffer now
|
|
129
|
+
if (pParserState.Pattern.isAsync)
|
|
130
|
+
{
|
|
131
|
+
return pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)), pData,
|
|
132
|
+
(pError, pAsyncOutput) =>
|
|
133
|
+
{
|
|
134
|
+
if (pError)
|
|
135
|
+
{
|
|
136
|
+
console.log(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
pParserState.OutputBuffer = pAsyncOutput;
|
|
140
|
+
// Flush the output buffer.
|
|
141
|
+
this.flushOutputBuffer(pParserState);
|
|
142
|
+
// End pattern mode
|
|
143
|
+
pParserState.Pattern = false;
|
|
144
|
+
pParserState.PatternMatch = false;
|
|
145
|
+
|
|
146
|
+
return fCallback();
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else
|
|
150
|
+
{
|
|
151
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStart.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStart.length+pParserState.Pattern.PatternEnd.length)), pData);
|
|
152
|
+
// Flush the output buffer.
|
|
153
|
+
this.flushOutputBuffer(pParserState);
|
|
154
|
+
// End pattern mode
|
|
155
|
+
pParserState.Pattern = false;
|
|
156
|
+
pParserState.PatternMatch = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return fCallback();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Parse a character in the buffer.
|
|
165
|
+
* @method parseCharacter
|
|
166
|
+
* @param {string} pCharacter - The character to append
|
|
167
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
parseCharacter (pCharacter, pParserState, pData)
|
|
171
|
+
{
|
|
172
|
+
// (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....
|
|
173
|
+
if (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))
|
|
174
|
+
{
|
|
175
|
+
// ... assign the node as the matched node.
|
|
176
|
+
this.assignNode(pParserState.ParseTree[pCharacter], pParserState);
|
|
177
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
178
|
+
}
|
|
179
|
+
// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)
|
|
180
|
+
else if (pParserState.PatternMatch)
|
|
181
|
+
{
|
|
182
|
+
// If the pattern has a subpattern with this key
|
|
183
|
+
if (pParserState.PatternMatch.hasOwnProperty(pCharacter))
|
|
184
|
+
{
|
|
185
|
+
// Continue matching patterns.
|
|
186
|
+
this.assignNode(pParserState.PatternMatch[pCharacter], pParserState);
|
|
187
|
+
}
|
|
188
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
189
|
+
if (pParserState.Pattern)
|
|
190
|
+
{
|
|
191
|
+
// ... Check if this is the end of the pattern (if we are matching a valid pattern)...
|
|
192
|
+
this.checkPatternEnd(pParserState, pData);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
196
|
+
else
|
|
197
|
+
{
|
|
198
|
+
pParserState.Output += pCharacter;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
parseCharacterAsync (pCharacter, pParserState, pData, fCallback)
|
|
203
|
+
{
|
|
204
|
+
// (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....
|
|
205
|
+
if (!pParserState.PatternMatch && pParserState.ParseTree.hasOwnProperty(pCharacter))
|
|
206
|
+
{
|
|
207
|
+
// ... assign the node as the matched node.
|
|
208
|
+
this.assignNode(pParserState.ParseTree[pCharacter], pParserState);
|
|
209
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
210
|
+
}
|
|
211
|
+
// (2) If we are in a pattern match (actively seeing if this is part of a new pattern token)
|
|
212
|
+
else if (pParserState.PatternMatch)
|
|
213
|
+
{
|
|
214
|
+
// If the pattern has a subpattern with this key
|
|
215
|
+
if (pParserState.PatternMatch.hasOwnProperty(pCharacter))
|
|
216
|
+
{
|
|
217
|
+
// Continue matching patterns.
|
|
218
|
+
this.assignNode(pParserState.PatternMatch[pCharacter], pParserState);
|
|
219
|
+
}
|
|
220
|
+
this.appendOutputBuffer(pCharacter, pParserState);
|
|
221
|
+
if (pParserState.Pattern)
|
|
222
|
+
{
|
|
223
|
+
// ... Check if this is the end of the pattern (if we are matching a valid pattern)...
|
|
224
|
+
return this.checkPatternEndAsync(pParserState, pData, fCallback);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// (3) If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
228
|
+
else
|
|
229
|
+
{
|
|
230
|
+
pParserState.Output += pCharacter;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return fCallback(null);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Parse a string for matches, and process any template segments that occur.
|
|
238
|
+
* @method parseString
|
|
239
|
+
* @param {string} pString - The string to parse.
|
|
240
|
+
* @param {Object} pParseTree - The parse tree to begin parsing from (usually root)
|
|
241
|
+
* @param {Object} pData - The data to pass to the function as a second parameter
|
|
242
|
+
* @param {function} fCallback - The callback function to call when the parse is complete
|
|
243
|
+
*/
|
|
244
|
+
parseString (pString, pParseTree, pData, fCallback)
|
|
245
|
+
{
|
|
246
|
+
if (typeof(fCallback) !== 'function')
|
|
247
|
+
{
|
|
248
|
+
let tmpParserState = this.newParserState(pParseTree);
|
|
249
|
+
|
|
250
|
+
for (var i = 0; i < pString.length; i++)
|
|
251
|
+
{
|
|
252
|
+
// TODO: This is not fast.
|
|
253
|
+
this.parseCharacter(pString[i], tmpParserState, pData, fCallback);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
this.flushOutputBuffer(tmpParserState);
|
|
257
|
+
|
|
258
|
+
return tmpParserState.Output;
|
|
259
|
+
}
|
|
260
|
+
else
|
|
261
|
+
{
|
|
262
|
+
// This is the async mode
|
|
263
|
+
let tmpParserState = this.newParserState(pParseTree);
|
|
264
|
+
|
|
265
|
+
this.eachLimit(pString, 1,
|
|
266
|
+
(pCharacter, fCharacterCallback) =>
|
|
267
|
+
{
|
|
268
|
+
this.parseCharacterAsync(pCharacter, tmpParserState, pData, fCharacterCallback);
|
|
269
|
+
},
|
|
270
|
+
(pError) =>
|
|
271
|
+
{
|
|
272
|
+
// Flush the remaining data
|
|
273
|
+
this.flushOutputBuffer(tmpParserState);
|
|
274
|
+
fCallback(pError, tmpParserState.Output);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
module.exports = StringParser;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetaTemplate Word Tree
|
|
3
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
4
|
+
* @description Create a tree (directed graph) of Javascript objects, one character per object.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
class WordTree
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* WordTree Constructor
|
|
11
|
+
*/
|
|
12
|
+
constructor()
|
|
13
|
+
{
|
|
14
|
+
this.ParseTree = {};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Add a child character to a Parse Tree node
|
|
19
|
+
* @method addChild
|
|
20
|
+
* @param {Object} pTree - A parse tree to push the characters into
|
|
21
|
+
* @param {string} pPattern - The string to add to the tree
|
|
22
|
+
* @param {number} pIndex - The index of the character in the pattern
|
|
23
|
+
* @returns {Object} The resulting leaf node that was added (or found)
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
addChild (pTree, pPattern, pIndex)
|
|
27
|
+
{
|
|
28
|
+
if (!pTree.hasOwnProperty(pPattern[pIndex]))
|
|
29
|
+
pTree[pPattern[pIndex]] = {};
|
|
30
|
+
|
|
31
|
+
return pTree[pPattern[pIndex]];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Add a Pattern to the Parse Tree
|
|
35
|
+
* @method addPattern
|
|
36
|
+
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
37
|
+
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
38
|
+
* @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.
|
|
39
|
+
* @return {bool} True if adding the pattern was successful
|
|
40
|
+
*/
|
|
41
|
+
addPattern (pPatternStart, pPatternEnd, pParser)
|
|
42
|
+
{
|
|
43
|
+
if (pPatternStart.length < 1)
|
|
44
|
+
return false;
|
|
45
|
+
|
|
46
|
+
if ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))
|
|
47
|
+
return false;
|
|
48
|
+
|
|
49
|
+
let tmpLeaf = this.ParseTree;
|
|
50
|
+
|
|
51
|
+
// Add the tree of leaves iteratively
|
|
52
|
+
for (var i = 0; i < pPatternStart.length; i++)
|
|
53
|
+
tmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);
|
|
54
|
+
|
|
55
|
+
tmpLeaf.PatternStart = pPatternStart;
|
|
56
|
+
tmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;
|
|
57
|
+
tmpLeaf.Parse = (typeof(pParser) === 'function') ? pParser :
|
|
58
|
+
(typeof(pParser) === 'string') ? () => { return pParser; } :
|
|
59
|
+
(pData) => { return pData; };
|
|
60
|
+
tmpLeaf.isPromise = false;
|
|
61
|
+
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Add a Pattern to the Parse Tree (asynchronous)
|
|
66
|
+
* @method addPattern
|
|
67
|
+
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
68
|
+
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
69
|
+
* @param {number} pParserAsync - The function (with an asynchronous callback) to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
70
|
+
* @return {bool} True if adding the pattern was successful
|
|
71
|
+
*/
|
|
72
|
+
addPatternAsync (pPatternStart, pPatternEnd, pParserAsync)
|
|
73
|
+
{
|
|
74
|
+
if (pPatternStart.length < 1)
|
|
75
|
+
return false;
|
|
76
|
+
|
|
77
|
+
if ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length < 1))
|
|
78
|
+
return false;
|
|
79
|
+
|
|
80
|
+
let tmpLeaf = this.ParseTree;
|
|
81
|
+
|
|
82
|
+
// Add the tree of leaves iteratively
|
|
83
|
+
for (var i = 0; i < pPatternStart.length; i++)
|
|
84
|
+
tmpLeaf = this.addChild(tmpLeaf, pPatternStart, i);
|
|
85
|
+
|
|
86
|
+
tmpLeaf.PatternStart = pPatternStart;
|
|
87
|
+
tmpLeaf.PatternEnd = ((typeof(pPatternEnd) === 'string') && (pPatternEnd.length > 0)) ? pPatternEnd : pPatternStart;
|
|
88
|
+
tmpLeaf.Parse = (typeof(pParserAsync) === 'function') ? pParserAsync :
|
|
89
|
+
(typeof(pParserAsync) === 'string') ? (pHash, pData, fCallback) => { fCallback(pParserPromise); } :
|
|
90
|
+
(pHash, pData, fCallback) => { return fCallback(pHash); };
|
|
91
|
+
tmpLeaf.isAsync = true;
|
|
92
|
+
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = WordTree;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
const libFableServiceBase = require('../Fable-ServiceManager.js').ServiceProviderBase;
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Precedent Meta-Templating
|
|
5
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
6
|
+
* @description Process text stream trie and postfix tree, parsing out meta-template expression functions.
|
|
7
|
+
*/
|
|
8
|
+
const libWordTree = require(`./Fable-Service-MetaTemplate/MetaTemplate-WordTree.js`);
|
|
9
|
+
const libStringParser = require(`./Fable-Service-MetaTemplate/MetaTemplate-StringParser.js`);
|
|
10
|
+
|
|
4
11
|
|
|
5
12
|
class FableServiceMetaTemplate extends libFableServiceBase
|
|
6
13
|
{
|
|
@@ -10,9 +17,15 @@ class FableServiceMetaTemplate extends libFableServiceBase
|
|
|
10
17
|
|
|
11
18
|
this.serviceType = 'MetaTemplate';
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
this.WordTree = new libWordTree();
|
|
21
|
+
|
|
22
|
+
// In order to allow asynchronous template processing we need to use the async.eachLimit function
|
|
23
|
+
this.StringParser = new libStringParser(this.fable.defaultServices.Utility.eachLimit);
|
|
24
|
+
|
|
25
|
+
this.ParseTree = this.WordTree.ParseTree;
|
|
14
26
|
}
|
|
15
27
|
|
|
28
|
+
|
|
16
29
|
/**
|
|
17
30
|
* Add a Pattern to the Parse Tree
|
|
18
31
|
* @method addPattern
|
|
@@ -23,23 +36,24 @@ class FableServiceMetaTemplate extends libFableServiceBase
|
|
|
23
36
|
*/
|
|
24
37
|
addPattern(pPatternStart, pPatternEnd, pParser)
|
|
25
38
|
{
|
|
26
|
-
return this.
|
|
39
|
+
return this.WordTree.addPattern(pPatternStart, pPatternEnd, pParser);
|
|
27
40
|
}
|
|
28
41
|
|
|
29
|
-
addPatternAsync(pPatternStart, pPatternEnd,
|
|
42
|
+
addPatternAsync(pPatternStart, pPatternEnd, pParserPromise)
|
|
30
43
|
{
|
|
31
|
-
return this.
|
|
44
|
+
return this.WordTree.addPatternAsync(pPatternStart, pPatternEnd, pParserPromise);
|
|
32
45
|
}
|
|
33
46
|
|
|
34
47
|
/**
|
|
35
48
|
* Parse a string with the existing parse tree
|
|
36
49
|
* @method parseString
|
|
37
50
|
* @param {string} pString - The string to parse
|
|
51
|
+
* @param {object} pData - Data to pass in as the second argument
|
|
38
52
|
* @return {string} The result from the parser
|
|
39
53
|
*/
|
|
40
54
|
parseString(pString, pData, fCallback)
|
|
41
55
|
{
|
|
42
|
-
return this.
|
|
56
|
+
return this.StringParser.parseString(pString, this.ParseTree, pData, fCallback);
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
|
|
@@ -13,20 +13,13 @@ class FableOperation extends libFableServiceBase
|
|
|
13
13
|
|
|
14
14
|
this.state = JSON.parse(_OperationStatePrototypeString);
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
// Match the service instantiation to the operation.
|
|
17
17
|
this.state.Metadata.Hash = this.Hash;
|
|
18
|
+
this.state.Metadata.UUID = this.UUID;
|
|
18
19
|
|
|
19
|
-
this.name = (typeof(this.options.Name) == 'string') ? this.options.Name : `Unnamed Operation ${this.state.Metadata.
|
|
20
|
-
}
|
|
20
|
+
this.name = (typeof(this.options.Name) == 'string') ? this.options.Name : `Unnamed Operation ${this.state.Metadata.UUID}`;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
return this.state.Metadata.GUID;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get log()
|
|
28
|
-
{
|
|
29
|
-
return this;
|
|
22
|
+
this.log = this;
|
|
30
23
|
}
|
|
31
24
|
|
|
32
25
|
writeOperationLog(pLogLevel, pLogText, pLogObject)
|