orator 4.0.2 → 5.0.0

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.
@@ -12,6 +12,7 @@
12
12
  "skipFiles": [
13
13
  "<node_internals>/**"
14
14
  ],
15
+ "cwd": "${workspaceFolder}/debug/",
15
16
  "program": "${workspaceFolder}/debug/Harness.js",
16
17
  "presentation": {
17
18
  "hidden": false,
package/debug/Harness.js CHANGED
@@ -13,9 +13,11 @@ let _Fable = new libFable({
13
13
  // > make sure to run "npm i orator-serviceserver-restify" from the parent directory first so the package is available
14
14
  // > please don't --save it!
15
15
  // _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer', require('orator-serviceserver-restify'));
16
- //const libOratorServiceServerRestify = require('orator-serviceserver-restify');
16
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
17
+ _Fable.serviceManager.addAndInstantiateServiceType('OratorServiceServer', libOratorServiceServerRestify);
17
18
 
18
- _Fable.serviceManager.addAndInitializeServiceType('Orator', libOrator);
19
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
20
+ const tmpServiceServer = _Fable.serviceManager.instantiateServiceProvider('Orator');
19
21
 
20
22
  // Start the service
21
23
  tmpServiceServer.startService();
@@ -39,4 +41,6 @@ tmpServiceServer.invoke('GET', tmpURI, null,
39
41
  (pError, pResponseData) =>
40
42
  {
41
43
  tmpServiceServer.log.info(`Response to [${tmpURI}] came back from IPC resulting in [${pResponseData}]!`)
42
- });
44
+ });
45
+
46
+ tmpServiceServer.addStaticRoute('site', 'Test.html', '/*', '/');
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "orator-debug-server",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "Harness.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "orator-serviceserver-restify": "^2.0.3"
13
+ }
14
+ }
@@ -1 +1 @@
1
- <html><head></head><body>Um</body></html>
1
+ <html><head></head><body>Umm</body></html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "orator",
3
- "version": "4.0.2",
4
- "description": "Unopinionated API behavior container - REST or IPC",
3
+ "version": "5.0.0",
4
+ "description": "Unopinionated API http server abstraction - REST or IPC",
5
5
  "main": "source/Orator.js",
6
6
  "scripts": {
7
7
  "start": "node source/Orator.js",
@@ -51,12 +51,14 @@
51
51
  },
52
52
  "homepage": "https://github.com/stevenvelozo/orator",
53
53
  "devDependencies": {
54
- "fable": "^3.0.96",
55
- "quackage": "^1.0.24"
54
+ "fable": "^3.0.143",
55
+ "quackage": "^1.0.33"
56
56
  },
57
57
  "dependencies": {
58
- "fable-serviceproviderbase": "^3.0.12",
59
- "find-my-way": "^7.7.0",
60
- "orator-serviceserver-base": "^1.0.0"
58
+ "fable-serviceproviderbase": "^3.0.13",
59
+ "finalhandler": "^1.2.0",
60
+ "find-my-way": "^8.2.0",
61
+ "orator-serviceserver-base": "^1.0.1",
62
+ "serve-static": "^1.15.0"
61
63
  }
62
64
  }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Represents a synthesized server response for the Orator service server IPC.
3
+ *
4
+ * @class
5
+ */
1
6
  class OratorServiceServerIPCSynthesizedResponse
2
7
  {
3
8
  constructor(pHandler, pLog, pRequestGUID)
@@ -27,6 +32,12 @@ class OratorServiceServerIPCSynthesizedResponse
27
32
  this.responseStatus = -1;
28
33
  }
29
34
 
35
+ /**
36
+ * Sends data to the server.
37
+ *
38
+ * @param {string|object} pData - The data to be sent. It can be either a string or an object.
39
+ * @returns {boolean} - Returns true if the data was successfully sent, false otherwise.
40
+ */
30
41
  send(pData)
