UNPKG

2.25 kBJavaScriptView Raw
1
2
3
4
5!function(xhr) {
6 var pending = []
7 , loaded = getSchema.loaded = {}
8
9 xhr.getSchema = getSchema
10 /**
11 * JSON Reference
12 * @see http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
13 * A JSON Reference is a JSON object, which contains a member named "$ref":
14 * { "$ref": "http://example.com/example.json#/foo/bar" }
15 *
16 *
17 * JSON Activity Streams
18 * http://activitystrea.ms/specs/json/schema/activity-schema.html
19 * https://tools.ietf.org/html/draft-snell-activitystreams-09
20 *
21 * official mime type is "application/schema+json"
22 */
23
24 function getSchema(ref, next) {
25 var parts = ref.split("#")
26 , file = parts[0]
27 , schema = loaded[file]
28 , path = decodeURIComponent((parts[1] || "").replace(/\+/g, " "))
29
30 if (schema && schema !== 1) {
31 return next && next(null, path ? Item.get(schema, path) : schema)
32 }
33
34 pending.push(arguments)
35 loaded[file] = 1
36
37 if (schema !== 1) xhr("GET", file, function(err, _schema) {
38 if (err) return next(err)
39
40 var i, ref
41 , refs = []
42 , schema = JSON.parse(_schema)
43 , cb = Fn.wait(function() {
44 loaded[file] = schema
45 if (pending.length) {
46 var arr = pending
47 pending = []
48 for (i = 0; ref = arr[i++]; ) {
49 getSchema.apply(null, ref)
50 }
51 }
52 })
53 resolveRefs(schema, refs, file, schema)
54 if (refs[0]) {
55 // TODO:2014-12-23:lauri:resolve multiple refs
56 // TODO:2014-12-23:lauri:resolve refs from other files
57 // TODO:2016-07-26:lauri:Fix resolving circular refs
58 for (i = 0; ref = refs[i]; i += 3) !function(ref, i, next) {
59 getSchema(ref, function(err, schema) {
60 refs[i+1][refs[i+2]] = schema
61 next()
62 })
63 }(ref, i, cb.wait())
64 }
65 cb()
66
67 }).send()
68 }
69
70 function resolveRefs(obj, refs, $id, schema, key, val) {
71 for (key in obj) if (val = obj[key]) {
72 if (typeof val.$id == "string") {
73 resolveRefs(loaded[val.$id] = val, refs, val.$id, val)
74 } else if (typeof val == "object") {
75 resolveRefs(val, refs, $id, schema)
76 }
77 if (val = val.$ref) {
78 if (val.charAt(0) == "#") {
79 val = val.slice(1)
80 obj[key] = val ? Item.get(schema, val) : schema
81 } else if (val.charAt(0) != "/") {
82 val = $id.replace(/[^\/]*$/, val)
83 refs.push(val, obj, key)
84 }
85 }
86 }
87 }
88
89}(xhr)
90
91
92