1+ const HttpStatusError = require ( './errors/HttpStatusError' ) ;
2+
3+ class Handler {
4+ constructor ( model , options = { limit : 50 , offset : 0 } ) {
5+ this . model = model ;
6+ this . limit = options . limit ;
7+ this . offset = options . offset ;
8+ }
9+
10+ async get ( req , res , next ) {
11+ try {
12+ const data = await this . findOne ( req . params ) ;
13+ res . send ( data ) ;
14+ } catch ( error ) {
15+ next ( error ) ;
16+ }
17+ }
18+
19+ async destroy ( req , res , next ) {
20+ try {
21+ const data = await this . findOne ( req . params ) ;
22+ await data . destroy ( ) ;
23+ res . sendStatus ( 204 ) ;
24+ } catch ( error ) {
25+ next ( error ) ;
26+ }
27+ }
28+
29+ async update ( req , res , next ) {
30+ try {
31+ const data = await this . findOne ( req , res , next ) ;
32+ const result = await data . updateAttributes ( req . body ) ;
33+ res . send ( result ) ;
34+ } catch ( error ) {
35+ next ( error ) ;
36+ }
37+ }
38+
39+ async findOne ( params , options = { where : { } } ) {
40+ const { rawAttributes } = this . model ;
41+
42+ for ( let key in params ) {
43+ if ( params . hasOwnProperty ( key ) && rawAttributes . hasOwnProperty ( key ) ) {
44+ options [ key ] = params [ key ] ;
45+ }
46+ }
47+
48+ const data = await this . model . findOne ( options ) ;
49+
50+ if ( ! data ) {
51+ throw new HttpStatusError ( 404 , 'Not Found' ) ;
52+ }
53+
54+ return data ;
55+ }
56+
57+ async findAndCountAll ( params , options = { where : { } } ) {
58+ const { fields, limit = this . limit , offset = this . offset , sort, ...filters } = params ;
59+ const { rawAttributes } = this . model ;
60+
61+ for ( let key in filters ) {
62+ if ( filters . hasOwnProperty ( key ) && rawAttributes . hasOwnProperty ( key ) ) {
63+ const value = filters [ key ] ;
64+ try {
65+ options . where [ key ] = JSON . parse ( value ) ;
66+ } catch ( error ) {
67+ options . where [ key ] = value . split ( ',' ) ;
68+ }
69+ }
70+ }
71+
72+ if ( fields ) {
73+ options . attributes = fields . split ( ',' ) ;
74+ }
75+
76+ if ( sort ) {
77+ const keys = sort . split ( ',' ) ;
78+
79+ options . order = keys . map ( ( key ) => {
80+ if ( key . indexOf ( '-' ) === 0 ) {
81+ return [ key . substr ( 1 ) , 'DESC' ] ;
82+ } else {
83+ return [ key , 'ASC' ] ;
84+ }
85+ } ) ;
86+ }
87+
88+ const { count, rows } = await this . Mode . findAndCountAll ( options ) ;
89+
90+ return {
91+ start : options . offset ,
92+ end : Math . max ( count , options . offset + offset . limit ) ,
93+ count,
94+ rows
95+ } ;
96+ }
97+
98+ async query ( req , res , next ) {
99+ try {
100+ const { start, end, count, rows } = await this . findAndCountAll ( req . query ) ;
101+
102+ res . set ( 'Content-Range' , `${ start } -${ end } /${ count } ` ) ;
103+ res . status ( end === count ? 200 : 206 ) ;
104+ res . send ( rows ) ;
105+ } catch ( error ) {
106+ next ( error ) ;
107+ }
108+ }
109+ }
0 commit comments