31
42
  {
32
43
  if (typeof(pData) == 'string')
@@ -6,6 +6,13 @@ const libOratorServiceServerIPCSynthesizedResponse = require('./Orator-ServiceSe
6
6
  // This library is the default router for our services
7
7
  const libFindMyWay = require('find-my-way');
8
8
 
9
+ /**
10
+ * OratorServiceServerIPC class.
11
+ *
12
+ * @class
13
+ * @extends libOratorServiceServerBase
14
+ * @classdesc Represents an IPC service server for Orator.
15
+ */
9
16
  class OratorServiceServerIPC extends libOratorServiceServerBase
10
17
  {
11
18
  constructor(pFable, pOptions, pServiceHash)
@@ -183,36 +190,85 @@ class OratorServiceServerIPC extends libOratorServiceServerBase
183
190
  };
184
191
  }
185
192
 
193
+ /**
194
+ * Handles the HTTP GET request for a specific route.
195
+ *
196
+ * @param {string} pRoute - The route to handle.
197
+ * @param {...Function} fRouteProcessingFunctions - The processing functions to execute for the route.
198
+ * @returns {Promise} A promise that resolves when the route processing is complete.
199
+ */
186
200
  doGet(pRoute, ...fRouteProcessingFunctions)
187
201
  {
188
202
  return this.addRouteProcessor('GET', pRoute, Array.from(fRouteProcessingFunctions));
189
203
  }
190
204
 
205
+ /**
206
+ * Handles the PUT request for a specific route.
207
+ *
208
+ * @param {string} pRoute - The route to handle.
209
+ * @param {...Function} fRouteProcessingFunctions - The processing functions to execute for the route.
210
+ * @returns {Promise} - A promise that resolves when the route processing is complete.
211
+ */
191
212
  doPut(pRoute, ...fRouteProcessingFunctions)
192
213
  {
193
214
  return this.addRouteProcessor('PUT', pRoute, Array.from(fRouteProcessingFunctions));
194
215
  }
195
216
 
217
+ /**
218
+ * Handles the HTTP POST request for a specific route.
219
+ *
220
+ * @param {string} pRoute - The route to handle.
221
+ * @param {...Function} fRouteProcessingFunctions - The processing functions to execute for the route.
222
+ * @returns {Promise} - A promise that resolves when the route processing is complete.
223
+ */
196
224
  doPost(pRoute, ...fRouteProcessingFunctions)
197
225
  {
198
226
  return this.addRouteProcessor('POST', pRoute, Array.from(fRouteProcessingFunctions));
199
227
  }
200
228
 
229
+ /**
230
+ * Handles the HTTP DEL request for a specific route.
231
+ *
232
+ * @param {string} pRoute - The route to be deleted.
233
+ * @param {...Function} fRouteProcessingFunctions - The route processing functions to be added.
234
+ * @returns {Object} - The updated route processor object.
235
+ */
201
236
  doDel(pRoute, ...fRouteProcessingFunctions)
202
237
  {
203
238
  return this.addRouteProcessor('DELETE', pRoute, Array.from(fRouteProcessingFunctions));
204
239
  }
205
240
 
241
+ /**
242
+ * Adds a PATCH route processor to the service server.
243
+ *
244
+ * @param {string} pRoute - The route to be processed.
245
+ * @param {...Function} fRouteProcessingFunctions - The route processing functions.
246
+ * @returns {boolean} - Returns true if the route processor was added successfully, false otherwise.
247
+ */
206
248
  doPatch(pRoute, ...fRouteProcessingFunctions)
207
249
  {
208
250
  return this.addRouteProcessor('PATCH', pRoute, Array.from(fRouteProcessingFunctions));
209
251
  }
210
252
 
253
+ /**
254
+ * Adds a route processor for the OPTIONS method.
255
+ *
256
+ * @param {string} pRoute - The route to add the processor to.
257
+ * @param {...Function} fRouteProcessingFunctions - The processing functions to be executed for the route.
258
+ * @returns {Object} - The updated Orator-ServiceServer-IPC object.
259
+ */
211
260
  doOpts(pRoute, ...fRouteProcessingFunctions)
212
261
  {
213
262
  return this.addRouteProcessor('OPTIONS', pRoute, Array.from(fRouteProcessingFunctions));
214
263
  }
215
264
 
265
+ /**
266
+ * Handles the HEAD request for a specific route.
267
+ *
268
+ * @param {string} pRoute - The route to handle.
269
+ * @param {...Function} fRouteProcessingFunctions - The processing functions to execute for the route.
270
+ * @returns {Promise} - A promise that resolves when the route processing is complete.
271
+ */
216
272
  doHead(pRoute, ...fRouteProcessingFunctions)
217
273
  {
218
274
  return this.addRouteProcessor('HEAD', pRoute, Array.from(fRouteProcessingFunctions));
@@ -221,7 +277,15 @@ class OratorServiceServerIPC extends libOratorServiceServerBase
221
277
  * End of Service Route Creation Functions
222
278
  */
223
279
 
224
- // Programmatically invoke a route
280
+ /**
281
+ * Invokes a method on the IPC provider.
282
+ *
283
+ * @param {string} pMethod - The method to invoke.
284
+ * @param {string} pRoute - The route to invoke.
285
+ * @param {any} pData - The data to pass to the method.
286
+ * @param {Function} fCallback - The callback function to handle the response.
287
+ * @throws {Error} Throws an error if invoked without a callback function.
288
+ */
225
289
  invoke(pMethod, pRoute, pData, fCallback)
226
290
  {
227
291
  // If the data is skipped and a callback is parameter 3, do the right thing
package/source/Orator.js CHANGED
@@ -11,8 +11,22 @@ const libFableServiceProviderBase = require('fable-serviceproviderbase');
11
11
 
12
12
  const libDefaultOratorServiceServer = require('./Orator-Default-ServiceServer.js');
13
13
 
14
+ const libServeStatic = require('serve-static');
15
+ const libFinalHandler = require('finalhandler');
16
+ const libMime = require('mime');
17
+
14
18
  const defaultOratorConfiguration = require('./Orator-Default-Configuration.js');
15
19
 
20
+ /**
21
+ * @class Orator
22
+ * @extends libFableServiceProviderBase
23
+ *
24
+ * Represents the Orator service provider.
25
+ *
26
+ * @param {Object} pFable - The Fable instance.
27
+ * @param {Object} pOptions - The options for the Orator service.
28
+ * @param {string} pServiceHash - The hash of the service.
29
+ */
16
30
  class Orator extends libFableServiceProviderBase
17
31
  {
18
32
  constructor(pFable, pOptions, pServiceHash)
@@ -25,11 +39,6 @@ class Orator extends libFableServiceProviderBase
25
39
  this.serviceServer = false;
26
40
  this.serviceServerProvider = false;
27
41
 
28
- if (typeof(pServiceProvider) !== 'undefined')
29
- {
30
- this.serviceServerProvider = pServiceProvider;
31
- }
32
-
33
42
  // Now check to see that the ServicePort is set (this used to be APIServerPort)
34
43
  if (!this.options.hasOwnProperty('ServicePort'))
35
44
  {
@@ -52,6 +61,9 @@ class Orator extends libFableServiceProviderBase
52
61
  }
53
62
  }
54
63
 
64
+ /**
65
+ * Lifecycle event that executes before initializing the service. For overloading.
66
+ */
55
67
  onBeforeInitialize()
56
68
  {
57
69
  if (this.fable.settings.LogNoisiness > 3)
@@ -59,6 +71,11 @@ class Orator extends libFableServiceProviderBase
59
71
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onBeforeInitialize:`);
60
72
  }
61
73
  }
74
+ /**
75
+ * Lifecycle event that executes before initializing the service. For overloading.
76
+ *
77
+ * @param {Function} fNext - The callback function to be called after the actions are executed.
78
+ */
62
79
  onBeforeInitializeAsync(fNext)
63
80
  {
64
81
  this.onBeforeInitialize();
@@ -97,12 +114,20 @@ class Orator extends libFableServiceProviderBase
97
114
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onInitialize:`);
98
115
  }
99
116
  }
117
+ /**
118
+ * Lifecycle event that executes at the moment of initializing the service. For overloading.
119
+ *
120
+ * @param {Function} fNext - The callback function to be executed after initialization.
121
+ */
100
122
  onInitializeAsync(fNext)
101
123
  {
102
124
  this.onInitialize();
103
125
  return fNext();
104
126
  }
105
127
 
128
+ /**
129
+ * Lifecycle event that executes after initializing the service. For overloading.
130
+ */
106
131
  onAfterInitialize()
107
132
  {
108
133
  if (this.fable.settings.LogNoisiness > 3)
@@ -110,12 +135,22 @@ class Orator extends libFableServiceProviderBase
110
135
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onAfterInitialize:`);
111
136
  }
112
137
  }
138
+ /**
139
+ * Lifecycle event that executes after initializing the service. For overloading.
140
+ * @param {Function} fNext - The callback function to be called after executing onAfterInitialize.
141
+ * @returns {Promise} - A promise that resolves when the callback function is called.
142
+ */
113
143
  onAfterInitializeAsync(fNext)
114
144
  {
115
145
  this.onAfterInitialize();
116
146
  return fNext();
117
147
  }
118
148
 
149
+ /**
150
+ * Initializes the Orator instance.
151
+ *
152
+ * @param {Function} fCallback - The callback function to be executed after initialization.
153
+ */
119
154
  initialize(fCallback)
120
155
  {
121
156
  // I hate this -- as long as we want to be "mostly" backwards compatible it needs to do it though
@@ -153,10 +188,22 @@ class Orator extends libFableServiceProviderBase
153
188
  }
154
189
  }
155
190
 
191
+ /**
192
+ * Lifecycle event that executes before starting the service. For overloading.
193
+ *
194
+ * @param {Function} fNext - The function to be executed before starting the service.
195
+ * @returns {Promise} A promise that resolves when the function is completed.
196
+ */
156
197
  onBeforeStartService(fNext)
157
198
  {
158
199
  return fNext();
159
200
  }
201
+ /**
202
+ * Lifecycle event that executes when the service starts. For overloading.
203
+ *
204
+ * @param {Function} fNext - The callback function to be called after the service starts.
205
+ * @returns {Promise} A promise that resolves when the service starts successfully, or rejects with an error.
206
+ */
160
207
  onStartService(fNext)
161
208
  {
162
209
  this.onAfterInitialize();
@@ -170,11 +217,22 @@ class Orator extends libFableServiceProviderBase
170
217
  }
171
218
  );
172
219
  }
220
+ /**
221
+ * Lifecycle event that executes after starting the service. For overloading.
222
+ *
223
+ * @param {Function} fNext - The callback function to be executed after the service starts.
224
+ * @returns {Promise} - A promise that resolves when the callback function is completed.
225
+ */
173
226
  onAfterStartService(fNext)
174
227
  {
175
228
  return fNext();
176
229
  }
177
230
 
231
+ /**
232
+ * Starts the service.
233
+ *
234
+ * @param {Function} fNext - The callback function to be executed after the service has started.
235
+ */
178
236
  startService(fNext)
179
237
  {
180
238
  var tmpNext = (typeof(fNext) === 'function') ? fNext : ()=>{};
@@ -208,6 +266,12 @@ class Orator extends libFableServiceProviderBase
208
266
  });
209
267
  }
210
268
 
269
+ /**
270
+ * Stops the service server.
271
+ *
272
+ * @param {Function} fCallback - The callback function to be executed after the service server is stopped.
273
+ * @returns {void}
274
+ */
211
275
  stopService(fCallback)
212
276
  {
213
277
  var tmpCallback = (typeof(fCallback) === 'function') ? fCallback : ()=>{};
@@ -229,28 +293,51 @@ class Orator extends libFableServiceProviderBase
229
293
  return this.serviceServer.close(tmpCallback);
230
294
  }
231
295
 
296
+ /**
297
+ * Programmatically invokes a method on the service server.
298
+ *
299
+ * @param {string} pMethod - The method to invoke.
300
+ * @param {string} pRoute - The route to invoke.
301
+ * @param {any} pData - The data to send with the invocation.
302
+ * @param {Function} fCallback - The callback function to execute after the invocation.
303
+ * @returns {any} - The result of the invocation.
304
+ */
232
305
  invoke(pMethod, pRoute, pData, fCallback)
233
306
  {
234
307
  //this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} invoking ${pMethod} ${pRoute}`);
235
308
  return this.serviceServer.invoke(pMethod, pRoute, pData, fCallback);
236
309
  }
