Skip to content

Commit af36ec3

Browse files
committed
Implement create
1 parent 82cc8ce commit af36ec3

2 files changed

Lines changed: 42 additions & 7 deletions

File tree

index.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ const scrud = {
2525
// globals
2626
let server
2727
let pgPool
28+
let pgPrefix = ''
2829
let base = ''
2930
let baseRgx = new RegExp(`^/?${base}/`)
31+
let maxBodyBytes = 1e6
3032
let 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
5669
module.exports = {register, start, logger, _find, _findAll, _create, _save}
5770

@@ -66,6 +79,8 @@ function register (name, opts) {
6679

6780
// start server
6881
function 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 }
107125
function _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
113134
function _save () { return null }
@@ -119,7 +140,14 @@ function resourceSearch (req, res, name) {
119140

120141
// resource method: create
121142
function 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

test/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@ try {
1313

1414
test('scrud actions are handled as expected', async (assert) => {
1515
await scrud.register('member')
16-
let opts = {port: 8092, base: '/api'}
16+
let postBody = {
17+
first: 'andrew',
18+
last: 'carpenter',
19+
zip: 37615,
20+
email: 'andrew@audioinhd.com'
21+
}
22+
let opts = {port: 8092, base: '/api', namespace: 'scrud'}
1723
Object.assign(opts, secrets)
1824
await scrud.start(opts)
1925
let base = `http://localhost:${opts.port}${opts.base}/member`
2026
let sParams = `${encodeURIComponent('?first=andrew')}`
2127
let s = await axios({method: 'GET', url: `${base}${sParams}`})
2228
assert.is(s.headers.scrud, 'member:search')
23-
let c = await axios({method: 'POST', url: `${base}`})
29+
let c = await axios({method: 'POST', url: `${base}`, data: postBody})
30+
console.log(c.data)
2431
assert.is(c.headers.scrud, 'member:create')
2532
let r = await axios({method: 'GET', url: `${base}/1`})
2633
assert.is(r.headers.scrud, 'member:read')

0 commit comments

Comments
 (0)