meadow-endpoints 3.0.7 → 4.0.3

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/Controller/Meadow-Endpoints-Controller-Base.js +161 -0
  13. package/source/Controller/components/Meadow-Endpoints-Controller-BehaviorInjection.js +125 -0
  14. package/source/Controller/components/Meadow-Endpoints-Controller-Error-StatusCodes.txt +189 -0
  15. package/source/Controller/components/Meadow-Endpoints-Controller-Error.js +118 -0
  16. package/source/Controller/components/Meadow-Endpoints-Controller-Log.js +103 -0
  17. package/source/Controller/utility/Meadow-Endpoints-Filter-Parser.js +225 -0
  18. package/source/Controller/utility/Meadow-Endpoints-Session-Marshaler.js +48 -0
  19. package/source/Controller/utility/Meadow-Endpoints-Stream-RecordArray.js +66 -0
  20. package/source/Meadow-Endpoints-Browser-Shim.js +14 -0
  21. package/source/Meadow-Endpoints.js +176 -565
  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 +53 -0
  45. package/source/endpoints/upsert/Meadow-Endpoint-Upsert.js +58 -0
  46. package/source/endpoints/upsert/Meadow-Operation-Upsert.js +132 -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
@@ -1,623 +1,234 @@
1
1
  /**
2
- * Meadow Data Broker Library
2
+ * Meadow Endpoints Service Data Broker Library
3
3
  *
4
4
  * @license MIT
5
- *
6
5
  * @author Steven Velozo <steven@velozo.com>
7
- * @module Meadow
8
6
  */
9
7
 
10
- /**
11
- * Meadow Data Broker Library
12
- *
13
- * @class MeadowEndpoints
14
- * @constructor
15
- */
16
- var MeadowEndpoints = function()
8
+ const libMeadowEndpointsControllerBase = require('./controller/Meadow-Endpoints-Controller-Base.js');
9
+ const libMeadow = require('meadow');
10
+
11
+ class MeadowEndpoints
17
12
  {
18
- function createNew(pMeadow)
13
+ constructor(pMeadow, pControllerOptions)
19
14
  {
20
- // If a valid Fable object isn't passed in, return a constructor
21
- if ((typeof(pMeadow) !== 'object') || !('fable' in pMeadow))
22
- {
23
- return {new: createNew};
24
- }
25
- var _Meadow = pMeadow;
26
- var _Fable = pMeadow.fable;
27
-
28
- var libAsync = require('async');
29
- var libRestRouteParse = require('./Restify-RouteParser.js');
15
+ this._Meadow = pMeadow;
16
+ // This is for backwards compatibility
17
+ this.DAL = this._Meadow;
30
18
 
31
- const _AuthenticationMode = _Fable.settings.MeadowAuthenticationMode || 'Disabled';
19
+ this._Controller = false;
20
+ this._ControllerOptions = (typeof(pControllerOptions) == 'object') ? pControllerOptions : {};
32
21
 
33
- var _CommonServices = require('./Meadow-CommonServices.js').new(pMeadow, _AuthenticationMode);
34
-
35
- // This holds any changed behaviors.
36
- var _BehaviorModifications = require('./Meadow-BehaviorModifications.js').new(pMeadow);
37
-
38
- // This holds the authorizers.
39
- var _Authorizers = require('./Meadow-Authorizers.js').new(pMeadow);
40
-
41
- // This checks that the user is authenticated. In the future, it will be overloadable.
42
- var _Authenticator = require('./Meadow-Authenticator.js')(_AuthenticationMode);
43
-
44
- // The default endpoints
45
- var _Endpoints = (
22
+ if (typeof(pMeadow) != 'object')
46
23
  {
47
- Create: require('./crud/Meadow-Endpoint-Create.js'),
48
- Creates: require('./crud/Meadow-Endpoint-BulkCreate.js'),
49
-
50
- Read: require('./crud/Meadow-Endpoint-Read.js'),
51
- ReadMax: require('./crud/Meadow-Endpoint-ReadMax.js'),
52
-
53
- Reads: require('./crud/Meadow-Endpoint-Reads.js'),
54
- ReadsBy: require('./crud/Meadow-Endpoint-ReadsBy.js'),
55
-
56
- ReadSelectList: require('./crud/Meadow-Endpoint-ReadSelectList.js'),
57
- ReadLiteList: require('./crud/Meadow-Endpoint-ReadLiteList.js'),
58
- ReadDistinctList: require('./crud/Meadow-Endpoint-ReadDistinctList.js'),
59
-
60
- Update: require('./crud/Meadow-Endpoint-Update.js'),
61
- Updates: require('./crud/Meadow-Endpoint-BulkUpdate.js'),
62
-
63
- Upsert: require('./crud/Meadow-Endpoint-Upsert.js'),
64
- Upserts: require('./crud/Meadow-Endpoint-BulkUpsert.js'),
65
-
66
- Delete: require('./crud/Meadow-Endpoint-Delete.js'),
67
- Undelete: require('./crud/Meadow-Endpoint-Undelete.js'),
68
-
69
- Count: require('./crud/Meadow-Endpoint-Count.js'),
70
- CountBy: require('./crud/Meadow-Endpoint-CountBy.js'),
71
-
72
- // Get the JSONSchema spec schema
73
- /* http://json-schema.org/examples.html
74
- * http://json-schema.org/latest/json-schema-core.html
75
- */
76
- Schema: require('./schema/Meadow-Endpoint-Schema.js'),
77
- // Validate a passed-in JSON object for if it matches the schema
78
- Validate: require('./schema/Meadow-Endpoint-Validate.js'),
79
- // Get an empty initialized JSON object for this.
80
- New: require('./schema/Meadow-Endpoint-New.js')
81
- });
82
-
83
- /**
84
- * Customize a default endpoint (or create more)
85
- *
86
- * @method setEndpoint
87
- */
88
- var setEndpoint = function(pEndpointHash, fEndpoint)
89
- {
90
- if (typeof(fEndpoint) === 'function')
91
- {
92
- _Endpoints[pEndpointHash] = fEndpoint;
93
- }
94
-
95
- return this;
96
- };
97
-
24
+ throw new Error('Meadow endpoints requires a valid Meadow DAL object as the first parameter of the constructor.');
25
+ }
98
26
 
99
- // The default authenticators
100
- var _EndpointAuthenticators = (
27
+ if (this._ControllerOptions.hasOwnProperty('ControllerInstance'))
101
28
  {
102
- Create: _Authenticator,
103
- Read: _Authenticator,
104
- Reads: _Authenticator,
105
- Update: _Authenticator,
106
- Delete: _Authenticator,
107
- Count: _Authenticator,
108
-
109
- Schema: _Authenticator,
110
- Validate: _Authenticator,
111
- New: _Authenticator
112
- });
113
-
114
- /**
115
- * Customize an endpoint Authenticator
116
- *
117
- * @method setEndpointAuthenticator
118
- */
119
- var setEndpointAuthenticator = function(pEndpointHash, fAuthenticator)
29
+ // Passed in already instantiated controller instance
30
+ this._Controller = this._ControllerOptions.ControllerInstance;
31
+ }
32
+ else if (this._ControllerOptions.hasOwnProperty('ControllerClass'))
120
33
  {
121
- if (typeof(fAuthenticator) === 'function')
122
- {
123
- _EndpointAuthenticators[pEndpointHash] = fAuthenticator;
124
- }
125
-
126
- return this;
127
- };
128
-
129
-
130
- // The default endpoint authorization levels
131
- var _EndpointAuthorizationLevels = (
34
+ // Passed in controller class, ready to initialize
35
+ this._Controller = new this._ControllerOptions.ControllerClass(this);
36
+ }
37
+ else
132
38
  {
133
- Create: 1,
134
- Read: 0,
135
- Reads: 0,
136
- Update: 1,
137
- Delete: 1,
138
- Count: 0,
139
-
140
- Schema: 0,
141
- Validate: 0,
142
- New: 1
143
- });
39
+ this._Controller = new libMeadowEndpointsControllerBase(this);
40
+ }
144
41
 
