@@ -25,8 +25,10 @@ const scrud = {
2525// globals
2626let server
2727let pgPool
28+ let pgPrefix = ''
2829let base = ''
2930let baseRgx = new RegExp ( `^/?${ base } /` )
31+ let maxBodyBytes = 1e6
3032let resources = { }
3133
3234// local helpers
@@ -39,19 +41,30 @@ const parseId = (url) => {
3941 return ( id || '' ) . match ( / ^ \d + $ / ) ? parseInt ( id , 10 ) : id || null
4042}
4143
42- const pgRun = ( query , args ) => {
44+ const callPgFunc = ( name , params ) => {
45+ let q = `SELECT * FROM ${ name } ($1);`
4346 if ( ! pgPool ) return Promise . reject ( new Error ( 'no database configured' ) )
4447 return new Promise ( ( resolve , reject ) => {
4548 pgPool . connect ( ( err , client , done ) => {
4649 if ( err ) return reject ( err )
47- client . query ( query , args , ( err , result ) => {
50+ client . query ( q , [ params ] , ( err , result ) => {
4851 done ( err )
49- return err ? reject ( err ) : resolve ( result . rows )
52+ if ( err ) return reject ( err )
53+ resolve ( ( result . rows [ 0 ] || { } ) [ name ] ? result . rows [ 0 ] [ name ] : [ ] )
5054 } )
5155 } )
5256 } )
5357}
5458
59+ const bodyParse = ( req ) => new Promise ( ( resolve , reject ) => {
60+ let body = ''
61+ req . on ( 'data' , ( d ) => {
62+ body += d . toString ( )
63+ if ( body . length > maxBodyBytes ) return reject ( new Error ( 'body too large' ) )
64+ } )
65+ req . on ( 'end' , ( ) => resolve ( body ? JSON . parse ( body ) : { } ) )
66+ } )
67+
5568// exports
5669module . exports = { register, start, logger, _find, _findAll, _create, _save}
5770
@@ -66,6 +79,8 @@ function register (name, opts) {
6679
6780// start server
6881function start ( opts = { } ) {
82+ if ( opts . namespace ) pgPrefix = `${ opts . namespace . toLowerCase ( ) } _`
83+ if ( opts . maxBodyBytes ) maxBodyBytes = opts . maxBodyBytes
6984 base = opts . base
7085 baseRgx = new RegExp ( `^/?${ base } /` )
7186 return new Promise ( ( resolve , reject ) => {
@@ -94,6 +109,9 @@ function handleRequest (req, res) {
94109 res . setHeader ( 'SCRUD' , `${ resource . name } :${ action } ` )
95110 req . id = parseId ( url )
96111 req . params = tinyParams ( url )
112+ req . once ( 'error' , ( err ) => {
113+ return res . end ( `{"data": null, "error": ${ JSON . stringify ( err ) } }` )
114+ } )
97115 return ( resource [ action ] || handlers [ action ] ) ( req , res , resource . name )
98116}
99117
@@ -107,7 +125,10 @@ function _find () { return null }
107125function _findAll ( ) { return null }
108126
109127// helper: create resource
110- function _create ( ) { return null }
128+ function _create ( resource , attrs ) {
129+ let firstRecord = ( d ) => Promise . resolve ( d [ 0 ] )
130+ return callPgFunc ( `${ pgPrefix } ${ resource } _create` , attrs ) . then ( firstRecord )
131+ }
111132
112133// helper: update resource
113134function _save ( ) { return null }
@@ -119,7 +140,14 @@ function resourceSearch (req, res, name) {
119140
120141// resource method: create
121142function resourceCreate ( req , res , name ) {
122- return res . end ( `{"data": null, "error": null}` )
143+ bodyParse ( req ) . then ( ( body ) => {
144+ req . params = Object . assign ( body , req . params )
145+ _create ( name , req . params ) . then ( ( d ) => {
146+ return res . end ( `{"data": ${ JSON . stringify ( d ) } , "error": null}` )
147+ } ) . catch ( ( err ) => {
148+ return res . end ( `{"data": null, "error": ${ JSON . stringify ( err ) } }` )
149+ } )
150+ } )
123151}
124152
125153// resource method: read
0 commit comments