Skip to content

Commit 88b2c19

Browse files
authored
Merge pull request #13 from ehmicky/feature/formats
Feature/formats
2 parents 5ce9538 + 42bed9d commit 88b2c19

10 files changed

+207
-59
lines changed

index.js

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ function convertSchema(schema, options) {
8686
}
8787

8888
validateType(schema.type);
89-
schema = convertTypes(schema, options);
89+
schema = convertTypes(schema);
90+
schema = convertFormat(schema, options);
9091

9192
if (typeof schema['x-patternProperties'] === 'object'
9293
&& options.supportPatternProperties) {
@@ -135,28 +136,94 @@ function validateType(type) {
135136
}
136137
}
137138

138-
function convertTypes(schema, options) {
139-
var toDateTime = options.dateToDateTime;
139+
function convertTypes(schema) {
140+
if (schema.type !== undefined && schema.nullable === true) {
141+
schema.type = [schema.type, 'null'];
142+
}
143+
144+
return schema;
145+
}
140146

141-
if (schema.type === undefined) {
147+
function convertFormat(schema, options) {
148+
var format = schema.format;
149+
150+
if (format === undefined || FORMATS.indexOf(format) !== -1) {
142151
return schema;
143152
}
144153

145-
if (schema.type == 'string' && schema.format == 'date' && toDateTime === true) {
146-
schema.format = 'date-time';
147-
}
154+
var converter = formatConverters[format];
148155

149-
if (! schema.format) {
150-
delete schema.format;
151-
}
156+
if (converter === undefined) { return schema; }
152157

153-
if (schema.nullable === true) {
154-
schema.type = [schema.type, 'null'];
158+
return converter(schema, options);
159+
}
160+
161+
// Valid JSON schema v4 formats
162+
var FORMATS = ['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference'];
163+
164+
function convertFormatInt32 (schema) {
165+
schema.minimum = MIN_INT_32;
166+
schema.maximum = MAX_INT_32;
167+
return schema;
168+
}
169+
170+
var MIN_INT_32 = 0 - Math.pow(2, 31);
171+
var MAX_INT_32 = Math.pow(2, 31) - 1;
172+
173+
function convertFormatInt64 (schema) {
174+
schema.minimum = MIN_INT_64;
175+
schema.maximum = MAX_INT_64;
176+
return schema;
177+
}
178+
179+
var MIN_INT_64 = 0 - Math.pow(2, 63);
180+
var MAX_INT_64 = Math.pow(2, 63) - 1;
181+
182+
function convertFormatFloat (schema) {
183+
schema.minimum = MIN_FLOAT;
184+
schema.maximum = MAX_FLOAT;
185+
return schema;
186+
}
187+
188+
var MIN_FLOAT = 0 - Math.pow(2, 128);
189+
var MAX_FLOAT = Math.pow(2, 128) - 1;
190+
191+
function convertFormatDouble (schema) {
192+
schema.minimum = MIN_DOUBLE;
193+
schema.maximum = MAX_DOUBLE;
194+
return schema;
195+
}
196+
197+
var MIN_DOUBLE = 0 - Number.MAX_VALUE;
198+
var MAX_DOUBLE = Number.MAX_VALUE;
199+
200+
function convertFormatDate (schema, options) {
201+
if (options.dateToDateTime === true) {
202+
schema.format = 'date-time';
155203
}
156204

157205
return schema;
158206
}
159207

208+
function convertFormatByte (schema) {
209+
schema.pattern = BYTE_PATTERN;
210+
return schema;
211+
}
212+
213+
// Matches base64 (RFC 4648)
214+
// Matches `standard` base64 not `base64url`. The specification does not
215+
// exclude it but current ongoing OpenAPI plans will distinguish btoh.
216+
var BYTE_PATTERN = '^[\\w\\d+\\/=]*$';
217+
218+
var formatConverters = {
219+
int32: convertFormatInt32,
220+
int64: convertFormatInt64,
221+
float: convertFormatFloat,
222+
double: convertFormatDouble,
223+
date: convertFormatDate,
224+
byte: convertFormatByte
225+
};
226+
160227
function convertPatternProperties(schema, handler) {
161228
schema.patternProperties = schema['x-patternProperties'];
162229
delete schema['x-patternProperties'];

test/combination_keywords.test.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ test('iterates allOfs', function(assert) {
1717
required: ['foo'],
1818
properties: {
1919
foo: {
20-
type: 'integer',
21-
format: 'int64'
20+
type: 'integer'
2221
}
2322
}
2423
},
2524
{
2625
allOf: [
2726
{
28-
type: 'number',
29-
format: 'double'
27+
type: 'number'
3028
}
3129
]
3230
}
@@ -43,16 +41,14 @@ test('iterates allOfs', function(assert) {
4341
required: ['foo'],
4442
properties: {
4543
foo: {
46-
type: 'integer',
47-
format: 'int64'
44+
type: 'integer'
4845
}
4946
}
5047
},
5148
{
5249
allOf: [
5350
{
54-
type: 'number',
55-
format: 'double'
51+
type: 'number'
5652
}
5753
]
5854
}
@@ -207,7 +203,6 @@ test('converts types in not', function(assert) {
207203
properties: {
208204
not: {
209205
type: 'string',
210-
format: 'password',
211206
minLength: 8
212207
}
213208
}
@@ -221,7 +216,6 @@ test('converts types in not', function(assert) {
221216
properties: {
222217
not: {
223218
type: 'string',
224-
format: 'password',
225219
minLength: 8
226220
}
227221
}
@@ -241,7 +235,6 @@ test('converts types in not', function(assert) {
241235
schema = {
242236
not: {
243237
type: 'string',
244-
format: 'password',
245238
minLength: 8
246239
}
247240
};
@@ -252,7 +245,6 @@ test('converts types in not', function(assert) {
252245
$schema: 'http://json-schema.org/draft-04/schema#',
253246
not: {
254247
type: 'string',
255-
format: 'password',
256248
minLength: 8
257249
}
258250
};

test/items.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ test('items', function(assert) {
1414
type: 'array',
1515
items: {
1616
type: 'string',
17-
format: 'date-time',
1817
example: '2017-01-01T12:34:56Z'
1918
}
2019
};
@@ -25,8 +24,7 @@ test('items', function(assert) {
2524
$schema: 'http://json-schema.org/draft-04/schema#',
2625
type: 'array',
2726
items: {
28-
type: 'string',
29-
format: 'date-time'
27+
type: 'string'
3028
}
3129
};
3230

test/numeric_types.test.js

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,76 +2,106 @@ var test = require('tape')
22
, convert = require('../')
33
;
44

5-
test('handles integer types', function(assert) {
5+
test('handles int32 format', function(assert) {
66
var schema
77
, result
88
, expected
99
;
1010

11-
assert.plan(2);
11+
assert.plan(1);
1212

1313
schema = {
1414
type: 'integer',
15+
format: 'int32'
1516
};
1617

1718
result = convert(schema);
1819

1920
expected = {
2021
$schema: 'http://json-schema.org/draft-04/schema#',
2122
type: 'integer',
23+
format: 'int32',
24+
minimum: 0 - Math.pow(2, 31),
25+
maximum: Math.pow(2, 31) - 1
2226
};
2327

24-
assert.deepEqual(result, expected, 'integer type untouched');
28+
assert.deepEqual(result, expected, 'int32 converted to minimum|maximum');
29+
});
30+
31+
test('handles int64 format', function(assert) {
32+
var schema
33+
, result
34+
, expected
35+
;
36+
37+
assert.plan(1);
2538

2639
schema = {
2740
type: 'integer',
28-
format: 'int32',
41+
format: 'int64'
2942
};
3043

3144
result = convert(schema);
3245

3346
expected = {
3447
$schema: 'http://json-schema.org/draft-04/schema#',
3548
type: 'integer',
36-
format: 'int32'
49+
format: 'int64',
50+
minimum: 0 - Math.pow(2, 63),
51+
maximum: Math.pow(2, 63) - 1
3752
};
3853

39-
assert.deepEqual(result, expected, 'integer type and format untouched');
54+
assert.deepEqual(result, expected, 'int64 converted to minimum|maximum');
4055
});
4156

42-
test('handles number types', function(assert) {
57+
test('handles float format', function(assert) {
4358
var schema
4459
, result
4560
, expected
4661
;
4762

48-
assert.plan(2);
63+
assert.plan(1);
4964

5065
schema = {
5166
type: 'number',
67+
format: 'float'
5268
};
5369

5470
result = convert(schema);
5571

5672
expected = {
5773
$schema: 'http://json-schema.org/draft-04/schema#',
5874
type: 'number',
75+
format: 'float',
76+
minimum: 0 - Math.pow(2, 128),
77+
maximum: Math.pow(2, 128) - 1
5978
};
6079

61-
assert.deepEqual(result, expected, 'number type untouched');
80+
assert.deepEqual(result, expected, 'float converted to minimum|maximum');
81+
});
82+
83+
test('handles double format', function(assert) {
84+
var schema
85+
, result
86+
, expected
87+
;
88+
89+
assert.plan(1);
6290

6391
schema = {
6492
type: 'number',
65-
format: 'float'
93+
format: 'double'
6694
};
6795

6896
result = convert(schema);
6997

7098
expected = {
7199
$schema: 'http://json-schema.org/draft-04/schema#',
72100
type: 'number',
73-
format: 'float'
101+
format: 'double',
102+
minimum: 0 - Number.MAX_VALUE,
103+
maximum: Number.MAX_VALUE
74104
};
75105

76-
assert.deepEqual(result, expected, 'number type and format untouched');
106+
assert.deepEqual(result, expected, 'double converted to minimum|maximum');
77107
});

test/properties.test.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ test('additionalProperties is an object', function(assert) {
134134
type: 'object',
135135
properties: {
136136
foo: {
137-
type: 'string',
138-
format: 'date-time'
137+
type: 'string'
139138
}
140139
}
141140
}
@@ -155,8 +154,7 @@ test('additionalProperties is an object', function(assert) {
155154
type: 'object',
156155
properties: {
157156
foo: {
158-
type: 'string',
159-
format: 'date-time'
157+
type: 'string'
160158
}
161159
}
162160
}

test/schemas/schema-1-expected.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
"cats": {
99
"type": "array",
1010
"items": {
11-
"type": "integer",
12-
"format": "int64"
11+
"type": "integer"
1312
}
1413
}
1514
}
@@ -20,8 +19,7 @@
2019
"dogs": {
2120
"type": "array",
2221
"items": {
23-
"type": "integer",
24-
"format": "int64"
22+
"type": "integer"
2523
}
2624
}
2725
}
@@ -118,4 +116,3 @@
118116
],
119117
"$schema": "http://json-schema.org/draft-04/schema#"
120118
}
121-

test/schemas/schema-1.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"type": "array",
1010
"items": {
1111
"type": "integer",
12-
"format": "int64",
1312
"example": [
1413
1
1514
]
@@ -24,7 +23,6 @@
2423
"type": "array",
2524
"items": {
2625
"type": "integer",
27-
"format": "int64",
2826
"example": [
2927
1
3028
]

test/schemas/schema-2-invalid-type.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"type": "array",
1010
"items": {
1111
"type": "integer",
12-
"format": "int64",
1312
"example": [
1413
1
1514
]
@@ -24,7 +23,6 @@
2423
"type": "array",
2524
"items": {
2625
"type": "integer",
27-
"format": "int64",
2826
"example": [
2927
1
3028
]

0 commit comments

Comments
 (0)