237
310
 
238
-
239
311
  /*
240
- * Legacy Orator Functions
312
+ * Legacy Orator / Backwards Compatibility Functions
241
313
  *************************************************************************/
314
+ /**
315
+ * Starts the web server.
316
+ *
317
+ * @param {Function} fNext - The callback function to be executed after the web server starts.
318
+ * @returns {Promise} A promise that resolves when the web server has started.
319
+ */
242
320
  startWebServer(fNext)
243
321
  {
244
322
  return this.startService(fNext);
245
323
  }
246
324
 
247
- // For legacy purposes
325
+ /**
326
+ * Stops the web server.
327
+ *
328
+ * @param {Function} fNext - The callback function to be called after the web server is stopped.
329
+ * @returns {Promise} A promise that resolves when the web server is stopped.
330
+ */
248
331
  stopWebServer(fNext)
249
332
  {
250
333
  return this.stopService(fNext);
251
334
  }
252
335
 
253
- // For legacy purposes
336
+ /**
337
+ * Retrieves the web server instance.
338
+ *
339
+ * @returns {WebServer} The web server instance.
340
+ */
254
341
  getWebServer()
255
342
  {
256
343
  // The old behavior was to lazily construct the service the first time
@@ -265,6 +352,85 @@ class Orator extends libFableServiceProviderBase
265
352
  /*************************************************************************
266
353
  * End of Legacy Orator Functions
267
354
  */
355
+
356
+ setMimeHeader(pFileName, pResponse)
357
+ {
358
+ let tmpHeader = libMime.lookup(pFileName);
359
+
360
+ if (!tmpHeader)
361
+ {
362
+ tmpHeader = 'application/octet-stream';
363
+ }
364
+
365
+ pResponse.setHeader('Content-Type', tmpHeader);
366
+ }
367
+
368
+ /**
369
+ * Serve a static folder, optionally with magic subdomain masking.
370
+ *
371
+ * @param {string} pFilePath The path on disk that we are serving files from.
372
+ * @param {string?} pDefaultFile (optional) The default file served if no specific file is requested.
373
+ * @param {string?} pRoute (optional) The route matcher that will be used. Defaults to everything.
374
+ * @param {string?} pRouteStrip (optional) If provided, this prefix will be removed from URL paths before being served.
375
+ * @param {object?} pParams (optional) Additional parameters to pass to serve-static.
376
+ * @return {boolean} true if the handler was successfully installed, otherwise false.
377
+ */
378
+ addStaticRoute(pFilePath, pDefaultFile, pRoute, pRouteStrip, pParams)
379
+ {
380
+ if (typeof(pFilePath) !== 'string')
381
+ {
382
+ this.fable.log.error('A file path must be passed in as part of the server.');
383
+ return false;
384
+ }
385
+
386
+ // Default to just serving from root
387
+ const tmpRoute = (typeof(pRoute) === 'undefined') ? '/*' : pRoute;
388
+ const tmpRouteStrip = (typeof(pRouteStrip) === 'undefined') ? '/' : pRouteStrip;
389
+
390
+ // Default to serving index.html
391
+ const tmpDefaultFile = (typeof(pDefaultFile) === 'undefined') ? 'index.html' : pDefaultFile;
392
+
393
+ this.fable.log.info('Orator mapping static route to files: '+tmpRoute+' ==> '+pFilePath+' '+tmpDefaultFile);
394
+
395
+ // Add the route
396
+ this.serviceServer.get(tmpRoute,
397
+ (pRequest, pResponse, fNext) =>
398
+ {
399
+ // See if there is a magic subdomain put at the beginning of a request.
400
+ // If there is, then we need to see if there is a subfolder and add that to the file path
401
+ let tmpHostSet = pRequest.headers.host.split('.');
402
+ let tmpPotentialSubfolderMagicHost = false;
403
+ let servePath = pFilePath;
404
+ // Check if there are more than one host in the host header (this will be 127 a lot)
405
+ if (tmpHostSet.length > 1)
406
+ {
407
+ tmpPotentialSubfolderMagicHost = tmpHostSet[0];
408
+ }
409
+ if (tmpPotentialSubfolderMagicHost)
410
+ {
411
+ // Check if the subfolder exists -- this is only one dimensional for now
412
+ let tmpPotentialSubfolder = servePath + tmpPotentialSubfolderMagicHost;
413
+ if (this.fable.FilePersistence.libFS.existsSync(tmpPotentialSubfolder))
414
+ {
415
+ // If it does, then we need to add it to the file path
416
+ servePath = `${tmpPotentialSubfolder}/`;
417
+ }
418
+ }
419
+ pRequest.url = pRequest.url.split('?')[0].substr(tmpRouteStrip.length) || '/';
420
+ pRequest.path = function()
421
+ {
422
+ return pRequest.url;
423
+ };
424
+
425
+ this.setMimeHeader(pRequest.url, pResponse);
426
+
427
+ const tmpServe = libServeStatic(servePath, Object.assign({ index: tmpDefaultFile }, pParams));
428
+ tmpServe(pRequest, pResponse, libFinalHandler(pRequest, pResponse));
429
+ // TODO: This may break things if a post request send handler is setup...
430
+ //fNext();
431
+ });
432
+ return true;
433
+ }
268
434
  }
269
435
 
270
436
  module.exports = Orator;