UNPKG

4.05 kBJavaScriptView Raw
1'use strict'
2
3const COLLECTION_FORMAT = {
4 CSV: ',',
5 SSV: ' ',
6 TSV: '\t',
7 PIPES: '|',
8 MULTI: '&' // multi query param instances foo=bar&foo=baz
9}
10
11exports.COLLECTION_FORMAT = COLLECTION_FORMAT
12exports.formatGroupData = formatGroupData
13exports.getPathParams = getPathParams
14exports.getFormData = getFormData
15
16function formatGroupData(groupSchema, groupData, groupId, req) {
17 const paramNames = Object.keys(groupSchema.properties)
18 if (!groupData) groupData = {}
19 const origGroupData = getOriginalGroup(req, groupId)
20 const reqParams = getReqParams(req, groupId)
21 paramNames.forEach(name => {
22 const paramSchema = groupSchema.properties[name]
23 let val = groupData[name]
24 val = parseCollectionFormat(paramSchema, val)
25 val = parseBoolean(paramSchema, val)
26 val = parseNumber(paramSchema, val)
27 val = applyDefaultValue(paramSchema, val)
28 origGroupData[name] = groupData[name] = val
29 if (reqParams && reqParams[name] !== undefined) {
30 reqParams[name] = val
31 }
32 })
33 return groupData
34}
35
36function parseCollectionFormat(paramSchema, value) {
37 if (paramSchema.type === 'array' && typeof value === 'string') {
38 return stringValueToArray(value, paramSchema.collectionFormat || 'csv')
39 }
40 return value
41}
42
43function parseBoolean(paramSchema, value) {
44 if (paramSchema.type === 'boolean') {
45 switch(`${value}`.toLowerCase().trim()) {
46 case 'true':
47 case '1':
48 case 'on':
49 case 'yes':
50 case 'y':
51 return true
52 case 'undefined':
53 return undefined
54 default:
55 return false
56 }
57 }
58 return value
59}
60
61function parseNumber(paramSchema, value) {
62 if ((paramSchema.type === 'integer' || paramSchema.type === 'number') && value !== '') {
63 const num = Number(value)
64 if (!isNaN(num)) return num
65 }
66 return value
67}
68
69function stringValueToArray(value, format) {
70 const delimiter = COLLECTION_FORMAT[format.toUpperCase()] || COLLECTION_FORMAT.CSV
71 return value.split(delimiter)
72}
73
74function applyDefaultValue(paramSchema, value) {
75 return (value === undefined && !paramSchema.required) ? paramSchema.default : value
76}
77
78function getPathParams(req, operation) {
79 const params = req.params ? req.params : req.params = {}
80 if (req.app) return params // express
81
82 // restify
83 // req.params may contain a mix of more than just path parameters
84 // as restify has the option to merge body and query params in here too.
85 // This forces us to pull out just the ones defined in the swagger spec.
86 // Note that this means we can't later determine if the client has sent
87 // extra path parameters so validation around this is not possible.
88
89 return operation.parameters
90 .filter(op => op.in === 'path')
91 .reduce((pathParams, op) => {
92 if (params[op.name] !== undefined) {
93 pathParams[op.name] = params[op.name]
94 }
95 return pathParams
96 }, {})
97}
98
99function getFormData(req) {
100 if (req.accepts('multipart/form-data') || req.accepts('application/x-www-form-urlencoded')) {
101 const formData = Object.assign({}, req.body)
102 if (Array.isArray(req.files)) {
103 req.files.forEach(file => {
104 formData[file.filename] = file
105 })
106 } else if (req.files && typeof req.files === 'object') {
107 Object.assign(formData, req.files)
108 }
109 else if (req.file && typeof req.files === 'object') {
110 formData[req.file.filename] = req.file
111 }
112 return formData
113 }
114 return null
115}
116
117function getOriginalGroup(req, groupId) {
118 switch (groupId) {
119 case 'header': return req.headers || {}
120 case 'path': return req.params || {}
121 case 'query': return (typeof req.query === 'function') ? {} : req.query || {}
122 case 'body':
123 case 'formData': return req.body || {}
124 default: return {}
125 }
126}
127
128/*
129 * If using Restify, grab the common params object.
130 * We'll merge back formatted query and path params
131 * if they existed unformatted in there previously.
132 */
133function getReqParams(req, groupId) {
134 return (req && !req.app && (groupId === 'query' || groupId === 'path'))
135 ? req.params
136 : undefined
137}