meadow-endpoints 3.0.7 → 4.0.2

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.
Files changed (127) hide show
  1. package/Dockerfile_LUXURYCode +1 -1
  2. package/README.md +48 -14
  3. package/debug/Animal.json +62 -0
  4. package/debug/Harness-Configuration.json +31 -0
  5. package/debug/Harness.js +7 -108
  6. package/debug/KillHarness.sh +10 -0
  7. package/dist/meadowendpoints.js +4402 -0
  8. package/dist/meadowendpoints.min.js +92 -0
  9. package/dist/meadowendpoints.min.js.map +1 -0
  10. package/gulpfile.js +83 -0
  11. package/package.json +27 -15
  12. package/source/Meadow-Endpoints-Browser-Shim.js +14 -0
  13. package/source/Meadow-Endpoints.js +176 -565
  14. package/source/controller/Meadow-Endpoints-Controller-Base.js +161 -0
  15. package/source/controller/components/Meadow-Endpoints-Controller-BehaviorInjection.js +125 -0
  16. package/source/controller/components/Meadow-Endpoints-Controller-Error-StatusCodes.txt +189 -0
  17. package/source/controller/components/Meadow-Endpoints-Controller-Error.js +118 -0
  18. package/source/controller/components/Meadow-Endpoints-Controller-Log.js +103 -0
  19. package/source/controller/utility/Meadow-Endpoints-Filter-Parser.js +225 -0
  20. package/source/controller/utility/Meadow-Endpoints-Session-Marshaler.js +48 -0
  21. package/source/controller/utility/Meadow-Endpoints-Stream-RecordArray.js +66 -0
  22. package/source/endpoints/count/Meadow-Endpoint-Count.js +49 -0
  23. package/source/endpoints/count/Meadow-Endpoint-CountBy.js +40 -0
  24. package/source/endpoints/create/Meadow-Endpoint-BulkCreate.js +53 -0
  25. package/source/endpoints/create/Meadow-Endpoint-Create.js +58 -0
  26. package/source/endpoints/create/Meadow-Operation-Create.js +83 -0
  27. package/source/endpoints/delete/Meadow-Endpoint-Delete.js +93 -0
  28. package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +108 -0
  29. package/source/endpoints/read/Meadow-Endpoint-Read.js +72 -0
  30. package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +92 -0
  31. package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +85 -0
  32. package/source/endpoints/read/Meadow-Endpoint-ReadMax.js +55 -0
  33. package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +89 -0
  34. package/source/endpoints/read/Meadow-Endpoint-Reads.js +75 -0
  35. package/source/endpoints/read/Meadow-Endpoint-ReadsBy.js +100 -0
  36. package/source/{crud → endpoints/read}/Meadow-Marshal-DistinctList.js +4 -13
  37. package/source/{crud → endpoints/read}/Meadow-Marshal-LiteList.js +5 -14
  38. package/source/endpoints/schema/Meadow-Endpoint-New.js +36 -0
  39. package/source/endpoints/schema/Meadow-Endpoint-Schema.js +36 -0
  40. package/source/endpoints/schema/Meadow-Endpoint-Validate.js +41 -0
  41. package/source/endpoints/update/Meadow-Endpoint-BulkUpdate.js +50 -0
  42. package/source/endpoints/update/Meadow-Endpoint-Update.js +58 -0
  43. package/source/endpoints/update/Meadow-Operation-Update.js +115 -0
  44. package/source/endpoints/upsert/Meadow-Endpoint-BulkUpsert.js +52 -0
  45. package/source/endpoints/upsert/Meadow-Endpoint-Upsert.js +57 -0
  46. package/source/endpoints/upsert/Meadow-Operation-Upsert.js +137 -0
  47. package/test/MeadowEndpoints_basic_tests.js +50 -2408
  48. package/test_support/bookstore-api-endpoint-exercises.paw +0 -0
  49. package/test_support/bookstore-configuration.json +28 -0
  50. package/test_support/bookstore-import-books-run.js +1 -0
  51. package/test_support/bookstore-import-books.js +215 -0
  52. package/test_support/bookstore-serve-meadow-endpoint-apis-IPC.js +138 -0
  53. package/test_support/bookstore-serve-meadow-endpoint-apis-run.js +6 -0
  54. package/test_support/bookstore-serve-meadow-endpoint-apis.js +129 -0
  55. package/test_support/data/books.csv +10001 -0
  56. package/test_support/model/ddl/BookStore.ddl +66 -0
  57. package/test_support/model/generated_diagram/README.md +1 -0
  58. package/test_support/model/generated_diagram/Stricture_Output.dot +13 -0
  59. package/test_support/model/generated_diagram/Stricture_Output.png +0 -0
  60. package/test_support/model/generated_documentation/Dictionary.md +18 -0
  61. package/test_support/model/generated_documentation/Model-Author.md +20 -0
  62. package/test_support/model/generated_documentation/Model-Book.md +26 -0
  63. package/test_support/model/generated_documentation/Model-BookAuthorJoin.md +14 -0
  64. package/test_support/model/generated_documentation/Model-BookPrice.md +25 -0
  65. package/test_support/model/generated_documentation/Model-Review.md +22 -0
  66. package/test_support/model/generated_documentation/ModelChangeTracking.md +17 -0
  67. package/test_support/model/generated_documentation/README.md +1 -0
  68. package/test_support/model/manual_scripts/DropTables.sql +5 -0
  69. package/test_support/model/manual_scripts/README.md +2 -0
  70. package/test_support/model/sql_create/BookStore-CreateDatabase.mysql.sql +116 -0
  71. package/test_support/model/sql_create/README.md +1 -0
  72. package/test_support/test_old/Tests.js +3243 -0
  73. package/test_support/test_old/untitled.js +88 -0
  74. package/source/Meadow-Authenticator.js +0 -31
  75. package/source/Meadow-Authorizers.js +0 -214
  76. package/source/Meadow-BehaviorModifications.js +0 -170
  77. package/source/Meadow-CommonServices.js +0 -206
  78. package/source/Meadow-MarshallSessionData.js +0 -64
  79. package/source/Restify-RouteParser.js +0 -114
  80. package/source/authorizers/Meadow-Authorizer-Allow.js +0 -17
  81. package/source/authorizers/Meadow-Authorizer-Deny.js +0 -17
  82. package/source/authorizers/Meadow-Authorizer-Mine.js +0 -47
  83. package/source/authorizers/Meadow-Authorizer-MyCustomer.js +0 -48
  84. package/source/crud/Meadow-Endpoint-BulkCreate.js +0 -67
  85. package/source/crud/Meadow-Endpoint-BulkUpdate.js +0 -74
  86. package/source/crud/Meadow-Endpoint-BulkUpsert.js +0 -76
  87. package/source/crud/Meadow-Endpoint-Count.js +0 -93
  88. package/source/crud/Meadow-Endpoint-CountBy.js +0 -101
  89. package/source/crud/Meadow-Endpoint-Create.js +0 -77
  90. package/source/crud/Meadow-Endpoint-Delete.js +0 -139
  91. package/source/crud/Meadow-Endpoint-Read.js +0 -109
  92. package/source/crud/Meadow-Endpoint-ReadDistinctList.js +0 -146
  93. package/source/crud/Meadow-Endpoint-ReadLiteList.js +0 -139
  94. package/source/crud/Meadow-Endpoint-ReadMax.js +0 -86
  95. package/source/crud/Meadow-Endpoint-ReadSelectList.js +0 -145
  96. package/source/crud/Meadow-Endpoint-Reads.js +0 -129
  97. package/source/crud/Meadow-Endpoint-ReadsBy.js +0 -155
  98. package/source/crud/Meadow-Endpoint-Undelete.js +0 -161
  99. package/source/crud/Meadow-Endpoint-Update.js +0 -80
  100. package/source/crud/Meadow-Endpoint-Upsert.js +0 -78
  101. package/source/crud/Meadow-Operation-Create.js +0 -105
  102. package/source/crud/Meadow-Operation-Update.js +0 -145
  103. package/source/crud/Meadow-Operation-Upsert.js +0 -106
  104. package/source/crud/Meadow-StreamRecordArray.js +0 -45
  105. package/source/schema/Meadow-Endpoint-New.js +0 -37
  106. package/source/schema/Meadow-Endpoint-Schema.js +0 -37
  107. package/source/schema/Meadow-Endpoint-Validate.js +0 -43
  108. package/test/Animal.json +0 -140
  109. package/test/MeadowEndpoints_disabledAuth_tests.js +0 -1325
  110. package/test/MeadowEndpoints_trustedSession_tests.js +0 -1731
  111. package/test/load/artillery-low.yml +0 -10
  112. package/test/load/cloud9setup.sh +0 -25
  113. package/test/load/package.json +0 -19
  114. package/test/load/test-schema-initializedatabase.sql +0 -29
  115. package/test/load/test-schema.json +0 -119
  116. package/test/load/test-server.js +0 -157
  117. package/test/scripts/InitializeDatabase-C9.sql +0 -7
  118. /package/{test/schemas → test_support/model}/json_schema/BookStore-Extended.json +0 -0
  119. /package/{test/schemas → test_support/model}/json_schema/BookStore-PICT.json +0 -0
  120. /package/{test/schemas → test_support/model}/json_schema/BookStore.json +0 -0
  121. /package/{test/schemas → test_support/model}/json_schema/README.md +0 -0
  122. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Author.json +0 -0
  123. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Book.json +0 -0
  124. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json +0 -0
  125. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookPrice.json +0 -0
  126. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Review.json +0 -0
  127. /package/{test/schemas → test_support/model}/meadow_schema/README.md +0 -0
