fable 3.0.72 → 3.0.74
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/dist/fable.compatible.js +24 -23
- package/dist/fable.compatible.min.js +2 -2
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +15 -14
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/package.json +2 -2
- package/source/services/Fable-Service-FilePersistence.js +8 -4
- package/source/services/Fable-Service-RestClient.js +66 -0
- package/test/RestClient_test.js +120 -99
- package/test/Utility_tests.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fable",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.74",
|
|
4
4
|
"description": "An entity behavior management and API bundling library.",
|
|
5
5
|
"main": "source/Fable.js",
|
|
6
6
|
"scripts": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"homepage": "https://github.com/stevenvelozo/fable",
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"quackage": "^1.0.
|
|
52
|
+
"quackage": "^1.0.19"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"async.eachlimit": "^0.5.2",
|
|
@@ -158,8 +158,7 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
158
158
|
// Check if the path is fully complete
|
|
159
159
|
if (tmpParameters.CurrentPathIndex >= tmpParameters.ActualPathParts.length)
|
|
160
160
|
{
|
|
161
|
-
fCallback(null);
|
|
162
|
-
return true;
|
|
161
|
+
return fCallback(null);
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
// Check if the path exists (and is a folder)
|
|
@@ -182,10 +181,15 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
182
181
|
// We have now created our folder and there was no error -- continue.
|
|
183
182
|
return this.makeFolderRecursive(tmpParameters, fCallback);
|
|
184
183
|
}
|
|
184
|
+
else if (pCreateError.code =='EEXIST')
|
|
185
|
+
{
|
|
186
|
+
// The folder exists -- our dev might be running this in parallel/async/whatnot.
|
|
187
|
+
return this.makeFolderRecursive(tmpParameters, fCallback);
|
|
188
|
+
}
|
|
185
189
|
else
|
|
186
190
|
{
|
|
187
|
-
|
|
188
|
-
return
|
|
191
|
+
console.log(pCreateError.code);
|
|
192
|
+
return fCallback(pCreateError);
|
|
189
193
|
}
|
|
190
194
|
});
|
|
191
195
|
}
|
|
@@ -26,6 +26,11 @@ class FableServiceRestClient extends libFableServiceBase
|
|
|
26
26
|
this.prepareRequestOptions = (pOptions) => { return pOptions; };
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
get simpleGet()
|
|
30
|
+
{
|
|
31
|
+
return libSimpleGet;
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
prepareCookies(pRequestOptions)
|
|
30
35
|
{
|
|
31
36
|
if (this.cookie)
|
|
@@ -102,6 +107,67 @@ class FableServiceRestClient extends libFableServiceBase
|
|
|
102
107
|
});
|
|
103
108
|
}
|
|
104
109
|
|
|
110
|
+
executeChunkedRequestBinary(pOptions, fCallback)
|
|
111
|
+
{
|
|
112
|
+
let tmpOptions = this.preRequest(pOptions);
|
|
113
|
+
|
|
114
|
+
tmpOptions.RequestStartTime = this.fable.log.getTimeStamp();
|
|
115
|
+
|
|
116
|
+
if (this.TraceLog)
|
|
117
|
+
{
|
|
118
|
+
this.fable.log.debug(`Beginning ${tmpOptions.method} request to ${tmpOptions.url} at ${tmpOptions.RequestStartTime}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
tmpOptions.json = false;
|
|
122
|
+
tmpOptions.encoding = null;
|
|
123
|
+
|
|
124
|
+
return libSimpleGet(tmpOptions,
|
|
125
|
+
(pError, pResponse)=>
|
|
126
|
+
{
|
|
127
|
+
if (pError)
|
|
128
|
+
{
|
|
129
|
+
return fCallback(pError, pResponse);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (this.TraceLog)
|
|
133
|
+
{
|
|
134
|
+
let tmpConnectTime = this.fable.log.getTimeStamp();
|
|
135
|
+
this.fable.log.debug(`--> ${tmpOptions.method} connected in ${this.dataFormat.formatTimeDelta(tmpOptions.RequestStartTime, tmpConnectTime)}ms code ${pResponse.statusCode}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
let tmpDataBuffer = false;
|
|
139
|
+
|
|
140
|
+
pResponse.on('data', (pChunk) =>
|
|
141
|
+
{
|
|
142
|
+
// For JSON, the chunk is the serialized object.
|
|
143
|
+
if (this.TraceLog)
|
|
144
|
+
{
|
|
145
|
+
let tmpChunkTime = this.fable.log.getTimeStamp();
|
|
146
|
+
this.fable.log.debug(`--> ${tmpOptions.method} data chunk size ${pChunk.length}b received in ${this.dataFormat.formatTimeDelta(tmpOptions.RequestStartTime, tmpChunkTime)}ms`);
|
|
147
|
+
}
|
|
148
|
+
// TODO: Potentially create a third option that streams this to a file? So it doesn't have to hold it all in memory.
|
|
149
|
+
if (!tmpDataBuffer)
|
|
150
|
+
{
|
|
151
|
+
tmpDataBuffer = Buffer.from(pChunk);
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
{
|
|
155
|
+
tmpDataBuffer = Buffer.concat([tmpDataBuffer, pChunk]);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
pResponse.on('end', ()=>
|
|
160
|
+
{
|
|
161
|
+
if (this.TraceLog)
|
|
162
|
+
{
|
|
163
|
+
let tmpCompletionTime = this.fable.log.getTimeStamp();
|
|
164
|
+
this.fable.log.debug(`==> ${tmpOptions.method} completed data size ${tmpDataBuffer.length}b received in ${this.dataFormat.formatTimeDelta(tmpOptions.RequestStartTime, tmpCompletionTime)}ms`);
|
|
165
|
+
}
|
|
166
|
+
return fCallback(pError, pResponse, tmpDataBuffer);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
105
171
|
executeJSONRequest(pOptions, fCallback)
|
|
106
172
|
{
|
|
107
173
|
pOptions.json = true;
|
package/test/RestClient_test.js
CHANGED
|
@@ -14,113 +14,134 @@ var Expect = Chai.expect;
|
|
|
14
14
|
// https://en.wiktionary.org/w/api.php?action=parse&prop=wikitext&format=json&page=dog
|
|
15
15
|
|
|
16
16
|
suite
|
|
17
|
-
(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
(
|
|
23
|
-
function() { }
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
suite
|
|
27
|
-
(
|
|
28
|
-
'Basic Requests',
|
|
29
|
-
function()
|
|
30
|
-
{
|
|
31
|
-
test
|
|
17
|
+
(
|
|
18
|
+
'Fable RestClient',
|
|
19
|
+
function ()
|
|
20
|
+
{
|
|
21
|
+
setup
|
|
32
22
|
(
|
|
33
|
-
|
|
34
|
-
function(fTestComplete)
|
|
35
|
-
{
|
|
36
|
-
let testFable = new libFable();
|
|
37
|
-
// Instantiate the RestClient Service Provider
|
|
38
|
-
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', {TraceLog: true}, 'RestClient-99');
|
|
39
|
-
|
|
40
|
-
// Download the wiktionary entry for dog!
|
|
41
|
-
tmpRestClient.getJSON('http://localhost:8086/1.0/Author/1',
|
|
42
|
-
(pError, pResponse, pBody)=>
|
|
43
|
-
{
|
|
44
|
-
Expect(pBody).to.be.an('object');
|
|
45
|
-
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
46
|
-
Expect(pBody.Name).to.equal('John Green');
|
|
47
|
-
fTestComplete();
|
|
48
|
-
});
|
|
49
|
-
}
|
|
23
|
+
function () { }
|
|
50
24
|
);
|
|
51
|
-
|
|
25
|
+
|
|
26
|
+
suite
|
|
52
27
|
(
|
|
53
|
-
'
|
|
54
|
-
function(
|
|
28
|
+
'Basic Requests',
|
|
29
|
+
function ()
|
|
55
30
|
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
31
|
+
test
|
|
32
|
+
(
|
|
33
|
+
'Perform a GET request.',
|
|
34
|
+
function (fTestComplete)
|
|
35
|
+
{
|
|
36
|
+
let testFable = new libFable();
|
|
37
|
+
// Instantiate the RestClient Service Provider
|
|
38
|
+
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', { TraceLog: true }, 'RestClient-99');
|
|
59
39
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
40
|
+
// Download the wiktionary entry for dog!
|
|
41
|
+
tmpRestClient.getJSON('http://localhost:8086/1.0/Author/1',
|
|
42
|
+
(pError, pResponse, pBody) =>
|
|
43
|
+
{
|
|
44
|
+
Expect(pBody).to.be.an('object');
|
|
45
|
+
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
46
|
+
Expect(pBody.Name).to.equal('John Green');
|
|
47
|
+
fTestComplete();
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
test
|
|
52
|
+
(
|
|
53
|
+
'Perform a POST request.',
|
|
54
|
+
function (fTestComplete)
|
|
55
|
+
{
|
|
56
|
+
let testFable = new libFable();
|
|
57
|
+
// Instantiate the RestClient Service Provider
|
|
58
|
+
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', { TraceLog: true }, 'RestClient-99');
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
72
|
-
Expect(pBody.Name).to.equal('Test Author');
|
|
73
|
-
fTestComplete();
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
);
|
|
77
|
-
test
|
|
78
|
-
(
|
|
79
|
-
'Perform a PUT request.',
|
|
80
|
-
function(fTestComplete)
|
|
81
|
-
{
|
|
82
|
-
let testFable = new libFable();
|
|
83
|
-
// Instantiate the RestClient Service Provider
|
|
84
|
-
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', {TraceLog: true}, 'RestClient-99');
|
|
60
|
+
tmpRestClient.prepareRequestOptions = (pOptions) =>
|
|
61
|
+
{
|
|
62
|
+
pOptions.headers = { 'Content-Type': 'application/json' };
|
|
63
|
+
return pOptions;
|
|
64
|
+
};
|
|
85
65
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
66
|
+
// Download the wiktionary entry for dog!
|
|
67
|
+
tmpRestClient.postJSON({ url: 'http://localhost:8086/1.0/Author', body: { Name: 'Test Author' } },
|
|
68
|
+
(pError, pResponse, pBody) =>
|
|
69
|
+
{
|
|
70
|
+
Expect(pBody).to.be.an('object');
|
|
71
|
+
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
72
|
+
Expect(pBody.Name).to.equal('Test Author');
|
|
73
|
+
fTestComplete();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
test
|
|
78
|
+
(
|
|
79
|
+
'Get a binary file.',
|
|
80
|
+
function (fTestComplete)
|
|
81
|
+
{
|
|
82
|
+
let testFable = new libFable();
|
|
83
|
+
// Instantiate the RestClient Service Provider
|
|
84
|
+
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', { TraceLog: true }, 'RestClient-99');
|
|
85
|
+
|
|
86
|
+
// Download the wiktionary entry for dog!
|
|
87
|
+
tmpRestClient.executeChunkedRequestBinary({ url: 'http://localhost:8086/1.0/Author/1', method: 'GET' },
|
|
88
|
+
(pError, pResponse, pBuffer) =>
|
|
89
|
+
{
|
|
90
|
+
Expect(pBuffer).to.be.instanceof(Buffer);
|
|
91
|
+
testFable.serviceManager.instantiateServiceProvider('FilePersistence');
|
|
92
|
+
// TODO: How to test this on all operating systems safely?
|
|
93
|
+
//testFable.FilePersistence.writeFileSync(`/tmp/RestClient_binary_test.jpg`, pBuffer);
|
|
94
|
+
fTestComplete();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
test
|
|
99
|
+
(
|
|
100
|
+
'Perform a PUT request.',
|
|
101
|
+
function (fTestComplete)
|
|
102
|
+
{
|
|
103
|
+
let testFable = new libFable();
|
|
104
|
+
// Instantiate the RestClient Service Provider
|
|
105
|
+
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', { TraceLog: true }, 'RestClient-99');
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
// Download the wiktionary entry for dog!
|
|
108
|
+
tmpRestClient.putJSON({ url: 'http://localhost:8086/1.0/Author/Upsert', body: { GUIDAuthor: 'TestAuthor', Name: 'Test Author 2' } },
|
|
109
|
+
(pError, pResponse, pBody) =>
|
|
110
|
+
{
|
|
111
|
+
Expect(pBody).to.be.an('object');
|
|
112
|
+
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
113
|
+
Expect(pBody.Name).to.equal('Test Author 2');
|
|
114
|
+
fTestComplete();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
test
|
|
119
|
+
(
|
|
120
|
+
'Perform an UPSERT request then a DELETE.',
|
|
121
|
+
function (fTestComplete)
|
|
115
122
|
{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
123
|
+
let testFable = new libFable();
|
|
124
|
+
// Instantiate the RestClient Service Provider
|
|
125
|
+
let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', { TraceLog: true }, 'RestClient-99');
|
|
126
|
+
|
|
127
|
+
// Download the wiktionary entry for dog!
|
|
128
|
+
tmpRestClient.putJSON({ url: 'http://localhost:8086/1.0/Author/Upsert', body: { Name: 'Test Author 2 DELETE' } },
|
|
129
|
+
(pError, pResponse, pBody) =>
|
|
130
|
+
{
|
|
131
|
+
Expect(pBody).to.be.an('object');
|
|
132
|
+
Expect(pBody.hasOwnProperty('Name')).to.equal(true);
|
|
133
|
+
Expect(pBody.Name).to.equal('Test Author 2 DELETE');
|
|
134
|
+
tmpRestClient.delJSON({ url: `http://localhost:8086/1.0/Author/${pBody.IDAuthor}` },
|
|
135
|
+
(pDeleteError, pDeleteResponse, pDeleteBody) =>
|
|
136
|
+
{
|
|
137
|
+
Expect(pDeleteBody.Count)
|
|
138
|
+
.to.equal(1);
|
|
139
|
+
fTestComplete();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
);
|
|
121
144
|
}
|
|
122
145
|
);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
);
|
|
146
|
+
}
|
|
147
|
+
);
|
package/test/Utility_tests.js
CHANGED
|
@@ -85,7 +85,7 @@ suite
|
|
|
85
85
|
testFable = new libFable();
|
|
86
86
|
testFable.services.Utility.buildHashedTemplate('HeadLine', '<h1><%= TitleText %> Page</h1>');
|
|
87
87
|
testFable.services.Utility.buildHashedTemplate('Slogan', '<p>Some people, like <%= Name %>, have all the fun.</p>');
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
// Access the low level service render function
|
|
90
90
|
Expect(testFable.servicesMap.Template.HeadLine.renderFunction({TitleText:'Test'})).to.equal('<h1>Test Page</h1>');
|
|
91
91
|
Expect(testFable.servicesMap.Template.Slogan.renderFunction({Name:'Jim'})).to.equal('<p>Some people, like Jim, have all the fun.</p>');
|