json-fs-query 2.3.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +79 -7
  2. package/browser/jsonFsQuery.js +12650 -13107
  3. package/browser/jsonFsQuery.min.js +1 -1
  4. package/dist/data/introspect/create.js +30 -1
  5. package/dist/data/introspect/create.min.js +1 -1
  6. package/dist/data/queries/groupBy.d.ts +20 -1
  7. package/dist/data/queries/groupBy.js +71 -9
  8. package/dist/data/queries/groupBy.min.js +1 -1
  9. package/dist/data/queries/limitOffset.d.ts +1 -1
  10. package/dist/data/queries/limitOffset.js +1 -1
  11. package/dist/data/queries/selectFields.d.ts +6 -4
  12. package/dist/data/queries/selectFields.js +15 -10
  13. package/dist/data/queries/selectFields.min.js +1 -1
  14. package/dist/data/utilities/databaseLock.js +2 -1
  15. package/dist/data/utilities/databaseLock.min.js +1 -1
  16. package/dist/data/utilities/parsers/findCommand.d.ts +2 -1
  17. package/dist/data/utilities/parsers/findCommand.js +4 -4
  18. package/dist/data/utilities/parsers/findCommand.min.js +1 -1
  19. package/dist/data/utilities/parsers/findConditions.d.ts +8 -9
  20. package/dist/data/utilities/parsers/findConditions.js +29 -41
  21. package/dist/data/utilities/parsers/findConditions.min.js +1 -1
  22. package/dist/data/utilities/parsers/findGroupBy.d.ts +6 -4
  23. package/dist/data/utilities/parsers/findGroupBy.js +17 -9
  24. package/dist/data/utilities/parsers/findGroupBy.min.js +1 -1
  25. package/dist/data/utilities/parsers/findInsertValues.d.ts +4 -3
  26. package/dist/data/utilities/parsers/findInsertValues.js +9 -9
  27. package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
  28. package/dist/data/utilities/parsers/findJoinClauses.d.ts +4 -3
  29. package/dist/data/utilities/parsers/findJoinClauses.js +20 -13
  30. package/dist/data/utilities/parsers/findJoinClauses.min.js +1 -1
  31. package/dist/data/utilities/parsers/findJoinEntity.d.ts +1 -1
  32. package/dist/data/utilities/parsers/findJoinEntity.js +3 -5
  33. package/dist/data/utilities/parsers/findJoinEntity.min.js +1 -1
  34. package/dist/data/utilities/parsers/findLimit.d.ts +4 -3
  35. package/dist/data/utilities/parsers/findLimit.js +8 -8
  36. package/dist/data/utilities/parsers/findLimit.min.js +1 -1
  37. package/dist/data/utilities/parsers/findMergeJoins.d.ts +4 -3
  38. package/dist/data/utilities/parsers/findMergeJoins.js +19 -12
  39. package/dist/data/utilities/parsers/findMergeJoins.min.js +1 -1
  40. package/dist/data/utilities/parsers/findOffset.d.ts +4 -3
  41. package/dist/data/utilities/parsers/findOffset.js +8 -8
  42. package/dist/data/utilities/parsers/findOffset.min.js +1 -1
  43. package/dist/data/utilities/parsers/findSelects.d.ts +4 -3
  44. package/dist/data/utilities/parsers/findSelects.js +13 -14
  45. package/dist/data/utilities/parsers/findSelects.min.js +1 -1
  46. package/dist/data/utilities/parsers/findSortClauses.d.ts +4 -3
  47. package/dist/data/utilities/parsers/findSortClauses.js +12 -12
  48. package/dist/data/utilities/parsers/findSortClauses.min.js +1 -1
  49. package/dist/data/utilities/parsers/findUpdateValues.d.ts +5 -7
  50. package/dist/data/utilities/parsers/findUpdateValues.js +10 -13
  51. package/dist/data/utilities/parsers/findUpdateValues.min.js +1 -1
  52. package/dist/data/utilities/parsers/parseQuery.js +83 -9
  53. package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
  54. package/dist/data/utilities/parsers/splitClauses.d.ts +29 -0
  55. package/dist/data/utilities/parsers/splitClauses.js +139 -0
  56. package/dist/data/utilities/parsers/splitClauses.min.js +1 -0
  57. package/dist/data/utilities/retrieveFile.js +2 -1
  58. package/dist/data/utilities/retrieveFile.min.js +1 -1
  59. package/dist/data/utilities/runQuery.js +5 -4
  60. package/dist/data/utilities/runQuery.min.js +1 -1
  61. package/package.json +5 -3
  62. package/dist/data/utilities/parsers/removeFromQuery.d.ts +0 -2
  63. package/dist/data/utilities/parsers/removeFromQuery.js +0 -8
  64. package/dist/data/utilities/parsers/removeFromQuery.min.js +0 -1
@@ -4,13 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.parseQuery = void 0;
7
- var _siFunciona = _interopRequireDefault(require("si-funciona"));
8
7
  var _findCommand = require("./findCommand");
9
8
  var _findInsertValues = require("./findInsertValues");
10
9
  var _findUpdateValues = require("./findUpdateValues");
11
10
  var _findJoinEntity = require("./findJoinEntity");
12
11
  var _findSelects = require("./findSelects");
13
12
  var _findConditions = require("./findConditions");
13
+ var _conditionTree = require("../conditionTree");
14
14
  var _findJoinClauses = require("./findJoinClauses");
15
15
  var _findMergeJoins = require("./findMergeJoins");
16
16
  var _findSortClauses = require("./findSortClauses");
@@ -20,8 +20,63 @@ var _findOffset = require("./findOffset");
20
20
  var _maskStrings = require("./maskStrings");
