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,100 @@
1
+ /**
2
+ * Meadow Endpoint - Read a Record
3
+ */
4
+ const doAPIEndpointReadsBy = function(pRequest, pResponse, fNext)
5
+ {
6
+ let tmpRequestState = this.initializeRequestState(pRequest, 'ReadsBy');
7
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
8
+
9
+ this.waterfall(
10
+ [
11
+ // 1. Construct the Query
12
+ (fStageComplete) =>
13
+ {
14
+ tmpRequestState.Query = this.DAL.query;
15
+
16
+ var tmpCap = false;
17
+ var tmpBegin = false;
18
+ if (typeof(pRequest.params.Begin) === 'string' ||
19
+ typeof(pRequest.params.Begin) === 'number')
20
+ {
21
+ tmpBegin = parseInt(pRequest.params.Begin);
22
+ }
23
+ if (typeof(pRequest.params.Cap) === 'string' ||
24
+ typeof(pRequest.params.Cap) === 'number')
25
+ {
26
+ tmpCap = parseInt(pRequest.params.Cap);
27
+ }
28
+ else
29
+ {
30
+ //maximum number of records to return by default on Read queries. Override via "MeadowDefaultMaxCap" fable setting.
31
+ tmpCap = (this.settings['MeadowDefaultMaxCap']) || 250;
32
+ }
33
+ tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);
34
+
35
+ return fStageComplete();
36
+ },
37
+ (fStageComplete) =>
38
+ {
39
+ function addField(pByField, pByValue)
40
+ {
41
+ if (pByValue.constructor === Array)
42
+ {
43
+ tmpRequestState.Query.addFilter(pByField, pByValue, 'IN', 'AND', 'RequestByField');
44
+ }
45
+ else
46
+ {
47
+ tmpRequestState.Query.addFilter(pByField, pByValue, '=', 'AND', 'RequestByField');
48
+ }
49
+ }
50
+
51
+ var tmpFilters = pRequest.params.Filters;
52
+ if (tmpFilters &&
53
+ tmpFilters.constructor === Array)
54
+ {
55
+ tmpFilters.forEach(function(filter)
56
+ {
57
+ addField(filter.ByField, filter.ByValue);
58
+ });
59
+ }
60
+ else
61
+ {
62
+ addField(pRequest.params.ByField, pRequest.params.ByValue);
63
+ }
64
+
65
+ return fStageComplete();
66
+ },
67
+ fBehaviorInjector(`Reads-QueryConfiguration`),
68
+ (fStageComplete) =>
69
+ {
70
+ this.DAL.doReads(tmpRequestState.Query,
71
+ (pError, pQuery, pRecords) =>
72
+ {
73
+ if (!pRecords)
74
+ {
75
+ return fStageComplete(this.ErrorHandler.getError('No records found.', 404));
76
+ }
77
+ tmpRequestState.Records = pRecords;
78
+ return fStageComplete();
79
+ });
80
+ },
81
+ fBehaviorInjector(`Reads-PostOperation`),
82
+ (fStageComplete) =>
83
+ {
84
+ return this.doStreamRecordArray(pResponse, tmpRequestState.Records, fStageComplete);
85
+ },
86
+ (fStageComplete) =>
87
+ {
88
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Read a list of records by ${pRequest.params.ByField} = ${pRequest.params.ByValue}`);
89
+ return fStageComplete();
90
+ }
91
+ ],
92
+ // 7. Return the results to the user
93
+ (pError) =>
94
+ {
95
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
96
+ }
97
+ );
98
+ };
99
+
100
+ module.exports = doAPIEndpointReadsBy;
@@ -1,16 +1,7 @@
1
1
  /**
2
- * Meadow Operation - Marshal an array of records into a lite list
3
- *
4
- * @license MIT
5
- *
6
- * @author Steven Velozo <steven@velozo.com>
7
- * @module Meadow
2
+ * Meadow Operation - Marshal an array of records into a distinct list
8
3
  */
9
- /**
10
- * Shared record marshaling code
11
- */
12
-
13
- var marshalDistinctList = (pRecords, pRequest, pFieldList) =>
4
+ const marshalDistinctList = function(pRecords, pRequest, pFieldList)
14
5
  {
15
6
  if (pRecords.length < 1)
16
7
  return [];
@@ -20,7 +11,7 @@ var marshalDistinctList = (pRecords, pRequest, pFieldList) =>
20
11
  let tmpFieldList = (typeof(pFieldList) !== 'undefined') ? pFieldList : [];
21
12
 
22
13
  // See if this record has a GUID in the schema
23
- let tmpGUID = (pRequest.DAL.defaultGUIdentifier && pRequest.DAL.defaultGUIdentifier.length > 0) ? pRequest.DAL.defaultGUIdentifier : false;
14
+ let tmpGUID = (this.DAL.defaultGUIdentifier && this.DAL.defaultGUIdentifier.length > 0) ? this.DAL.defaultGUIdentifier : false;
24
15
  // Peek at the first record to check for updatedate
25
16
  let tmpHasUpdateDate = (pRecords[0].hasOwnProperty('UpdateDate')) ? true : false;
26
17
  //Include all GUID and ID fields on the record
@@ -52,4 +43,4 @@ var marshalDistinctList = (pRecords, pRequest, pFieldList) =>
52
43
  return tmpDistinctList;
53
44
  };
54
45
 
55
- module.exports = marshalDistinctList;
46
+ module.exports = marshalDistinctList;
@@ -1,16 +1,7 @@
1
1
  /**
2
2
  * Meadow Operation - Marshal an array of records into a lite list
3
- *
4
- * @license MIT
5
- *
6
- * @author Steven Velozo <steven@velozo.com>
7
- * @module Meadow
8
3
  */
9
- /**
10
- * Shared record marshaling code
11
- */
12
-
13
- var marshalLiteList = (pRecords, pRequest, pFieldList) =>
4
+ const marshalLiteList = function(pRecords, pRequest, pFieldList)
14
5
  {
15
6
  if (pRecords.length < 1)
16
7
  return [];
@@ -20,7 +11,7 @@ var marshalLiteList = (pRecords, pRequest, pFieldList) =>
20
11
  let tmpFieldList = (typeof(pFieldList) !== 'undefined') ? pFieldList : [];
21
12
 
22
13
  // See if this record has a GUID in the schema
23
- let tmpGUID = (pRequest.DAL.defaultGUIdentifier && pRequest.DAL.defaultGUIdentifier.length > 0) ? pRequest.DAL.defaultGUIdentifier : false;
14
+ let tmpGUID = (this.DAL.defaultGUIdentifier && this.DAL.defaultGUIdentifier.length > 0) ? this.DAL.defaultGUIdentifier : false;
24
15
  // Peek at the first record to check for updatedate
25
16
  let tmpHasUpdateDate = (pRecords[0].hasOwnProperty('UpdateDate')) ? true : false;
26
17
  //Include all GUID and ID fields on the record
@@ -50,9 +41,9 @@ var marshalLiteList = (pRecords, pRequest, pFieldList) =>
50
41
  {
51
42
  let tmpLiteRecord = (
52
43
  {
53
- Value: pRequest.BehaviorModifications.processTemplate('SelectList', {Record:pRecords[i]}, pRequest.DAL.scope+' #<%= Record.'+pRequest.DAL.defaultIdentifier+'%>')
44
+ Value: this.BehaviorInjection.processTemplate('SelectList', {Record:pRecords[i]}, this.DAL.scope+' #<%= Record.'+this.DAL.defaultIdentifier+'%>')
54
45
  });
55
- tmpLiteRecord[pRequest.DAL.defaultIdentifier] = pRecords[i][pRequest.DAL.defaultIdentifier];
46
+ tmpLiteRecord[this.DAL.defaultIdentifier] = pRecords[i][this.DAL.defaultIdentifier];
56
47
 
57
48
  if (tmpGUID)
58
49
  tmpLiteRecord[tmpGUID] = pRecords[i][tmpGUID];
@@ -71,4 +62,4 @@ var marshalLiteList = (pRecords, pRequest, pFieldList) =>
71
62
  return tmpLiteList;
72
63
  };
73
64
 
74
- module.exports = marshalLiteList;
65
+ module.exports = marshalLiteList;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Meadow Endpoint - Get a New, empty Record
3
+ */
4
+ const doAPIEndpointNew = function(pRequest, pResponse, fNext)
5
+ {
6
+ let tmpRequestState = this.initializeRequestState(pRequest, 'New');
7
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
8
+
9
+ this.waterfall(
10
+ [
11
+ fBehaviorInjector(`New-PreOperation`),
12
+ (fStageComplete) =>
13
+ {
14
+ // If during the PreOperation this was set, we can
15
+ if (!tmpRequestState.EmptyEntityRecord)
16
+ {
17
+ tmpRequestState.EmptyEntityRecord = this.extend({}, this.DAL.schemaFull.defaultObject);
18
+ }
19
+ return fStageComplete();
20
+ },
21
+ fBehaviorInjector(`New-PostOperation`),
22
+ (fStageComplete) =>
23
+ {
24
+ pResponse.send(tmpRequestState.EmptyEntityRecord);
25
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Delivered New ${this.DAL.scope} Record`);
26
+ return fStageComplete();
27
+ }
28
+ ],
29
+ (pError) =>
30
+ {
31
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
32
+ }
33
+ );
34
+ };
35
+
36
+ module.exports = doAPIEndpointNew;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Meadow Endpoint - Get the Record Schema
3
+ */
4
+ const doAPIEndpointSchema = function (pRequest, pResponse, fNext)
5
+ {
6
+ let tmpRequestState = this.initializeRequestState(pRequest, 'Schema');
7
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
8
+
9
+ this.waterfall(
10
+ [
11
+ fBehaviorInjector(`Schema-PreOperation`),
12
+ (fStageComplete) =>
13
+ {
14
+ // If during the PreOperation this was set, we won't overwrite
15
+ if (!pRequest.JSONSchema)
16
+ {
17
+ tmpRequestState.JSONSchema = this.extend({}, this.DAL.jsonSchema);
18
+ }
19
+ return fStageComplete();
20
+ },
21
+ fBehaviorInjector(`Schema-PostOperation`),
22
+ (fStageComplete) =>
23
+ {
24
+ pResponse.send(tmpRequestState.JSONSchema);
25
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Delivered JSONSchema for ${this.DAL.scope}`);
26
+ return fStageComplete();
27
+ }
28
+ ],
29
+ (pError) =>
30
+ {
31
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
32
+ }
33
+ );
34
+ };
35
+
36
+ module.exports = doAPIEndpointSchema;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Meadow Endpoint - Validate a Record
3
+ */
4
+ const doAPIEndpointValidate = function(pRequest, pResponse, fNext)
5
+ {
6
+ let tmpRequestState = this.initializeRequestState(pRequest, 'Validate');
7
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
8
+
9
+ this.waterfall(
10
+ [
11
+ fBehaviorInjector(`Validate-PreOperation`),
12
+ (fStageComplete) =>
13
+ {
14
+ if (typeof(pRequest.body) !== 'object')
15
+ {
16
+ return fStageComplete(this.ErrorHandler.getError('Record validate failure - a valid JSON object is required.', 500));
17
+ }
18
+ tmpRequestState.Record = pRequest.body;
19
+ return fStageComplete();
20
+ },
21
+ (fStageComplete) =>
22
+ {
23
+ tmpRequestState.RecordValidation = this.DAL.schemaFull.validateObject(tmpRequestState.Record);
24
+ return fStageComplete();
25
+ },
26
+ fBehaviorInjector(`Validate-PostOperation`),
27
+ (fStageComplete) =>
28
+ {
29
+ pResponse.send(tmpRequestState.RecordValidation);
30
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Validated Record for ${this.DAL.scope} - ${tmpRequestState.RecordValidation}`);
31
+ return fStageComplete();
32
+ }
33
+ ],
34
+ (pError) =>
35
+ {
36
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
37
+ }
38
+ );
39
+ };
40
+
41
+ module.exports = doAPIEndpointValidate;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Meadow Endpoint - Update a set of Records
3
+ */
4
+ const doUpdate = require('./Meadow-Operation-Update.js');
5
+
6
+ const doAPIEndpointUpdate = function(pRequest, pResponse, fNext)
7
+ {
8
+ let tmpRequestState = this.initializeRequestState(pRequest, 'UpdateBulk');
9
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
10
+
11
+ tmpRequestState.UpdatedRecords = [];
12
+
13
+ this.waterfall(
14
+ [
15
+ (fStageComplete) =>
16
+ {
17
+ if (!Array.isArray(pRequest.body))
18
+ {
19
+ return fStageComplete(this.ErrorHandler.getError('Record update failure - a valid record is required.', 500));
20
+ }
21
+
22
+ tmpRequestState.BulkRecords = pRequest.body;
23
+
24
+ return fStageComplete();
25
+ },
26
+ (fStageComplete) =>
27
+ {
28
+ this.eachLimit(tmpRequestState.BulkRecords, 1,
29
+ (pRecord, fCallback) =>
30
+ {
31
+ doUpdate.call(this, pRecord, pRequest, tmpRequestState, pResponse, fCallback);
32
+ }, fStageComplete);
33
+ },
34
+ (fStageComplete) =>
35
+ {
36
+ return this.doStreamRecordArray(pResponse, tmpRequestState.UpdatedRecords, fStageComplete);
37
+ },
38
+ (fStageComplete) =>
39
+ {
40
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Bulk updated ${tmpRequestState.UpdatedRecords.length} records`);
41
+ return fStageComplete();
42
+ }
43
+ ],
44
+ (pError) =>
45
+ {
46
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
47
+ });
48
+ };
49
+
50
+ module.exports = doAPIEndpointUpdate;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Meadow Endpoint - Update a Record
3
+ */
4
+ const doUpdate = require('./Meadow-Operation-Update.js');
5
+
6
+ const doAPIEndpointUpdate = function(pRequest, pResponse, fNext)
7
+ {
8
+ let tmpRequestState = this.initializeRequestState(pRequest, 'Update');
9
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
10
+
11
+ this.waterfall(
12
+ [
13
+ (fStageComplete) =>
14
+ {
15
+ if (typeof(pRequest.body) !== 'object')
16
+ {
17
+ return fStageComplete(this.ErrorHandler.getError('Record update failure - a valid record is required.', 400));
18
+ }
19
+ if (pRequest.body[this.DAL.defaultIdentifier] < 1)
20
+ {
21
+ return fStageComplete(this.ErrorHandler.getError('Record update failure - a valid record ID is required in the passed-in record.', 400));
22
+ }
23
+
24
+ tmpRequestState.Record = pRequest.body;
25
+ return fStageComplete();
26
+ },
27
+ (fStageComplete) =>
28
+ {
29
+ doUpdate.call(this, pRequest.body, pRequest, tmpRequestState, pResponse, fStageComplete);
30
+ },
31
+ (fStageComplete) =>
32
+ {
33
+ if (tmpRequestState.RecordUpdateError)
34
+ {
35
+ return fStageComplete(tmpRequestState.RecordUpdateErrorObject);
36
+ }
37
+ if (tmpRequestState.UpdatedRecords.length < 1)
38
+ {
39
+ return fStageComplete(this.ErrorHandler.getError('Unknown record update failure - no updated records returned.', 500));
40
+ }
41
+
42
+ tmpRequestState.Record = tmpRequestState.UpdatedRecords[0];
43
+
44
+ return fStageComplete();
45
+ },
46
+ (fStageComplete) =>
47
+ {
48
+ pResponse.send(tmpRequestState.Record);
49
+ return fStageComplete();
50
+ }
51
+ ],
52
+ (pError) =>
53
+ {
54
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
55
+ });
56
+ };
57
+
58
+ module.exports = doAPIEndpointUpdate;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Meadow Operation - Update a record
3
+ */
4
+ const doUpdate = function(pRecordToModify, pRequest, pRequestState, pResponse, fCallback, pOptionalCachedUpdatingRecord)
5
+ {
6
+ // This is a virtual operation
7
+ let tmpRequestState = this.cloneAsyncSafeRequestState(pRequestState, 'doUpdate');
8
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
9
+
10
+ // If there is not a default identifier or cached record, fail
11
+ if ((pRecordToModify[this.DAL.defaultIdentifier] < 1) && (typeof(pOptionalCachedUpdatingRecord) === 'undefined'))
12
+ {
13
+ return fCallback('Record update failure - a valid record ID is required in the passed-in record.');
14
+ }
15
+
16
+ if (!Array.isArray(tmpRequestState.ParentRequestState.UpdatedRecords))
17
+ {
18
+ tmpRequestState.ParentRequestState.UpdatedRecords = [];
19
+ }
20
+
21
+ this.waterfall(
22
+ [
23
+ (fStageComplete) =>
24
+ {
25
+ tmpRequestState.RecordToModify = pRecordToModify;
26
+
27
+ if (typeof(pOptionalCachedUpdatingRecord) !== 'undefined')
28
+ {
29
+ // Use the cached updating record instead of reading a record.
30
+ tmpRequestState.OriginalRecord = pOptionalCachedUpdatingRecord;
31
+ return fStageComplete();
32
+ }
33
+ else
34
+ {
35
+ tmpRequestState.Query = this.DAL.query;
36
+
37
+ tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier, tmpRequestState.RecordToModify[this.DAL.defaultIdentifier]);
38
+
39
+ // Load the record so we can do security checks on it
40
+ this.DAL.doRead(tmpRequestState.Query,
41
+ (pError, pQuery, pRecord) =>
42
+ {
43
+ if (pError)
44
+ {
45
+ return fStageComplete(pError);
46
+ }
47
+ if (!pRecord)
48
+ {
49
+ return fStageComplete(this.ErrorHandler.getError('Record not Found', 404));
50
+ }
51
+ tmpRequestState.Record = pRecord;
52
+ return fStageComplete();
53
+ });
54
+ }
55
+ },
56
+ (fStageComplete) =>
57
+ {
58
+ tmpRequestState.Query = this.DAL.query;
59
+ return fStageComplete();
60
+ },
61
+ (fStageComplete) =>
62
+ {
63
+ tmpRequestState.Query.setIDUser(tmpRequestState.SessionData.UserID);
64
+ tmpRequestState.Query.addRecord(tmpRequestState.RecordToModify);
65
+
66
+ return fStageComplete();
67
+ },
68
+ (fStageComplete) =>
69
+ {
70
+ this.DAL.doUpdate(tmpRequestState.Query,
71
+ (pError, pQuery, pReadQuery, pRecord) =>
72
+ {
73
+ if (pError)
74
+ {
75
+ if (typeof(pError) == 'string')
76
+ {
77
+ return fStageComplete(this.ErrorHandler.getError(pError, 500));
78
+ }
79
+ else
80
+ {
81
+ return fStageComplete(pError);
82
+ }
83
+ }
84
+ if (!pRecord)
85
+ {
86
+ return fStageComplete(this.ErrorHandler.getError(`Error in DAL Update: No record returned from persistence engine.`, 500));
87
+ }
88
+ tmpRequestState.Record = pRecord;
89
+ return fStageComplete();
90
+ });
91
+ },
92
+ (fStageComplete) => { return this.BehaviorInjection.runBehavior(`Update-PostOperation`, this, pRequest, tmpRequestState, fStageComplete); },
93
+ (fStageComplete) =>
94
+ {
95
+ tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);
96
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Updated record with ID ${tmpRequestState.Record[this.DAL.defaultIdentifier]}`);
97
+ return fStageComplete();
98
+ }
99
+ ], (pError) =>
100
+ {
101
+ if (pError)
102
+ {
103
+ tmpRequestState.Record.Error = pError;
104
+
105
+ tmpRequestState.ParentRequestState.RecordUpdateError = true;
106
+ tmpRequestState.ParentRequestState.RecordUpdateErrorObject = pError;
107
+
108
+ tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);
109
+ }
110
+
111
+ return fCallback();
112
+ });
113
+ };
114
+
115
+ module.exports = doUpdate;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Meadow Endpoint - Upsert a set of Records
3
+ */
4
+ const doUpsert = require('./Meadow-Operation-Upsert.js');
5
+
6
+ const marshalLiteList = require('../read/Meadow-Marshal-LiteList.js');
7
+
8
+ const doAPIEndpointUpserts = function(pRequest, pResponse, fNext)
9
+ {
10
+ let tmpRequestState = this.initializeRequestState(pRequest, 'UpsertBulk');
11
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
12
+
13
+ tmpRequestState.CreatedRecords = [];
14
+ tmpRequestState.UpdatedRecords = [];
15
+ tmpRequestState.UpsertedRecords = [];
16
+
17
+ this.waterfall(
18
+ [
19
+ (fStageComplete) =>
20
+ {
21
+ if (!Array.isArray(pRequest.body))
22
+ {
23
+ return fStageComplete(this.ErrorHandler.getError(`Record bulk upsert failure - a valid array of records is required.`, 500));
24
+ }
25
+
26
+ tmpRequestState.BulkRecords = pRequest.body;
27
+
28
+ return fStageComplete();
29
+ },
30
+ (fStageComplete) =>
31
+ {
32
+ this.eachLimit(tmpRequestState.BulkRecords, 1,
33
+ (pRecord, fCallback) =>
34
+ {
35
+ doUpsert.call(this, pRecord, pRequest, tmpRequestState, pResponse, fCallback);
36
+ }, fStageComplete);
37
+ },
38
+ (fStageComplete) =>
39
+ {
40
+ return this.doStreamRecordArray(pResponse, marshalLiteList.call(this, tmpRequestState.UpsertedRecords, pRequest), fStageComplete);
41
+ },
42
+ (fStageComplete) =>
43
+ {
44
+ this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Bulk upsert complete -- ${tmpRequestState.UpsertedRecords} records processed`);
45
+ return fStageComplete();
46
+ }
47
+ ], (pError) =>
48
+ {
49
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
50
+ });
51
+ };
52
+ module.exports = doAPIEndpointUpserts;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Meadow Endpoint - Upsert (Insert OR Update) a Record
3
+ */
4
+ var doUpsert = require('./Meadow-Operation-Upsert.js');
5
+
6
+ var doAPIEndpointUpsert = function(pRequest, pResponse, fNext)
7
+ {
8
+ let tmpRequestState = this.initializeRequestState(pRequest, 'Upsert');
9
+ let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
10
+
11
+ // Configure the request for the generic create & update operations
12
+ tmpRequestState.CreatedRecords = [];
13
+ tmpRequestState.UpdatedRecords = [];
14
+ tmpRequestState.UpsertedRecords = [];
15
+
16
+ this.waterfall(
17
+ [
18
+ (fStageComplete) =>
19
+ {
20
+ //1. Validate request body to ensure it is a valid record
21
+ if (typeof(pRequest.body) !== 'object')
22
+ {
23
+ return fStageComplete(this.ErrorHandler.getError('Record upsert failure - a valid record is required.', 500));
24
+ }
25
+
26
+ tmpRequestState.RecordToUpsert = pRequest.body;
27
+
28
+ return fStageComplete();
29
+ },
30
+ (fStageComplete) =>
31
+ {
32
+ doUpsert.call(this, tmpRequestState.RecordToUpsert, pRequest, tmpRequestState, pResponse, fStageComplete);
33
+ },
34
+ (fStageComplete) =>
35
+ {
36
+ if (tmpRequestState.RecordUpsertError)
37
+ {
38
+ return fStageComplete(tmpRequestState.RecordUpsertErrorMessage);
39
+ }
40
+ if (tmpRequestState.UpsertedRecords.length < 1)
41
+ {
42
+ return fStageComplete(this.ErrorHandler.getError('Record upsert unknown failure - no record back from Upsert operation.', 500));
43
+ }
44
+
45
+ tmpRequestState.Record = tmpRequestState.UpsertedRecords[0];
46
+
47
+ pResponse.send(tmpRequestState.Record);
48
+
49
+ return fStageComplete();
50
+ }
51
+ ], (pError) =>
52
+ {
53
+ return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
54
+ });
55
+ };
56
+
57
+ module.exports = doAPIEndpointUpsert;