UNPKG

4.22 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, name, req)
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, name, req) {
75 if (value === undefined && !paramSchema.required && paramSchema.default !== undefined) {
76 if (!req.appliedDefaults) req.appliedDefaults = {}
77 req.appliedDefaults[name] = true
78 return paramSchema.default
79 }
80 return value
81}
82
83function getPathParams(req, operation) {
84 const params = req.params ? req.params : req.params = {}
85 if (req.app) return params // express
86
87 // restify
88 // req.params may contain a mix of more than just path parameters
89 // as restify has the option to merge body and query params in here too.
90 // This forces us to pull out just the ones defined in the swagger spec.
91 // Note that this means we can't later determine if the client has sent
92 // extra path parameters so validation around this is not possible.
93
94 return operation.parameters
95 .filter(op => op.in === 'path')
96 .reduce((pathParams, op) => {
97 if (params[op.name] !== undefined) {
98 pathParams[op.name] = params[op.name]
99 }
100 return pathParams
101 }, {})
102}
103
104function getFormData(req) {
105 if (req.accepts('multipart/form-data') || req.accepts('application/x-www-form-urlencoded')) {
106 const formData = Object.assign({}, req.body)
107 if (Array.isArray(req.files)) {
108 req.files.forEach(file => {
109 formData[file.filename] = file
110 })
111 } else if (req.files && typeof req.files === 'object') {
112 Object.assign(formData, req.files)
113 }
114 else if (req.file && typeof req.files === 'object') {
115 formData[req.file.filename] = req.file
116 }
117 return formData
118 }
119 return null
120}
121
122function getOriginalGroup(req, groupId) {
123 switch (groupId) {
124 case 'header': return req.headers || {}
125 case 'path': return req.params || {}
126 case 'query': return (typeof req.query === 'function') ? {} : req.query || {}
127 case 'body':
128 case 'formData': return req.body || {}
129 default: return {}
130 }
131}
132
133/*
134 * If using Restify, grab the common params object.
135 * We'll merge back formatted query and path params
136 * if they existed unformatted in there previously.
137 */
138function getReqParams(req, groupId) {
139 return (req && !req.app && (groupId === 'query' || groupId === 'path'))
140 ? req.params
141 : undefined
142}