Skip to content

Commit e9e889e

Browse files
authoredOct 18, 2017
Merge pull request #397 from richardlay/master
Added option to use "label" as the next model name prefix
2 parents c379231 + 2d9d40b commit e9e889e

File tree

7 files changed

+89
-10
lines changed

7 files changed

+89
-10
lines changed
 

‎lib/builder.js

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ internals.removeNoneSchemaOptions = function(options) {
240240
'reuseDefinitions',
241241
'uiCompleteScript',
242242
'deReference',
243+
'definitionPrefix',
243244
'validatorUrl',
244245
'jsonEditor',
245246
'acceptToProduce',

‎lib/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module.exports = {
2020
'uiCompleteScript': null,
2121
'xProperties': true,
2222
'reuseDefinitions': true,
23+
'definitionPrefix': 'default',
2324
'deReference': false,
2425
'validatorUrl': '//online.swagger.io/validator',
2526
'acceptToProduce': true, // internal, NOT public

‎lib/definitions.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ internals.definitions.prototype.append = function (definitionName, definition, c
4444
out = definitionName;
4545
} else {
4646
// create new definition
47-
out = internals.append(null, definition, currentCollection, settings);
47+
out = internals.append(definitionName, definition, currentCollection, true, settings);
4848
}
4949
} else {
5050
// create new definition
51-
out = internals.append(definitionName, definition, currentCollection, settings);
51+
out = internals.append(definitionName, definition, currentCollection, false, settings);
5252
}
5353

5454
return out;
@@ -64,7 +64,7 @@ internals.definitions.prototype.append = function (definitionName, definition, c
6464
* @param {Object} settings
6565
* @return {String}
6666
*/
67-
internals.append = function (definitionName, definition, currentCollection, settings) {
67+
internals.append = function (definitionName, definition, currentCollection, forceDynamicName, settings) {
6868

6969
let out;
7070
let foundDefinitionName;
@@ -79,7 +79,17 @@ internals.append = function (definitionName, definition, currentCollection, sett
7979
out = foundDefinitionName;
8080
} else {
8181
// else create a new item using definitionName or next model number
82-
out = definitionName || internals.nextModelName(currentCollection);
82+
if (forceDynamicName) {
83+
if (settings.definitionPrefix === 'useLabel') {
84+
out = internals.nextModelName(definitionName + ' ', currentCollection);
85+
}
86+
else {
87+
out = internals.nextModelName('Model ', currentCollection);
88+
}
89+
}
90+
else {
91+
out = definitionName || internals.nextModelName('Model ', currentCollection);
92+
}
8393
currentCollection[out] = definition;
8494
}
8595
return out;
@@ -126,22 +136,22 @@ internals.hash = function (obj) {
126136
/**
127137
* creates a new unique model name
128138
*
139+
* @param {String} nextModelNamePrefix
129140
* @param {Object} currentCollection
130141
* @return {String}
131142
*/
132-
internals.nextModelName = function (currentCollection) {
133-
143+
internals.nextModelName = function (nextModelNamePrefix, currentCollection) {
134144
let highest = 0;
135145
let key;
136146
for (key in currentCollection) {
137-
if (Utilities.startsWith(key, 'Model')) {
138-
let num = parseInt(key.replace('Model', ''), 10);
147+
if (Utilities.startsWith(key, nextModelNamePrefix)) {
148+
let num = parseInt(key.replace(nextModelNamePrefix, ''), 10) || 0;
139149
if (num && num > highest) {
140150
highest = num;
141151
}
142152
}
143153
}
144-
return 'Model ' + (highest + 1);
154+
return nextModelNamePrefix + (highest + 1);
145155
};
146156

147157

‎lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const schema = Joi.object({
3131
uiCompleteScript: Joi.string().allow(null),
3232
xProperties: Joi.boolean(),
3333
reuseDefinitions: Joi.boolean(),
34+
definitionPrefix: Joi.string(),
3435
deReference: Joi.boolean(),
3536
validatorUrl: Joi.string().allow(null),
3637
acceptToProduce: Joi.boolean(),

‎optionsreference.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ JSON (JSON endpoint needed to create UI)
3939
* `produces`: (array) The mimetypes produced - default: `['application/json']`
4040
* `xProperties`: Adds JOI data that cannot be use directly by swagger as metadata - default: `true`,
4141
* `reuseDefinitions`: Reuse of definition models to save space - default: `true`,
42+
* `definitionPrefix`: Dynamic naming convention. `default` or `useLabel` - default: `default`,
4243
* `deReference`: Dereferences JSON output - default: `false`,
4344
* `debug`: Validates the JSON ouput against swagger specification - default: `false`,
4445

‎test/Integration/definitions-test.js

+64
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,70 @@ lab.experiment('definitions', () => {
189189
});
190190
});
191191

192+
lab.test('definitionPrefix = useLabel', (done) => {
193+
194+
// use the label as a prefix for dynamic model names
195+
196+
const tempRoutes = [{
197+
method: 'POST',
198+
path: '/store1/',
199+
config: {
200+
handler: Helper.defaultHandler,
201+
tags: ['api'],
202+
validate: {
203+
payload: Joi.object({
204+
a: Joi.number(),
205+
b: Joi.number(),
206+
operator: Joi.string(),
207+
equals: Joi.number()
208+
}).label('A')
209+
}
210+
}
211+
}, {
212+
method: 'POST',
213+
path: '/store2/',
214+
config: {
215+
handler: Helper.defaultHandler,
216+
tags: ['api'],
217+
validate: {
218+
payload: Joi.object({
219+
c: Joi.number(),
220+
v: Joi.number(),
221+
operator: Joi.string(),
222+
equals: Joi.number()
223+
}).label('A A')
224+
}
225+
}
226+
}, {
227+
method: 'POST',
228+
path: '/store3/',
229+
config: {
230+
handler: Helper.defaultHandler,
231+
tags: ['api'],
232+
validate: {
233+
payload: Joi.object({
234+
c: Joi.number(),
235+
f: Joi.number(),
236+
operator: Joi.string(),
237+
equals: Joi.number()
238+
}).label('A')
239+
}
240+
}
241+
}];
242+
243+
Helper.createServer({ definitionPrefix: 'useLabel' }, tempRoutes, (err, server) => {
244+
245+
expect(err).to.equal(null);
246+
server.inject({ method: 'GET', url: '/swagger.json' }, function (response) {
247+
248+
expect(response.statusCode).to.equal(200);
249+
expect(response.result.definitions.A).to.exist();
250+
expect(response.result.definitions['A A']).to.exist();
251+
expect(response.result.definitions['A 1']).to.exist();
252+
Helper.validate(response, done, expect);
253+
});
254+
});
255+
});
192256

193257
lab.test('test that optional array is not in swagger output', (done) => {
194258

‎usageguide.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ validate: {
119119
```
120120
__NOTE: the plugin reuses "definition models" these describe each JSON object use by an API i.e. a "user". This feature
121121
was added to reduce the size of the JSON. The reuse of models can cause names to be reused as well. Please switch
122-
`options.reuseDefinitions` to `false` if you are nameing your JOI objects.__
122+
`options.reuseDefinitions` to `false` if you are naming your JOI objects. By default objects are named in a "Model #"
123+
format. To use the `label`, specify `options.definitionPrefix` as `useLabel`.__
123124

124125

125126

0 commit comments

Comments
 (0)
Please sign in to comment.