42
+ // Pull version from the settings; default to 1.0
43
+ this.EndpointVersion = this._Controller.settings.MeadowEndpointVersion || '1.0';
44
+ // Pull endpoint name from settings if the user to override the endpoint "name" eventually.
45
+ this.EndpointName = this.DAL.scope;
46
+ // This allows a wily developer to change what this prefix is....
47
+ this.EndpointPrefix = `/${this.EndpointVersion}/${this.EndpointName}`;
145
48
 
146
- // The default behaviors available.
49
+ // The default behavior sets available.
147
50
  // Turning these off before wiring the endpoints up will result in their counterpart endpoints not being available.
148
- var _EnabledBehaviors = (
51
+ this._EnabledBehaviorSets = (
149
52
  {
150
53
  Create: true,
151
- // POST [/1.0/SomeEndpoint]
152
-
153
54
  Read: true,
154
- // GET [/1.0/SomeEndpoint/:IDRecord]
155
- // GET [/1.0/SomeEndpoint/Max/:ColumnName]
156
-
157
55
  Reads: true,
158
- // GET [/1.0/SomeEndpoints]
159
- // GET [/1.0/SomeEndpoints/:Begin/:Cap]
160
- // GET [/1.0/SomeEndpoints/By/:ByField/:ByValue]
161
- // GET [/1.0/SomeEndpoints/By/:ByField/:ByValue/:Begin/:Cap]
162
- // GET [/1.0/SomeEndpoints/FilteredTo/:Filter]
163
- // GET [/1.0/SomeEndpoints/FilteredTo/:Filter/:Begin/:Cap]
164
- // GET [/1.0/SomeEndpointSelect]
165
- // GET [/1.0/SomeEndpointSelect/:Begin/:Cap]
166
- // GET [/1.0/SomeEndpointSelect/FilteredTo/:Filter]
167
- // GET [/1.0/SomeEndpointSelect/FilteredTo/:Filter/:Begin/:Cap]
168
- // GET [/1.0/SomeEndpoint/Lite]
169
- // GET [/1.0/SomeEndpoint/Lite/:Begin/:Cap]
170
- // GET [/1.0/SomeEndpoint/Lite/FilteredTo/:Filter]
171
- // GET [/1.0/SomeEndpoint/Lite/FilteredTo/:Filter/:Begin/:Cap]
172
- // GET [/1.0/SomeEndpoint/LiteExtended/:ExtraColumns]
173
- // GET [/1.0/SomeEndpoint/LiteExtended/:ExtraColumns/:Begin/:Cap]
174
- // GET [/1.0/SomeEndpoint/LiteExtended/:ExtraColumns/FilteredTo/:Filter]
175
- // GET [/1.0/SomeEndpoint/LiteExtended/:ExtraColumns/FilteredTo/:Filter/:Begin/:Cap]
176
- // GET [/1.0/SomeEndpoint/Distinct/:Columns]
177
- // GET [/1.0/SomeEndpoint/Distinct/:Columns/:Begin/:Cap]
178
- // GET [/1.0/SomeEndpoint/Distinct/:Columns/FilteredTo/:Filter]
179
- // GET [/1.0/SomeEndpoint/Distinct/:Columns/FilteredTo/:Filter/:Begin/:Cap]
180
-
181
56
  Update: true,
182
- // PUT [/1.0/SomeEndpoint]
183
- // PUT [/1.0/SomeEndpoint/Upsert]
184
-
185
57
  Delete: true,
186
- // DEL [/1.0/SomeEndpoint]
187
- // DEL [/1.0/SomeEndpoint/:IDRecord]
188
- // GET [/1.0/SomeEndpoint/Undelete/:IDRecord]
189
-
190
58
  Count: true,
191
- // GET [/1.0/SomeEndpoints/Count]
192
- // GET [/1.0/SomeEndpoints/Count/By/:ByField/:ByValue]
193
- // GET [/1.0/SomeEndpoints/Count/FilteredTo/:Filter]
194
-
195
59
  Schema: true,
196
- // GET [/1.0/SomeEndpoint/Schema]
197
-
198
60
  Validate: true,
199
- // POST [/1.0/SomeEndpoint/Schema/Validate]
200
-
201
61
  New: true
202
- // GET [/1.0/SomeEndpoint/Schema/New]
203
62
  });
204
63
 
205
- /**
206
- * Customize an endpoint Authorization Level
207
- *
208
- * @method setEndpointAuthorization
209
- */
210
- var setEndpointAuthorization = function(pEndpointHash, pAuthorizationLevel)
211
- {
212
- _EndpointAuthorizationLevels[pEndpointHash] = pAuthorizationLevel;
213
- return true;
214
- };
215
-
216
-
217
- /**
218
- * Add the common services object to the request early in the route chain
219
- */
220
- var wireCommonServices = function (pRequest, pResponse, fNext)
64
+ // The default endpoints
65
+ this._Endpoints = (
221
66
  {
222
- // TODO: There is a shared state issue with using this as the source for the authorization levels. Fix it.
223
- pRequest.CommonServices = _CommonServices;
224
- fNext();
225
- };
226
-
67
+ Create: require('./endpoints/create/Meadow-Endpoint-Create.js'),
68
+ Creates: require('./endpoints/create/Meadow-Endpoint-BulkCreate.js'),
227
69
 
228
- /**
229
- * Add the explicit state to the request that is coming through this endpoint
230
- */
231
- var wireState = function (pRequest, pResponse, fNext)
232
- {
233
- // TODO: There is a shared state issue with using this as the source for the authorization levels. Fix it.
234
- pRequest.EndpointAuthorizationLevels = _EndpointAuthorizationLevels;
235
- pRequest.DAL = _Meadow;
236
- pRequest.BehaviorModifications = _BehaviorModifications;
237
- pRequest.Authorizers = _Authorizers;
238
- pRequest.forEachRecord = function(fIterator)
239
- {
240
- if (pRequest.Record)
241
- return fIterator(pRequest.Record)
242
- else if (pRequest.Records)
243
- return pRequest.Records.forEach(fIterator);
244
- }
70
+ Read: require('./endpoints/read/Meadow-Endpoint-Read.js'),
71
+ ReadMax: require('./endpoints/read/Meadow-Endpoint-ReadMax.js'),
245
72
 
246
- //maximum number of records to return by default on Read queries. Override via "MeadowDefaultMaxCap" fable setting.
247
- pRequest.DEFAULT_MAX_CAP = (_Fable.settings['MeadowDefaultMaxCap']) || 250;
73
+ Reads: require('./endpoints/read/Meadow-Endpoint-Reads.js'),
74
+ ReadsBy: require('./endpoints/read/Meadow-Endpoint-ReadsBy.js'),
248
75
 
249
- fNext();
250
- };
76
+ ReadSelectList: require('./endpoints/read/Meadow-Endpoint-ReadSelectList.js'),
77
+ ReadLiteList: require('./endpoints/read/Meadow-Endpoint-ReadLiteList.js'),
78
+ ReadDistinctList: require('./endpoints/read/Meadow-Endpoint-ReadDistinctList.js'),
251
79
 
252
- /**
253
- * Reparse route parameters, attach 'formattedParams' to Request obj
254
- */
255
- var formatRouteParams = function(pRequest, pResponse, fNext)
256
- {
257
- if (pRequest.method === 'GET')
258
- {
259
- var tmpParams = libRestRouteParse(
260
- pRequest.route.path,
261
- pRequest.url
262
- );
80
+ Update: require('./endpoints/update/Meadow-Endpoint-Update.js'),
81
+ Updates: require('./endpoints/update/Meadow-Endpoint-BulkUpdate.js'),
263
82
 
264
- for(var key in tmpParams)
265
- {
266
- var tmpArray = tmpParams[key].split(',');
267
- if (tmpArray.length > 1)
268
- {
269
- for(var i=0; i<tmpArray.length; i++)
270
- {
271
- tmpArray[i] = decodeURIComponent(tmpArray[i]);
272
- }
83
+ Upsert: require('./endpoints/upsert/Meadow-Endpoint-Upsert.js'),
84
+ Upserts: require('./endpoints/upsert/Meadow-Endpoint-BulkUpsert.js'),
273
85
 
274
- tmpParams[key] = tmpArray;
275
- }
276
- else
277
- {
278
- tmpParams[key] = decodeURIComponent(tmpParams[key]);
279
- }
280
- }
86
+ Delete: require('./endpoints/delete/Meadow-Endpoint-Delete.js'),
87
+ Undelete: require('./endpoints/delete/Meadow-Endpoint-Undelete.js'),
281
88
 
282
- pRequest.formattedParams = tmpParams;
283
- }
89
+ Count: require('./endpoints/count/Meadow-Endpoint-Count.js'),
90
+ CountBy: require('./endpoints/count/Meadow-Endpoint-CountBy.js'),
284
91
 
285
- //libRestRouteParse
286
- return fNext();
287
- };
92
+ // Get the JSONSchema spec schema
93
+ /* http://json-schema.org/examples.html
94
+ * http://json-schema.org/latest/json-schema-core.html
95
+ */
96
+ Schema: require('./endpoints/schema/Meadow-Endpoint-Schema.js'),
97
+ // Validate a passed-in JSON object for if it matches the schema
98
+ Validate: require('./endpoints/schema/Meadow-Endpoint-Validate.js'),
99
+ // Get an empty initialized JSON object for this.
100
+ New: require('./endpoints/schema/Meadow-Endpoint-New.js')
101
+ });
102
+ }
288
103
 