21
21
  var _parseCreate = require("./parseCreate");
22
22
  var _parseSchemaStatement = require("./parseSchemaStatement");
23
+ var _splitClauses = require("./splitClauses");
23
24
  var _startsQuery = require("./startsQuery");
24
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
25
+ // Each clause's own step, and what its body must start with (for the error when it doesn't)
26
+ const clauseSteps = {
27
+ values: {
28
+ step: _findInsertValues.findInsertValues,
29
+ expected: 'an assignment (field = value)'
30
+ },
31
+ set: {
32
+ step: _findUpdateValues.findUpdateValues,
33
+ expected: 'an assignment (field = value)'
34
+ },
35
+ select: {
36
+ step: _findSelects.findSelects,
37
+ expected: 'a field'
38
+ },
39
+ on: {
40
+ step: _findJoinClauses.findJoinClauses,
41
+ expected: 'a join condition (a.x = b.y)'
42
+ },
43
+ merge: {
44
+ step: _findMergeJoins.findMergeJoins,
45
+ expected: 'a merge (a.x with b.y)'
46
+ },
47
+ where: {
48
+ step: _findConditions.findConditions,
49
+ expected: 'a condition'
50
+ },
51
+ 'group by': {
52
+ step: _findGroupBy.findGroupBy,
53
+ expected: 'a field'
54
+ },
55
+ sort: {
56
+ step: _findSortClauses.findSortClauses,
57
+ expected: 'a field'
58
+ },
59
+ limit: {
60
+ step: _findLimit.findLimit,
61
+ expected: 'a whole number'
62
+ },
63
+ offset: {
64
+ step: _findOffset.findOffset,
65
+ expected: 'a whole number'
66
+ }
67
+ };
68
+ /**
69
+ * The error for text a step couldn't read: another query run on without a `;`, or text that doesn't belong.
70
+ * @param rest The text left over, masked
71
+ * @param after What was read before it, masked
72
+ */
73
+ const leftoverError = (rest, after) => {
74
+ const shown = text => (0, _maskStrings.unmaskStrings)(text, '\'');
75
+ if (_startsQuery.startsQueryMatch.test(rest)) {
76
+ return new Error(`Missing ; before: ${shown(rest)}`);
77
+ }
78
+ return new Error(`Unexpected "${shown(rest)}" after "${shown(after)}"`);
79
+ };
25
80
  /**
26
81
  * Break a query down into its components.
27
82
  * @param query
@@ -44,10 +99,6 @@ const parseQuery = query => {
44
99
  create: undefined,
45
100
  ifExists: undefined
46
101
  };
47
- const {
48
- curry,
49
- pipe
50
- } = _siFunciona.default;
51
102
  // No find* step may see inside a string or an array: each one becomes a placeholder holding its value
52
103
  query = (0, _maskStrings.maskArrays)((0, _maskStrings.maskStrings)(query));
53
104
  // A create statement has its own shape (a bracketed list of fields and keys), so it gets its own parser
@@ -65,13 +116,36 @@ const parseQuery = query => {
65
116
  if (_parseSchemaStatement.schemaStatementMatch.test(query)) {
66
117
  return Object.assign(parsedQuery, (0, _parseSchemaStatement.parseSchemaStatement)(query));
67
118
  }
68
- query = pipe(curry(_findCommand.findCommand)(parsedQuery), curry(_findInsertValues.findInsertValues)(parsedQuery), curry(_findUpdateValues.findUpdateValues)(parsedQuery), curry(_findJoinEntity.findJoinEntity)(parsedQuery), curry(_findSelects.findSelects)(parsedQuery), curry(_findConditions.findConditions)(parsedQuery), curry(_findJoinClauses.findJoinClauses)(parsedQuery), curry(_findMergeJoins.findMergeJoins)(parsedQuery), curry(_findSortClauses.findSortClauses)(parsedQuery), curry(_findGroupBy.findGroupBy)(parsedQuery), curry(_findLimit.findLimit)(parsedQuery), curry(_findOffset.findOffset)(parsedQuery))(query);
69
- if (query) {
119
+ // Clauses come at most once each, in a fixed order (see clauseOrder); each step reads only its own clause's body
120
+ const split = (0, _splitClauses.splitClauses)(query);
121
+ if (!split) {
122
+ query = query.trim();
70
123
  if (_startsQuery.startsQueryMatch.test(query)) {
71
- throw new Error(`Missing ; before: ${(0, _maskStrings.unmaskStrings)(query.trim(), '\'')}`);
124
+ throw new Error(`Missing ; before: ${(0, _maskStrings.unmaskStrings)(query, '\'')}`);
72
125
  }
73
126
  throw new Error(`Unrecognized query value: ${(0, _maskStrings.unmaskStrings)(query, '\'')}`);
74
127
  }
128
+ (0, _findJoinEntity.findJoinEntity)(parsedQuery, (0, _findCommand.findCommand)(parsedQuery, split.head));
129
+ parsedQuery.where = (0, _conditionTree.allOf)([]);
130
+ if (split.leading) {
131
+ throw leftoverError(split.leading, split.head);
132
+ }
133
+ for (const {
134
+ keyword,
135
+ body
136
+ } of split.clauses) {
137
+ const {
138
+ step,
139
+ expected
140
+ } = clauseSteps[keyword];
141
+ const rest = step(parsedQuery, body);
142
+ if (rest === body) {
143
+ throw new Error(`Missing ${expected} after ${keyword}${body ? `: ${(0, _maskStrings.unmaskStrings)(body, '\'')}` : ''}`);
144
+ }
145
+ if (rest) {
146
+ throw leftoverError(rest, `${keyword} ${body.slice(0, body.length - rest.length).trim()}`);
147
+ }
148
+ }
75
149
  return parsedQuery;
76
150
  };
77
151
  exports.parseQuery = parseQuery;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseQuery=void 0;var _siFunciona=_interopRequireDefault(require("si-funciona")),_findCommand=require("./findCommand"),_findInsertValues=require("./findInsertValues"),_findUpdateValues=require("./findUpdateValues"),_findJoinEntity=require("./findJoinEntity"),_findSelects=require("./findSelects"),_findConditions=require("./findConditions"),_findJoinClauses=require("./findJoinClauses"),_findMergeJoins=require("./findMergeJoins"),_findSortClauses=require("./findSortClauses"),_findGroupBy=require("./findGroupBy"),_findLimit=require("./findLimit"),_findOffset=require("./findOffset"),_maskStrings=require("./maskStrings"),_parseCreate=require("./parseCreate"),_parseSchemaStatement=require("./parseSchemaStatement"),_startsQuery=require("./startsQuery");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const parseQuery=e=>{const i={command:void 0,entity:void 0,joinEntity:void 0,selectClauses:[],insertValues:[],updateValues:{},where:void 0,joinClauses:[],mergeJoins:[],sortClauses:[],groupBy:void 0,limit:void 0,offset:void 0,create:void 0,ifExists:void 0},{curry:r,pipe:n}=_siFunciona.default;if(e=(0,_maskStrings.maskArrays)((0,_maskStrings.maskStrings)(e)),_parseCreate.createMatch.test(e)){const{entity:r,create:n}=(0,_parseCreate.parseCreate)(e);return Object.assign(i,{command:"create",entity:r,create:n})}if(_parseSchemaStatement.schemaStatementMatch.test(e))return Object.assign(i,(0,_parseSchemaStatement.parseSchemaStatement)(e));if(e=n(r(_findCommand.findCommand)(i),r(_findInsertValues.findInsertValues)(i),r(_findUpdateValues.findUpdateValues)(i),r(_findJoinEntity.findJoinEntity)(i),r(_findSelects.findSelects)(i),r(_findConditions.findConditions)(i),r(_findJoinClauses.findJoinClauses)(i),r(_findMergeJoins.findMergeJoins)(i),r(_findSortClauses.findSortClauses)(i),r(_findGroupBy.findGroupBy)(i),r(_findLimit.findLimit)(i),r(_findOffset.findOffset)(i))(e)){if(_startsQuery.startsQueryMatch.test(e))throw new Error(`Missing ; before: ${(0,_maskStrings.unmaskStrings)(e.trim(),"'")}`);throw new Error(`Unrecognized query value: ${(0,_maskStrings.unmaskStrings)(e,"'")}`)}return i};exports.parseQuery=parseQuery;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseQuery=void 0;var _findCommand=require("./findCommand"),_findInsertValues=require("./findInsertValues"),_findUpdateValues=require("./findUpdateValues"),_findJoinEntity=require("./findJoinEntity"),_findSelects=require("./findSelects"),_findConditions=require("./findConditions"),_conditionTree=require("../conditionTree"),_findJoinClauses=require("./findJoinClauses"),_findMergeJoins=require("./findMergeJoins"),_findSortClauses=require("./findSortClauses"),_findGroupBy=require("./findGroupBy"),_findLimit=require("./findLimit"),_findOffset=require("./findOffset"),_maskStrings=require("./maskStrings"),_parseCreate=require("./parseCreate"),_parseSchemaStatement=require("./parseSchemaStatement"),_splitClauses=require("./splitClauses"),_startsQuery=require("./startsQuery");const clauseSteps={values:{step:_findInsertValues.findInsertValues,expected:"an assignment (field = value)"},set:{step:_findUpdateValues.findUpdateValues,expected:"an assignment (field = value)"},select:{step:_findSelects.findSelects,expected:"a field"},on:{step:_findJoinClauses.findJoinClauses,expected:"a join condition (a.x = b.y)"},merge:{step:_findMergeJoins.findMergeJoins,expected:"a merge (a.x with b.y)"},where:{step:_findConditions.findConditions,expected:"a condition"},"group by":{step:_findGroupBy.findGroupBy,expected:"a field"},sort:{step:_findSortClauses.findSortClauses,expected:"a field"},limit:{step:_findLimit.findLimit,expected:"a whole number"},offset:{step:_findOffset.findOffset,expected:"a whole number"}},leftoverError=(e,t)=>{const i=e=>(0,_maskStrings.unmaskStrings)(e,"'");return _startsQuery.startsQueryMatch.test(e)?new Error(`Missing ; before: ${i(e)}`):new Error(`Unexpected "${i(e)}" after "${i(t)}"`)},parseQuery=e=>{const t={command:void 0,entity:void 0,joinEntity:void 0,selectClauses:[],insertValues:[],updateValues:{},where:void 0,joinClauses:[],mergeJoins:[],sortClauses:[],groupBy:void 0,limit:void 0,offset:void 0,create:void 0,ifExists:void 0};if(e=(0,_maskStrings.maskArrays)((0,_maskStrings.maskStrings)(e)),_parseCreate.createMatch.test(e)){const{entity:i,create:r}=(0,_parseCreate.parseCreate)(e);return Object.assign(t,{command:"create",entity:i,create:r})}if(_parseSchemaStatement.schemaStatementMatch.test(e))return Object.assign(t,(0,_parseSchemaStatement.parseSchemaStatement)(e));const i=(0,_splitClauses.splitClauses)(e);if(!i){if(e=e.trim(),_startsQuery.startsQueryMatch.test(e))throw new Error(`Missing ; before: ${(0,_maskStrings.unmaskStrings)(e,"'")}`);throw new Error(`Unrecognized query value: ${(0,_maskStrings.unmaskStrings)(e,"'")}`)}if((0,_findJoinEntity.findJoinEntity)(t,(0,_findCommand.findCommand)(t,i.head)),t.where=(0,_conditionTree.allOf)([]),i.leading)throw leftoverError(i.leading,i.head);for(const{keyword:e,body:r}of i.clauses){const{step:i,expected:s}=clauseSteps[e],n=i(t,r);if(n===r)throw new Error(`Missing ${s} after ${e}${r?`: ${(0,_maskStrings.unmaskStrings)(r,"'")}`:""}`);if(n)throw leftoverError(n,`${e} ${r.slice(0,r.length-n.length).trim()}`)}return t};exports.parseQuery=parseQuery;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The clauses each command allows, in the order they must come. create, drop, describe and show have their own
3
+ * parsers and never get here.
4
+ */
5
+ export declare const clauseOrder: {
6
+ [command: string]: string[];
7
+ };
8
+ export declare const whereHint = "use and / or inside one where clause (where a = 1 and b = 2)";
9
+ export type SplitClause = {
10
+ keyword: string;
11
+ body: string;
12
+ };
13
+ export type SplitQuery = {
14
+ command: string;
15
+ head: string;
16
+ leading: string;
17
+ clauses: SplitClause[];
18
+ };
19
+ /**
20
+ * Split a masked query (see maskStrings) into its clauses, reading its top-level words once, left to right. A clause
21
+ * word counts only as a whole word outside brackets, and not where it must be a name: as a clause's first word
22
+ * (`sort limit`), after a comma or `as`, or before a comparator (`where limit = 1`).
23
+ * @param query
24
+ * @returns undefined when the query doesn't start with read, insert, update or delete (left to the find* steps).
25
+ * @throws {Error} For a joined record outside read, a clause the command doesn't allow, a repeated clause, a clause out
26
+ * of order, or the 2.x forms of a second where (`and where`, `or where`, or a plain repeat).
27
+ */
28
+ export declare const splitClauses: (query: string) => SplitQuery | undefined;
29
+ //# sourceMappingURL=splitClauses.d.ts.map
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.whereHint = exports.splitClauses = exports.clauseOrder = void 0;
7
+ require("core-js/modules/es.array.includes.js");
8
+ require("core-js/modules/esnext.set.add-all.js");
9
+ require("core-js/modules/esnext.set.delete-all.js");
10
+ require("core-js/modules/esnext.set.difference.js");
11
+ require("core-js/modules/esnext.set.every.js");
12
+ require("core-js/modules/esnext.set.filter.js");
13
+ require("core-js/modules/esnext.set.find.js");
14
+ require("core-js/modules/esnext.set.intersection.js");
15
+ require("core-js/modules/esnext.set.is-disjoint-from.js");
16
+ require("core-js/modules/esnext.set.is-subset-of.js");
17
+ require("core-js/modules/esnext.set.is-superset-of.js");
18
+ require("core-js/modules/esnext.set.join.js");
19
+ require("core-js/modules/esnext.set.map.js");
20
+ require("core-js/modules/esnext.set.reduce.js");
21
+ require("core-js/modules/esnext.set.some.js");
22
+ require("core-js/modules/esnext.set.symmetric-difference.js");
23
+ require("core-js/modules/esnext.set.union.js");
24
+ var _maskStrings = require("./maskStrings");
25
+ /**
26
+ * The clauses each command allows, in the order they must come. create, drop, describe and show have their own
27
+ * parsers and never get here.
28
+ */
29
+ const clauseOrder = exports.clauseOrder = {
30
+ read: ['select', 'on', 'merge', 'where', 'group by', 'sort', 'limit', 'offset'],
31
+ insert: ['values'],
32
+ update: ['set', 'where'],
33
+ delete: ['where']
34
+ };
35
+ const clauseWords = [...new Set(Object.values(clauseOrder).flat())];
36
+ // The command, the record name and an optional joined record (`read workouts.exercises`, or `read workouts .exercises`)
37
+ const headMatch = /^\s*(delete|insert|read|update)\s+([a-z0-9_-]+(\s*\.[a-z0-9_-]+)?)/i;
38
+ // Placeholders (see maskStrings) as one token each, so their hex can't read as a word; words; then the two-character
39
+ // comparators before any other single character
40
+ const tokenMatch = new RegExp(`${_maskStrings.placeholderSource}|${_maskStrings.arraySource}|[a-z0-9_.-]+|<>|!=|>=|<=|\\S`, 'gi');
41
+ // What can follow a field in a condition: a clause word followed by one of these is a field (`where limit = 1`)
42
+ const conditionWords = ['=', '!=', '<>', '>', '<', '>=', '<=', 'in', 'between', 'like', 'is', 'exists', 'does'];
43
+ // `and on` carries on the on clause instead of starting another; so does a merge straight after another
44
+ // (`merge a.x with b.y merge c.z with d.w`, with or without `and`)
45
+ const continues = {
46
+ on: previous => previous === 'and',
47
+ merge: () => true
48
+ };
49
+ // What a second where clause should have been: its conditions joined with and / or inside the first
50
+ const whereHint = exports.whereHint = 'use and / or inside one where clause (where a = 1 and b = 2)';
51
+ /**
52
+ * Split a masked query (see maskStrings) into its clauses, reading its top-level words once, left to right. A clause
53
+ * word counts only as a whole word outside brackets, and not where it must be a name: as a clause's first word
54
+ * (`sort limit`), after a comma or `as`, or before a comparator (`where limit = 1`).
55
+ * @param query
56
+ * @returns undefined when the query doesn't start with read, insert, update or delete (left to the find* steps).
57
+ * @throws {Error} For a joined record outside read, a clause the command doesn't allow, a repeated clause, a clause out
58
+ * of order, or the 2.x forms of a second where (`and where`, `or where`, or a plain repeat).
59
+ */
60
+ const splitClauses = query => {
61
+ const head = query.match(headMatch);
62
+ if (!head) {
63
+ return undefined;
64
+ }
65
+ const command = head[1].toLowerCase();
66
+ const allowed = clauseOrder[command];
67
+ const article = /^[aeiou]/.test(command) ? 'an' : 'a';
68
+ if (head[3] && command !== 'read') {
69
+ throw new Error(`A joined record (${head[2]}) isn't allowed in ${article} ${command} query`);
70
+ }
71
+ const tokens = [...query.slice(head[0].length).matchAll(tokenMatch)].map(({
72
+ 0: text,
73
+ index
74
+ }) => ({
75
+ text,
76
+ lower: text.toLowerCase(),
77
+ start: head[0].length + index
78
+ }));
79
+ const found = [];
80
+ let depth = 0;
81
+ let bodyStarts = false;
82
+ for (let index = 0; index < tokens.length; index++) {
83
+ const {
84
+ lower,
85
+ start
86
+ } = tokens[index];
87
+ const previous = tokens[index - 1]?.lower;
88
+ const next = tokens[index + 1]?.lower;
89
+ if (lower === '(' || lower === ')') {
90
+ depth += lower === '(' ? 1 : -1;
91
+ }
92
+ const keyword = lower === 'group' && next === 'by' ? 'group by' : lower;
93
+ const isName = bodyStarts || previous === ',' || previous === 'as' || conditionWords.includes(next);
94
+ bodyStarts = false;
95
+ if (depth > 0 || keyword === 'by' || !clauseWords.includes(keyword) || isName) {
96
+ continue;
97
+ }
98
+ const current = found[found.length - 1]?.keyword;
99
+ if (current === keyword && continues[keyword]?.(previous)) {
100
+ continue;
101
+ }
102
+ // 2.x read `and where` / `or where` as `and` / `or`, and a second where as `and`
103
+ const hasWhere = found.some(clause => clause.keyword === 'where');
104
+ if (keyword === 'where' && hasWhere && (previous === 'and' || previous === 'or')) {
105
+ throw new Error(`"${previous} where" is no longer supported: ${whereHint}`);
106
+ }
107
+ if (!allowed.includes(keyword)) {
108
+ throw new Error(`"${keyword}" isn't allowed in ${article} ${command} query (allowed: ${allowed.join(', ')})`);
109
+ }
110
+ if (current && allowed.indexOf(keyword) < allowed.indexOf(current)) {
111
+ throw new Error(`"${keyword}" can't come after "${current}" (order: ${allowed.join(', ')})`);
112
+ }
113
+ if (found.some(clause => clause.keyword === keyword)) {
114
+ throw new Error(`Only one "${keyword}" clause is allowed${keyword === 'where' ? `: ${whereHint}` : ''}`);
115
+ }
116
+ if (keyword === 'group by') {
117
+ index++;
118
+ }
119
+ found.push({
120
+ keyword,
121
+ start,
122
+ end: tokens[index].start + tokens[index].text.length
123
+ });
124
+ bodyStarts = true;
125
+ }
126
+ return {
127
+ command,
128
+ head: head[0].trim(),
129
+ leading: query.slice(head[0].length, found[0]?.start ?? query.length).trim(),
130
+ clauses: found.map(({
131
+ keyword,
132
+ end
133
+ }, index) => ({
134
+ keyword,
135
+ body: query.slice(end, found[index + 1]?.start ?? query.length).trim()
136
+ }))
137
+ };
138
+ };
139
+ exports.splitClauses = splitClauses;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.whereHint=exports.splitClauses=exports.clauseOrder=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _maskStrings=require("./maskStrings");const clauseOrder=exports.clauseOrder={read:["select","on","merge","where","group by","sort","limit","offset"],insert:["values"],update:["set","where"],delete:["where"]},clauseWords=[...new Set(Object.values(clauseOrder).flat())],headMatch=/^\s*(delete|insert|read|update)\s+([a-z0-9_-]+(\s*\.[a-z0-9_-]+)?)/i,tokenMatch=new RegExp(`${_maskStrings.placeholderSource}|${_maskStrings.arraySource}|[a-z0-9_.-]+|<>|!=|>=|<=|\\S`,"gi"),conditionWords=["=","!=","<>",">","<",">=","<=","in","between","like","is","exists","does"],continues={on:e=>"and"===e,merge:()=>!0},whereHint=exports.whereHint="use and / or inside one where clause (where a = 1 and b = 2)",splitClauses=e=>{const s=e.match(headMatch);if(!s)return;const r=s[1].toLowerCase(),t=clauseOrder[r],o=/^[aeiou]/.test(r)?"an":"a";if(s[3]&&"read"!==r)throw new Error(`A joined record (${s[2]}) isn't allowed in ${o} ${r} query`);const n=[...e.slice(s[0].length).matchAll(tokenMatch)].map((({0:e,index:r})=>({text:e,lower:e.toLowerCase(),start:s[0].length+r}))),i=[];let l=0,d=!1;for(let e=0;e<n.length;e++){const{lower:s,start:u}=n[e],a=n[e-1]?.lower,c=n[e+1]?.lower;"("!==s&&")"!==s||(l+="("===s?1:-1);const w="group"===s&&"by"===c?"group by":s,j=d||","===a||"as"===a||conditionWords.includes(c);if(d=!1,l>0||"by"===w||!clauseWords.includes(w)||j)continue;const m=i[i.length-1]?.keyword;if(m===w&&continues[w]?.(a))continue;const h=i.some((e=>"where"===e.keyword));if("where"===w&&h&&("and"===a||"or"===a))throw new Error(`"${a} where" is no longer supported: ${whereHint}`);if(!t.includes(w))throw new Error(`"${w}" isn't allowed in ${o} ${r} query (allowed: ${t.join(", ")})`);if(m&&t.indexOf(w)<t.indexOf(m))throw new Error(`"${w}" can't come after "${m}" (order: ${t.join(", ")})`);if(i.some((e=>e.keyword===w)))throw new Error(`Only one "${w}" clause is allowed${"where"===w?`: ${whereHint}`:""}`);"group by"===w&&e++,i.push({keyword:w,start:u,end:n[e].start+n[e].text.length}),d=!0}return{command:r,head:s[0].trim(),leading:e.slice(s[0].length,i[0]?.start??e.length).trim(),clauses:i.map((({keyword:s,end:r},t)=>({keyword:s,body:e.slice(r,i[t+1]?.start??e.length).trim()})))}};exports.splitClauses=splitClauses;
@@ -7,7 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.retrieveFile = void 0;
8
8
  var jsEnv = _interopRequireWildcard(require("browser-or-node"));
