UNPKG

15.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: !0
5});
6
7var acorn = require("acorn"), bson = require("bson");
8
9function _construct(Parent, args, Class) {
10 return (_construct = _isNativeReflectConstruct() ? Reflect.construct : function(Parent, args, Class) {
11 var a = [ null ];
12 a.push.apply(a, args);
13 var instance = new (Function.bind.apply(Parent, a));
14 return Class && _setPrototypeOf(instance, Class.prototype), instance;
15 }).apply(null, arguments);
16}
17
18function _isNativeReflectConstruct() {
19 if ("undefined" == typeof Reflect || !Reflect.construct) return !1;
20 if (Reflect.construct.sham) return !1;
21 if ("function" == typeof Proxy) return !0;
22 try {
23 return Date.prototype.toString.call(Reflect.construct(Date, [], (function() {}))),
24 !0;
25 } catch (e) {
26 return !1;
27 }
28}
29
30function _setPrototypeOf(o, p) {
31 return (_setPrototypeOf = Object.setPrototypeOf || function(o, p) {
32 return o.__proto__ = p, o;
33 })(o, p);
34}
35
36function _toConsumableArray(arr) {
37 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
38}
39
40function _nonIterableSpread() {
41 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
42}
43
44function _unsupportedIterableToArray(o, minLen) {
45 if (o) {
46 if ("string" == typeof o) return _arrayLikeToArray(o, minLen);
47 var n = Object.prototype.toString.call(o).slice(8, -1);
48 return "Object" === n && o.constructor && (n = o.constructor.name), "Map" === n || "Set" === n ? Array.from(o) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? _arrayLikeToArray(o, minLen) : void 0;
49 }
50}
51
52function _iterableToArray(iter) {
53 if ("undefined" != typeof Symbol && Symbol.iterator in Object(iter)) return Array.from(iter);
54}
55
56function _arrayWithoutHoles(arr) {
57 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
58}
59
60function _arrayLikeToArray(arr, len) {
61 (null == len || len > arr.length) && (len = arr.length);
62 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
63 return arr2;
64}
65
66function NumberLong(v) {
67 return "string" == typeof v ? bson.Long.fromString(v) : bson.Long.fromNumber(v);
68}
69
70var SCOPE = {
71 RegExp: RegExp,
72 Binary: function(buffer, subType) {
73 return new bson.Binary(buffer, subType);
74 },
75 BinData: function(t, d) {
76 return new bson.Binary(Buffer.from(d, "base64"), t);
77 },
78 UUID: function(u) {
79 return new bson.Binary(Buffer.from(u.replace(/-/g, ""), "hex"), 4);
80 },
81 Code: function(c, s) {
82 return new bson.Code(c, s);
83 },
84 DBRef: function(namespace, oid, db, fields) {
85 return new bson.DBRef(namespace, oid, db, fields);
86 },
87 Decimal128: function(s) {
88 return bson.Decimal128.fromString(s);
89 },
90 NumberDecimal: function(s) {
91 return bson.Decimal128.fromString(s);
92 },
93 Double: function(s) {
94 return new bson.Double(s);
95 },
96 Int32: function(i) {
97 return new bson.Int32(i);
98 },
99 NumberInt: function(s) {
100 return parseInt(s, 10);
101 },
102 Long: function(low, high) {
103 return new bson.Long(low, high);
104 },
105 NumberLong: NumberLong,
106 Int64: NumberLong,
107 Map: function(arr) {
108 return new bson.Map(arr);
109 },
110 MaxKey: function() {
111 return new bson.MaxKey;
112 },
113 MinKey: function() {
114 return new bson.MinKey;
115 },
116 ObjectID: function(i) {
117 return new bson.ObjectID(i);
118 },
119 ObjectId: function(i) {
120 return new bson.ObjectID(i);
121 },
122 Symbol: function(i) {
123 return new bson.BSONSymbol(i);
124 },
125 Timestamp: function(low, high) {
126 return new bson.Timestamp(low, high);
127 },
128 ISODate: function() {
129 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
130 return _construct(Date, _toConsumableArray(args));
131 },
132 Date: function(_Date) {
133 function Date() {
134 return _Date.apply(this, arguments);
135 }
136 return Date.toString = function() {
137 return _Date.toString();
138 }, Date;
139 }((function() {
140 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) args[_key2] = arguments[_key2];
141 return _construct(Date, _toConsumableArray(args));
142 }))
143}, GLOBALS = Object.freeze({
144 Infinity: 1 / 0,
145 NaN: NaN,
146 undefined: void 0
147}), ALLOWED_CLASS_EXPRESSIONS = {
148 Math: {
149 class: Math,
150 allowedMethods: {
151 abs: !0,
152 acos: !0,
153 acosh: !0,
154 asin: !0,
155 asinh: !0,
156 atan: !0,
157 atan2: !0,
158 atanh: !0,
159 cbrt: !0,
160 ceil: !0,
161 clz32: !0,
162 cos: !0,
163 cosh: !0,
164 exp: !0,
165 expm1: !0,
166 floor: !0,
167 fround: !0,
168 hypot: !0,
169 imul: !0,
170 log: !0,
171 log10: !0,
172 log1p: !0,
173 log2: !0,
174 max: !0,
175 min: !0,
176 pow: !0,
177 round: !0,
178 sign: !0,
179 sin: !0,
180 sinh: !0,
181 sqrt: !0,
182 tan: !0,
183 tanh: !0,
184 trunc: !0
185 }
186 },
187 Date: {
188 class: Date,
189 allowedMethods: {
190 getDate: !0,
191 getDay: !0,
192 getFullYear: !0,
193 getHours: !0,
194 getMilliseconds: !0,
195 getMinutes: !0,
196 getMonth: !0,
197 getSeconds: !0,
198 getTime: !0,
199 getTimezoneOffset: !0,
200 getUTCDate: !0,
201 getUTCDay: !0,
202 getUTCFullYear: !0,
203 getUTCHours: !0,
204 getUTCMilliseconds: !0,
205 getUTCMinutes: !0,
206 getUTCMonth: !0,
207 getUTCSeconds: !0,
208 getYear: !0,
209 now: !0,
210 setDate: !0,
211 setFullYear: !0,
212 setHours: !0,
213 setMilliseconds: !0,
214 setMinutes: !0,
215 setMonth: !0,
216 setSeconds: !0,
217 setTime: !0,
218 setUTCDate: !0,
219 setUTCFullYear: !0,
220 setUTCHours: !0,
221 setUTCMilliseconds: !0,
222 setUTCMinutes: !0,
223 setUTCMonth: !0,
224 setUTCSeconds: !0,
225 setYear: !0,
226 toISOString: !0
227 }
228 },
229 ISODate: {
230 class: Date,
231 allowedMethods: "Date"
232 }
233}, GLOBAL_FUNCTIONS = Object.freeze(Object.keys(SCOPE));
234
235function getScopeFunction(key) {
236 if (SCOPE[key]) return SCOPE[key];
237 throw new Error("Attempted to access scope property '".concat(key, "' that doesn't exist"));
238}
239
240function isMethodWhitelisted(member, property) {
241 if (ALLOWED_CLASS_EXPRESSIONS[member]) {
242 var allowedMethods = ALLOWED_CLASS_EXPRESSIONS[member].allowedMethods;
243 return "string" == typeof allowedMethods ? ALLOWED_CLASS_EXPRESSIONS[allowedMethods].allowedMethods[property] : allowedMethods[property];
244 }
245 return !1;
246}
247
248function getClass(member) {
249 if (ALLOWED_CLASS_EXPRESSIONS[member]) return ALLOWED_CLASS_EXPRESSIONS[member].class;
250 throw new Error("Attempted to access member '".concat(member, "' that doesn't exist"));
251}
252
253function _classCallCheck(instance, Constructor) {
254 if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
255}
256
257function _defineProperty(obj, key, value) {
258 return key in obj ? Object.defineProperty(obj, key, {
259 value: value,
260 enumerable: !0,
261 configurable: !0,
262 writable: !0
263 }) : obj[key] = value, obj;
264}
265
266var ParseMode, Checker = function Checker(options) {
267 var _this = this;
268 _classCallCheck(this, Checker), this.options = options, _defineProperty(this, "checkSafeCall", (function(node) {
269 var allowMethods = _this.options.allowMethods;
270 if ("Identifier" === node.callee.type) return GLOBAL_FUNCTIONS.indexOf(node.callee.name) >= 0 && node.arguments.every(_this.checkSafeExpression);
271 if (allowMethods && "MemberExpression" === node.callee.type) {
272 var object = node.callee.object, property = node.callee.property;
273 return "Identifier" === object.type && "Identifier" === property.type ? isMethodWhitelisted(object.name, property.name) && node.arguments.every(_this.checkSafeExpression) : "NewExpression" !== object.type && "CallExpression" !== object.type || "Identifier" !== object.callee.type ? _this.checkSafeExpression(object) && node.arguments.every(_this.checkSafeExpression) : isMethodWhitelisted(object.callee.name, property.name) && node.arguments.every(_this.checkSafeExpression);
274 }
275 return !1;
276 })), _defineProperty(this, "checkSafeExpression", (function(node) {
277 switch (node.type) {
278 case "Identifier":
279 return GLOBALS.hasOwnProperty(node.name);
280
281 case "Literal":
282 return !0;
283
284 case "ArrayExpression":
285 return node.elements.every(_this.checkSafeExpression);
286
287 case "UnaryExpression":
288 return _this.checkSafeExpression(node.argument);
289
290 case "BinaryExpression":
291 return _this.checkSafeExpression(node.left) && _this.checkSafeExpression(node.right);
292
293 case "CallExpression":
294 case "NewExpression":
295 return _this.checkSafeCall(node);
296
297 case "ObjectExpression":
298 return node.properties.every((function(property) {
299 return !property.computed && !property.method && (!![ "Literal", "Identifier" ].includes(property.key.type) && ([ "FunctionExpression", "ArrowFunctionExpression" ].includes(property.value.type) || _this.checkSafeExpression(property.value)));
300 }));
301
302 default:
303 return !1;
304 }
305 }));
306}, checkTree = function(node, options) {
307 if ("Program" === node.type && (1 === node.body.length && "ExpressionStatement" === node.body[0].type)) return new Checker(options).checkSafeExpression(node.body[0].expression);
308 return !1;
309}, unaryExpression = function(node) {
310 if (!node.prefix) throw new Error("Malformed UnaryExpression");
311 switch (node.operator) {
312 case "-":
313 return -walk(node.argument);
314
315 case "+":
316 return +walk(node.argument);
317
318 case "!":
319 return !walk(node.argument);
320
321 case "~":
322 return ~walk(node.argument);
323
324 default:
325 throw new Error("Invalid UnaryExpression Provided: '".concat(node.operator, "'"));
326 }
327}, binaryExpression = function(node) {
328 var left = node.left, right = node.right;
329 switch (node.operator) {
330 case "==":
331 return walk(left) == walk(right);
332
333 case "!=":
334 return walk(left) != walk(right);
335
336 case "===":
337 return walk(left) === walk(right);
338
339 case "!==":
340 return walk(left) !== walk(right);
341
342 case "<":
343 return walk(left) < walk(right);
344
345 case "<=":
346 return walk(left) <= walk(right);
347
348 case ">":
349 return walk(left) > walk(right);
350
351 case ">=":
352 return walk(left) >= walk(right);
353
354 case "<<":
355 return walk(left) << walk(right);
356
357 case ">>":
358 return walk(left) >> walk(right);
359
360 case ">>>":
361 return walk(left) >>> walk(right);
362
363 case "+":
364 return walk(left) + walk(right);
365
366 case "-":
367 return walk(left) - walk(right);
368
369 case "*":
370 return walk(left) * walk(right);
371
372 case "/":
373 return walk(left) / walk(right);
374
375 case "%":
376 return walk(left) % walk(right);
377
378 case "**":
379 return Math.pow(walk(left), walk(right));
380
381 case "|":
382 return walk(left) | walk(right);
383
384 case "^":
385 return walk(left) ^ walk(right);
386
387 case "&":
388 return walk(left) & walk(right);
389
390 case "in":
391 return walk(left) in walk(right);
392
393 case "instanceof":
394 return walk(left) instanceof walk(right);
395
396 default:
397 throw new Error("Invalid BinaryExpression Provided: '".concat(node.operator, "'"));
398 }
399}, memberExpression = function(node) {
400 switch (node.callee.type) {
401 case "Identifier":
402 var callee = getScopeFunction(node.callee.name), args = node.arguments.map((function(arg) {
403 return walk(arg);
404 }));
405 return callee.apply(callee, args);
406
407 case "MemberExpression":
408 var calleeThis = "Identifier" === node.callee.object.type ? getClass(node.callee.object.name) : walk(node.callee.object), calleeFn = "Identifier" === node.callee.property.type && node.callee.property.name;
409 if (!calleeFn) throw new Error("Expected CallExpression property to be an identifier");
410 var _args = node.arguments.map((function(arg) {
411 return walk(arg);
412 }));
413 return calleeThis[calleeFn].apply(calleeThis, _args);
414
415 default:
416 throw new Error("Should not evaluate invalid expressions");
417 }
418}, functionExpression = function(node) {
419 var _node$loc, source = (null === (_node$loc = node.loc) || void 0 === _node$loc ? void 0 : _node$loc.source) || "", range = node.range || [];
420 return source.slice(range[0], range[1]);
421}, walk = function walk(node) {
422 switch (node.type) {
423 case "Identifier":
424 if (GLOBALS.hasOwnProperty(node.name)) return GLOBALS[node.name];
425 throw new Error("".concat(node.name, " is not a valid Identifier"));
426
427 case "Literal":
428 return node.value;
429
430 case "UnaryExpression":
431 return unaryExpression(node);
432
433 case "BinaryExpression":
434 return binaryExpression(node);
435
436 case "ArrayExpression":
437 return node.elements.map((function(node) {
438 return walk(node);
439 }));
440
441 case "CallExpression":
442 case "NewExpression":
443 return memberExpression(node);
444
445 case "ObjectExpression":
446 var obj = {};
447 return node.properties.forEach((function(property) {
448 var key = "Identifier" === property.key.type ? property.key.name : walk(property.key);
449 obj[key] = walk(property.value);
450 })), obj;
451
452 case "FunctionExpression":
453 case "ArrowFunctionExpression":
454 return functionExpression(node);
455
456 default:
457 throw new Error;
458 }
459}, executeAST = function(node) {
460 if ("Program" === node.type && 1 === node.body.length && "ExpressionStatement" === node.body[0].type) return walk(node.body[0].expression);
461 throw new Error("Invalid AST Found");
462};
463
464function ownKeys(object, enumerableOnly) {
465 var keys = Object.keys(object);
466 if (Object.getOwnPropertySymbols) {
467 var symbols = Object.getOwnPropertySymbols(object);
468 enumerableOnly && (symbols = symbols.filter((function(sym) {
469 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
470 }))), keys.push.apply(keys, symbols);
471 }
472 return keys;
473}
474
475function _objectSpread(target) {
476 for (var i = 1; i < arguments.length; i++) {
477 var source = null != arguments[i] ? arguments[i] : {};
478 i % 2 ? ownKeys(Object(source), !0).forEach((function(key) {
479 _defineProperty$1(target, key, source[key]);
480 })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach((function(key) {
481 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
482 }));
483 }
484 return target;
485}
486
487function _defineProperty$1(obj, key, value) {
488 return key in obj ? Object.defineProperty(obj, key, {
489 value: value,
490 enumerable: !0,
491 configurable: !0,
492 writable: !0
493 }) : obj[key] = value, obj;
494}
495
496!function(ParseMode) {
497 ParseMode.Strict = "strict", ParseMode.Extended = "extended", ParseMode.Loose = "loose";
498}(ParseMode || (ParseMode = {}));
499
500var StrictOptions = {
501 allowMethods: !1,
502 allowComments: !1
503}, ExtendedOptions = {
504 allowMethods: !0
505}, LooseOptions = {
506 allowMethods: !0,
507 allowComments: !0
508};
509
510function getModeOptions(mode) {
511 switch (mode) {
512 case ParseMode.Strict:
513 return StrictOptions;
514
515 case ParseMode.Extended:
516 return ExtendedOptions;
517
518 case ParseMode.Loose:
519 return LooseOptions;
520 }
521}
522
523var DefaultOptions = _objectSpread({
524 mode: ParseMode.Strict
525}, StrictOptions);
526
527function buildOptions(options) {
528 return _objectSpread(_objectSpread(_objectSpread({}, DefaultOptions), getModeOptions(options && options.mode || ParseMode.Strict)), options);
529}
530
531function buildAST(input) {
532 var hasComments = !1;
533 return {
534 ast: acorn.parse(input, {
535 ecmaVersion: 6,
536 onComment: function() {
537 return hasComments = !0;
538 },
539 locations: !0,
540 ranges: !0,
541 sourceFile: input
542 }),
543 hasComments: hasComments
544 };
545}
546
547function parse(input, options) {
548 var parsedOptions = buildOptions(options), _buildAST = buildAST("(".concat(input, ")")), hasComments = _buildAST.hasComments, ast = _buildAST.ast;
549 return (!hasComments || parsedOptions.allowComments) && checkTree(ast, parsedOptions) ? executeAST(ast) : "";
550}
551
552exports.default = parse;