104
+ get controller()
105
+ {
106
+ return this._Controller;
107
+ }
108
+ set controller(pController)
109
+ {
110
+ this._Controller = pController;
111
+ }
289
112
 
290
- /**
291
- * Wire up routes for the API
292
- *
293
- * @method connectRoutes
294
- * @param {Object} pRestServer The Restify server object to add routes to
295
- */
296
- var connectRoutes = function(pRestServer)
113
+ /**
114
+ * Customize a default endpoint (or create more)
115
+ *
116
+ * @method setEndpoint
117
+ */
118
+ setBehaviorEndpoint(pEndpointHash, fEndpoint)
119
+ {
120
+ if (typeof(fEndpoint) === 'function')
297
121
  {
298
- // TODO: Pull version from the config file.
299
- const tmpEndpointVersion = _Fable.settings.MeadowEndpointVersion || '1.0';
300
- // TODO: Allow the user to override the endpoint "name" eventually.
301
- const tmpEndpointName = _Meadow.scope;
302
-
303
- _Fable.log.trace('Creating endpoint', { Version: tmpEndpointVersion, Name: tmpEndpointName });
304
-
305
- const tmpEndpointPrefix = `/${tmpEndpointVersion}/${tmpEndpointName}`;
306
-
307
- if (!pRestServer._AttachedMeadowEndpointsRequestHandlers)
308
- {
309
- pRestServer._AttachedMeadowEndpointsRequestHandlers = true;
310
- // Connect the common services to the route
311
- pRestServer.use(wireCommonServices);
312
-
313
- // Build formattedParams route parameters
314
- pRestServer.use(formatRouteParams);
315
-
316
- // Marshall session data in, if needed / configured
317
- pRestServer.use(require('./Meadow-MarshallSessionData')(_Fable));
318
- }
319
-
320
- // These special schema services must come in the route table before the READ because they
321
- // technically block out the routes for the IDRecord 'Schema' (e.g. /1.0/EntityName/Schema)
322
- if (_EnabledBehaviors.Schema)
323
- {
324
- pRestServer.get(`${tmpEndpointPrefix}/Schema`, _EndpointAuthenticators.Schema, wireState, _Endpoints.Schema);
325
- }
326
- if (_EnabledBehaviors.New)
327
- {
328
- pRestServer.get(`${tmpEndpointPrefix}/Schema/New`, _EndpointAuthenticators.New, wireState, _Endpoints.New);
329
- }
330
- if (_EnabledBehaviors.Validate)
331
- {
332
- pRestServer.post(`${tmpEndpointPrefix}/Schema/Validate`, _CommonServices.bodyParser(), _EndpointAuthenticators.Validate, wireState, _Endpoints.Validate);
333
- }
122
+ this._Endpoints[pEndpointHash] = fEndpoint;
123
+ }
334
124
 
335
- // Custom single record endpoints
125
+ return this;
126
+ }
336
127
 
