@hitchy/plugin-odem-rest 0.4.8 → 0.5.0

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/index.js CHANGED
@@ -1,31 +1,3 @@
1
- /**
2
- * (c) 2018 cepharum GmbH, Berlin, http://cepharum.de
3
- *
4
- * The MIT License (MIT)
5
- *
6
- * Copyright (c) 2018 cepharum GmbH
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in all
16
- * copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- * SOFTWARE.
25
- *
26
- * @author: cepharum
27
- */
28
-
29
1
  "use strict";
30
2
 
31
3
  const { posix: { resolve } } = require( "path" );
@@ -34,6 +6,9 @@ module.exports = function() {
34
6
  const api = this;
35
7
  const { runtime: { services: Services, models: Models }, utility: { case: Case } } = api;
36
8
 
9
+ const logDebug = api.log( "hitchy:odem:rest:debug" );
10
+ const logError = api.log( "hitchy:odem:rest:error" );
11
+
37
12
  return {
38
13
  policies() {
39
14
  const { config: { model: modelConfig = {} } } = api;
@@ -45,6 +20,7 @@ module.exports = function() {
45
20
  const after = new Map();
46
21
 
47
22
  before.set( `ALL ${urlPrefix}`, CORS.getCommonRequestFilter() );
23
+ before.set( `ALL ${resolve( urlPrefix, ".schema" )}`, CORS.getRequestFilterForSchemata() );
48
24
  after.set( `ALL ${resolve( urlPrefix, ".schema" )}`, reqNotSupported );
49
25
 
50
26
  for ( let i = 0, numNames = modelNames.length; i < numNames; i++ ) {
@@ -53,6 +29,9 @@ module.exports = function() {
53
29
  const model = Models[name] || {};
54
30
 
55
31
  before.set( `ALL ${resolve( urlPrefix, routeName )}`, CORS.getRequestFilterForModel( model ) );
32
+ before.set( `ALL ${resolve( urlPrefix, routeName, ".schema" )}`, CORS.getRequestFilterForModelSchema( model ) );
33
+ before.set( `ALL ${resolve( urlPrefix, routeName, ":uuid" )}`, CORS.getRequestFilterForModelItem( model ) );
34
+
56
35
  after.set( `ALL ${resolve( urlPrefix, routeName )}`, reqNotSupported );
57
36
  }
58
37
 
@@ -63,8 +42,8 @@ module.exports = function() {
63
42
  /**
64
43
  * Responds on failure in case of not having handled request before.
65
44
  *
66
- * @param {HitchyIncomingMessage} req request descriptor
67
- * @param {HitchyServerResponse} res response manager
45
+ * @param {Hitchy.Core.IncomingMessage} req request descriptor
46
+ * @param {Hitchy.Core.ServerResponse} res response manager
68
47
  * @param {function(error:?Error):void} next callback to invoke when finished
69
48
  * @returns {void}
70
49
  */
@@ -118,8 +97,8 @@ module.exports = function() {
118
97
  /**
119
98
  * Handles request for listing schemata of all available models.
120
99
  *
121
- * @param {HitchyIncomingMessage} req request descriptor
122
- * @param {HitchyServerResponse} res response manager
100
+ * @param {Hitchy.Core.IncomingMessage} req request descriptor
101
+ * @param {Hitchy.Core.ServerResponse} res response manager
123
102
  * @returns {void}
124
103
  */
125
104
  function reqFetchSchemata( req, res ) {
@@ -197,8 +176,8 @@ module.exports = function() {
197
176
  /**
198
177
  * Responds on success.
199
178
  *
200
- * @param {HitchyIncomingMessage} req request descriptor
201
- * @param {HitchyServerResponse} res response manager
179
+ * @param {Hitchy.Core.IncomingMessage} req request descriptor
180
+ * @param {Hitchy.Core.ServerResponse} res response manager
202
181
  * @returns {void}
203
182
  */
204
183
  function reqSuccess( req, res ) {
@@ -225,12 +204,12 @@ module.exports = function() {
225
204
  /**
226
205
  * Handles request for fetching schema of selected model.
227
206
  *
228
- * @param {HitchyIncomingMessage} req description of request
229
- * @param {HitchyServerResponse} res API for creating response
207
+ * @param {Hitchy.Core.IncomingMessage} req description of request
208
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
230
209
  * @returns {void}
231
210
  */
232
211
  function reqFetchSchema( req, res ) {
233
- this.api.log( "hitchy:odem:rest" )( "got request fetching schema" );
212
+ logDebug( "got request fetching schema" );
234
213
 
235
214
  if ( !Services.OdemRestSchema.mayBeExposed( req, Model ) ) {
236
215
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -244,12 +223,12 @@ module.exports = function() {
244
223
  * Handles request for checking whether some selected item of model exists
245
224
  * or not.
246
225
  *
247
- * @param {HitchyIncomingMessage} req description of request
248
- * @param {HitchyServerResponse} res API for creating response
226
+ * @param {Hitchy.Core.IncomingMessage} req description of request
227
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
249
228
  * @returns {Promise|undefined} promises request processed successfully
250
229
  */
251
230
  function reqCheckItem( req, res ) {
252
- this.api.log( "hitchy:odem:rest" )( "got request checking if some item exists" );
231
+ logDebug( "got request checking if some item exists" );
253
232
 
254
233
  if ( !Schema.mayBeExposed( req, Model ) ) {
255
234
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -269,7 +248,7 @@ module.exports = function() {
269
248
  res.status( exists ? 200 : 404 ).send();
270
249
  } )
271
250
  .catch( error => {
272
- this.api.log( "hitchy:odem:rest" )( "checking %s:", routeName, error );
251
+ logError( "checking %s:", routeName, error );
273
252
  res.status( 500 ).json( { error: error.message } );
274
253
  } );
275
254
  }
@@ -277,12 +256,12 @@ module.exports = function() {
277
256
  /**
278
257
  * Handles request for fetching data of selected item.
279
258
  *
280
- * @param {HitchyIncomingMessage} req description of request
281
- * @param {HitchyServerResponse} res API for creating response
259
+ * @param {Hitchy.Core.IncomingMessage} req description of request
260
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
282
261
  * @returns {Promise} promises request processed successfully
283
262
  */
284
263
  function reqFetchItem( req, res ) {
285
- this.api.log( "hitchy:odem:rest" )( "got request fetching some item" );
264
+ logDebug( "got request fetching some item" );
286
265
 
287
266
  if ( !Schema.mayBeExposed( req, Model ) ) {
288
267
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -298,9 +277,10 @@ module.exports = function() {
298
277
  const item = new Model( uuid ); // eslint-disable-line new-cap
299
278
 
300
279
  return item.load()
301
- .then( loaded => res.json( loaded.toObject() ) )
280
+ .then( loaded => res.json( loaded.toObject( { serialized: true } ) ) )
302
281
  .catch( error => {
303
- this.api.log( "hitchy:odem:rest" )( "fetching %s:", routeName, error );
282
+ logError( "fetching %s:", routeName, error );
283
+
304
284
  switch ( error.code ) {
305
285
  case "ENOENT" : {
306
286
  res.status( 404 ).json( { error: "selected item not found" } );
@@ -317,12 +297,12 @@ module.exports = function() {
317
297
  * Fetches items of a collection optionally required to match some provided
318
298
  * query.
319
299
  *
320
- * @param {HitchyIncomingMessage} req incoming request
321
- * @param {HitchyServerResponse} res response controller
300
+ * @param {Hitchy.Core.IncomingMessage} req incoming request
301
+ * @param {Hitchy.Core.ServerResponse} res response controller
322
302
  * @returns {Promise} promises response sent
323
303
  */
324
304
  function reqFetchItems( req, res ) {
325
- this.api.log( "hitchy:odem:rest" )( "got request fetching items" );
305
+ logDebug( "got request fetching items" );
326
306
 
327
307
  if ( !Schema.mayBeExposed( req, Model ) ) {
328
308
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -372,12 +352,12 @@ module.exports = function() {
372
352
  /**
373
353
  * Handles request for listing all items of model.
374
354
  *
375
- * @param {HitchyIncomingMessage} req description of request
376
- * @param {HitchyServerResponse} res API for creating response
355
+ * @param {Hitchy.Core.IncomingMessage} req description of request
356
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
377
357
  * @returns {Promise|undefined} promises request processed successfully
378
358
  */
379
359
  function reqListMatches( req, res ) {
380
- this.api.log( "hitchy:odem:rest" )( "got request listing matching items" );
360
+ logDebug( "got request listing matching items" );
381
361
 
382
362
  if ( !Schema.mayBeExposed( req, Model ) ) {
383
363
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -405,7 +385,7 @@ module.exports = function() {
405
385
  } )
406
386
  .then( matches => {
407
387
  const result = {
408
- items: matches.map( m => m.toObject() ),
388
+ items: matches.map( m => m.toObject( { serialized: true } ) ),
409
389
  };
410
390
 
411
391
  if ( meta ) {
@@ -416,7 +396,8 @@ module.exports = function() {
416
396
  res.json( result );
417
397
  } )
418
398
  .catch( error => {
419
- this.api.log( "hitchy:odem:rest" )( "querying %s:", routeName, error );
399
+ logError( "querying %s:", routeName, error );
400
+
420
401
  res.status( 500 ).json( { error: error.message } );
421
402
  } );
422
403
  }
@@ -425,12 +406,12 @@ module.exports = function() {
425
406
  * Handles request for listing all items of model matching single given
426
407
  * condition.
427
408
  *
428
- * @param {HitchyIncomingMessage} req description of request
429
- * @param {HitchyServerResponse} res API for creating response
409
+ * @param {Hitchy.Core.IncomingMessage} req description of request
410
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
430
411
  * @returns {Promise|undefined} promises request processed successfully
431
412
  */
432
413
  function reqListAll( req, res ) {
433
- this.api.log( "hitchy:odem:rest" )( "got request listing all items" );
414
+ logDebug( "got request listing all items" );
434
415
 
435
416
  if ( !Schema.mayBeExposed( req, Model ) ) {
436
417
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -447,7 +428,7 @@ module.exports = function() {
447
428
  }, { loadRecords, metaCollector: meta } )
448
429
  .then( matches => {
449
430
  const result = {
450
- items: matches.map( m => m.toObject() ),
431
+ items: matches.map( m => m.toObject( { serialized: true } ) ),
451
432
  };
452
433
 
453
434
  if ( meta ) {
@@ -458,7 +439,8 @@ module.exports = function() {
458
439
  res.json( result );
459
440
  } )
460
441
  .catch( error => {
461
- this.api.log( "hitchy:odem:rest" )( "listing %s:", routeName, error );
442
+ logError( "listing %s:", routeName, error );
443
+
462
444
  res.status( 500 ).json( { error: error.message } );
463
445
  } );
464
446
  }
@@ -466,12 +448,12 @@ module.exports = function() {
466
448
  /**
467
449
  * Handles request for adding new item.
468
450
  *
469
- * @param {HitchyIncomingMessage} req description of request
470
- * @param {HitchyServerResponse} res API for creating response
451
+ * @param {Hitchy.Core.IncomingMessage} req description of request
452
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
471
453
  * @returns {Promise|undefined} promises request processed successfully
472
454
  */
473
455
  function reqCreateItem( req, res ) {
474
- this.api.log( "hitchy:odem:rest" )( "got request creating item" );
456
+ logDebug( "got request creating item" );
475
457
 
476
458
  if ( !Schema.mayBeExposed( req, Model ) ) {
477
459
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -483,7 +465,7 @@ module.exports = function() {
483
465
  return ( req.method === "GET" ? Promise.resolve( req.query ) : req.fetchBody() )
484
466
  .then( record => {
485
467
  if ( record.uuid ) {
486
- this.api.log( "hitchy:odem:rest" )( "creating %s:", routeName, "new entry can not be created with uuid" );
468
+ logDebug( "creating %s:", routeName, "new entry can not be created with uuid" );
487
469
  res.status( 400 ).json( { error: "new entry can not be created with uuid" } );
488
470
  return undefined;
489
471
  }
@@ -507,12 +489,12 @@ module.exports = function() {
507
489
  }
508
490
 
509
491
  return item.save().then( saved => {
510
- this.api.log( "hitchy:odem:rest" )( "created %s with %s", routeName, saved.uuid );
492
+ logDebug( "created %s with %s", routeName, saved.uuid );
511
493
  res.status( 201 ).json( { uuid: saved.uuid } );
512
494
  } );
513
495
  } )
514
496
  .catch( error => {
515
- this.api.log( "hitchy:odem:rest" )( "creating %s:", routeName, error );
497
+ logError( "creating %s:", routeName, error );
516
498
  res.status( 500 ).json( { error: error.message } );
517
499
  } );
518
500
  }
@@ -520,12 +502,12 @@ module.exports = function() {
520
502
  /**
521
503
  * Handles request for updating properties of a selected item.
522
504
  *
523
- * @param {HitchyIncomingMessage} req description of request
524
- * @param {HitchyServerResponse} res API for creating response
505
+ * @param {Hitchy.Core.IncomingMessage} req description of request
506
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
525
507
  * @returns {Promise|undefined} promises request processed successfully
526
508
  */
527
509
  function reqModifyItem( req, res ) {
528
- this.api.log( "hitchy:odem:rest" )( "got request to modify some item" );
510
+ logDebug( "got request to modify some item" );
529
511
 
530
512
  if ( !Schema.mayBeExposed( req, Model ) ) {
531
513
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -553,6 +535,7 @@ module.exports = function() {
553
535
  ] )
554
536
  .then( ( [ loaded, record ] ) => {
555
537
  if ( record ) {
538
+ // FIXME consider using Odem's Model.fromObject() method here
556
539
  const names = Object.keys( record );
557
540
  const numNames = names.length;
558
541
 
@@ -563,21 +546,21 @@ module.exports = function() {
563
546
  const name = names[i];
564
547
 
565
548
  if ( definedProps[name] ) {
566
- loaded.$properties[name] = record[name];
549
+ loaded.$properties[name] = record[name]; // eslint-disable-line no-param-reassign
567
550
  } else if ( definedComputed[name] ) {
568
- loaded[name] = record[name];
551
+ loaded[name] = record[name]; // eslint-disable-line no-param-reassign
569
552
  }
570
553
  }
571
554
  }
572
555
 
573
556
  return loaded.save()
574
557
  .then( saved => {
575
- res.json( saved.toObject() );
558
+ res.json( saved.toObject( { serialized: true } ) );
576
559
  } );
577
560
  } );
578
561
  } )
579
562
  .catch( error => {
580
- this.api.log( "hitchy:odem:rest" )( "updating %s:", routeName, error );
563
+ logError( "updating %s:", routeName, error );
581
564
  res.status( 500 ).json( { error: error.message } );
582
565
  } );
583
566
  }
@@ -586,12 +569,12 @@ module.exports = function() {
586
569
  /**
587
570
  * Handles request for updating properties of a selected item.
588
571
  *
589
- * @param {HitchyIncomingMessage} req description of request
590
- * @param {HitchyServerResponse} res API for creating response
572
+ * @param {Hitchy.Core.IncomingMessage} req description of request
573
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
591
574
  * @returns {Promise|undefined} promises request processed successfully
592
575
  */
593
576
  function reqReplaceItem( req, res ) {
594
- this.api.log( "hitchy:odem:rest" )( "got request replacing some item" );
577
+ logDebug( "got request replacing some item" );
595
578
 
596
579
  if ( !Schema.mayBeExposed( req, Model ) ) {
597
580
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -647,7 +630,7 @@ module.exports = function() {
647
630
  res.json( { uuid: saved.uuid } );
648
631
  } )
649
632
  .catch( error => {
650
- this.api.log( "hitchy:odem:rest" )( "updating %s:", routeName, error );
633
+ logError( "updating %s:", routeName, error );
651
634
  res.status( 500 ).json( { error: error.message } );
652
635
  } );
653
636
  }
@@ -655,12 +638,12 @@ module.exports = function() {
655
638
  /**
656
639
  * Handles request for removing selected item.
657
640
  *
658
- * @param {HitchyIncomingMessage} req description of request
659
- * @param {HitchyServerResponse} res API for creating response
641
+ * @param {Hitchy.Core.IncomingMessage} req description of request
642
+ * @param {Hitchy.Core.ServerResponse} res API for creating response
660
643
  * @returns {Promise|undefined} promises request processed successfully
661
644
  */
662
645
  function reqRemoveItem( req, res ) {
663
- this.api.log( "hitchy:odem:rest" )( "got request removing some item" );
646
+ logDebug( "got request removing some item" );
664
647
 
665
648
  if ( !Schema.mayBeExposed( req, Model ) ) {
666
649
  res.status( 403 ).json( { error: "access forbidden by model" } );
@@ -685,12 +668,12 @@ module.exports = function() {
685
668
  action: "remove"
686
669
  } ) )
687
670
  .catch( error => {
688
- this.api.log( "hitchy:odem:rest" )( "removing %s:", routeName, error );
671
+ logError( "removing %s:", routeName, error );
689
672
  res.status( 500 ).json( { error: error.message } );
690
673
  } );
691
674
  }
692
675
 
693
- this.api.log( "hitchy:odem:rest" )( "request for removing missing %s ignored", routeName );
676
+ logError( "request for removing missing %s ignored", routeName );
694
677
  res.status( 404 ).json( { error: "no such entry" } );
695
678
 
696
679
  return undefined;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@hitchy/plugin-odem-rest",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "description": "HTTP REST API for Hitchy's ODM",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
8
- "test": "hitchy-pm odem --exec mocha --ui=tdd test/**/*.js"
8
+ "test": "hitchy-pm odem --exec mocha --ui=tdd 'test/scripts/**/*.js'",
9
+ "coverage": "hitchy-pm odem --exec c8 mocha --ui=tdd 'test/scripts/**/*.js'"
9
10
  },
10
11
  "repository": "https://gitlab.com/hitchy/plugin-odem-rest.git",
11
12
  "keywords": [
@@ -17,15 +18,16 @@
17
18
  "bugs": "https://gitlab.com/hitchy/plugin-odem-rest/-/issues",
18
19
  "homepage": "https://gitlab.com/hitchy/plugin-odem-rest#plugin-odem-rest",
19
20
  "peerDependencies": {
20
- "@hitchy/core": "^0.6.4",
21
- "@hitchy/plugin-odem": "^0.5.7"
21
+ "@hitchy/core": "^0.6.18",
22
+ "@hitchy/plugin-odem": "^0.7.0"
22
23
  },
23
24
  "devDependencies": {
24
- "eslint": "^7.0.0",
25
- "eslint-config-cepharum": "^1.0.11",
26
- "eslint-plugin-promise": "^4.2.1",
27
- "@hitchy/server-dev-tools": "^0.2.7",
28
- "mocha": "^7.1.2",
25
+ "@hitchy/server-dev-tools": "^0.4.2",
26
+ "c8": "^7.11.0",
27
+ "eslint": "^8.13.0",
28
+ "eslint-config-cepharum": "^1.0.12",
29
+ "eslint-plugin-promise": "^6.0.0",
30
+ "mocha": "^9.2.2",
29
31
  "should": "^13.2.3",
30
32
  "should-http": "^0.1.1"
31
33
  }