orator 4.0.3 → 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
@@ -41,4 +41,6 @@ tmpServiceServer.invoke('GET', tmpURI, null,
41
41
  (pError, pResponseData) =>
42
42
  {
43
43
  tmpServiceServer.log.info(`Response to [${tmpURI}] came back from IPC resulting in [${pResponseData}]!`)
44
- });
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.3",
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)
@@ -47,6 +61,9 @@ class Orator extends libFableServiceProviderBase
47
61
  }
48
62
  }
49
63
 
64
+ /**
65
+ * Lifecycle event that executes before initializing the service. For overloading.
66
+ */
50
67
  onBeforeInitialize()
51
68
  {
52
69
  if (this.fable.settings.LogNoisiness > 3)
@@ -54,6 +71,11 @@ class Orator extends libFableServiceProviderBase
54
71
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onBeforeInitialize:`);
55
72
  }
56
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
+ */
57
79
  onBeforeInitializeAsync(fNext)
58
80
  {
59
81
  this.onBeforeInitialize();
@@ -92,12 +114,20 @@ class Orator extends libFableServiceProviderBase
92
114
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onInitialize:`);
93
115
  }
94
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
+ */
95
122
  onInitializeAsync(fNext)
96
123
  {
97
124
  this.onInitialize();
98
125
  return fNext();
99
126
  }
100
127
 
128
+ /**
129
+ * Lifecycle event that executes after initializing the service. For overloading.
130
+ */
101
131
  onAfterInitialize()
102
132
  {
103
133
  if (this.fable.settings.LogNoisiness > 3)
@@ -105,12 +135,22 @@ class Orator extends libFableServiceProviderBase
105
135
  this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onAfterInitialize:`);
106
136
  }
107
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
+ */
108
143
  onAfterInitializeAsync(fNext)
109
144
  {
110
145
  this.onAfterInitialize();
111
146
  return fNext();
112
147
  }
113
148
 
149
+ /**
150
+ * Initializes the Orator instance.
151
+ *
152
+ * @param {Function} fCallback - The callback function to be executed after initialization.
153
+ */
114
154
  initialize(fCallback)
115
155
  {
116
156
  // I hate this -- as long as we want to be "mostly" backwards compatible it needs to do it though
@@ -148,10 +188,22 @@ class Orator extends libFableServiceProviderBase
148
188
  }
149
189
  }
150
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
+ */
151
197
  onBeforeStartService(fNext)
152
198
  {
153
199
  return fNext();
154
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
+ */
155
207
  onStartService(fNext)
156
208
  {
157
209
  this.onAfterInitialize();
@@ -165,11 +217,22 @@ class Orator extends libFableServiceProviderBase
165
217
  }
166
218
  );
167
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
+ */
168
226
  onAfterStartService(fNext)
169
227
  {
170
228
  return fNext();
171
229
  }
172
230
 
231
+ /**
232
+ * Starts the service.
233
+ *
234
+ * @param {Function} fNext - The callback function to be executed after the service has started.
235
+ */
173
236
  startService(fNext)
174
237
  {
175
238
  var tmpNext = (typeof(fNext) === 'function') ? fNext : ()=>{};
@@ -203,6 +266,12 @@ class Orator extends libFableServiceProviderBase
203
266
  });
204
267
  }
205
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
+ */
206
275
  stopService(fCallback)
207
276
  {
208
277
  var tmpCallback = (typeof(fCallback) === 'function') ? fCallback : ()=>{};
@@ -224,28 +293,51 @@ class Orator extends libFableServiceProviderBase
224
293
  return this.serviceServer.close(tmpCallback);
225
294
  }
226
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
+ */
227
305
  invoke(pMethod, pRoute, pData, fCallback)
228
306
  {
229
307
  //this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} invoking ${pMethod} ${pRoute}`);
230
308
  return this.serviceServer.invoke(pMethod, pRoute, pData, fCallback);
231
309
  }
232
310
 
233
-
234
311
  /*
235
- * Legacy Orator Functions
312
+ * Legacy Orator / Backwards Compatibility Functions
236
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
+ */
237
320
  startWebServer(fNext)
238
321
  {
239
322
  return this.startService(fNext);
240
323
  }
241
324
 
242
- // 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
+ */
243
331
  stopWebServer(fNext)
244
332
  {
245
333
  return this.stopService(fNext);
246
334
  }
247
335
 
248
- // For legacy purposes
336
+ /**
337
+ * Retrieves the web server instance.
338
+ *
339
+ * @returns {WebServer} The web server instance.
340
+ */
249
341
  getWebServer()
250
342
  {
251
343
  // The old behavior was to lazily construct the service the first time
@@ -260,6 +352,85 @@ class Orator extends libFableServiceProviderBase
260
352
  /*************************************************************************
261
353
  * End of Legacy Orator Functions
262
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
+ }
263
434
  }
264
435
 
265
436
  module.exports = Orator;