@@ -0,0 +1,161 @@
1
+ const libAsyncWaterfall = require('async/waterfall');
2
+
3
+ const libBaseLogController = require('./components/Meadow-Endpoints-Controller-Log.js')
4
+
5
+ const libBaseErrorController = require('./components/Meadow-Endpoints-Controller-Error.js');
6
+ const libBaseBehaviorInjectionController = require('./components/Meadow-Endpoints-Controller-BehaviorInjection.js');
7
+
8
+ const libMeadowEndpointsFilterParser = require('./utility/Meadow-Endpoints-Filter-Parser.js');
9
+ const libMeadowEndpointsSessionMarshaler = require('./utility/Meadow-Endpoints-Session-Marshaler.js');
10
+ const libMeadowEndpointsStreamRecordArray = require('./utility/Meadow-Endpoints-Stream-RecordArray.js');
11
+
12
+ class MeadowEndpointControllerBase
13
+ {
14
+ constructor(pMeadowEndpoints)
15
+ {
16
+ this.DAL = pMeadowEndpoints.DAL;
17
+ this.ControllerOptions = pMeadowEndpoints._ControllerOptions
18
+
19
+ // Application Services
20
+ this._Settings = false;
21
+ this._LogController = false;
22
+
23
+ // Logic and Behavior
24
+ this._BehaviorInjectionController = false;
25
+ this._ErrorController = false;
26
+
27
+ // Internal async utility functions
28
+ this.waterfall = this.DAL.fable.Utility.waterfall;
29
+ this.eachLimit = this.DAL.fable.Utility.eachLimit;
30
+ this.extend = this.DAL.fable.Utility.extend;
31
+
32
+ if ((typeof(pControllerOptions) != 'object') || pControllerOptions.hasOwnProperty('ControllerClass'))
33
+ {
34
+ this.initializeDefaultUnsetControllers(this);
35
+ }
36
+
37
+ // Behavior functions
38
+ this._FilterParser = new libMeadowEndpointsFilterParser(this);
39
+ this._SessionMarshaler = new libMeadowEndpointsSessionMarshaler(this);
40
+ this._StreamRecordArray = new libMeadowEndpointsStreamRecordArray(this);
41
+ }
42
+
43
+ initializeDefaultUnsetControllers(pController)
44
+ {
45
+ // Application Services
46
+ if (!this._Settings)
47
+ {
48
+ this._Settings = pController.DAL.fable.settings;
49
+ }
50
+ if (!this._Settings.hasOwnProperty('MeadowEndpointsDefaultSessionObject'))
51
+ {
52
+ this._Settings.MeadowEndpointsDefaultSessionObject = (
53
+ {
54
+ CustomerID: 0,
55
+ SessionID: '0x0000',
56
+ DeviceID: 'Unset',
57
+ UserID: 0,
58
+ UserRole: 'None',
59
+ UserRoleIndex: 0,
60
+ LoggedIn: false
61
+ });
62
+ }
63
+ if (!this._LogController)
64
+ {
65
+ this._LogController = new libBaseLogController(pController);
66
+ }
67
+ if (!this._BehaviorInjectionController)
68
+ {
69
+ this._BehaviorInjectionController = new libBaseBehaviorInjectionController(pController);
70
+ }
71
+ if (!this._ErrorController)
72
+ {
73
+ this._ErrorController = new libBaseErrorController(pController);
74
+ }
75
+ }
76
+
77
+ initializeRequestState(pRequest, pVerb)
78
+ {
79
+ let tmpRequestState = {};
80
+
81
+ tmpRequestState.Verb = (typeof(pVerb) == 'string') ? pVerb : 'Unnamed_Custom_Behavior';
82
+ tmpRequestState.SessionData = this.getSessionData(pRequest);
83
+
84
+ return tmpRequestState;
85
+ }
86
+
87
+ // Clone the session data and verb to a new request state object
88
+ cloneAsyncSafeRequestState(pRequestState, pNewVerb)
89
+ {
90
+ let tmpSafeRequestState = (
91
+ {
92
+ ParentRequestState: pRequestState,
93
+ SessionData: pRequestState.SessionData
94
+ });
95
+
96
+ tmpSafeRequestState.Verb = (typeof(pNewVerb) == 'string') ? pNewVerb : pRequestState.Verb;
97
+
98
+ return tmpSafeRequestState;
99
+ }
100
+
101
+ // Override this to provide an alternate ending function that is run with every endpoint.
102
+ _BeginDataRequestFunction(pRequest, pResponse, fNext)
103
+ {
104
+ return fNext();
105
+ }
106
+
107
+ beginMeadowRequest(pRequest, pResponse, fNext)
108
+ {
109
+ this._BeginDataRequestFunction(pRequest, pResponse, fNext);
110
+ }
111
+
112
+ // Override this to provide an alternate ending function that is run with every endpoint.
113
+ _EndDataRequestFunction(pRequest, pResponse, fNext)
114
+ {
115
+ return fNext();
116
+ }
117
+
118
+ endMeadowRequest(pRequest, pResponse, fNext)
119
+ {
120
+ this._EndDataRequestFunction(pRequest, pResponse, fNext);
121
+ }
122
+
123
+ // Application Services
124
+ get settings() {return this._Settings; }
125
+ set settings(pSettings) { this._Settings = pSettings; }
126
+
127
+ get log() {return this._LogController; }
128
+ set log(pLogController) { this._LogController = pLogController; }
129
+
130
+ // Logic and Behavior
131
+ get BehaviorInjection() {return this._BehaviorInjectionController; }
132
+ set BehaviorInjection(pBehaviorInjectionController) { this._BehaviorInjectionController = pBehaviorInjectionController; }
133
+
134
+ get ErrorHandler() {return this._ErrorController; }
135
+ set ErrorHandler(pErrorController) { this._ErrorController = pErrorController; }
136
+
137
+ parseFilter(pFilterString, pQuery)
138
+ {
139
+ return this._FilterParser.parseFilter(pFilterString, pQuery);
140
+ }
141
+
142
+ doStreamRecordArray(pResponse, pRecords, fCallback)
143
+ {
144
+ return this._StreamRecordArray.streamRecordArray(pResponse, pRecords, fCallback);
145
+ }
146
+
147
+ getSessionData(pRequest)
148
+ {
149
+ return this._SessionMarshaler.getSessionData(pRequest);
150
+ }
151
+ }
152
+
153
+ module.exports = MeadowEndpointControllerBase;
154
+
155
+ // Export the base classes for the controller components, for inheritance
156
+ module.exports.BaseErrorController = libBaseErrorController;
157
+ module.exports.BaseBehaviorInjectionController = libBaseBehaviorInjectionController;
158
+
159
+ module.exports.BaseFilterParser = libMeadowEndpointsFilterParser;
160
+ module.exports.BaseSessionMarshaler = libMeadowEndpointsSessionMarshaler;
161
+ module.exports.BaseStreamRecordArray = libMeadowEndpointsStreamRecordArray;
@@ -0,0 +1,125 @@
1
+ class MeadowEndpointsControllerBehaviorInjectionBase
2
+ {
3
+ constructor(pController)
4
+ {
5
+ this._Controller = pController;
6
+
7
+ // The template compilation function
8
+ this.template = this._Controller.DAL.fable.Utility.template;
9
+
10
+ // An object to hold modifications to specific behaviors.
11
+ this._BehaviorFunctions = {};
12
+
13
+ // A set of objects to hold the specific templates and their compiled functions
14
+ this._Templates = {};
15
+ this._TemplateFunctions = {};
16
+ }
17
+
18
+ /**
19
+ * Set a specific behavior.
20
+ *
21
+ * The anatomy of a behavior function is as follows:
22
+ *
23
+ * var someBehavior = function(pRequest, fCallback)
24
+ * {
25
+ * // Do some stuff with pRequest...
26
+ * if (pRequest.UserSession.UserRoleIndex < 5)
27
+ * tmpRequestState.Query.addFilter('Customer', pRequest.UserSession.IDCustomer);
28
+ * return fCallback(false);
29
+ * }
30
+ *
31
+ * It is important to note that the fCallback function expects false if no error, or a string message if there is one.
32
+ */
33
+ setBehavior(pBehaviorHash, fBehavior)
34
+ {
35
+ this._BehaviorFunctions[pBehaviorHash] = fBehavior;
36
+ }
37
+
38
+ /**
39
+ * This method runs a behavior at a specific hash, and returns true.
40
+ * Or it returns false if there was no behavior there.
41
+ * Behaviors should expect their state to be in the pRequest object, per the example in setBehavior
42
+ */
43
+ runBehavior(pBehaviorHash, pController, pRequest, pRequestState, fCallback)
44
+ {
45
+ // Run an injected behavior (if it exists)
46
+ if (this._BehaviorFunctions.hasOwnProperty(pBehaviorHash))
47
+ {
48
+ try
49
+ {
50
+ // Call the behavior with the scoped [this] of the Meadow behavior
51
+ // NOTE: If you define a behavior with lambda arrow syntax, it will *not* respect the call
52
+ return this._BehaviorFunctions[pBehaviorHash].call(pController, pRequest, pRequestState, fCallback);
53
+ }
54
+ catch (pInjectedBehaviorError)
55
+ {
56
+ return fCallback(pInjectedBehaviorError);
57
+ }
58
+ }
59
+
60
+ return fCallback();
61
+ }
62
+
63
+ /**
64
+ * Get a template.
65
+ */
66
+ getTemplate(pTemplateHash)
67
+ {
68
+ if (this._Templates.hasOwnProperty(pTemplateHash))
69
+ {
70
+ return this._Templates[pTemplateHash];
71
+ }
72
+ else
73
+ {
74
+ return false;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Set a template.
80
+ */
81
+ setTemplate(pTemplateHash, pTemplate)
82
+ {
83
+ // Store both the cached text as well as the function
84
+ this._Templates[pTemplateHash] = pTemplate;
85
+ this._TemplateFunctions[pTemplateHash] = this.template(pTemplate);
86
+ }
87
+
88
+ /**
89
+ * Get a template function.
90
+ */
91
+ getTemplateFunction(pTemplateHash)
92
+ {
93
+ if (this._TemplateFunctions.hasOwnProperty(pTemplateHash))
94
+ {
95
+ return this._TemplateFunctions[pTemplateHash];
96
+ }
97
+ else
98
+ {
99
+ return false;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Process a template at a hash, and return the result.
105
+ */
106
+ processTemplate(pTemplateHash, pTemplateData, pDefaultTemplate)
107
+ {
108
+ var tmpTemplateFunction = this.getTemplateFunction(pTemplateHash);
109
+ var tmpTemplateData = (typeof(pTemplateData) === 'undefined') ? {} : pTemplateData;
110
+
111
+ // This makes the function fairly laziliy loading.
112
+ if (tmpTemplateFunction === false)
113
+ {
114
+ // If the template doesn't exist, try to use the passed-in default and set that as the template.
115
+ // Otherwise make it empty.
116
+ this.setTemplate(pTemplateHash, (typeof(pDefaultTemplate) === 'undefined') ? '' : pDefaultTemplate);
117
+ tmpTemplateFunction = this.getTemplateFunction(pTemplateHash);
118
+ }
119
+
120
+ // Now process and return the underscore template.
121
+ return tmpTemplateFunction(tmpTemplateData);
122
+ }
123
+ }
124
+
125
+ module.exports = MeadowEndpointsControllerBehaviorInjectionBase;
@@ -0,0 +1,189 @@
1
+ PULLED FROM https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
2
+
3
+ Internet Assigned Numbers Authority
4
+
5
+ Hypertext Transfer Protocol (HTTP) Status Code Registry
6
+
7
+ Last Updated
8
+ 2022-06-08
9
+
10
+ Available Formats
11
+ [IMG]
12
+ XML [IMG]
13
+ HTML [IMG]
14
+ Plain text
15
+
16
+ Registry included below
17
+
18
+ * HTTP Status Codes
19
+
20
+ HTTP Status Codes
21
+
22
+ Registration Procedure(s)
23
+
24
+ IETF Review
25
+
26
+ Reference
27
+ [RFC9110, Section 16.2.1]
28
+
29
+ Note
30
+
31
+ 1xx: Informational - Request received, continuing process
32
+ 2xx: Success - The action was successfully received, understood, and accepted
33
+ 3xx: Redirection - Further action must be taken in order to complete the request
34
+ 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
35
+ 5xx: Server Error - The server failed to fulfill an apparently valid request
36
+
37
+ Value Description Reference
38
+ 100 Continue [RFC9110, Section 15.2.1]
39
+ 101 Switching Protocols [RFC9110, Section 15.2.2]
40
+ 102 Processing [RFC2518]
41
+ 103 Early Hints [RFC8297]
42
+ 104-199 Unassigned
43
+ 200 OK [RFC9110, Section 15.3.1]
44
+ 201 Created [RFC9110, Section 15.3.2]
45
+ 202 Accepted [RFC9110, Section 15.3.3]
46
+ 203 Non-Authoritative Information [RFC9110, Section 15.3.4]
47
+ 204 No Content [RFC9110, Section 15.3.5]
48
+ 205 Reset Content [RFC9110, Section 15.3.6]
49
+ 206 Partial Content [RFC9110, Section 15.3.7]
50
+ 207 Multi-Status [RFC4918]
51
+ 208 Already Reported [RFC5842]
52
+ 209-225 Unassigned
53
+ 226 IM Used [RFC3229]
54
+ 227-299 Unassigned
55
+ 300 Multiple Choices [RFC9110, Section 15.4.1]
56
+ 301 Moved Permanently [RFC9110, Section 15.4.2]
57
+ 302 Found [RFC9110, Section 15.4.3]
58
+ 303 See Other [RFC9110, Section 15.4.4]
59
+ 304 Not Modified [RFC9110, Section 15.4.5]
60
+ 305 Use Proxy [RFC9110, Section 15.4.6]
61
+ 306 (Unused) [RFC9110, Section 15.4.7]
62
+ 307 Temporary Redirect [RFC9110, Section 15.4.8]
63
+ 308 Permanent Redirect [RFC9110, Section 15.4.9]
64
+ 309-399 Unassigned
65
+ 400 Bad Request [RFC9110, Section 15.5.1]
66
+ 401 Unauthorized [RFC9110, Section 15.5.2]
67
+ 402 Payment Required [RFC9110, Section 15.5.3]
68
+ 403 Forbidden [RFC9110, Section 15.5.4]
69
+ 404 Not Found [RFC9110, Section 15.5.5]
70
+ 405 Method Not Allowed [RFC9110, Section 15.5.6]
71
+ 406 Not Acceptable [RFC9110, Section 15.5.7]
72
+ 407 Proxy Authentication Required [RFC9110, Section 15.5.8]
73
+ 408 Request Timeout [RFC9110, Section 15.5.9]
74
+ 409 Conflict [RFC9110, Section 15.5.10]
75
+ 410 Gone [RFC9110, Section 15.5.11]
76
+ 411 Length Required [RFC9110, Section 15.5.12]
77
+ 412 Precondition Failed [RFC9110, Section 15.5.13]
78
+ 413 Content Too Large [RFC9110, Section 15.5.14]
79
+ 414 URI Too Long [RFC9110, Section 15.5.15]
80
+ 415 Unsupported Media Type [RFC9110, Section 15.5.16]
81
+ 416 Range Not Satisfiable [RFC9110, Section 15.5.17]
82
+ 417 Expectation Failed [RFC9110, Section 15.5.18]
83
+ 418 (Unused) [RFC9110, Section 15.5.19]
84
+ 419-420 Unassigned
85
+ 421 Misdirected Request [RFC9110, Section 15.5.20]
86
+ 422 Unprocessable Content [RFC9110, Section 15.5.21]
87
+ 423 Locked [RFC4918]
88
+ 424 Failed Dependency [RFC4918]
89
+ 425 Too Early [RFC8470]
90
+ 426 Upgrade Required [RFC9110, Section 15.5.22]
91
+ 427 Unassigned
92
+ 428 Precondition Required [RFC6585]
93
+ 429 Too Many Requests [RFC6585]
94
+ 430 Unassigned
95
+ 431 Request Header Fields Too Large [RFC6585]
96
+ 432-450 Unassigned
97
+ 451 Unavailable For Legal Reasons [RFC7725]
98
+ 452-499 Unassigned
99
+ 500 Internal Server Error [RFC9110, Section 15.6.1]
100
+ 501 Not Implemented [RFC9110, Section 15.6.2]
101
+ 502 Bad Gateway [RFC9110, Section 15.6.3]
102
+ 503 Service Unavailable [RFC9110, Section 15.6.4]
103
+ 504 Gateway Timeout [RFC9110, Section 15.6.5]
104
+ 505 HTTP Version Not Supported [RFC9110, Section 15.6.6]
105
+ 506 Variant Also Negotiates [RFC2295]
106
+ 507 Insufficient Storage [RFC4918]
107
+ 508 Loop Detected [RFC5842]
108
+ 509 Unassigned
109
+ 510 Not Extended (OBSOLETED) [RFC2774][status-change-http-experiments-to-historic]
110
+ 511 Network Authentication Required [RFC6585]
111
+ 512-599 Unassigned
112
+
113
+ Licensing Terms
114
+
115
+ Value Description Reference
116
+ 100 Continue [RFC9110, Section 15.2.1]
117
+ 101 Switching Protocols [RFC9110, Section 15.2.2]
118
+ 102 Processing [RFC2518]
119
+ 103 Early Hints [RFC8297]
120
+ 104-199 Unassigned
121
+ 200 OK [RFC9110, Section 15.3.1]
122
+ 201 Created [RFC9110, Section 15.3.2]
123
+ 202 Accepted [RFC9110, Section 15.3.3]
124
+ 203 Non-Authoritative Information [RFC9110, Section 15.3.4]
125
+ 204 No Content [RFC9110, Section 15.3.5]
126
+ 205 Reset Content [RFC9110, Section 15.3.6]
127
+ 206 Partial Content [RFC9110, Section 15.3.7]
128
+ 207 Multi-Status [RFC4918]
129
+ 208 Already Reported [RFC5842]
130
+ 209-225 Unassigned
131
+ 226 IM Used [RFC3229]
132
+ 227-299 Unassigned
133
+ 300 Multiple Choices [RFC9110, Section 15.4.1]
134
+ 301 Moved Permanently [RFC9110, Section 15.4.2]
135
+ 302 Found [RFC9110, Section 15.4.3]
136
+ 303 See Other [RFC9110, Section 15.4.4]
137
+ 304 Not Modified [RFC9110, Section 15.4.5]
138
+ 305 Use Proxy [RFC9110, Section 15.4.6]
139
+ 306 (Unused) [RFC9110, Section 15.4.7]
140
+ 307 Temporary Redirect [RFC9110, Section 15.4.8]
141
+ 308 Permanent Redirect [RFC9110, Section 15.4.9]
142
+ 309-399 Unassigned
143
+ 400 Bad Request [RFC9110, Section 15.5.1]
144
+ 401 Unauthorized [RFC9110, Section 15.5.2]
145
+ 402 Payment Required [RFC9110, Section 15.5.3]
146
+ 403 Forbidden [RFC9110, Section 15.5.4]
147
+ 404 Not Found [RFC9110, Section 15.5.5]
148
+ 405 Method Not Allowed [RFC9110, Section 15.5.6]
149
+ 406 Not Acceptable [RFC9110, Section 15.5.7]
150
+ 407 Proxy Authentication Required [RFC9110, Section 15.5.8]
151
+ 408 Request Timeout [RFC9110, Section 15.5.9]
152
+ 409 Conflict [RFC9110, Section 15.5.10]
153
+ 410 Gone [RFC9110, Section 15.5.11]
154
+ 411 Length Required [RFC9110, Section 15.5.12]
155
+ 412 Precondition Failed [RFC9110, Section 15.5.13]
156
+ 413 Content Too Large [RFC9110, Section 15.5.14]
157
+ 414 URI Too Long [RFC9110, Section 15.5.15]
158
+ 415 Unsupported Media Type [RFC9110, Section 15.5.16]
159
+ 416 Range Not Satisfiable [RFC9110, Section 15.5.17]
160
+ 417 Expectation Failed [RFC9110, Section 15.5.18]
161
+ 418 (Unused) [RFC9110, Section 15.5.19]
162
+ 419-420 Unassigned
163
+ 421 Misdirected Request [RFC9110, Section 15.5.20]
164
+ 422 Unprocessable Content [RFC9110, Section 15.5.21]
165
+ 423 Locked [RFC4918]
166
+ 424 Failed Dependency [RFC4918]
167
+ 425 Too Early [RFC8470]
168
+ 426 Upgrade Required [RFC9110, Section 15.5.22]
169
+ 427 Unassigned
170
+ 428 Precondition Required [RFC6585]
171
+ 429 Too Many Requests [RFC6585]
172
+ 430 Unassigned
173
+ 431 Request Header Fields Too Large [RFC6585]
174
+ 432-450 Unassigned
175
+ 451 Unavailable For Legal Reasons [RFC7725]
176
+ 452-499 Unassigned
177
+ 500 Internal Server Error [RFC9110, Section 15.6.1]
178
+ 501 Not Implemented [RFC9110, Section 15.6.2]
179
+ 502 Bad Gateway [RFC9110, Section 15.6.3]
180
+ 503 Service Unavailable [RFC9110, Section 15.6.4]
181
+ 504 Gateway Timeout [RFC9110, Section 15.6.5]
182
+ 505 HTTP Version Not Supported [RFC9110, Section 15.6.6]
183
+ 506 Variant Also Negotiates [RFC2295]
184
+ 507 Insufficient Storage [RFC4918]
185
+ 508 Loop Detected [RFC5842]
186
+ 509 Unassigned
187
+ 510 Not Extended (OBSOLETED) [RFC2774][status-change-http-experiments-to-historic]
188
+ 511 Network Authentication Required [RFC6585]
189
+ 512-599 Unassigned
@@ -0,0 +1,118 @@
1
+ class MeadowEndpointsControllerErrorBase
2
+ {
3
+ constructor(pController)
4
+ {
5
+ this._Controller = pController;
6
+ }
7
+
8
+ // Get the error object
9
+ getError(pMessage, pStatusCode, pSuppressSoftwareTrace)
10
+ {
11
+ let tmpError = new Error(pMessage);
12
+
13
+ // Default the error status code to 400 if none is passed
14
+ tmpError.StatusCode = (typeof(pStatusCode) == 'number') ? pStatusCode : 400;
15
+ // This suppresses the stack trace from being sent back or logged.
16
+ // And by default it does not send a stack trace, as we expect errors created this way to be protocol, schema or data related.
17
+ tmpError.SuppressSoftwareTrace = (typeof(pSuppressSoftwareTrace) != 'undefined') ? pSuppressSoftwareTrace : true;
18
+
19
+ return tmpError;
20
+ }
21
+
22
+ // Handle an error if set -- some errors don't send the response back because they aren't fully errory errors.
23
+ handleErrorIfSet(pRequest, pRequestState, pResponse, pError, fCallback)
24
+ {
25
+ if (pError)
26
+ {
27
+ return this.sendError(pRequest, pRequestState, pResponse, pError, fCallback);
28
+ }
29
+
30
+ return fCallback();
31
+ }
32
+
33
+ // Send an error object
34
+ sendError(pRequest, pRequestState, pResponse, pError, fCallback)
35
+ {
36
+ this._Controller.log.logRequestError(pRequest, pRequestState, pError);
37
+
38
+ // TODO: Detect if we've already sent headers?
39
+ if (!this._Controller.ControllerOptions.SendErrorStatusCodes)
40
+ {
41
+ let tmpStatusCode = (pError.hasOwnProperty('StatusCode')) ? pError.StatusCode : 500;
42
+ pResponse.status(tmpStatusCode);
43
+ }
44
+
45
+ let tmpResponseObject = (
46
+ {
47
+ Error:pError.message,
48
+ StatusCode:pError.StatusCode
49
+ });
50
+
51
+ tmpResponseObject = this._Controller.ErrorHandler.prepareRequestContextOutputObject(tmpResponseObject, pRequest, pRequestState, pError);
52
+
53
+ pResponse.send(tmpResponseObject);
54
+
55
+ fCallback(pError);
56
+ }
57
+
58
+ // This looks for some generic markers in the request state and puts them into a log or send object
59
+ prepareRequestContextOutputObject(pObjectToPopulate, pRequest, pRequestState, pError)
60
+ {
61
+ // Internally created errors supress stack traces
62
+ if (pError)
63
+ {
64
+ pObjectToPopulate.Error = pError.message;
65
+ pObjectToPopulate.Code = pError.code;
66
+ pObjectToPopulate.StatusCode = pError.StatusCode;
67
+
68
+ if (!pError.SuppressSoftwareTrace)
69
+ {
70
+ pObjectToPopulate.Stack = pError.stack;
71
+ }
72
+
73
+ if (pRequestState.hasOwnProperty('Record'))
74
+ {
75
+ pObjectToPopulate.Record = pRequestState.Record;
76
+ }
77
+
78
+ if (pRequestState.hasOwnProperty('Query') && (typeof(pRequestState.Query) == 'object'))
79
+ {
80
+ if (pRequestState.Query.query)
81
+ {
82
+ if (typeof(pRequestState.Query.query.body) == 'string')
83
+ {
84
+ pObjectToPopulate.Query = pRequestState.Query.query.body;
85
+ }
86
+
87
+ if ((typeof(pRequestState.Query.query.parameters) == 'object'))
88
+ {
89
+ pObjectToPopulate.QueryParameters = pRequestState.Query.query.parameters;
90
+
91
+ pObjectToPopulate.RebuiltQueryString = (typeof(pObjectToPopulate.Query) == 'string') ? pObjectToPopulate.Query : '';
92
+
93
+ // This gnarly bit of code attempts to reconstruct a non prepared string version of the query, to help.
94
+ let tmpQueryParameterSet = Object.keys(pObjectToPopulate.QueryParameters);
95
+ for (let i = 0; i < tmpQueryParameterSet.length; i++)
96
+ {
97
+ switch(typeof(tmpQueryParameterSet[i]))
98
+ {
99
+ case 'number':
100
+ pObjectToPopulate.RebuiltQueryString = pObjectToPopulate.RebuiltQueryString.replace(new RegExp(`:${tmpQueryParameterSet[i]}\\b`, 'g'), `'${pObjectToPopulate.QueryParameters[tmpQueryParameterSet[i]]}'`);
101
+ break;
102
+ case 'string':
103
+ // TODO: This may need more ... nuance...
104
+ default:
105
+ pObjectToPopulate.RebuiltQueryString = pObjectToPopulate.RebuiltQueryString.replace(new RegExp(`:${tmpQueryParameterSet[i]}\\b`,'g'), pObjectToPopulate.QueryParameters[tmpQueryParameterSet[i]]);
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ return pObjectToPopulate;
115
+ }
116
+ }
117
+
118
+ module.exports = MeadowEndpointsControllerErrorBase;
@@ -0,0 +1,103 @@
1
+ class MeadowEndpointsControllerLogBase
2
+ {
3
+ constructor(pController)
4
+ {
5
+ this._Controller = pController;
6
+ }
7
+
8
+ // This is called for every successful request log line. Be careful what you add in overloads!
9
+ prepareLogData(pRequest, pRequestState, pLogData)
10
+ {
11
+ // TODO: Discuss if these should be configurations
12
+ if (pRequestState.hasOwnProperty('Record'))
13
+ {
14
+ if (pRequestState.Record.hasOwnProperty(this._Controller.DAL.defaultIdentifier))
15
+ {
16
+ pLogData[this._Controller.DAL.defaultIdentifier] = pRequestState.Record[this._Controller.DAL.defaultIdentifier];
17
+ }
18
+ if (pRequestState.Record.hasOwnProperty(this._Controller.DAL.defaultGUIdentifier))
19
+ {
20
+ pLogData[this._Controller.DAL.defaultGUIdentifier] = pRequestState.Record[this._Controller.DAL.defaultGUIdentifier];
21
+ }
22
+ }
23
+ if (pRequestState.hasOwnProperty('UpdatedRecords'))
24
+ {
25
+ pLogData.UpdatedRecordCount = pRequestState.UpdatedRecords.length;
26
+ }
27
+ if (pRequestState.hasOwnProperty('CreatedRecords'))
28
+ {
29
+ pLogData.UpdatedRecordCount = pRequestState.CreatedRecords.length;
30
+ }
31
+ if (pRequestState.hasOwnProperty('UpsertedRecords'))
32
+ {
33
+ pLogData.UpdatedRecordCount = pRequestState.UpsertedRecords.length;
34
+ }
35
+ return pLogData;
36
+ }
37
+
38
+ // This is called whenever an endpoint is completed successfully
39
+ requestCompletedSuccessfully(pRequest, pRequestState, pActionSummary)
40
+ {
41
+ let tmpLogData = (
42
+ {
43
+ SessionID: pRequestState.SessionData.SessionID,
44
+ RequestID: pRequest.RequestUUID,
45
+ RequestURL: pRequest.url,
46
+ Scope: this._Controller.DAL.scope,
47
+ Action: `${this._Controller.DAL.scope}-${pRequestState.Verb}`,
48
+ Verb: pRequestState.Verb
49
+ });
50
+
51
+ this._Controller.log.info(pActionSummary, this.prepareLogData(pRequest, pRequestState, tmpLogData));
52
+ }
53
+
54
+ // This is called whenever an endpoint is completed successfully
55
+ logRequestError(pRequest, pRequestState, pError)
56
+ {
57
+ let tmpErrorLogData = (
58
+ {
59
+ SessionID: pRequestState.SessionData.SessionID,
60
+ RequestID: pRequest.RequestUUID,
61
+ RequestURL: pRequest.url,
62
+ Scope: this._Controller.DAL.scope,
63
+ Action: `${this._Controller.DAL.scope}-${pRequestState.Verb}`,
64
+ Verb: pRequestState.Verb,
65
+ });
66
+
67
+ tmpErrorLogData = this._Controller.ErrorHandler.prepareRequestContextOutputObject(tmpErrorLogData, pRequest, pRequestState, pError);
68
+
69
+ this._Controller.log.error(pError.message, this.prepareLogData(pRequest, pRequestState, tmpErrorLogData));
70
+ }
71
+
72
+ trace(pLogText, pLogObject)
73
+ {
74
+ this._Controller.DAL.log.trace(pLogText, pLogObject);
75
+ }
76
+
77
+ debug(pLogText, pLogObject)
78
+ {
79
+ this._Controller.DAL.log.debug(pLogText, pLogObject);
80
+ }
81
+
82
+ info(pLogText, pLogObject)
83
+ {
84
+ this._Controller.DAL.log.info(pLogText, pLogObject);
85
+ }
86
+
87
+ warn(pLogText, pLogObject)
88
+ {
89
+ this._Controller.DAL.log.warn(pLogText, pLogObject);
90
+ }
91
+
92
+ error(pLogText, pLogObject)
93
+ {
94
+ this._Controller.DAL.log.error(pLogText, pLogObject);
95
+ }
96
+
97
+ fatal(pLogText, pLogObject)
98
+ {
99
+ this._Controller.DAL.log.fatal(pLogText, pLogObject);
100
+ }
101
+ }
102
+
103
+ module.exports = MeadowEndpointsControllerLogBase;