UNPKG

3.44 kBJavaScriptView Raw
1'use strict';
2
3/*eslint-disable max-len*/
4
5var YAMLException = require('./exception');
6var Type = require('./type');
7
8
9function compileList(schema, name, result) {
10 var exclude = [];
11
12 schema[name].forEach(function (currentType) {
13 result.forEach(function (previousType, previousIndex) {
14 if (previousType.tag === currentType.tag &&
15 previousType.kind === currentType.kind &&
16 previousType.multi === currentType.multi) {
17
18 exclude.push(previousIndex);
19 }
20 });
21
22 result.push(currentType);
23 });
24
25 return result.filter(function (type, index) {
26 return exclude.indexOf(index) === -1;
27 });
28}
29
30
31function compileMap(/* lists... */) {
32 var result = {
33 scalar: {},
34 sequence: {},
35 mapping: {},
36 fallback: {},
37 multi: {
38 scalar: [],
39 sequence: [],
40 mapping: [],
41 fallback: []
42 }
43 }, index, length;
44
45 function collectType(type) {
46 if (type.multi) {
47 result.multi[type.kind].push(type);
48 result.multi['fallback'].push(type);
49 } else {
50 result[type.kind][type.tag] = result['fallback'][type.tag] = type;
51 }
52 }
53
54 for (index = 0, length = arguments.length; index < length; index += 1) {
55 arguments[index].forEach(collectType);
56 }
57 return result;
58}
59
60
61function Schema(definition) {
62 return this.extend(definition);
63}
64
65
66Schema.prototype.extend = function extend(definition) {
67 var implicit = [];
68 var explicit = [];
69
70 if (definition instanceof Type) {
71 // Schema.extend(type)
72 explicit.push(definition);
73
74 } else if (Array.isArray(definition)) {
75 // Schema.extend([ type1, type2, ... ])
76 explicit = explicit.concat(definition);
77
78 } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
79 // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
80 if (definition.implicit) implicit = implicit.concat(definition.implicit);
81 if (definition.explicit) explicit = explicit.concat(definition.explicit);
82
83 } else {
84 throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' +
85 'or a schema definition ({ implicit: [...], explicit: [...] })');
86 }
87
88 implicit.forEach(function (type) {
89 if (!(type instanceof Type)) {
90 throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
91 }
92
93 if (type.loadKind && type.loadKind !== 'scalar') {
94 throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
95 }
96
97 if (type.multi) {
98 throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');
99 }
100 });
101
102 explicit.forEach(function (type) {
103 if (!(type instanceof Type)) {
104 throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
105 }
106 });
107
108 var result = Object.create(Schema.prototype);
109
110 result.implicit = (this.implicit || []).concat(implicit);
111 result.explicit = (this.explicit || []).concat(explicit);
112
113 result.compiledImplicit = compileList(result, 'implicit', []);
114 result.compiledExplicit = compileList(result, 'explicit', []);
115 result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
116
117 return result;
118};
119
120
121module.exports = Schema;