meadow-endpoints 4.0.16 → 4.0.17
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/dist/meadow-endpoints.js +51 -8
- package/dist/meadow-endpoints.js.map +1 -1
- package/dist/meadow-endpoints.min.js +5 -5
- package/dist/meadow-endpoints.min.js.map +1 -1
- package/package.json +1 -1
- package/source/endpoints/create/Meadow-Endpoint-BulkCreate.js +6 -0
- package/source/endpoints/create/Meadow-Endpoint-Create.js +8 -0
- package/source/endpoints/delete/Meadow-Endpoint-Delete.js +6 -0
- package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +5 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +7 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +6 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +6 -0
- package/source/endpoints/update/Meadow-Operation-Update.js +8 -0
- package/test/MeadowEndpoints_basic_tests.js +332 -0
package/dist/meadow-endpoints.js
CHANGED
|
@@ -5918,10 +5918,22 @@ this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest
|
|
|
5918
5918
|
* Meadow Endpoint - Count a Record filtered by a single value
|
|
5919
5919
|
*/const doAPIEndpointCountBy=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'CountBy');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query;tmpRequestState.Query.addFilter(pRequest.params.ByField,pRequest.params.ByValue,'=','AND','RequestByField');return fStageComplete();},fBehaviorInjector(`CountBy-QueryConfiguration`),fStageComplete=>{this.DAL.doCount(tmpRequestState.Query,(pError,pQuery,pCount)=>{tmpRequestState.Result={Count:pCount};return fStageComplete(pError);});},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,'Delivered recordset count of '+tmpRequestState.Result.Count+'.');pResponse.send(tmpRequestState.Result);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointCountBy;},{}],201:[function(require,module,exports){/**
|
|
5920
5920
|
* Meadow Endpoint - Create a set of Record in Bulk
|
|
5921
|
-
*/const doCreate=require('./Meadow-Operation-Create.js');const doAPIEndpointBulkCreate=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'CreateBulk');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};tmpRequestState.CreatedRecords=[];this.waterfall([fStageComplete=>{if(!Array.isArray(pRequest.body)){return fStageComplete(this.ErrorHandler.getError('Bulk record create failure - a valid array of records to create is required.',500));}pRequest.RecordsToBulkCreate=pRequest.body;return fStageComplete();}
|
|
5921
|
+
*/const doCreate=require('./Meadow-Operation-Create.js');const doAPIEndpointBulkCreate=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'CreateBulk');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};tmpRequestState.CreatedRecords=[];this.waterfall([fStageComplete=>{if(!Array.isArray(pRequest.body)){return fStageComplete(this.ErrorHandler.getError('Bulk record create failure - a valid array of records to create is required.',500));}pRequest.RecordsToBulkCreate=pRequest.body;return fStageComplete();},// Endpoint-level pre-request hook for bulk creates. Mirror of
|
|
5922
|
+
// Create-PreRequest in the singular Create endpoint — fires
|
|
5923
|
+
// after body-array validation and before any per-record
|
|
5924
|
+
// operation. Use cases include bulk idempotency suppression /
|
|
5925
|
+
// dedup across the incoming batch.
|
|
5926
|
+
fBehaviorInjector(`CreateBulk-PreRequest`),fBehaviorInjector(`CreateBulk-PreOperation`),fStageComplete=>{// TODO: Research parallelism opportunities from custom routes
|
|
5922
5927
|
this.eachLimit(pRequest.RecordsToBulkCreate,1,(pRecord,fCallback)=>{doCreate.call(this,pRecord,pRequest,tmpRequestState,pResponse,fCallback);},fStageComplete);},fBehaviorInjector(`CreateBulk-PostOperation`),fStageComplete=>{return this.doStreamRecordArray(pResponse,tmpRequestState.CreatedRecords,fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Bulk created ${tmpRequestState.CreatedRecords.length} records`);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointBulkCreate;},{"./Meadow-Operation-Create.js":203}],202:[function(require,module,exports){/**
|
|
5923
5928
|
* Meadow Endpoint - Create a Record
|
|
5924
|
-
*/const doCreate=require('./Meadow-Operation-Create.js');const doAPIEndpointCreate=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'Create');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{if(typeof pRequest.body!=='object'){return fStageComplete(this.ErrorHandler.getError('Record create failure - a valid record is required.',500));}return fStageComplete();}
|
|
5929
|
+
*/const doCreate=require('./Meadow-Operation-Create.js');const doAPIEndpointCreate=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'Create');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{if(typeof pRequest.body!=='object'){return fStageComplete(this.ErrorHandler.getError('Record create failure - a valid record is required.',500));}return fStageComplete();},// Endpoint-level pre-request hook. Runs after the body-type check
|
|
5930
|
+
// but before any operation work, mirroring ME 2.x's
|
|
5931
|
+
// Create-PreRequest stage. Use cases include idempotency
|
|
5932
|
+
// suppression (e.g. look up by primary GUID and short-circuit
|
|
5933
|
+
// if the row already exists). Handlers can abort the operation
|
|
5934
|
+
// by calling fStageComplete with a truthy error or by fully
|
|
5935
|
+
// writing pResponse and returning a sentinel.
|
|
5936
|
+
fBehaviorInjector(`Create-PreRequest`),fStageComplete=>{doCreate.call(this,pRequest.body,pRequest,tmpRequestState,pResponse,fStageComplete);},fStageComplete=>{if(tmpRequestState.RecordCreateError){return fStageComplete(tmpRequestState.RecordCreateErrorObject);}if(tmpRequestState.CreatedRecords.length<1){return fStageComplete(this.ErrorHandler.getError('Unknown record create failure - no created records returned.',500));}tmpRequestState.Record=tmpRequestState.CreatedRecords[0];return fStageComplete();},fStageComplete=>{pResponse.send(tmpRequestState.Record);return fStageComplete();},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Created a ${this.DAL.scope} record ID ${tmpRequestState.Record[this.DAL.defaultIdentifier]}`);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointCreate;},{"./Meadow-Operation-Create.js":203}],203:[function(require,module,exports){/**
|
|
5925
5937
|
* Meadow Operation - Create a record function
|
|
5926
5938
|
*/const doCreate=function(pRecord,pRequest,pRequestState,pResponse,fCallback){// This is a virtual operation
|
|
5927
5939
|
let tmpRequestState=this.cloneAsyncSafeRequestState(pRequestState,'doCreate');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};if(!Array.isArray(tmpRequestState.ParentRequestState.CreatedRecords)){tmpRequestState.ParentRequestState.CreatedRecords=[];}this.waterfall([fStageComplete=>{tmpRequestState.RecordToCreate=pRecord;//Make sure record gets created with a customerID
|
|
@@ -5932,7 +5944,12 @@ this.DAL.doCreate(tmpRequestState.Query,(pError,pQuery,pReadQuery,pNewRecord)=>{
|
|
|
5932
5944
|
*/const doAPIEndpointDelete=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'Delete');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};tmpRequestState.IDRecord=0;tmpRequestState.RecordCount={Count:0};this.waterfall([fStageComplete=>{if(typeof pRequest.params.IDRecord==='string'){tmpRequestState.IDRecord=pRequest.params.IDRecord;}else if(typeof pRequest.body[this.DAL.defaultIdentifier]==='number'){tmpRequestState.IDRecord=pRequest.body[this.DAL.defaultIdentifier];}else if(typeof pRequest.body[this.DAL.defaultIdentifier]==='string'){tmpRequestState.IDRecord=pRequest.body[this.DAL.defaultIdentifier];}// Although the Meadow delete behavior does allow multiple deletes, we require an identifier.
|
|
5933
5945
|
// If a developer wants bulk delete, it will require a custom endpoint.
|
|
5934
5946
|
if(tmpRequestState.IDRecord<1){return fStageComplete(this.ErrorHandler.getError('Record delete failure - a valid record ID is required in the passed-in record.',500));}return fStageComplete();},fStageComplete=>{tmpRequestState.Query=this.DAL.query;tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier,tmpRequestState.IDRecord);tmpRequestState.Query.setIDUser(tmpRequestState.SessionData.UserID);return fStageComplete();},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Delete-QueryConfiguration`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{// Load the record so we can do security checks on it
|
|
5935
|
-
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not found.',404));}tmpRequestState.Record=pRecord
|
|
5947
|
+
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not found.',404));}tmpRequestState.Record=pRecord;// Alias the loaded pre-delete row for symmetry
|
|
5948
|
+
// with Update (see Meadow-Operation-Update.js).
|
|
5949
|
+
// Post-op hooks that compare pre/post values can
|
|
5950
|
+
// reliably read OriginalRecord without having to
|
|
5951
|
+
// know which stage overwrote Record.
|
|
5952
|
+
tmpRequestState.OriginalRecord=pRecord;return fStageComplete();});},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Delete-PreOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{// Do the delete
|
|
5936
5953
|
this.DAL.doDelete(tmpRequestState.Query,(pError,pQuery,pCount)=>{// MySQL returns the number of rows deleted
|
|
5937
5954
|
tmpRequestState.RecordCount.Count=pCount;return fStageComplete(pError);});},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Delete-PostOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{pResponse.send(tmpRequestState.RecordCount);this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Deleted ${tmpRequestState.RecordCount.Count} ${this.DAL.scope} records with ID ${tmpRequestState.IDRecord}`);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointDelete;},{}],205:[function(require,module,exports){/**
|
|
5938
5955
|
* Meadow Endpoint - Undelete a Record
|
|
@@ -5941,7 +5958,11 @@ tmpRequestState.RecordCount.Count=pCount;return fStageComplete(pError);});},fSta
|
|
|
5941
5958
|
if(tmpIDRecord<1){return fNext(this.ErrorHandler.getError('Record undelete failure - a valid record ID is required.',500));}tmpRequestState.RecordCount={Count:0};this.waterfall([fStageComplete=>{// Validate that the schema has a deleted bit
|
|
5942
5959
|
var tmpSchema=this.DAL.schema;var tmpHasDeletedBit=false;for(let i=0;i<tmpSchema.length;i++){if(tmpSchema[i].Type=='Deleted'){tmpHasDeletedBit=true;}}if(!tmpHasDeletedBit){return fStageComplete(this.ErrorHandler.getError('No undelete bit on record.',500));}return fStageComplete();},fStageComplete=>{// Now see if the record, with this identifier, for this user, exists with the deleted bit set to 1
|
|
5943
5960
|
tmpRequestState.Query=this.DAL.query;tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier,tmpIDRecord);tmpRequestState.Query.addFilter('Deleted',1);tmpRequestState.Query.setIDUser(tmpRequestState.SessionData.UserID);return fStageComplete();},fStageComplete=>{// Load the record so we can do security checks on it
|
|
5944
|
-
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not found.',404));}tmpRequestState.Record=pRecord
|
|
5961
|
+
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not found.',404));}tmpRequestState.Record=pRecord;// Alias the loaded pre-undelete row for symmetry
|
|
5962
|
+
// with Update / Delete (see their endpoints). Post-op
|
|
5963
|
+
// hooks that compare pre/post values can reliably
|
|
5964
|
+
// read OriginalRecord.
|
|
5965
|
+
tmpRequestState.OriginalRecord=pRecord;return fStageComplete();});},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Undelete-PreOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{// Do the undelete
|
|
5945
5966
|
this.DAL.doUndelete(tmpRequestState.Query,(pError,pQuery,pCount)=>{// MySQL returns the number of rows deleted
|
|
5946
5967
|
tmpRequestState.RecordCount={Count:pCount};return fStageComplete(pError);});},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Undelete-PostOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{pResponse.send(tmpRequestState.RecordCount);this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,'Undeleted '+tmpRequestState.RecordCount.Count+' records with ID '+tmpIDRecord+'.');return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointUndelete;},{}],206:[function(require,module,exports){/**
|
|
5947
5968
|
* Meadow Endpoint - Read a Record
|
|
@@ -5951,17 +5972,32 @@ tmpRequestState.RecordSearchCriteria=`${this.DAL.defaultIdentifier} = ${pRequest
|
|
|
5951
5972
|
* Meadow Endpoint - Read a list of Records with a specified set of columns, distinct by those columns.
|
|
5952
5973
|
*/const marshalDistinctList=require('./Meadow-Marshal-DistinctList.js');const doAPIEndpointReadDistinct=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'ReadDistinct');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};tmpRequestState.DistinctColumns;this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query.setDistinct(true);/** @type {number | boolean} */let tmpCap=false;/** @type {number | boolean} */let tmpBegin=false;if(typeof pRequest.params.Begin==='string'||typeof pRequest.params.Begin==='number'){tmpBegin=parseInt(pRequest.params.Begin,10);}if(typeof pRequest.params.Cap==='string'||typeof pRequest.params.Cap==='number'){tmpCap=parseInt(pRequest.params.Cap,10);}else{//maximum number of records to return by default on Read queries. Override via "MeadowDefaultMaxCap" fable setting.
|
|
5953
5974
|
tmpCap=this.settings['MeadowDefaultMaxCap']||250;}tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);if(typeof pRequest.params.Filter==='string'){// If a filter has been passed in, parse it and add the values to the query.
|
|
5954
|
-
this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest.params.Filter){tmpRequestState.Query.setFilter(pRequest.params.Filter);}if(typeof pRequest.params.Columns==='string'){tmpRequestState.DistinctColumns=pRequest.params.Columns.split(',');if(!tmpRequestState.DistinctColumns){return fStageComplete({Code:400,Message:'Columns to distinct on must be provided.'});}tmpRequestState.Query.setDataElements(tmpRequestState.DistinctColumns);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.Records=pRecords;return fStageComplete();}
|
|
5975
|
+
this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest.params.Filter){tmpRequestState.Query.setFilter(pRequest.params.Filter);}if(typeof pRequest.params.Columns==='string'){tmpRequestState.DistinctColumns=pRequest.params.Columns.split(',');if(!tmpRequestState.DistinctColumns){return fStageComplete({Code:400,Message:'Columns to distinct on must be provided.'});}tmpRequestState.Query.setDataElements(tmpRequestState.DistinctColumns);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.Records=pRecords;return fStageComplete();},// Stage-specific post-op hook. Fires after DAL read but BEFORE
|
|
5976
|
+
// the records are projected to distinct-column shape, so
|
|
5977
|
+
// handlers can run against full rows. Separate from
|
|
5978
|
+
// Reads-PostOperation so registering one doesn't unintentionally
|
|
5979
|
+
// fire on the other. Hash matches the endpoint's action label
|
|
5980
|
+
// (initializeRequestState(..., 'ReadDistinct')).
|
|
5981
|
+
fBehaviorInjector(`ReadDistinct-PostOperation`),fStageComplete=>{tmpRequestState.ResultRecords=marshalDistinctList.call(this,tmpRequestState.Records,pRequest,tmpRequestState.DistinctColumns);return fStageComplete();},fStageComplete=>{return this.doStreamRecordArray(pResponse,tmpRequestState.ResultRecords,fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Read a recordset distinct lite list with ${tmpRequestState.ResultRecords.length} results.`);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointReadDistinct;},{"./Meadow-Marshal-DistinctList.js":213}],208:[function(require,module,exports){/**
|
|
5955
5982
|
* Meadow Endpoint - Read a list of lite Records (for Drop-downs and such)
|
|
5956
5983
|
*/const marshalLiteList=require('./Meadow-Marshal-LiteList.js');const doAPIEndpointReadLite=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'ReadsLite');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([// 1a. Get the records
|
|
5957
5984
|
fStageComplete=>{tmpRequestState.Query=this.DAL.query;// TODO: Limit the query to the columns we need for the templated expression
|
|
5958
5985
|
/** @type {number | boolean} */var tmpCap=false;/** @type {number | boolean} */var tmpBegin=false;if(typeof pRequest.params.Begin==='string'||typeof pRequest.params.Begin==='number'){tmpBegin=parseInt(pRequest.params.Begin,10);}if(typeof pRequest.params.Cap==='string'||typeof pRequest.params.Cap==='number'){tmpCap=parseInt(pRequest.params.Cap,10);}else{//maximum number of records to return by default on Read queries. Override via "MeadowDefaultMaxCap" fable setting.
|
|
5959
5986
|
tmpCap=this.settings['MeadowDefaultMaxCap']||250;}tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);if(typeof pRequest.params.Filter==='string'){// If a filter has been passed in, parse it and add the values to the query.
|
|
5960
|
-
this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest.params.Filter){tmpRequestState.Query.setFilter(pRequest.params.Filter);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.RawRecords=pRecords
|
|
5987
|
+
this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest.params.Filter){tmpRequestState.Query.setFilter(pRequest.params.Filter);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.RawRecords=pRecords;// Expose the loaded records under pRequestState.Records
|
|
5988
|
+
// so post-op hooks operate on the same shape regular
|
|
5989
|
+
// Reads uses. Marshalling to lite shape runs AFTER the
|
|
5990
|
+
// hook so hooks see full rows.
|
|
5991
|
+
tmpRequestState.Records=pRecords;return fStageComplete();},fBehaviorInjector(`ReadsLite-PostOperation`),fStageComplete=>{tmpRequestState.Records=marshalLiteList.call(this,tmpRequestState.RawRecords,pRequest,typeof pRequest.params.ExtraColumns==='string'?pRequest.params.ExtraColumns.split(','):[]);return fStageComplete();},fStageComplete=>{return this.doStreamRecordArray(pResponse,tmpRequestState.Records,fNext);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Read a recordset lite list with ${tmpRequestState.Records.length} results`);return fStageComplete();}],(pError,pResultRecords)=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointReadLite;},{"./Meadow-Marshal-LiteList.js":214}],209:[function(require,module,exports){/**
|
|
5961
5992
|
* Meadow Endpoint - Read the Max Value of a Column in a Set
|
|
5962
5993
|
*/const doAPIEndpointReadMax=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'ReadMax');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query;return fStageComplete();},fStageComplete=>{tmpRequestState.ColumnName=pRequest.params.ColumnName;tmpRequestState.Query.setSort({Column:tmpRequestState.ColumnName,Direction:'Descending'});tmpRequestState.Query.setCap(1);return fStageComplete();},fBehaviorInjector(`ReadMax-QueryConfiguration`),fStageComplete=>{this.DAL.doRead(tmpRequestState.Query,fStageComplete);},(pQuery,pRecord,fStageComplete)=>{if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not Found',404));}tmpRequestState.Record=pRecord;return fStageComplete();},fStageComplete=>{this.BehaviorInjection.runBehavior(`ReadMax-PostOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Read max record of ${this.DAL.scope} on ${tmpRequestState.ColumnName}`);pResponse.send(tmpRequestState.Record);}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointReadMax;},{}],210:[function(require,module,exports){/**
|
|
5963
5994
|
* Meadow Endpoint - Read a select list of Records (for Drop-downs and such)
|
|
5964
|
-
*/const doAPIEndpointReadSelectList=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'ReadsBy');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query;/** @type {number | boolean} */var tmpCap=false;/** @type {number | boolean} */var tmpBegin=false;if(typeof pRequest.params.Begin==='string'||typeof pRequest.params.Begin==='number'){tmpBegin=parseInt(pRequest.params.Begin);}if(typeof pRequest.params.Cap==='string'||typeof pRequest.params.Cap==='number'){tmpCap=parseInt(pRequest.params.Cap);}else{tmpCap=this.settings['MeadowDefaultMaxCap']||250;}tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);if(typeof pRequest.params.Filter==='string'){this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.Records=pRecords;return fStageComplete();}
|
|
5995
|
+
*/const doAPIEndpointReadSelectList=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'ReadsBy');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query;/** @type {number | boolean} */var tmpCap=false;/** @type {number | boolean} */var tmpBegin=false;if(typeof pRequest.params.Begin==='string'||typeof pRequest.params.Begin==='number'){tmpBegin=parseInt(pRequest.params.Begin);}if(typeof pRequest.params.Cap==='string'||typeof pRequest.params.Cap==='number'){tmpCap=parseInt(pRequest.params.Cap);}else{tmpCap=this.settings['MeadowDefaultMaxCap']||250;}tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);if(typeof pRequest.params.Filter==='string'){this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(pRecords.length<1){pRecords=[];}tmpRequestState.Records=pRecords;return fStageComplete();},// Stage-specific post-op hook. Fires after DAL read but
|
|
5996
|
+
// BEFORE the records are projected to select-list
|
|
5997
|
+
// (Hash/Value) shape, so handlers can run against full
|
|
5998
|
+
// rows. Separate from Reads-PostOperation so registering
|
|
5999
|
+
// one doesn't unintentionally fire on the other.
|
|
6000
|
+
fBehaviorInjector(`ReadSelectList-PostOperation`),fStageComplete=>{tmpRequestState.SelectList=[];for(var i=0;i<tmpRequestState.Records.length;i++){tmpRequestState.SelectList.push({Hash:tmpRequestState.Records[i][this.DAL.defaultIdentifier],Value:this.BehaviorInjection.processTemplate('SelectList',{Record:tmpRequestState.Records[i]},this.DAL.scope+' #<%= Record.'+this.DAL.defaultIdentifier+'%>')});}return fStageComplete();},fStageComplete=>{return this.doStreamRecordArray(pResponse,tmpRequestState.SelectList,fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Read a recordset lite list with ${tmpRequestState.SelectList.length} results.`);return fStageComplete();}],(pError,pResultRecords)=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointReadSelectList;},{}],211:[function(require,module,exports){/**
|
|
5965
6001
|
* Meadow Endpoint - Read a Set of Records
|
|
5966
6002
|
*/const doAPIEndpointReads=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'Reads');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};this.waterfall([fStageComplete=>{tmpRequestState.Query=this.DAL.query;/** @type {number | boolean} */var tmpCap=false;/** @type {number | boolean} */var tmpBegin=false;if(typeof pRequest.params.Begin==='string'||typeof pRequest.params.Begin==='number'){tmpBegin=parseInt(pRequest.params.Begin);}if(typeof pRequest.params.Cap==='string'||typeof pRequest.params.Cap==='number'){tmpCap=parseInt(pRequest.params.Cap);}else{tmpCap=this.settings['MeadowDefaultMaxCap']||250;}tmpRequestState.Query.setCap(tmpCap).setBegin(tmpBegin);if(typeof pRequest.params.Filter==='string'){// If a filter has been passed in, parse it and add the values to the query.
|
|
5967
6003
|
this.parseFilter(pRequest.params.Filter,tmpRequestState.Query);}else if(pRequest.params.Filter){tmpRequestState.Query.setFilter(pRequest.params.Filter);}return fStageComplete();},fBehaviorInjector(`Reads-QueryConfiguration`),fStageComplete=>{this.DAL.doReads(tmpRequestState.Query,fStageComplete);},(pQuery,pRecords,fStageComplete)=>{if(!pRecords){return fStageComplete(this.ErrorHandler.getError('No records found.',404));}tmpRequestState.Records=pRecords;return fStageComplete();},fBehaviorInjector(`Reads-PostOperation`),fStageComplete=>{this.doStreamRecordArray(pResponse,tmpRequestState.Records,fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,'Read a list of records.');return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointReads;},{}],212:[function(require,module,exports){/**
|
|
@@ -6002,7 +6038,14 @@ if(!pRequest.JSONSchema){tmpRequestState.JSONSchema=this.extend({},this.DAL.json
|
|
|
6002
6038
|
let tmpRequestState=this.cloneAsyncSafeRequestState(pRequestState,'doUpdate');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};// If there is not a default identifier or cached record, fail
|
|
6003
6039
|
if(pRecordToModify[this.DAL.defaultIdentifier]<1&&typeof pOptionalCachedUpdatingRecord==='undefined'){return fCallback('Record update failure - a valid record ID is required in the passed-in record.');}if(!Array.isArray(tmpRequestState.ParentRequestState.UpdatedRecords)){tmpRequestState.ParentRequestState.UpdatedRecords=[];}this.waterfall([fStageComplete=>{tmpRequestState.RecordToModify=pRecordToModify;if(typeof pOptionalCachedUpdatingRecord!=='undefined'){// Use the cached updating record instead of reading a record.
|
|
6004
6040
|
tmpRequestState.OriginalRecord=pOptionalCachedUpdatingRecord;return fStageComplete();}else{tmpRequestState.Query=this.DAL.query;tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier,tmpRequestState.RecordToModify[this.DAL.defaultIdentifier]);// Load the record so we can do security checks on it
|
|
6005
|
-
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(pError){return fStageComplete(pError);}if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not Found',404));}tmpRequestState.Record=pRecord
|
|
6041
|
+
this.DAL.doRead(tmpRequestState.Query,(pError,pQuery,pRecord)=>{if(pError){return fStageComplete(pError);}if(!pRecord){return fStageComplete(this.ErrorHandler.getError('Record not Found',404));}tmpRequestState.Record=pRecord;// Alias the loaded pre-update row under an
|
|
6042
|
+
// unambiguous name. pRequestState.Record gets
|
|
6043
|
+
// overwritten with the POST-update row later in
|
|
6044
|
+
// this waterfall; OriginalRecord preserves the
|
|
6045
|
+
// PRE-update reference for post-op hooks that
|
|
6046
|
+
// need to compare before/after values (change
|
|
6047
|
+
// logs, customer-boundary checks, etc.).
|
|
6048
|
+
tmpRequestState.OriginalRecord=pRecord;return fStageComplete();});}},fStageComplete=>{tmpRequestState.Query=this.DAL.query;return fStageComplete();},fBehaviorInjector(`Update-PreOperation`),fStageComplete=>{tmpRequestState.Query.setIDUser(tmpRequestState.SessionData.UserID);tmpRequestState.Query.addRecord(tmpRequestState.RecordToModify);return fStageComplete();},fBehaviorInjector(`Update-QueryConfiguration`),fStageComplete=>{this.DAL.doUpdate(tmpRequestState.Query,(pError,pQuery,pReadQuery,pRecord)=>{if(pError){if(typeof pError=='string'){return fStageComplete(this.ErrorHandler.getError(pError,500));}else{return fStageComplete(pError);}}if(!pRecord){return fStageComplete(this.ErrorHandler.getError(`Error in DAL Update: No record returned from persistence engine.`,500));}tmpRequestState.Record=pRecord;return fStageComplete();});},fStageComplete=>{return this.BehaviorInjection.runBehavior(`Update-PostOperation`,this,pRequest,tmpRequestState,fStageComplete);},fStageComplete=>{tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Updated record with ID ${tmpRequestState.Record[this.DAL.defaultIdentifier]}`);return fStageComplete();}],pError=>{if(pError){// Ensure we have a record object to attach the error to
|
|
6006
6049
|
if(tmpRequestState.Record){tmpRequestState.Record.Error=pError;}else{tmpRequestState.Record={Error:pError};}tmpRequestState.ParentRequestState.RecordUpdateError=true;tmpRequestState.ParentRequestState.RecordUpdateErrorObject=pError;tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);}return fCallback();});};module.exports=doUpdate;},{}],221:[function(require,module,exports){/**
|
|
6007
6050
|
* Meadow Endpoint - Upsert a set of Records
|
|
6008
6051
|
*/const doUpsert=require('./Meadow-Operation-Upsert.js');const marshalLiteList=require('../read/Meadow-Marshal-LiteList.js');const doAPIEndpointUpserts=function(pRequest,pResponse,fNext){let tmpRequestState=this.initializeRequestState(pRequest,'UpsertBulk');let fBehaviorInjector=pBehaviorHash=>{return fStageComplete=>{this.BehaviorInjection.runBehavior(pBehaviorHash,this,pRequest,tmpRequestState,fStageComplete);};};tmpRequestState.CreatedRecords=[];tmpRequestState.UpdatedRecords=[];tmpRequestState.UpsertedRecords=[];tmpRequestState.ErrorRecords=[];this.waterfall([fStageComplete=>{if(!Array.isArray(pRequest.body)){return fStageComplete(this.ErrorHandler.getError(`Record bulk upsert failure - a valid array of records is required.`,500));}tmpRequestState.BulkRecords=pRequest.body;return fStageComplete();},fBehaviorInjector(`UpsertBulk-PreOperation`),fStageComplete=>{this.eachLimit(tmpRequestState.BulkRecords,1,(pRecord,fCallback)=>{doUpsert.call(this,pRecord,pRequest,tmpRequestState,pResponse,fCallback);},fStageComplete);},fBehaviorInjector(`UpsertBulk-PostOperation`),fStageComplete=>{return this.doStreamRecordArray(pResponse,marshalLiteList.call(this,tmpRequestState.UpsertedRecords,pRequest),fStageComplete);},fStageComplete=>{this.log.requestCompletedSuccessfully(pRequest,tmpRequestState,`Bulk upsert complete -- ${tmpRequestState.UpsertedRecords.length} records processed`);return fStageComplete();}],pError=>{return this.ErrorHandler.handleErrorIfSet(pRequest,tmpRequestState,pResponse,pError,fNext);});};module.exports=doAPIEndpointUpserts;},{"../read/Meadow-Marshal-LiteList.js":214,"./Meadow-Operation-Upsert.js":223}],222:[function(require,module,exports){/**
|