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.
- package/Dockerfile_LUXURYCode +1 -1
- package/README.md +48 -14
- package/debug/Animal.json +62 -0
- package/debug/Harness-Configuration.json +31 -0
- package/debug/Harness.js +7 -108
- package/debug/KillHarness.sh +10 -0
- package/dist/meadowendpoints.js +4402 -0
- package/dist/meadowendpoints.min.js +92 -0
- package/dist/meadowendpoints.min.js.map +1 -0
- package/gulpfile.js +83 -0
- package/package.json +27 -15
- package/source/Controller/Meadow-Endpoints-Controller-Base.js +161 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-BehaviorInjection.js +125 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Error-StatusCodes.txt +189 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Error.js +118 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Log.js +103 -0
- package/source/Controller/utility/Meadow-Endpoints-Filter-Parser.js +225 -0
- package/source/Controller/utility/Meadow-Endpoints-Session-Marshaler.js +48 -0
- package/source/Controller/utility/Meadow-Endpoints-Stream-RecordArray.js +66 -0
- package/source/Meadow-Endpoints-Browser-Shim.js +14 -0
- package/source/Meadow-Endpoints.js +176 -565
- package/source/endpoints/count/Meadow-Endpoint-Count.js +49 -0
- package/source/endpoints/count/Meadow-Endpoint-CountBy.js +40 -0
- package/source/endpoints/create/Meadow-Endpoint-BulkCreate.js +53 -0
- package/source/endpoints/create/Meadow-Endpoint-Create.js +58 -0
- package/source/endpoints/create/Meadow-Operation-Create.js +83 -0
- package/source/endpoints/delete/Meadow-Endpoint-Delete.js +93 -0
- package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +108 -0
- package/source/endpoints/read/Meadow-Endpoint-Read.js +72 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +92 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +85 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadMax.js +55 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +89 -0
- package/source/endpoints/read/Meadow-Endpoint-Reads.js +75 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadsBy.js +100 -0
- package/source/{crud → endpoints/read}/Meadow-Marshal-DistinctList.js +4 -13
- package/source/{crud → endpoints/read}/Meadow-Marshal-LiteList.js +5 -14
- package/source/endpoints/schema/Meadow-Endpoint-New.js +36 -0
- package/source/endpoints/schema/Meadow-Endpoint-Schema.js +36 -0
- package/source/endpoints/schema/Meadow-Endpoint-Validate.js +41 -0
- package/source/endpoints/update/Meadow-Endpoint-BulkUpdate.js +50 -0
- package/source/endpoints/update/Meadow-Endpoint-Update.js +58 -0
- package/source/endpoints/update/Meadow-Operation-Update.js +115 -0
- package/source/endpoints/upsert/Meadow-Endpoint-BulkUpsert.js +53 -0
- package/source/endpoints/upsert/Meadow-Endpoint-Upsert.js +58 -0
- package/source/endpoints/upsert/Meadow-Operation-Upsert.js +132 -0
- package/test/MeadowEndpoints_basic_tests.js +50 -2408
- package/test_support/bookstore-api-endpoint-exercises.paw +0 -0
- package/test_support/bookstore-configuration.json +28 -0
- package/test_support/bookstore-import-books-run.js +1 -0
- package/test_support/bookstore-import-books.js +215 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis-IPC.js +138 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis-run.js +6 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis.js +129 -0
- package/test_support/data/books.csv +10001 -0
- package/test_support/model/ddl/BookStore.ddl +66 -0
- package/test_support/model/generated_diagram/README.md +1 -0
- package/test_support/model/generated_diagram/Stricture_Output.dot +13 -0
- package/test_support/model/generated_diagram/Stricture_Output.png +0 -0
- package/test_support/model/generated_documentation/Dictionary.md +18 -0
- package/test_support/model/generated_documentation/Model-Author.md +20 -0
- package/test_support/model/generated_documentation/Model-Book.md +26 -0
- package/test_support/model/generated_documentation/Model-BookAuthorJoin.md +14 -0
- package/test_support/model/generated_documentation/Model-BookPrice.md +25 -0
- package/test_support/model/generated_documentation/Model-Review.md +22 -0
- package/test_support/model/generated_documentation/ModelChangeTracking.md +17 -0
- package/test_support/model/generated_documentation/README.md +1 -0
- package/test_support/model/manual_scripts/DropTables.sql +5 -0
- package/test_support/model/manual_scripts/README.md +2 -0
- package/test_support/model/sql_create/BookStore-CreateDatabase.mysql.sql +116 -0
- package/test_support/model/sql_create/README.md +1 -0
- package/test_support/test_old/Tests.js +3243 -0
- package/test_support/test_old/untitled.js +88 -0
- package/source/Meadow-Authenticator.js +0 -31
- package/source/Meadow-Authorizers.js +0 -214
- package/source/Meadow-BehaviorModifications.js +0 -170
- package/source/Meadow-CommonServices.js +0 -206
- package/source/Meadow-MarshallSessionData.js +0 -64
- package/source/Restify-RouteParser.js +0 -114
- package/source/authorizers/Meadow-Authorizer-Allow.js +0 -17
- package/source/authorizers/Meadow-Authorizer-Deny.js +0 -17
- package/source/authorizers/Meadow-Authorizer-Mine.js +0 -47
- package/source/authorizers/Meadow-Authorizer-MyCustomer.js +0 -48
- package/source/crud/Meadow-Endpoint-BulkCreate.js +0 -67
- package/source/crud/Meadow-Endpoint-BulkUpdate.js +0 -74
- package/source/crud/Meadow-Endpoint-BulkUpsert.js +0 -76
- package/source/crud/Meadow-Endpoint-Count.js +0 -93
- package/source/crud/Meadow-Endpoint-CountBy.js +0 -101
- package/source/crud/Meadow-Endpoint-Create.js +0 -77
- package/source/crud/Meadow-Endpoint-Delete.js +0 -139
- package/source/crud/Meadow-Endpoint-Read.js +0 -109
- package/source/crud/Meadow-Endpoint-ReadDistinctList.js +0 -146
- package/source/crud/Meadow-Endpoint-ReadLiteList.js +0 -139
- package/source/crud/Meadow-Endpoint-ReadMax.js +0 -86
- package/source/crud/Meadow-Endpoint-ReadSelectList.js +0 -145
- package/source/crud/Meadow-Endpoint-Reads.js +0 -129
- package/source/crud/Meadow-Endpoint-ReadsBy.js +0 -155
- package/source/crud/Meadow-Endpoint-Undelete.js +0 -161
- package/source/crud/Meadow-Endpoint-Update.js +0 -80
- package/source/crud/Meadow-Endpoint-Upsert.js +0 -78
- package/source/crud/Meadow-Operation-Create.js +0 -105
- package/source/crud/Meadow-Operation-Update.js +0 -145
- package/source/crud/Meadow-Operation-Upsert.js +0 -106
- package/source/crud/Meadow-StreamRecordArray.js +0 -45
- package/source/schema/Meadow-Endpoint-New.js +0 -37
- package/source/schema/Meadow-Endpoint-Schema.js +0 -37
- package/source/schema/Meadow-Endpoint-Validate.js +0 -43
- package/test/Animal.json +0 -140
- package/test/MeadowEndpoints_disabledAuth_tests.js +0 -1325
- package/test/MeadowEndpoints_trustedSession_tests.js +0 -1731
- package/test/load/artillery-low.yml +0 -10
- package/test/load/cloud9setup.sh +0 -25
- package/test/load/package.json +0 -19
- package/test/load/test-schema-initializedatabase.sql +0 -29
- package/test/load/test-schema.json +0 -119
- package/test/load/test-server.js +0 -157
- package/test/scripts/InitializeDatabase-C9.sql +0 -7
- /package/{test/schemas → test_support/model}/json_schema/BookStore-Extended.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/BookStore-PICT.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/BookStore.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/README.md +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Author.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Book.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookPrice.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Review.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/README.md +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Read a list of lite Records (for Drop-downs and such)
|
|
3
|
+
*/
|
|
4
|
+
const marshalLiteList = require('./Meadow-Marshal-LiteList.js');
|
|
5
|
+
|
|
6
|
+
const doAPIEndpointReadLite = function(pRequest, pResponse, fNext)
|
|
7
|
+
{
|
|
8
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'ReadsLite');
|
|
9
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
10
|
+
|
|
11
|
+
this.waterfall(
|
|
12
|
+
[
|
|
13
|
+
// 1a. Get the records
|
|
14
|
+
(fStageComplete) =>
|
|
15
|
+
{
|
|
16
|
+
tmpRequestState.Query = this.DAL.query;
|
|
17
|
+
// TODO: Limit the query to the columns we need for the templated expression
|
|
18
|
+
|
|
19
|
+
var tmpCap = false;
|
|
20
|
+
var tmpBegin = false;
|
|
21
|
+
if (typeof(pRequest.params.Begin) === 'string' ||
|
|
22
|
+
typeof(pRequest.params.Begin) === 'number')
|
|
23
|
+
{
|
|
24
|
+
tmpBegin = parseInt(pRequest.params.Begin, 10);
|
|
25
|
+
}
|
|
26
|
+
if (typeof(pRequest.params.Cap) === 'string' ||
|
|
27
|
+
typeof(pRequest.params.Cap) === 'number')
|
|
28
|
+
{
|
|
29
|
+
tmpCap = parseInt(pRequest.params.Cap, 10);
|
|
30
|
+
}
|
|
31
|
+
else
|
|
32
|
+
{
|
|
33
|
+
//maximum number of records to return by default on Read queries. Override via "MeadowDefaultMaxCap" fable setting.
|
|
34
|
+
tmpCap = (this.settings['MeadowDefaultMaxCap']) || 250;
|
|
35
|
+
}
|
|
36
|
+
tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);
|
|
37
|
+
if (typeof(pRequest.params.Filter) === 'string')
|
|
38
|
+
{
|
|
39
|
+
// If a filter has been passed in, parse it and add the values to the query.
|
|
40
|
+
this.parseFilter(pRequest.params.Filter, tmpRequestState.Query);
|
|
41
|
+
}
|
|
42
|
+
else if (pRequest.params.Filter)
|
|
43
|
+
{
|
|
44
|
+
tmpRequestState.Query.setFilter(pRequest.params.Filter);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return fStageComplete();
|
|
48
|
+
},
|
|
49
|
+
fBehaviorInjector(`Reads-QueryConfiguration`),
|
|
50
|
+
(fStageComplete) =>
|
|
51
|
+
{
|
|
52
|
+
this.DAL.doReads(tmpRequestState.Query, fStageComplete);
|
|
53
|
+
},
|
|
54
|
+
(pQuery, pRecords, fStageComplete) =>
|
|
55
|
+
{
|
|
56
|
+
if (pRecords.length < 1)
|
|
57
|
+
{
|
|
58
|
+
pRecords = [];
|
|
59
|
+
}
|
|
60
|
+
tmpRequestState.RawRecords = pRecords;
|
|
61
|
+
return fStageComplete();
|
|
62
|
+
},
|
|
63
|
+
(fStageComplete) =>
|
|
64
|
+
{
|
|
65
|
+
tmpRequestState.Records = marshalLiteList.call(this, tmpRequestState.RawRecords, pRequest, (typeof(pRequest.params.ExtraColumns) === 'string') ? pRequest.params.ExtraColumns.split(',') : []);
|
|
66
|
+
return fStageComplete();
|
|
67
|
+
},
|
|
68
|
+
(fStageComplete) =>
|
|
69
|
+
{
|
|
70
|
+
return this.doStreamRecordArray(pResponse, tmpRequestState.Records, fNext);
|
|
71
|
+
},
|
|
72
|
+
(fStageComplete) =>
|
|
73
|
+
{
|
|
74
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Read a recordset lite list with ${tmpRequestState.Records.length} results`);
|
|
75
|
+
return fStageComplete();
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
(pError, pResultRecords) =>
|
|
79
|
+
{
|
|
80
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
module.exports = doAPIEndpointReadLite;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Read the Max Value of a Column in a Set
|
|
3
|
+
*/
|
|
4
|
+
const doAPIEndpointReadMax = function(pRequest, pResponse, fNext)
|
|
5
|
+
{
|
|
6
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'ReadMax');
|
|
7
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
8
|
+
|
|
9
|
+
this.waterfall(
|
|
10
|
+
[
|
|
11
|
+
(fStageComplete) =>
|
|
12
|
+
{
|
|
13
|
+
tmpRequestState.Query = this.DAL.query;
|
|
14
|
+
return fStageComplete();
|
|
15
|
+
},
|
|
16
|
+
(fStageComplete) =>
|
|
17
|
+
{
|
|
18
|
+
tmpRequestState.ColumnName = pRequest.params.ColumnName;
|
|
19
|
+
tmpRequestState.Query.setSort({Column:tmpRequestState.ColumnName, Direction:'Descending'});
|
|
20
|
+
tmpRequestState.Query.setCap(1);
|
|
21
|
+
|
|
22
|
+
return fStageComplete();
|
|
23
|
+
},
|
|
24
|
+
fBehaviorInjector(`ReadMax-QueryConfiguration`),
|
|
25
|
+
(fStageComplete) =>
|
|
26
|
+
{
|
|
27
|
+
this.DAL.doRead(tmpRequestState.Query, fStageComplete);
|
|
28
|
+
},
|
|
29
|
+
(pQuery, pRecord, fStageComplete) =>
|
|
30
|
+
{
|
|
31
|
+
if (!pRecord)
|
|
32
|
+
{
|
|
33
|
+
return fStageComplete(this.ErrorHandler.getError('Record not Found', 404));
|
|
34
|
+
}
|
|
35
|
+
tmpRequestState.Record = pRecord;
|
|
36
|
+
return fStageComplete();
|
|
37
|
+
},
|
|
38
|
+
(fStageComplete) =>
|
|
39
|
+
{
|
|
40
|
+
this.BehaviorInjection.runBehavior(`ReadMax-PostOperation`, this, pRequest, tmpRequestState, fStageComplete);
|
|
41
|
+
},
|
|
42
|
+
(fStageComplete) =>
|
|
43
|
+
{
|
|
44
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Read max record of ${this.DAL.scope} on ${tmpRequestState.ColumnName}`);
|
|
45
|
+
pResponse.send(tmpRequestState.Record);
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
(pError) =>
|
|
49
|
+
{
|
|
50
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
module.exports = doAPIEndpointReadMax;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Read a select list of Records (for Drop-downs and such)
|
|
3
|
+
*/
|
|
4
|
+
const doAPIEndpointReadSelectList = 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
|
+
(fStageComplete) =>
|
|
12
|
+
{
|
|
13
|
+
tmpRequestState.Query = this.DAL.query;
|
|
14
|
+
|
|
15
|
+
var tmpCap = false;
|
|
16
|
+
var tmpBegin = false;
|
|
17
|
+
if (typeof(pRequest.params.Begin) === 'string' ||
|
|
18
|
+
typeof(pRequest.params.Begin) === 'number')
|
|
19
|
+
{
|
|
20
|
+
tmpBegin = parseInt(pRequest.params.Begin);
|
|
21
|
+
}
|
|
22
|
+
if (typeof(pRequest.params.Cap) === 'string' ||
|
|
23
|
+
typeof(pRequest.params.Cap) === 'number')
|
|
24
|
+
{
|
|
25
|
+
tmpCap = parseInt(pRequest.params.Cap);
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
{
|
|
29
|
+
tmpCap = (this.settings['MeadowDefaultMaxCap']) || 250;
|
|
30
|
+
}
|
|
31
|
+
tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);
|
|
32
|
+
if (typeof(pRequest.params.Filter) === 'string')
|
|
33
|
+
{
|
|
34
|
+
this.parseFilter(pRequest.params.Filter, tmpRequestState.Query);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return fStageComplete();
|
|
38
|
+
},
|
|
39
|
+
fBehaviorInjector(`Reads-QueryConfiguration`),
|
|
40
|
+
(fStageComplete) =>
|
|
41
|
+
{
|
|
42
|
+
this.DAL.doReads(tmpRequestState.Query, fStageComplete);
|
|
43
|
+
},
|
|
44
|
+
(pQuery, pRecords, fStageComplete) =>
|
|
45
|
+
{
|
|
46
|
+
if (pRecords.length < 1)
|
|
47
|
+
{
|
|
48
|
+
pRecords = [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
tmpRequestState.Records = pRecords;
|
|
52
|
+
|
|
53
|
+
return fStageComplete();
|
|
54
|
+
},
|
|
55
|
+
(fStageComplete) =>
|
|
56
|
+
{
|
|
57
|
+
tmpRequestState.SelectList = [];
|
|
58
|
+
|
|
59
|
+
for (var i = 0; i < tmpRequestState.Records.length; i++)
|
|
60
|
+
{
|
|
61
|
+
tmpRequestState.SelectList.push
|
|
62
|
+
(
|
|
63
|
+
{
|
|
64
|
+
Hash: tmpRequestState.Records[i][this.DAL.defaultIdentifier],
|
|
65
|
+
Value: this.BehaviorInjection.processTemplate('SelectList', {Record:tmpRequestState.Records[i]}, this.DAL.scope+' #<%= Record.'+this.DAL.defaultIdentifier+'%>')
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return fStageComplete();
|
|
71
|
+
},
|
|
72
|
+
(fStageComplete) =>
|
|
73
|
+
{
|
|
74
|
+
return this.doStreamRecordArray(pResponse, tmpRequestState.SelectList, fStageComplete);
|
|
75
|
+
},
|
|
76
|
+
(fStageComplete) =>
|
|
77
|
+
{
|
|
78
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Read a recordset lite list with ${tmpRequestState.SelectList.length} results.`);
|
|
79
|
+
return fStageComplete();
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
(pError, pResultRecords) =>
|
|
83
|
+
{
|
|
84
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
module.exports = doAPIEndpointReadSelectList;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Read a Set of Records
|
|
3
|
+
*/
|
|
4
|
+
const doAPIEndpointReads = function(pRequest, pResponse, fNext)
|
|
5
|
+
{
|
|
6
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'Reads');
|
|
7
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
8
|
+
|
|
9
|
+
this.waterfall(
|
|
10
|
+
[
|
|
11
|
+
(fStageComplete) =>
|
|
12
|
+
{
|
|
13
|
+
tmpRequestState.Query = this.DAL.query;
|
|
14
|
+
|
|
15
|
+
var tmpCap = false;
|
|
16
|
+
var tmpBegin = false;
|
|
17
|
+
if (typeof(pRequest.params.Begin) === 'string' ||
|
|
18
|
+
typeof(pRequest.params.Begin) === 'number')
|
|
19
|
+
{
|
|
20
|
+
tmpBegin = parseInt(pRequest.params.Begin);
|
|
21
|
+
}
|
|
22
|
+
if (typeof(pRequest.params.Cap) === 'string' ||
|
|
23
|
+
typeof(pRequest.params.Cap) === 'number')
|
|
24
|
+
{
|
|
25
|
+
tmpCap = parseInt(pRequest.params.Cap);
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
{
|
|
29
|
+
tmpCap = (this.settings['MeadowDefaultMaxCap']) || 250;
|
|
30
|
+
}
|
|
31
|
+
tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);
|
|
32
|
+
if (typeof(pRequest.params.Filter) === 'string')
|
|
33
|
+
{
|
|
34
|
+
// If a filter has been passed in, parse it and add the values to the query.
|
|
35
|
+
this.parseFilter(pRequest.params.Filter, tmpRequestState.Query);
|
|
36
|
+
}
|
|
37
|
+
else if (pRequest.params.Filter)
|
|
38
|
+
{
|
|
39
|
+
tmpRequestState.Query.setFilter(pRequest.params.Filter);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return fStageComplete();
|
|
43
|
+
},
|
|
44
|
+
fBehaviorInjector(`Reads-QueryConfiguration`),
|
|
45
|
+
(fStageComplete) =>
|
|
46
|
+
{
|
|
47
|
+
this.DAL.doReads(tmpRequestState.Query, fStageComplete);
|
|
48
|
+
},
|
|
49
|
+
(pQuery, pRecords, fStageComplete) =>
|
|
50
|
+
{
|
|
51
|
+
if (!pRecords)
|
|
52
|
+
{
|
|
53
|
+
return fStageComplete(this.ErrorHandler.getError('No records found.', 404));
|
|
54
|
+
}
|
|
55
|
+
tmpRequestState.Records = pRecords;
|
|
56
|
+
return fStageComplete();
|
|
57
|
+
},
|
|
58
|
+
fBehaviorInjector(`Reads-PostOperation`),
|
|
59
|
+
(fStageComplete) =>
|
|
60
|
+
{
|
|
61
|
+
this.doStreamRecordArray(pResponse, tmpRequestState.Records, fStageComplete);
|
|
62
|
+
},
|
|
63
|
+
(fStageComplete) =>
|
|
64
|
+
{
|
|
65
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, 'Read a list of records.');
|
|
66
|
+
return fStageComplete();
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
(pError) =>
|
|
70
|
+
{
|
|
71
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
module.exports = doAPIEndpointReads;
|
|
@@ -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
|
|
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 = (
|
|
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 = (
|
|
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:
|
|
44
|
+
Value: this.BehaviorInjection.processTemplate('SelectList', {Record:pRecords[i]}, this.DAL.scope+' #<%= Record.'+this.DAL.defaultIdentifier+'%>')
|
|
54
45
|
});
|
|
55
|
-
tmpLiteRecord[
|
|
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;
|