source: imaps-frontend/node_modules/ajv/lib/compile/util.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[d565449]1'use strict';
2
3
4module.exports = {
5 copy: copy,
6 checkDataType: checkDataType,
7 checkDataTypes: checkDataTypes,
8 coerceToTypes: coerceToTypes,
9 toHash: toHash,
10 getProperty: getProperty,
11 escapeQuotes: escapeQuotes,
12 equal: require('fast-deep-equal'),
13 ucs2length: require('./ucs2length'),
14 varOccurences: varOccurences,
15 varReplace: varReplace,
16 schemaHasRules: schemaHasRules,
17 schemaHasRulesExcept: schemaHasRulesExcept,
18 schemaUnknownRules: schemaUnknownRules,
19 toQuotedString: toQuotedString,
20 getPathExpr: getPathExpr,
21 getPath: getPath,
22 getData: getData,
23 unescapeFragment: unescapeFragment,
24 unescapeJsonPointer: unescapeJsonPointer,
25 escapeFragment: escapeFragment,
26 escapeJsonPointer: escapeJsonPointer
27};
28
29
30function copy(o, to) {
31 to = to || {};
32 for (var key in o) to[key] = o[key];
33 return to;
34}
35
36
37function checkDataType(dataType, data, strictNumbers, negate) {
38 var EQUAL = negate ? ' !== ' : ' === '
39 , AND = negate ? ' || ' : ' && '
40 , OK = negate ? '!' : ''
41 , NOT = negate ? '' : '!';
42 switch (dataType) {
43 case 'null': return data + EQUAL + 'null';
44 case 'array': return OK + 'Array.isArray(' + data + ')';
45 case 'object': return '(' + OK + data + AND +
46 'typeof ' + data + EQUAL + '"object"' + AND +
47 NOT + 'Array.isArray(' + data + '))';
48 case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
49 NOT + '(' + data + ' % 1)' +
50 AND + data + EQUAL + data +
51 (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')';
52 case 'number': return '(typeof ' + data + EQUAL + '"' + dataType + '"' +
53 (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')';
54 default: return 'typeof ' + data + EQUAL + '"' + dataType + '"';
55 }
56}
57
58
59function checkDataTypes(dataTypes, data, strictNumbers) {
60 switch (dataTypes.length) {
61 case 1: return checkDataType(dataTypes[0], data, strictNumbers, true);
62 default:
63 var code = '';
64 var types = toHash(dataTypes);
65 if (types.array && types.object) {
66 code = types.null ? '(': '(!' + data + ' || ';
67 code += 'typeof ' + data + ' !== "object")';
68 delete types.null;
69 delete types.array;
70 delete types.object;
71 }
72 if (types.number) delete types.integer;
73 for (var t in types)
74 code += (code ? ' && ' : '' ) + checkDataType(t, data, strictNumbers, true);
75
76 return code;
77 }
78}
79
80
81var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]);
82function coerceToTypes(optionCoerceTypes, dataTypes) {
83 if (Array.isArray(dataTypes)) {
84 var types = [];
85 for (var i=0; i<dataTypes.length; i++) {
86 var t = dataTypes[i];
87 if (COERCE_TO_TYPES[t]) types[types.length] = t;
88 else if (optionCoerceTypes === 'array' && t === 'array') types[types.length] = t;
89 }
90 if (types.length) return types;
91 } else if (COERCE_TO_TYPES[dataTypes]) {
92 return [dataTypes];
93 } else if (optionCoerceTypes === 'array' && dataTypes === 'array') {
94 return ['array'];
95 }
96}
97
98
99function toHash(arr) {
100 var hash = {};
101 for (var i=0; i<arr.length; i++) hash[arr[i]] = true;
102 return hash;
103}
104
105
106var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
107var SINGLE_QUOTE = /'|\\/g;
108function getProperty(key) {
109 return typeof key == 'number'
110 ? '[' + key + ']'
111 : IDENTIFIER.test(key)
112 ? '.' + key
113 : "['" + escapeQuotes(key) + "']";
114}
115
116
117function escapeQuotes(str) {
118 return str.replace(SINGLE_QUOTE, '\\$&')
119 .replace(/\n/g, '\\n')
120 .replace(/\r/g, '\\r')
121 .replace(/\f/g, '\\f')
122 .replace(/\t/g, '\\t');
123}
124
125
126function varOccurences(str, dataVar) {
127 dataVar += '[^0-9]';
128 var matches = str.match(new RegExp(dataVar, 'g'));
129 return matches ? matches.length : 0;
130}
131
132
133function varReplace(str, dataVar, expr) {
134 dataVar += '([^0-9])';
135 expr = expr.replace(/\$/g, '$$$$');
136 return str.replace(new RegExp(dataVar, 'g'), expr + '$1');
137}
138
139
140function schemaHasRules(schema, rules) {
141 if (typeof schema == 'boolean') return !schema;
142 for (var key in schema) if (rules[key]) return true;
143}
144
145
146function schemaHasRulesExcept(schema, rules, exceptKeyword) {
147 if (typeof schema == 'boolean') return !schema && exceptKeyword != 'not';
148 for (var key in schema) if (key != exceptKeyword && rules[key]) return true;
149}
150
151
152function schemaUnknownRules(schema, rules) {
153 if (typeof schema == 'boolean') return;
154 for (var key in schema) if (!rules[key]) return key;
155}
156
157
158function toQuotedString(str) {
159 return '\'' + escapeQuotes(str) + '\'';
160}
161
162
163function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
164 var path = jsonPointers // false by default
165 ? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
166 : (isNumber ? '\'[\' + ' + expr + ' + \']\'' : '\'[\\\'\' + ' + expr + ' + \'\\\']\'');
167 return joinPaths(currentPath, path);
168}
169
170
171function getPath(currentPath, prop, jsonPointers) {
172 var path = jsonPointers // false by default
173 ? toQuotedString('/' + escapeJsonPointer(prop))
174 : toQuotedString(getProperty(prop));
175 return joinPaths(currentPath, path);
176}
177
178
179var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
180var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
181function getData($data, lvl, paths) {
182 var up, jsonPointer, data, matches;
183 if ($data === '') return 'rootData';
184 if ($data[0] == '/') {
185 if (!JSON_POINTER.test($data)) throw new Error('Invalid JSON-pointer: ' + $data);
186 jsonPointer = $data;
187 data = 'rootData';
188 } else {
189 matches = $data.match(RELATIVE_JSON_POINTER);
190 if (!matches) throw new Error('Invalid JSON-pointer: ' + $data);
191 up = +matches[1];
192 jsonPointer = matches[2];
193 if (jsonPointer == '#') {
194 if (up >= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl);
195 return paths[lvl - up];
196 }
197
198 if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl);
199 data = 'data' + ((lvl - up) || '');
200 if (!jsonPointer) return data;
201 }
202
203 var expr = data;
204 var segments = jsonPointer.split('/');
205 for (var i=0; i<segments.length; i++) {
206 var segment = segments[i];
207 if (segment) {
208 data += getProperty(unescapeJsonPointer(segment));
209 expr += ' && ' + data;
210 }
211 }
212 return expr;
213}
214
215
216function joinPaths (a, b) {
217 if (a == '""') return b;
218 return (a + ' + ' + b).replace(/([^\\])' \+ '/g, '$1');
219}
220
221
222function unescapeFragment(str) {
223 return unescapeJsonPointer(decodeURIComponent(str));
224}
225
226
227function escapeFragment(str) {
228 return encodeURIComponent(escapeJsonPointer(str));
229}
230
231
232function escapeJsonPointer(str) {
233 return str.replace(/~/g, '~0').replace(/\//g, '~1');
234}
235
236
237function unescapeJsonPointer(str) {
238 return str.replace(/~1/g, '/').replace(/~0/g, '~');
239}
Note: See TracBrowser for help on using the repository browser.