Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support for JSON schema referencing in toJSON().

  • Loading branch information...
commit 600b9a3372a29fbe1d1da631a1d3ca9c83a09d7d 1 parent b606996
@molnarg authored
View
69 lib/Schema.js
@@ -4,12 +4,6 @@ var def = require('def.js')
var Schema = module.exports = function() {}
Schema.prototype = {
- getId : function() {
- if (!this.id) this.id = 'id-' + Math.floor(Math.random()*100000)
-
- return this.id
- },
-
leafs : function() {
return { certain : [ this ], uncertain : [] }
},
@@ -36,7 +30,7 @@ Schema.prototype = {
if (this.wrapped) return this.validate
this.wrapped = true
- var publicFunctions = [ 'seal', 'toJSON', 'generate', 'getId', 'leafs', 'unwrap' ]
+ var publicFunctions = [ 'seal', 'toJSON', 'generate', 'leafs', 'unwrap' ]
publicFunctions = publicFunctions.concat(this.publicFunctions || [])
for (var i = 0; i < publicFunctions.length; i++) {
@@ -51,15 +45,68 @@ Schema.prototype = {
return this
},
- toJSON : function() {
- var json = {}
+ toJSON : session(function(makeReference) {
+ var json, session = Schema.session
- if (this.id != null) json.id = this.id
- if (this.doc != null) json.description = this.doc
+ // Initializing session if it isnt
+ if (!session.serialized) session.serialized = { objects: [], jsons: [], ids: [] }
+ var index = session.serialized.objects.indexOf(this)
+ if (makeReference && index !== -1) {
+ // This was already serialized, returning a JSON schema reference ($ref)
+ json = session.serialized.jsons[index]
+
+ // If there was no id given, generating one now
+ if (json.id == null) {
+ do {
+ json.id = 'id-' + Math.floor(Math.random()*100000)
+ } while (session.serialized.ids.indexOf(json.id) !== -1)
+ session.serialized.ids.push(json.id)
+ }
+
+ json = { '$ref': json.id }
+
+ } else {
+ // This was not serialized yet, serializing now
+ json = {}
+
+ if (this.doc != null) json.description = this.doc
+
+ // Registering that this was serialized and storing the json
+ session.serialized.objects.push(this)
+ session.serialized.jsons.push(json)
+ }
+
return json
+ })
+}
+
+var active = false
+function session(f) {
+ var proxy = function() {
+ if (active) {
+ // There's an active session, just forwarding to the original function
+ return f.apply(this, arguments)
+
+ } else {
+ // The initiator is the one who handles the active flag, and clears the session when it's over
+ active = true
+
+ var result = f.apply(this, arguments)
+
+ // Cleanup
+ for (var i in session) delete session[i]
+ active = false
+
+ return result
+ }
}
+
+ for (var i in f) proxy[i] = f[i].bind(f)
+
+ return proxy
}
+Schema.session = session
Schema.fromJS = def()
View
8 lib/extensions/Array.js
@@ -51,8 +51,10 @@ var ArraySchema = module.exports = Schema.extend({
}
},
- toJSON : function() {
- var json = Schema.prototype.toJSON.call(this)
+ toJSON : Schema.session(function() {
+ var json = Schema.prototype.toJSON.call(this, true)
+
+ if (json['$ref'] != null) return json
json.tpye = 'array'
@@ -61,7 +63,7 @@ var ArraySchema = module.exports = Schema.extend({
if (this.itemSchema !== anything) json.items = this.itemSchema.toJSON()
return json
- }
+ })
})
Schema.fromJSON.def(function(sch) {
View
8 lib/patterns/object.js
@@ -114,8 +114,10 @@ var ObjectSchema = module.exports = Schema.extend({
}
},
- toJSON : function() {
- var i, property, regexp, json = Schema.prototype.toJSON.call(this)
+ toJSON : Schema.session(function() {
+ var i, property, regexp, json = Schema.prototype.toJSON.call(this, true)
+
+ if (json['$ref'] != null) return json
json.type = 'object'
@@ -141,7 +143,7 @@ var ObjectSchema = module.exports = Schema.extend({
}
return json
- }
+ })
})
// Testing if a given string is a real regexp or just a single string escaped
View
8 lib/patterns/or.js
@@ -30,13 +30,15 @@ var OrSchema = module.exports = Schema.extend({
return { certain : certain, uncertain : uncertain }
},
- toJSON : function() {
- var json = Schema.prototype.toJSON.call(this)
+ toJSON : Schema.session(function() {
+ var json = Schema.prototype.toJSON.call(this, true)
, subjsons = this.schemas.map(function(sch) { return sch.toJSON() })
, onlyEquality = subjsons.every(function(json) {
return json['enum'] instanceof Array && json['enum'].length === 1
})
+ if (json['$ref'] != null) return json
+
if (onlyEquality) {
json['enum'] = subjsons.map(function(json) {
return json['enum'][0]
@@ -50,7 +52,7 @@ var OrSchema = module.exports = Schema.extend({
}
return json
- }
+ })
})
Please sign in to comment.
Something went wrong with that request. Please try again.