operations.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.$where = exports.$options = exports.$size = exports.$all = exports.$and = exports.$type = exports.$not = exports.$regex = exports.$exists = exports.$mod = exports.$gte = exports.$gt = exports.$lte = exports.$lt = exports.$in = exports.$nin = exports.$elemMatch = exports.$nor = exports.$or = exports.$ne = exports.$eq = exports.$Size = void 0;
  4. const core_1 = require("./core");
  5. const utils_1 = require("./utils");
  6. class $Ne extends core_1.NamedBaseOperation {
  7. constructor() {
  8. super(...arguments);
  9. this.propop = true;
  10. }
  11. init() {
  12. this._test = core_1.createTester(this.params, this.options.compare);
  13. }
  14. reset() {
  15. super.reset();
  16. this.keep = true;
  17. }
  18. next(item) {
  19. if (this._test(item)) {
  20. this.done = true;
  21. this.keep = false;
  22. }
  23. }
  24. }
  25. // https://docs.mongodb.com/manual/reference/operator/query/elemMatch/
  26. class $ElemMatch extends core_1.NamedBaseOperation {
  27. constructor() {
  28. super(...arguments);
  29. this.propop = true;
  30. }
  31. init() {
  32. if (!this.params || typeof this.params !== "object") {
  33. throw new Error(`Malformed query. $elemMatch must by an object.`);
  34. }
  35. this._queryOperation = core_1.createQueryOperation(this.params, this.owneryQuery, this.options);
  36. }
  37. reset() {
  38. super.reset();
  39. this._queryOperation.reset();
  40. }
  41. next(item) {
  42. if (utils_1.isArray(item)) {
  43. for (let i = 0, { length } = item; i < length; i++) {
  44. // reset query operation since item being tested needs to pass _all_ query
  45. // operations for it to be a success
  46. this._queryOperation.reset();
  47. const child = item[i];
  48. this._queryOperation.next(child, i, item);
  49. this.keep = this.keep || this._queryOperation.keep;
  50. }
  51. this.done = true;
  52. }
  53. else {
  54. this.done = false;
  55. this.keep = false;
  56. }
  57. }
  58. }
  59. class $Not extends core_1.NamedBaseOperation {
  60. constructor() {
  61. super(...arguments);
  62. this.propop = true;
  63. }
  64. init() {
  65. this._queryOperation = core_1.createQueryOperation(this.params, this.owneryQuery, this.options);
  66. }
  67. reset() {
  68. this._queryOperation.reset();
  69. }
  70. next(item, key, owner) {
  71. this._queryOperation.next(item, key, owner);
  72. this.done = this._queryOperation.done;
  73. this.keep = !this._queryOperation.keep;
  74. }
  75. }
  76. class $Size extends core_1.NamedBaseOperation {
  77. constructor() {
  78. super(...arguments);
  79. this.propop = true;
  80. }
  81. init() { }
  82. next(item) {
  83. if (utils_1.isArray(item) && item.length === this.params) {
  84. this.done = true;
  85. this.keep = true;
  86. }
  87. // if (parent && parent.length === this.params) {
  88. // this.done = true;
  89. // this.keep = true;
  90. // }
  91. }
  92. }
  93. exports.$Size = $Size;
  94. const assertGroupNotEmpty = (values) => {
  95. if (values.length === 0) {
  96. throw new Error(`$and/$or/$nor must be a nonempty array`);
  97. }
  98. };
  99. class $Or extends core_1.NamedBaseOperation {
  100. constructor() {
  101. super(...arguments);
  102. this.propop = false;
  103. }
  104. init() {
  105. assertGroupNotEmpty(this.params);
  106. this._ops = this.params.map(op => core_1.createQueryOperation(op, null, this.options));
  107. }
  108. reset() {
  109. this.done = false;
  110. this.keep = false;
  111. for (let i = 0, { length } = this._ops; i < length; i++) {
  112. this._ops[i].reset();
  113. }
  114. }
  115. next(item, key, owner) {
  116. let done = false;
  117. let success = false;
  118. for (let i = 0, { length } = this._ops; i < length; i++) {
  119. const op = this._ops[i];
  120. op.next(item, key, owner);
  121. if (op.keep) {
  122. done = true;
  123. success = op.keep;
  124. break;
  125. }
  126. }
  127. this.keep = success;
  128. this.done = done;
  129. }
  130. }
  131. class $Nor extends $Or {
  132. constructor() {
  133. super(...arguments);
  134. this.propop = false;
  135. }
  136. next(item, key, owner) {
  137. super.next(item, key, owner);
  138. this.keep = !this.keep;
  139. }
  140. }
  141. class $In extends core_1.NamedBaseOperation {
  142. constructor() {
  143. super(...arguments);
  144. this.propop = true;
  145. }
  146. init() {
  147. this._testers = this.params.map(value => {
  148. if (core_1.containsOperation(value, this.options)) {
  149. throw new Error(`cannot nest $ under ${this.constructor.name.toLowerCase()}`);
  150. }
  151. return core_1.createTester(value, this.options.compare);
  152. });
  153. }
  154. next(item, key, owner) {
  155. let done = false;
  156. let success = false;
  157. for (let i = 0, { length } = this._testers; i < length; i++) {
  158. const test = this._testers[i];
  159. if (test(item)) {
  160. done = true;
  161. success = true;
  162. break;
  163. }
  164. }
  165. this.keep = success;
  166. this.done = done;
  167. }
  168. }
  169. class $Nin extends $In {
  170. constructor() {
  171. super(...arguments);
  172. this.propop = true;
  173. }
  174. next(item, key, owner) {
  175. super.next(item, key, owner);
  176. this.keep = !this.keep;
  177. }
  178. }
  179. class $Exists extends core_1.NamedBaseOperation {
  180. constructor() {
  181. super(...arguments);
  182. this.propop = true;
  183. }
  184. next(item, key, owner) {
  185. if (owner.hasOwnProperty(key) === this.params) {
  186. this.done = true;
  187. this.keep = true;
  188. }
  189. }
  190. }
  191. class $And extends core_1.NamedGroupOperation {
  192. constructor(params, owneryQuery, options, name) {
  193. super(params, owneryQuery, options, params.map(query => core_1.createQueryOperation(query, owneryQuery, options)), name);
  194. this.propop = false;
  195. assertGroupNotEmpty(params);
  196. }
  197. next(item, key, owner) {
  198. this.childrenNext(item, key, owner);
  199. }
  200. }
  201. class $All extends core_1.NamedGroupOperation {
  202. constructor(params, owneryQuery, options, name) {
  203. super(params, owneryQuery, options, params.map(query => core_1.createQueryOperation(query, owneryQuery, options)), name);
  204. this.propop = true;
  205. }
  206. next(item, key, owner) {
  207. this.childrenNext(item, key, owner);
  208. }
  209. }
  210. const $eq = (params, owneryQuery, options) => new core_1.EqualsOperation(params, owneryQuery, options);
  211. exports.$eq = $eq;
  212. const $ne = (params, owneryQuery, options, name) => new $Ne(params, owneryQuery, options, name);
  213. exports.$ne = $ne;
  214. const $or = (params, owneryQuery, options, name) => new $Or(params, owneryQuery, options, name);
  215. exports.$or = $or;
  216. const $nor = (params, owneryQuery, options, name) => new $Nor(params, owneryQuery, options, name);
  217. exports.$nor = $nor;
  218. const $elemMatch = (params, owneryQuery, options, name) => new $ElemMatch(params, owneryQuery, options, name);
  219. exports.$elemMatch = $elemMatch;
  220. const $nin = (params, owneryQuery, options, name) => new $Nin(params, owneryQuery, options, name);
  221. exports.$nin = $nin;
  222. const $in = (params, owneryQuery, options, name) => new $In(params, owneryQuery, options, name);
  223. exports.$in = $in;
  224. exports.$lt = core_1.numericalOperation(params => b => b < params);
  225. exports.$lte = core_1.numericalOperation(params => b => b <= params);
  226. exports.$gt = core_1.numericalOperation(params => b => b > params);
  227. exports.$gte = core_1.numericalOperation(params => b => b >= params);
  228. const $mod = ([mod, equalsValue], owneryQuery, options) => new core_1.EqualsOperation(b => utils_1.comparable(b) % mod === equalsValue, owneryQuery, options);
  229. exports.$mod = $mod;
  230. const $exists = (params, owneryQuery, options, name) => new $Exists(params, owneryQuery, options, name);
  231. exports.$exists = $exists;
  232. const $regex = (pattern, owneryQuery, options) => new core_1.EqualsOperation(new RegExp(pattern, owneryQuery.$options), owneryQuery, options);
  233. exports.$regex = $regex;
  234. const $not = (params, owneryQuery, options, name) => new $Not(params, owneryQuery, options, name);
  235. exports.$not = $not;
  236. const typeAliases = {
  237. number: v => typeof v === "number",
  238. string: v => typeof v === "string",
  239. bool: v => typeof v === "boolean",
  240. array: v => Array.isArray(v),
  241. null: v => v === null,
  242. timestamp: v => v instanceof Date
  243. };
  244. const $type = (clazz, owneryQuery, options) => new core_1.EqualsOperation(b => {
  245. if (typeof clazz === "string") {
  246. if (!typeAliases[clazz]) {
  247. throw new Error(`Type alias does not exist`);
  248. }
  249. return typeAliases[clazz](b);
  250. }
  251. return b != null ? b instanceof clazz || b.constructor === clazz : false;
  252. }, owneryQuery, options);
  253. exports.$type = $type;
  254. const $and = (params, ownerQuery, options, name) => new $And(params, ownerQuery, options, name);
  255. exports.$and = $and;
  256. const $all = (params, ownerQuery, options, name) => new $All(params, ownerQuery, options, name);
  257. exports.$all = $all;
  258. const $size = (params, ownerQuery, options) => new $Size(params, ownerQuery, options, "$size");
  259. exports.$size = $size;
  260. const $options = () => null;
  261. exports.$options = $options;
  262. const $where = (params, ownerQuery, options) => {
  263. let test;
  264. if (utils_1.isFunction(params)) {
  265. test = params;
  266. }
  267. else if (!process.env.CSP_ENABLED) {
  268. test = new Function("obj", "return " + params);
  269. }
  270. else {
  271. throw new Error(`In CSP mode, sift does not support strings in "$where" condition`);
  272. }
  273. return new core_1.EqualsOperation(b => test.bind(b)(b), ownerQuery, options);
  274. };
  275. exports.$where = $where;
  276. //# sourceMappingURL=operations.js.map