9
9
  var _config = require("./config");
10
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
+ var e;
11
+ function _interopRequireWildcard(t, r) { if (!r && t && t.__esModule) return t; var n, a, o = Object.defineProperty, f = { __proto__: null, default: t }; if (Object(t) !== t) return f; if (e || "function" != typeof WeakMap || (e = new WeakMap()), e) { if (e.has(t)) return e.get(t); e.set(t, f); } for (a in t) "default" !== a && {}.hasOwnProperty.call(t, a) && ((n = o && Object.getOwnPropertyDescriptor(t, a)) && (n.get || n.set) ? o(f, a, n) : f[a] = t[a]); return f; }
11
12
  const retrieveFile = async path => {
12
13
  let retrieveFn = url => fetch(url).then(res => res.json());
13
14
  const relativePath = jsEnv.isBrowser ? (0, _config.getSetting)('relativePath', '') : '';
@@ -1 +1 @@
1
- "use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.retrieveFile=void 0;var jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config");function _interopRequireWildcard(e,r){if("function"==typeof WeakMap)var t=new WeakMap,i=new WeakMap;return(_interopRequireWildcard=function(e,r){if(!r&&e&&e.__esModule)return e;var o,n,a={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return a;if(o=r?i:t){if(o.has(e))return o.get(e);o.set(e,a)}for(const r in e)"default"!==r&&{}.hasOwnProperty.call(e,r)&&((n=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,r))&&(n.get||n.set)?o(a,r,n):a[r]=e[r]);return a})(e,r)}const retrieveFile=async e=>{let r=e=>fetch(e).then((e=>e.json()));const t=jsEnv.isBrowser?(0,_config.getSetting)("relativePath",""):"";if(jsEnv.isNode){const{readFile:e}=require("fs/promises");r=r=>e(r).then((e=>JSON.parse(e)))}const i=`${t}${(0,_config.getSetting)("databasePath","database/")}${e}`,o=await r(i).catch((e=>console.error(e)));if(!o)throw new Error(`Could not read ${e}`);return o};exports.retrieveFile=retrieveFile;
1
+ "use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.retrieveFile=void 0;var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config");function _interopRequireWildcard(r,t){if(!t&&r&&r.__esModule)return r;var i,o,n=Object.defineProperty,s={__proto__:null,default:r};if(Object(r)!==r)return s;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(r))return e.get(r);e.set(r,s)}for(o in r)"default"!==o&&{}.hasOwnProperty.call(r,o)&&((i=n&&Object.getOwnPropertyDescriptor(r,o))&&(i.get||i.set)?n(s,o,i):s[o]=r[o]);return s}const retrieveFile=async e=>{let r=e=>fetch(e).then((e=>e.json()));const t=jsEnv.isBrowser?(0,_config.getSetting)("relativePath",""):"";if(jsEnv.isNode){const{readFile:e}=require("fs/promises");r=r=>e(r).then((e=>JSON.parse(e)))}const i=`${t}${(0,_config.getSetting)("databasePath","database/")}${e}`,o=await r(i).catch((e=>console.error(e)));if(!o)throw new Error(`Could not read ${e}`);return o};exports.retrieveFile=retrieveFile;
@@ -101,8 +101,8 @@ const runQuery = async parsed => {
101
101
  // anything has looked at it at all. readEntity() (below) can't tell those two states apart on its own (it reloads
102
102
  // whenever the array is empty), so getConditionIndexedList reports which entities it resolved: once any indexed
103
103
  // condition has narrowed entity's rows, they are the candidates (every condition is applied to them below) and
104
- // must not be reloaded. This used to ask whether EVERY condition was indexed, so `where date = 'none' and where
105
- // reps = 10` reloaded every row and returned, updated or deleted all rows with reps 10.
104
+ // must not be reloaded. This used to ask whether EVERY condition was indexed, so `where date = 'none' and reps =
105
+ // 10` reloaded every row and returned, updated or deleted all rows with reps 10.
106
106
  const resolved = new Set();
107
107
  parsed = await (0, _getConditionIndexedList.getConditionIndexedList)(parsed, recordData, dataSet, resolved);
108
108
  const entityResolved = resolved.has(parsed.entity);
@@ -144,10 +144,11 @@ const runQuery = async parsed => {
144
144
  if (parsed.command !== 'delete' && parsed.command !== 'update') {
145
145
  dataSet[parsed.entity] = (0, _where.whereTree)(dataSet[parsed.entity], parsed.where, perPair ? parsed.joinEntity : undefined);
146
146
  }
147
+ // Sorted before grouping, so the groups come in sorted order; limit and offset count groups once there are any
147
148
  dataSet[parsed.entity] = (0, _sortBy.sortBy)(dataSet[parsed.entity], parsed.sortClauses);
148
- dataSet[parsed.entity] = (0, _limitOffset.limitOffset)(dataSet[parsed.entity], parsed.offset, parsed.limit);
149
149
  dataSet[parsed.entity] = (0, _groupBy.groupBy)(dataSet[parsed.entity], parsed.groupBy);
150
- dataSet[parsed.entity] = (0, _selectFields.selectFields)(dataSet[parsed.entity], parsed.selectClauses);
150
+ dataSet[parsed.entity] = (0, _limitOffset.limitOffset)(dataSet[parsed.entity], parsed.offset, parsed.limit);
151
+ dataSet[parsed.entity] = (0, _selectFields.selectFields)(dataSet[parsed.entity], parsed.selectClauses, Boolean(parsed.groupBy?.length));
151
152
  return dataSet;
152
153
  };
153
154
  exports.runQuery = runQuery;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.runQuery=void 0,require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _deleteEntity=require("../queries/deleteEntity"),_insertEntity=require("../queries/insertEntity"),_readEntity=require("../queries/readEntity"),_updateEntity=require("../queries/updateEntity"),_createRecord=require("../queries/createRecord"),_dropRecord=require("../queries/dropRecord"),_describeRecord=require("../queries/describeRecord"),_showRecords=require("../queries/showRecords"),_joinEntity=require("../queries/joinEntity"),_mergeJoins=require("../queries/mergeJoins"),_where=require("../queries/where"),_sortBy=require("../queries/sortBy"),_groupBy=require("../queries/groupBy"),_limitOffset=require("../queries/limitOffset"),_selectFields=require("../queries/selectFields"),_retrieveRecord=require("./retrieveRecord"),_getConditionIndexedList=require("./getConditionIndexedList"),_getJoinIndexedList=require("./getJoinIndexedList"),_isEntityProperty=require("./parsers/isEntityProperty"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_fieldType=require("./fieldType"),_conditionTree=require("./conditionTree"),_conditionEntities=require("./conditionEntities");const typeClauses=async(e,t)=>{for(const r of[...(0,_conditionTree.conditionsOf)(e.where),...e.sortClauses]){let i=e.entity,s=r.property;(0,_isEntityProperty.isEntityProperty)(s)&&({entity:i,property:s}=(0,_splitEntityProperty.splitEntityProperty)(s)),Object.prototype.hasOwnProperty.call(t,i)||(t[i]=await(0,_retrieveRecord.retrieveRecord)(i)),r.type=(0,_fieldType.fieldType)(t[i],s)}},runQuery=async e=>{const t=void 0!==e.where&&(0,_conditionEntities.conditionEntities)(e);switch(e.command){case"create":return{[e.entity]:await(0,_createRecord.createRecord)(e.entity,e.create)};case"drop":return{[e.entity]:await(0,_dropRecord.dropRecord)(e.entity,e.ifExists)};case"describe":return{[e.entity]:await(0,_describeRecord.describeRecord)(e.entity)};case"show":return{[e.entity]:await(0,_showRecords.showRecords)()}}const r={[e.entity]:await(0,_retrieveRecord.retrieveRecord)(e.entity)};void 0!==e.joinEntity&&(r[e.joinEntity]=await(0,_retrieveRecord.retrieveRecord)(e.joinEntity)),await typeClauses(e,r);let i={[e.entity]:[]};const s=new Set;e=await(0,_getConditionIndexedList.getConditionIndexedList)(e,r,i,s);const n=s.has(e.entity);switch("delete"!==(e=await(0,_getJoinIndexedList.getJoinIndexedList)(e,r,i)).command&&"update"!==e.command||(n||(i=await(0,_readEntity.readEntity)(e.entity,i)),i[e.entity]=(0,_where.whereTree)(i[e.entity],e.where)),e.command){case"delete":i=await(0,_deleteEntity.deleteEntity)(e.entity,i);break;case"insert":i=await(0,_insertEntity.insertEntity)(e.entity,e.insertValues,i);break;case"read":n||(i=await(0,_readEntity.readEntity)(e.entity,i));break;case"update":i=await(0,_updateEntity.updateEntity)(e.entity,e.updateValues,i);break;default:throw new Error(`Unknown command: ${e.command}`)}return i=await(0,_joinEntity.joinEntity)(e.entity,e.joinEntity,i,e.joinClauses,n,s.has(e.joinEntity)),i=await(0,_mergeJoins.mergeJoins)(i,e.mergeJoins),"delete"!==e.command&&"update"!==e.command&&(i[e.entity]=(0,_where.whereTree)(i[e.entity],e.where,t?e.joinEntity:void 0)),i[e.entity]=(0,_sortBy.sortBy)(i[e.entity],e.sortClauses),i[e.entity]=(0,_limitOffset.limitOffset)(i[e.entity],e.offset,e.limit),i[e.entity]=(0,_groupBy.groupBy)(i[e.entity],e.groupBy),i[e.entity]=(0,_selectFields.selectFields)(i[e.entity],e.selectClauses),i};exports.runQuery=runQuery;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.runQuery=void 0,require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _deleteEntity=require("../queries/deleteEntity"),_insertEntity=require("../queries/insertEntity"),_readEntity=require("../queries/readEntity"),_updateEntity=require("../queries/updateEntity"),_createRecord=require("../queries/createRecord"),_dropRecord=require("../queries/dropRecord"),_describeRecord=require("../queries/describeRecord"),_showRecords=require("../queries/showRecords"),_joinEntity=require("../queries/joinEntity"),_mergeJoins=require("../queries/mergeJoins"),_where=require("../queries/where"),_sortBy=require("../queries/sortBy"),_groupBy=require("../queries/groupBy"),_limitOffset=require("../queries/limitOffset"),_selectFields=require("../queries/selectFields"),_retrieveRecord=require("./retrieveRecord"),_getConditionIndexedList=require("./getConditionIndexedList"),_getJoinIndexedList=require("./getJoinIndexedList"),_isEntityProperty=require("./parsers/isEntityProperty"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_fieldType=require("./fieldType"),_conditionTree=require("./conditionTree"),_conditionEntities=require("./conditionEntities");const typeClauses=async(e,t)=>{for(const r of[...(0,_conditionTree.conditionsOf)(e.where),...e.sortClauses]){let i=e.entity,s=r.property;(0,_isEntityProperty.isEntityProperty)(s)&&({entity:i,property:s}=(0,_splitEntityProperty.splitEntityProperty)(s)),Object.prototype.hasOwnProperty.call(t,i)||(t[i]=await(0,_retrieveRecord.retrieveRecord)(i)),r.type=(0,_fieldType.fieldType)(t[i],s)}},runQuery=async e=>{const t=void 0!==e.where&&(0,_conditionEntities.conditionEntities)(e);switch(e.command){case"create":return{[e.entity]:await(0,_createRecord.createRecord)(e.entity,e.create)};case"drop":return{[e.entity]:await(0,_dropRecord.dropRecord)(e.entity,e.ifExists)};case"describe":return{[e.entity]:await(0,_describeRecord.describeRecord)(e.entity)};case"show":return{[e.entity]:await(0,_showRecords.showRecords)()}}const r={[e.entity]:await(0,_retrieveRecord.retrieveRecord)(e.entity)};void 0!==e.joinEntity&&(r[e.joinEntity]=await(0,_retrieveRecord.retrieveRecord)(e.joinEntity)),await typeClauses(e,r);let i={[e.entity]:[]};const s=new Set;e=await(0,_getConditionIndexedList.getConditionIndexedList)(e,r,i,s);const n=s.has(e.entity);switch("delete"!==(e=await(0,_getJoinIndexedList.getJoinIndexedList)(e,r,i)).command&&"update"!==e.command||(n||(i=await(0,_readEntity.readEntity)(e.entity,i)),i[e.entity]=(0,_where.whereTree)(i[e.entity],e.where)),e.command){case"delete":i=await(0,_deleteEntity.deleteEntity)(e.entity,i);break;case"insert":i=await(0,_insertEntity.insertEntity)(e.entity,e.insertValues,i);break;case"read":n||(i=await(0,_readEntity.readEntity)(e.entity,i));break;case"update":i=await(0,_updateEntity.updateEntity)(e.entity,e.updateValues,i);break;default:throw new Error(`Unknown command: ${e.command}`)}return i=await(0,_joinEntity.joinEntity)(e.entity,e.joinEntity,i,e.joinClauses,n,s.has(e.joinEntity)),i=await(0,_mergeJoins.mergeJoins)(i,e.mergeJoins),"delete"!==e.command&&"update"!==e.command&&(i[e.entity]=(0,_where.whereTree)(i[e.entity],e.where,t?e.joinEntity:void 0)),i[e.entity]=(0,_sortBy.sortBy)(i[e.entity],e.sortClauses),i[e.entity]=(0,_groupBy.groupBy)(i[e.entity],e.groupBy),i[e.entity]=(0,_limitOffset.limitOffset)(i[e.entity],e.offset,e.limit),i[e.entity]=(0,_selectFields.selectFields)(i[e.entity],e.selectClauses,Boolean(e.groupBy?.length)),i};exports.runQuery=runQuery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-fs-query",
3
- "version": "2.3.1",
3
+ "version": "3.1.0",
4
4
  "description": "Use json files to manage and read data.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,8 +43,9 @@
43
43
  },
44
44
  "homepage": "https://github.com/jheagle/json-file-db#readme",
45
45
  "devDependencies": {
46
+ "@babel/core": "^8.1.0",
46
47
  "gulp": "^5.0.1",
47
- "js-build-tools": "^6.6.0",
48
+ "js-build-tools": "^8.0.0",
48
49
  "release-it": "^21.1.1",
49
50
  "test-filesystem": "^2.0.2",
50
51
  "typedoc": "^0.28.20"
@@ -63,6 +64,7 @@
63
64
  "core-js": false,
64
65
  "core-js-pure": false,
65
66
  "@parcel/watcher": false,
66
- "unrs-resolver": false
67
+ "unrs-resolver": false,
68
+ "esbuild": false
67
69
  }
68
70
  }
@@ -1,2 +0,0 @@
1
- export declare const removeFromQuery: (substring: string, query: string) => string;
2
- //# sourceMappingURL=removeFromQuery.d.ts.map
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.removeFromQuery = void 0;
7
- const removeFromQuery = (substring, query) => query.replace(substring, '').trim();
8
- exports.removeFromQuery = removeFromQuery;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeFromQuery=void 0;const removeFromQuery=(e,r)=>r.replace(e,"").trim();exports.removeFromQuery=removeFromQuery;