Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 19eeb74

Browse files
committed
Add base crud() method
1 parent d7275df commit 19eeb74

2 files changed

Lines changed: 175 additions & 46 deletions

File tree

examples/test.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,26 @@ const put3 = function put3() {
6666
console.log('put3()')
6767
}
6868

69-
const routes = createRest(e => {
70-
e.before(before1)
71-
e.after(after1)
69+
const routes = createRest(root => {
70+
root.before(before1)
71+
root.after(after1)
7272

73-
e.post('/', post1)
73+
// root.post('/', post1)
7474

75-
e.scope('demo', e => {
76-
e.before(before2)
77-
e.after(after2)
75+
// root.scope('demo', demo => {
76+
// demo.before(before2)
77+
// demo.after(after2)
7878

79-
e.get('/', get1)
80-
e.get('/foo', get2)
79+
// demo.get('/', get1)
80+
// demo.get('/foo', get2)
8181

82-
e.scope('bar', e => {
83-
e.before(before3)
84-
e.after(after3)
82+
// demo.scope('bar', bar => {
83+
// bar.before(before3)
84+
// bar.after(after3)
8585

86-
e.put('/', put3)
87-
})
88-
})
86+
// bar.put('/', put3)
87+
// })
88+
// })
8989
})
9090

9191
const strf = (data, indent = ' ') => stringify(data, {

lib/index.js

Lines changed: 160 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pluralize from 'pluralize'
12
import { createRestInstanceSymbol } from './symbol'
23

34
/**
@@ -256,10 +257,10 @@ export class Maker {
256257
* @throws {Error} Path should not be deep
257258
* @throws {TypeError} Maybe you forget to add listener?
258259
* @example
259-
* createRest(r => {
260-
* r.get('name', () => console.log('Handled get /name request'))
261-
* r.get(() => console.log('Handled get / request'))
262-
* r.get('create',
260+
* createRest(root => {
261+
* root.get('name', () => console.log('Handled get /name request'))
262+
* root.get(() => console.log('Handled get / request'))
263+
* root.get('create',
263264
* (req, res, next) => next(),
264265
* authorize('user'),
265266
* () => console.log('Handled get /create with middlewares')
@@ -277,10 +278,10 @@ export class Maker {
277278
* @throws {Error} Path should not be deep
278279
* @throws {TypeError} Maybe you forget to add listener?
279280
* @example
280-
* createRest(r => {
281-
* r.put('name', () => console.log('Handled put /name request'))
282-
* r.put(() => console.log('Handled put / request'))
283-
* r.put('create',
281+
* createRest(root => {
282+
* root.put('name', () => console.log('Handled put /name request'))
283+
* root.put(() => console.log('Handled put / request'))
284+
* root.put('create',
284285
* (req, res, next) => next(),
285286
* authorize('user'),
286287
* () => console.log('Handled put /create with middlewares')
@@ -298,10 +299,10 @@ export class Maker {
298299
* @throws {Error} Path should not be deep
299300
* @throws {TypeError} Maybe you forget to add listener?
300301
* @example
301-
* createRest(r => {
302-
* r.delete('name', () => console.log('Handled delete /name request'))
303-
* r.delete(() => console.log('Handled delete / request'))
304-
* r.delete('create',
302+
* createRest(root => {
303+
* root.delete('name', () => console.log('Handled delete /name request'))
304+
* root.delete(() => console.log('Handled delete / request'))
305+
* root.delete('create',
305306
* (req, res, next) => next(),
306307
* authorize('user'),
307308
* () => console.log('Handled delete /create with middlewares')
@@ -319,10 +320,10 @@ export class Maker {
319320
* @throws {Error} Path should not be deep
320321
* @throws {TypeError} Maybe you forget to add listener?
321322
* @example
322-
* createRest(r => {
323-
* r.patch('name', () => console.log('Handled patch /name request'))
324-
* r.patch(() => console.log('Handled patch / request'))
325-
* r.patch('create',
323+
* createRest(root => {
324+
* root.patch('name', () => console.log('Handled patch /name request'))
325+
* root.patch(() => console.log('Handled patch / request'))
326+
* root.patch('create',
326327
* (req, res, next) => next(),
327328
* authorize('user'),
328329
* () => console.log('Handled patch /create with middlewares')
@@ -341,13 +342,13 @@ export class Maker {
341342
* @property {object} [methodNames] Change method names
342343
*
343344
* @example <caption>Usage with `only`</caption>
344-
* createRest(r => {
345-
* r.resource('foo', FooController, { only: ['read'] })
345+
* createRest(root => {
346+
* root.resource('foo', FooController, { only: ['read'] })
346347
* })
347348
*
348349
* @example <caption>Usage with `except`</caption>
349-
* createRest(r => {
350-
* r.resource('bar', BarController, { except: ['destroy', 'update'] })
350+
* createRest(root => {
351+
* root.resource('bar', BarController, { except: ['destroy', 'update'] })
351352
* })
352353
*
353354
* @example <caption>Method names</caption>
@@ -357,15 +358,15 @@ export class Maker {
357358
* justExample() {},
358359
* youDontNeedThis() {},
359360
* }
360-
* createRest(r => {
361-
* r.resource('demo', Controller, { methodNames: {
361+
* createRest(root => {
362+
* root.resource('demo', Controller, { methodNames: {
362363
* read: 'justExample', create: 'createDemo', update: 'updateMe', destroy: 'youDontNeedThis',
363364
* }})
364365
* })
365366
*/
366367

367368
/**
368-
* Create CRUD methods for single resource.
369+
* Add CRUD methods for single resource.
369370
*
370371
* Resources not merging. Use only one resource for path.
371372
* @param {string} name Name of the resource. Create route path from
@@ -384,10 +385,10 @@ export class Maker {
384385
* read() {},
385386
* update() {},
386387
* }
387-
* const routes = createRest(r => {
388-
* r.resource('example', Controller)
389-
* r.resource('demo', Controller, { only: ['create', 'read'] })
390-
* r.resource('single', Controller, { except: ['destroy', 'create'] })
388+
* const routes = createRest(root => {
389+
* root.resource('example', Controller)
390+
* root.resource('demo', Controller, { only: ['create', 'read'] })
391+
* root.resource('single', Controller, { except: ['destroy', 'create'] })
391392
* })
392393
* printRoutes(routes, true)
393394
*/
@@ -428,18 +429,146 @@ export class Maker {
428429
usedList = methodsList
429430
}
430431

431-
this.scope(name, r => {
432-
r.before(controller.beforeEach)
433-
r.after(controller.afterEach)
432+
this.scope(name, scope => {
433+
scope.before(controller.beforeEach)
434+
scope.after(controller.afterEach)
434435

435436
usedList
436437
.filter(handler => methodsList.includes(handler))
437438
.map(handler => [handler, methods[handler]])
438439
.forEach(([handler, httpMethod]) => {
439-
r[httpMethod](resolveMethodName(handler, controller))
440+
scope[httpMethod](resolveMethodName(handler, controller))
440441
})
441442
})
442443
}
444+
445+
/**
446+
* @desc Configure your `crud('name', controller, options)`
447+
* @typedef {object} crudOptions
448+
* @property {string[]} [only] Keep only that handlers: `[index, read, create, update, patch, destroy]`
449+
* @property {string[]} [except] Keep all except that handlers
450+
* @property {string} [memberId] Change :memberId in the URI
451+
*
452+
* @example <caption>Usage with `only`</caption>
453+
* createRest(root => {
454+
* root.crud('books', BooksController, { only: ['read', 'index] })
455+
* })
456+
* // GET /books -> index()
457+
* // GET /books/:bookId -> read()
458+
*
459+
* @example <caption>Usage with `except`</caption>
460+
* createRest(root => {
461+
* root.crud('songs', SongsController, { except: ['destroy', 'update'] })
462+
* })
463+
* // GET /songs -> index()
464+
* // POST /songs -> create()
465+
* // GET /songs/:songId -> read()
466+
* // PATCH /songs/:songId -> patch()
467+
*
468+
* @example <caption>Member ID renaming</caption>
469+
* createRest(root => {
470+
* root.crud('images', ImagesController, { memberId: 'imgid' })
471+
* })
472+
* // GET /images -> index()
473+
* // POST /images -> create()
474+
* // GET /images/:imgid -> read()
475+
* // PUT /images/:imgid -> update()
476+
* // PATCH /images/:imgid -> patch()
477+
* // DELETE /images/:imgid -> destroy()
478+
*/
479+
480+
/**
481+
* Add index, create, read, update, patch, remove methods to manage resource
482+
* @param {string} name Name of the crud. Crud path created from. Example: `books`
483+
* @param {CrudController} controller Object with methods
484+
* @param {crudOptions} [options={}] Options for crud
485+
*
486+
* @example <caption>Full example</caption>
487+
* createRest(root => {
488+
* root.crud('users', UsersController)
489+
* })
490+
* // GET /users -> index()
491+
* // POST /users -> create()
492+
* // GET /users/:userId -> read()
493+
* // PUT /users/:userId -> update()
494+
* // PATCH /users/:userId -> patch()
495+
* // DELETE /users/:userId -> destroy()
496+
*/
497+
crud(name, controller, options = {}) {
498+
/**
499+
* index : get /
500+
* create : post /
501+
* read : get /:id
502+
* update : put /:id
503+
* patch : patch /:id
504+
* remove : delete /:id
505+
*/
506+
if (!name || name.length === 0) {
507+
throw new Error('Crud should be named')
508+
}
509+
510+
if (typeof controller !== 'object') {
511+
return undefined
512+
}
513+
514+
if (options.only && options.except) {
515+
throw new Error(`You can't use 'except' and 'only' options at the same time`)
516+
}
517+
518+
const noMethodsSlicingOption = (!options.only || options.only.length === 0)
519+
&& (!options.except || options.except.length === 0)
520+
521+
/**
522+
* Check method existing in options `only` or `except`
523+
* @param {string} methodName
524+
* @private
525+
*/
526+
const checkMethod = methodName =>
527+
noMethodsSlicingOption
528+
|| (options.only && options.only.length && options.only.includes(methodName))
529+
|| (options.except && options.except.length && !options.except.includes(methodName))
530+
531+
const memberId = `:${options.memberId}` || `:${pluralize.singular}Id`
532+
533+
this.scope(name, scope => {
534+
scope.before(controller.beforeEach)
535+
scope.after(controller.afterEach)
536+
537+
if (checkMethod('index')) {
538+
scope.get('/', controller.index)
539+
}
540+
541+
if (checkMethod('create')) {
542+
scope.post('/', controller.create)
543+
}
544+
545+
scope.scope(memberId, member => {
546+
if (checkMethod('read')) {
547+
member.get('/', controller.read)
548+
}
549+
550+
if (checkMethod('update')) {
551+
member.put('/', controller.update)
552+
}
553+
554+
if (checkMethod('patch')) {
555+
if (controller.patch) {
556+
member.patch('/', controller.patch)
557+
}
558+
else if (checkMethod('update')) {
559+
member.patch('/', controller.update)
560+
}
561+
else {
562+
// no PATCH /:id add
563+
}
564+
}
565+
566+
if (checkMethod('destroy')) {
567+
member.delete('/', controller.destroy)
568+
}
569+
})
570+
})
571+
}
443572
}
444573

445574
/**

0 commit comments

Comments
 (0)