337
- // Standard CRUD and Count endpoints
338
- if (_EnabledBehaviors.Create)
339
- {
340
- pRestServer.post(`${tmpEndpointPrefix}`, _CommonServices.bodyParser(), _EndpointAuthenticators.Create, wireState, _Endpoints.Create);
341
- pRestServer.post(`${tmpEndpointPrefix}s`, _CommonServices.bodyParser(), _EndpointAuthenticators.Create, wireState, _Endpoints.Creates);
342
- }
343
- if (_EnabledBehaviors.Read)
344
- {
345
- pRestServer.get(`${tmpEndpointPrefix}/Max/:ColumnName`, _EndpointAuthenticators.Read, wireState, _Endpoints.ReadMax);
346
- pRestServer.get(`${tmpEndpointPrefix}/:IDRecord`, _EndpointAuthenticators.Read, wireState, _Endpoints.Read);
347
- }
348
- if (_EnabledBehaviors.Reads)
349
- {
350
- pRestServer.get(`${tmpEndpointPrefix}s`, _EndpointAuthenticators.Reads, wireState, _Endpoints.Reads);
351
- pRestServer.get(`${tmpEndpointPrefix}s/By/:ByField/:ByValue`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadsBy);
352
- pRestServer.get(`${tmpEndpointPrefix}s/By/:ByField/:ByValue/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadsBy);
353
- pRestServer.get(`${tmpEndpointPrefix}s/FilteredTo/:Filter`, _EndpointAuthenticators.Reads, wireState, _Endpoints.Reads);
354
- pRestServer.get(`${tmpEndpointPrefix}s/FilteredTo/:Filter/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.Reads);
355
- pRestServer.get(`${tmpEndpointPrefix}Select`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadSelectList);
356
- pRestServer.get(`${tmpEndpointPrefix}Select/FilteredTo/:Filter`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadSelectList);
357
- pRestServer.get(`${tmpEndpointPrefix}Select/FilteredTo/:Filter/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadSelectList);
358
- pRestServer.get(`${tmpEndpointPrefix}Select/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadSelectList);
359
- pRestServer.get(`${tmpEndpointPrefix}s/Lite`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
360
- pRestServer.get(`${tmpEndpointPrefix}s/Lite/FilteredTo/:Filter`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
361
- pRestServer.get(`${tmpEndpointPrefix}s/Lite/FilteredTo/:Filter/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
362
- pRestServer.get(`${tmpEndpointPrefix}s/Lite/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
363
- pRestServer.get(`${tmpEndpointPrefix}s/LiteExtended/:ExtraColumns`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
364
- pRestServer.get(`${tmpEndpointPrefix}s/LiteExtended/:ExtraColumns/FilteredTo/:Filter`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
365
- pRestServer.get(`${tmpEndpointPrefix}s/LiteExtended/:ExtraColumns/FilteredTo/:Filter/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
366
- pRestServer.get(`${tmpEndpointPrefix}s/LiteExtended/:ExtraColumns/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadLiteList);
367
- pRestServer.get(`${tmpEndpointPrefix}s/Distinct/:Columns`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadDistinctList);
368
- pRestServer.get(`${tmpEndpointPrefix}s/Distinct/:Columns/FilteredTo/:Filter`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadDistinctList);
369
- pRestServer.get(`${tmpEndpointPrefix}s/Distinct/:Columns/FilteredTo/:Filter/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadDistinctList);
370
- pRestServer.get(`${tmpEndpointPrefix}s/Distinct/:Columns/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.ReadDistinctList);
371
- pRestServer.get(`${tmpEndpointPrefix}s/:Begin/:Cap`, _EndpointAuthenticators.Reads, wireState, _Endpoints.Reads);
372
- }
373
- if (_EnabledBehaviors.Update)
374
- {
375
- pRestServer.put(`${tmpEndpointPrefix}`, _CommonServices.bodyParser(), _EndpointAuthenticators.Update, wireState, _Endpoints.Update);
376
- pRestServer.put(`${tmpEndpointPrefix}s`, _CommonServices.bodyParser(), _EndpointAuthenticators.Update, wireState, _Endpoints.Updates);
377
- pRestServer.put(`${tmpEndpointPrefix}/Upsert`, _CommonServices.bodyParser(), _EndpointAuthenticators.Update, wireState, _Endpoints.Upsert);
378
- pRestServer.put(`${tmpEndpointPrefix}/Upserts`, _CommonServices.bodyParser(), _EndpointAuthenticators.Update, wireState, _Endpoints.Upserts);
379
- }
380
- if (_EnabledBehaviors.Delete)
381
- {
382
- pRestServer.del(`${tmpEndpointPrefix}`, _CommonServices.bodyParser(), _EndpointAuthenticators.Delete, wireState, _Endpoints.Delete);
383
- pRestServer.del(`${tmpEndpointPrefix}/:IDRecord`, _EndpointAuthenticators.Delete, wireState, _Endpoints.Delete);
384
- pRestServer.get(`${tmpEndpointPrefix}/Undelete/:IDRecord`, _EndpointAuthenticators.Delete, wireState, _Endpoints.Undelete);
385
- }
386
- if (_EnabledBehaviors.Count)
387
- {
388
- pRestServer.get(`${tmpEndpointPrefix}s/Count`, _EndpointAuthenticators.Count, wireState, _Endpoints.Count);
389
- pRestServer.get(`${tmpEndpointPrefix}s/Count/By/:ByField/:ByValue`, _EndpointAuthenticators.Count, wireState, _Endpoints.CountBy);
390
- pRestServer.get(`${tmpEndpointPrefix}s/Count/FilteredTo/:Filter`, _EndpointAuthenticators.Count, wireState, _Endpoints.Count);
391
- }
392
- };
128
+ connectRoute(pServiceServer, pRequestMethod, pRoutePartial, pEndpointProcessingFunction, pBehaviorName)
129
+ {
130
+ let tmpRoute = `${this.EndpointPrefix}${pRoutePartial}`;
131
+ let tmpBehaviorName = (typeof(pBehaviorName) == 'string') ? pBehaviorName : 'an unnamed custom behavior'
393
132
 
133
+ this._Controller.log.trace(`...meadow-endpoints mapping a ${pRequestMethod} endpoint for scope ${this.DAL.scope} on route [${tmpRoute}] which runs ${tmpBehaviorName}.`);
394
134
 
395
- /**
396
- * Emulate a response object
397
- */
398
- var wireResponse = function(pResponse, fCallback)
135
+ try
399
136
  {
400
- pResponse.send = function(data)
401
- {
402
- this.body = data;
403
-
404
- if (!data.Error)
405
- {
406
- if (data.constructor === Array)
407
- {
408
- this.Records = data;
409
- }
410
- else
411
- {
412
- this.Record = data;
413
- }
414
- }
415
- };
416
-
417
- Object.defineProperty(pResponse, 'text',
418
- {
419
- get: function() { return JSON.stringify(pResponse.body); },
420
- enumerable: true
421
- });
137
+ (pServiceServer[pRequestMethod])(tmpRoute, pEndpointProcessingFunction.bind(this._Controller));
138
+ }
139
+ catch (pServiceServerRouteConnectError)
140
+ {
141
+ this._Controller.log.error(`...error mapping ${pBehaviorName} to method ${pRequestMethod} for scope ${this.DAL.scope} to route [${tmpRoute}]: ${pServiceServerRouteConnectError}`, pServiceServerRouteConnectError.stack);
142
+ }
143
+ return true;
144
+ }
422
145
 
423
- return fCallback();
424
- };
146
+ connectRoutes(pServiceServer)
147
+ {
148
+ this._Controller.log.trace(`Creating automatic meadow endpoints at prefix [${this.EndpointPrefix}] for scope ${this.DAL.scope}...`);
425
149
 
426
- var _InvokeSetupCallback;
427
- var getInvokeSetupCallback = function()
150
+ // These special schema services must come in the route table before the READ because they
151
+ // technically block out the routes for the IDRecord 'Schema' (e.g. GET[/1.0/EntityName/Schema] ==NEEDS=> GET[/1.0/EntityName/100])
152
+ if (this._EnabledBehaviorSets.Schema)
428
153
  {
429
- return _InvokeSetupCallback;
430
- };
431
-
432
- var setInvokeSetupCallback = function(fCallback)
154
+ this.connectRoute(pServiceServer, 'get', `/Schema`, this._Endpoints.Schema, `the internal behavior _Endpoints.Schema`);
155
+ }
156
+ if (this._EnabledBehaviorSets.New)
433
157
  {
434
- _InvokeSetupCallback = fCallback;
435
- };
436
-
437
- /**
438
- * Invoke a meadow endpoint programmatically
439
- *
440
- * @method invokeEndpoint
441
- */
442
- var invokeEndpoint = function(pMethod, pData, pOptions, fCallback)
158
+ this.connectRoute(pServiceServer, 'get', `/Schema/New`, this._Endpoints.New, `the internal behavior _Endpoints.New`);
159
+ }
160
+ if (this._EnabledBehaviorSets.Validate)
443
161
  {
444
- var tmpCallback = (typeof(pOptions) === 'function') ? pOptions : fCallback;
445
-
446
- if (!_Endpoints[pMethod])
447
- {
448
- _CommonServices.log.error('Endpoint \'' + pMethod + '\' does not exist!');
449
- return tmpCallback('Endpoint \'' + pMethod + '\' does not exist!'); //might be better as an exception
450
- }
451
-
452
- // TODO: should switch depending on type
453
- // TODO: should we keep this around, just make a deep copy of 'pOptions'
454
- var pRequest = {params: pData, formattedParams: pData, body: pData};
455
- if (typeof(pOptions) === 'object' && typeof(pOptions.header) === 'function') {
456
- // carry over header function
457
- pRequest.header = pOptions.header.bind(pOptions);
458
- }
459
- var pResponse = {};
460
-
461
- libAsync.waterfall([
462
- function(fStageComplete)
463
- {
464
- return wireResponse(pResponse, fStageComplete);
465
- },
466
- function(fStageComplete)
467
- {
468
- //allow consumer to specify user session data
469
- if (pOptions.UserSession)
470
- {
471
- //make a copy of the UserSession
472
- pRequest.UserSession = JSON.parse(JSON.stringify(pOptions.UserSession));
473
- }
474
- else
475
- {
476
- //else fill in default user session data
477
- pRequest.EndpointInvoked = true; //bypass session auth check
478
- pRequest.UserSession = { UserID: 0, UserRoleIndex: 0 };
479
- }
480
-
481
- // The Satchel is a workaround to pass state between query invocation and query decoration
482
- // Unfortunately, it has other uses, so we can't safely remove it here; this creates a risk of
483
- // cross-request state contamination (which we have seen cause issues).
484
- //FIXME: We should rework invokeEndpoint to make this state management unnecessary
485
- pRequest.Satchel = pOptions.Satchel;
486
- //internal invoke mark as authenticated (because this is not called via webservice)
487
- pRequest.EndpointAuthenticated = true;
488
-
489
- if (_InvokeSetupCallback && typeof(_InvokeSetupCallback) == 'function')
490
- {
491
- _InvokeSetupCallback(pRequest, pResponse, typeof(pOptions) === 'object' && pOptions);
492
- }
493
- return fStageComplete();
494
- },
495
- function(fStageComplete)
496
- {
497
- return wireCommonServices(pRequest, pResponse, fStageComplete);
498
- },
499
- function(fStageComplete)
500
- {
501
- return wireState(pRequest, pResponse, fStageComplete);
502
- },
503
- function(fStageComplete)
504
- {
505
- //Invoke the endpoint method
506
- _Endpoints[pMethod](pRequest, pResponse, function(err)
507
- {
508
- return fStageComplete(err, pResponse);
509
- });
510
- }
511
- ],
512
- function complete(err)
513
- {
514
- return tmpCallback(err, pResponse);
515
- });
516
- };
517
-
162
+ this.connectRoute(pServiceServer, 'postWithBodyParser', `/Schema/Validate`, this._Endpoints.Validate, `the internal behavior _Endpoints.Validate`);
163
+ }
518
164
 
519
- /**
520
- * Container Object for our Factory Pattern
521
- */
522
- var tmpNewMeadowEndpointObject = (
165
+ // Standard CRUD and Count endpoints
166
+ if (this._EnabledBehaviorSets.Create)
523
167
  {
524
- setEndpoint: setEndpoint,
525
- setEndpointAuthenticator: setEndpointAuthenticator,
526
- setEndpointAuthorization: setEndpointAuthorization,
527
-
528
- wireState: wireState,
529
-
530
- connectRoutes: connectRoutes,
531
-
532
- parseFilter: require('meadow-filter').parse,
533
-
534
- // Expose the DAL
535
- DAL: _Meadow,
536
-
537
- getInvokeSetupCallback: getInvokeSetupCallback,
538
- setInvokeSetupCallback: setInvokeSetupCallback,
539
- invokeEndpoint: invokeEndpoint,
540
-
541
- // Factory
542
- new: createNew
543
- });
544
-
545
- /**
546
- * Endpoint Authorization Levels
547
- *
548
- * @property endpointAuthorizationLevels
549
- * @type object
550
- */
551
- Object.defineProperty(tmpNewMeadowEndpointObject, 'endpointAuthorizationLevels',
552
- {
553
- get: function() { return _EndpointAuthorizationLevels; },
554
- enumerable: true
555
- });
556
-
557
- /**
558
- * Endpoints
559
- *
560
- * @property endpoints
561
- * @type object
562
- */
563
- Object.defineProperty(tmpNewMeadowEndpointObject, 'endpoints',
564
- {
565
- get: function() { return _Endpoints; },
566
- enumerable: true
567
- });
568
-
569
- /**
570
- * EndpointAuthenticators
571
- *
572
- * @property endpointAuthorizers
573
- * @type object
574
- */
575
- Object.defineProperty(tmpNewMeadowEndpointObject, 'endpointAuthorizers',
576
- {
577
- get: function() { return _Authorizers; },
578
- enumerable: true
579
- });
580
-
581
- /**
582
- * EndpointAuthenticators
583
- *
584
- * @property endpointAuthenticators
585
- * @type object
586
- */
587
- Object.defineProperty(tmpNewMeadowEndpointObject, 'endpointAuthenticators',
588
- {
589
- get: function() { return _EndpointAuthenticators; },
590
- enumerable: true
591
- });
592
-
593
- /**
594
- * EnabledBehaviors
595
- *
596
- * @property enabledBehaviors
597
- * @type object
598
- */
599
- Object.defineProperty(tmpNewMeadowEndpointObject, 'enabledBehaviors',
600
- {
601
- get: function() { return _EnabledBehaviors; },
602
- enumerable: true
603
- });
168
+ this.connectRoute(pServiceServer, 'postWithBodyParser', ``, this._Endpoints.Create, `the internal behavior _Endpoints.Create`);
169
+ this.connectRoute(pServiceServer, 'postWithBodyParser', `s`, this._Endpoints.Creates, `the internal behavior _Endpoints.Creates`);
170
+ }
171
+ if (this._EnabledBehaviorSets.Read)
172
+ {
173
+ this.connectRoute(pServiceServer, 'get', `/Max/:ColumnName`, this._Endpoints.ReadMax, `the internal behavior _Endpoints.ReadMax`);
174
+ this.connectRoute(pServiceServer, 'get', `/:IDRecord`, this._Endpoints.Read, `the internal behavior _Endpoints.Read`);
175
+ }
176
+ if (this._EnabledBehaviorSets.Reads)
177
+ {
178
+ this.connectRoute(pServiceServer, 'get', `s`, this._Endpoints.Reads, `the internal behavior _Endpoints.Reads`);
179
+ this.connectRoute(pServiceServer, 'get', `s/By/:ByField/:ByValue`, this._Endpoints.ReadsBy, `the internal behavior _Endpoints.ReadsBy`);
180
+ this.connectRoute(pServiceServer, 'get', `s/By/:ByField/:ByValue/:Begin/:Cap`, this._Endpoints.ReadsBy, `the internal behavior _Endpoints.ReadsBy`);
181
+ this.connectRoute(pServiceServer, 'get', `s/FilteredTo/:Filter`, this._Endpoints.Reads, `the internal behavior _Endpoints.Reads`);
182
+ this.connectRoute(pServiceServer, 'get', `s/FilteredTo/:Filter/:Begin/:Cap`, this._Endpoints.Reads, `the internal behavior _Endpoints.Reads`);
183
+ this.connectRoute(pServiceServer, 'get', `Select`, this._Endpoints.ReadSelectList, `the internal behavior _Endpoints.ReadSelectList`);
184
+ this.connectRoute(pServiceServer, 'get', `Select/FilteredTo/:Filter`, this._Endpoints.ReadSelectList, `the internal behavior _Endpoints.ReadSelectList`);
185
+ this.connectRoute(pServiceServer, 'get', `Select/FilteredTo/:Filter/:Begin/:Cap`, this._Endpoints.ReadSelectList, `the internal behavior _Endpoints.ReadSelectList`);
186
+ this.connectRoute(pServiceServer, 'get', `Select/:Begin/:Cap`, this._Endpoints.ReadSelectList, `the internal behavior _Endpoints.ReadSelectList`);
187
+ this.connectRoute(pServiceServer, 'get', `s/Lite`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
188
+ this.connectRoute(pServiceServer, 'get', `s/Lite/FilteredTo/:Filter`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
189
+ this.connectRoute(pServiceServer, 'get', `s/Lite/FilteredTo/:Filter/:Begin/:Cap`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
190
+ this.connectRoute(pServiceServer, 'get', `s/Lite/:Begin/:Cap`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
191
+ this.connectRoute(pServiceServer, 'get', `s/LiteExtended/:ExtraColumns`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
192
+ this.connectRoute(pServiceServer, 'get', `s/LiteExtended/:ExtraColumns/FilteredTo/:Filter`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
193
+ this.connectRoute(pServiceServer, 'get', `s/LiteExtended/:ExtraColumns/FilteredTo/:Filter/:Begin/:Cap`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
194
+ this.connectRoute(pServiceServer, 'get', `s/LiteExtended/:ExtraColumns/:Begin/:Cap`, this._Endpoints.ReadLiteList, `the internal behavior _Endpoints.ReadLiteList`);
195
+ this.connectRoute(pServiceServer, 'get', `s/Distinct/:Columns`, this._Endpoints.ReadDistinctList, `the internal behavior _Endpoints.ReadDistinctList`);
196
+ this.connectRoute(pServiceServer, 'get', `s/Distinct/:Columns/FilteredTo/:Filter`, this._Endpoints.ReadDistinctList, `the internal behavior _Endpoints.ReadDistinctList`);
197
+ this.connectRoute(pServiceServer, 'get', `s/Distinct/:Columns/FilteredTo/:Filter/:Begin/:Cap`, this._Endpoints.ReadDistinctList, `the internal behavior _Endpoints.ReadDistinctList`);
198
+ this.connectRoute(pServiceServer, 'get', `s/Distinct/:Columns/:Begin/:Cap`, this._Endpoints.ReadDistinctList, `the internal behavior _Endpoints.ReadDistinctList`);
199
+ this.connectRoute(pServiceServer, 'get', `s/:Begin/:Cap`, this._Endpoints.Reads, `the internal behavior _Endpoints.Reads`);
200
+ }
201
+ if (this._EnabledBehaviorSets.Update)
202
+ {
203
+ this.connectRoute(pServiceServer, 'putWithBodyParser', ``, this._Endpoints.Update, `the internal behavior _Endpoints.Update`);
204
+ this.connectRoute(pServiceServer, 'putWithBodyParser', `s`, this._Endpoints.Updates, `the internal behavior _Endpoints.Updates`);
205
+ this.connectRoute(pServiceServer, 'putWithBodyParser', `/Upsert`, this._Endpoints.Upsert, `the internal behavior _Endpoints.Upsert`);
206
+ this.connectRoute(pServiceServer, 'putWithBodyParser', `/Upserts`, this._Endpoints.Upserts, `the internal behavior _Endpoints.Upserts`);
207
+ }
208
+ if (this._EnabledBehaviorSets.Delete)
209
+ {
210
+ this.connectRoute(pServiceServer, 'del', ``, this._Endpoints.Delete, `the internal behavior _Endpoints.Delete`);
211
+ this.connectRoute(pServiceServer, 'del', `/:IDRecord`, this._Endpoints.Delete, `the internal behavior _Endpoints.Delete`);
212
+ this.connectRoute(pServiceServer, 'get', `/Undelete/:IDRecord`, this._Endpoints.Undelete, `the internal behavior _Endpoints.Undelete`);
213
+ }
214
+ if (this._EnabledBehaviorSets.Count)
215
+ {
216
+ this.connectRoute(pServiceServer, 'get', `s/Count`, this._Endpoints.Count, `the internal behavior _Endpoints.Count`);
217
+ this.connectRoute(pServiceServer, 'get', `s/Count/By/:ByField/:ByValue`, this._Endpoints.CountBy, `the internal behavior _Endpoints.CountBy`);
218
+ this.connectRoute(pServiceServer, 'get', `s/Count/FilteredTo/:Filter`, this._Endpoints.Count, `the internal behavior _Endpoints.Count`);
219
+ }
220
+ }
221
+ }
604
222
 
605
- /**
606
- * Behavior Modifications
607
- *
608
- * @property behaviorModifications
609
- * @type object
610
- */
611
- Object.defineProperty(tmpNewMeadowEndpointObject, 'behaviorModifications',
612
- {
613
- get: function() { return _BehaviorModifications; },
614
- enumerable: true
615
- });
616
223
 
617
- return tmpNewMeadowEndpointObject;
618
- }
224
+ // This is for backwards compatibility
225
+ function autoConstruct(pMeadow, pControllerOptions)
226
+ {
227
+ return new MeadowEndpoints(pMeadow, pControllerOptions);
228
+ }
619
229
 
620
- return createNew();
621
- };
230
+ module.exports = MeadowEndpoints;
231
+ module.exports.new = autoConstruct;
622
232
 
623
- module.exports = new MeadowEndpoints();
233
+ module.exports.Meadow = libMeadow;
234
+ module.exports.BaseController = libMeadowEndpointsControllerBase;