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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fable",
3
- "version": "3.0.72",
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.14"
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
- fCallback(pCreateError);
188
- return false;
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;
@@ -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
- 'Fable RestClient',
19
- function()
20
- {
21
- setup
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
- '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');
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
- test
25
+
26
+ suite
52
27
  (
53
- 'Perform a POST request.',
54
- function(fTestComplete)
28
+ 'Basic Requests',
29
+ function ()
55
30
  {
56
- let testFable = new libFable();
57
- // Instantiate the RestClient Service Provider
58
- let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', {TraceLog: true}, 'RestClient-99');
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
- tmpRestClient.prepareRequestOptions = (pOptions) =>
61
- {
62
- pOptions.headers = {'Content-Type':'application/json'};
63
- return pOptions;
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
- // 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
- '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
- // Download the wiktionary entry for dog!
87
- tmpRestClient.putJSON({url: 'http://localhost:8086/1.0/Author/Upsert', body:{GUIDAuthor:'TestAuthor', Name:'Test Author 2'}},
88
- (pError, pResponse, pBody)=>
89
- {
90
- Expect(pBody).to.be.an('object');
91
- Expect(pBody.hasOwnProperty('Name')).to.equal(true);
92
- Expect(pBody.Name).to.equal('Test Author 2');
93
- fTestComplete();
94
- });
95
- }
96
- );
97
- test
98
- (
99
- 'Perform an UPSERT request then a DELETE.',
100
- function(fTestComplete)
101
- {
102
- let testFable = new libFable();
103
- // Instantiate the RestClient Service Provider
104
- let tmpRestClient = testFable.serviceManager.instantiateServiceProvider('RestClient', {TraceLog: true}, 'RestClient-99');
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
- // Download the wiktionary entry for dog!
107
- tmpRestClient.putJSON({url: 'http://localhost:8086/1.0/Author/Upsert', body:{Name:'Test Author 2 DELETE'}},
108
- (pError, pResponse, pBody)=>
109
- {
110
- Expect(pBody).to.be.an('object');
111
- Expect(pBody.hasOwnProperty('Name')).to.equal(true);
112
- Expect(pBody.Name).to.equal('Test Author 2 DELETE');
113
- tmpRestClient.delJSON({url: `http://localhost:8086/1.0/Author/${pBody.IDAuthor}`},
114
- (pDeleteError, pDeleteResponse, pDeleteBody) =>
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
- Expect(pDeleteBody.Count)
117
- .to.equal(1);
118
- fTestComplete();
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
+ );
@@ -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>');