@leyyo/query 1.0.2 → 1.2.1

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.
@@ -0,0 +1,2 @@
1
+ export * from './invalid-query-value.error';
2
+ export * from './index.types';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./invalid-query-value.error"), exports);
18
+ __exportStar(require("./index.types"), exports);
@@ -0,0 +1 @@
1
+ export type QueryErrorCode = 'xxx' | 'field:invalid' | 'field:empty' | 'field:raw-both' | 'field:raw-none' | 'as:invalid' | 'raw:invalid' | 'raw:empty' | 'op:invalid-key' | 'op:invalid-type' | 'asc:invalid-key' | 'asc:invalid-type' | 'value:invalid-type' | 'value:invalid-item' | 'integer:invalid' | 'integer:min' | 'select:item' | 'select:body' | 'where:item' | 'where:body' | 'having:item' | 'having:body' | 'groupBy:item' | 'groupBy:body' | 'orderBy:item' | 'orderBy:body' | 'page:conflict' | 'limit:conflict' | 'pagination:invalid-key' | 'pagination:invalid-type';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ import { QueryErrorCode } from "./index.types";
2
+ export declare class InvalidQueryValueError extends Error {
3
+ readonly message: string;
4
+ readonly path: string;
5
+ constructor(code: QueryErrorCode, message: string, path: string);
6
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidQueryValueError = void 0;
4
+ class InvalidQueryValueError extends Error {
5
+ constructor(code, message, path) {
6
+ super(`[${code}] ${message} at ${path}`);
7
+ this.message = message;
8
+ this.path = path;
9
+ }
10
+ }
11
+ exports.InvalidQueryValueError = InvalidQueryValueError;
@@ -1,6 +1,5 @@
1
- import type { KeyOf } from "@leyyo/common";
2
- export interface FieldRegular<T> {
3
- field: KeyOf<T>;
1
+ export interface FieldRegular<K extends string> {
2
+ field: K;
4
3
  }
5
4
  export interface FieldRaw {
6
5
  raw: string;
@@ -1,8 +1,7 @@
1
- import type { KeyOf } from "@leyyo/common";
2
1
  import type { FieldRaw, FieldRegular } from "../field";
3
- export type GroupByAny<T> = Array<KeyOf<T> | GroupByGivenRegular<T> | GroupByGivenRaw>;
4
- export type GroupByGivenRegular<T> = FieldRegular<T>;
2
+ export type GroupByAny<K extends string> = Array<K | GroupByGivenRegular<K> | GroupByGivenRaw>;
3
+ export type GroupByGivenRegular<K extends string> = FieldRegular<K>;
5
4
  export type GroupByGivenRaw = FieldRaw;
6
- export type GroupBy<T> = Array<GroupByItemRegular<T> | GroupByItemRaw>;
7
- export type GroupByItemRegular<T> = FieldRegular<T>;
5
+ export type GroupBy<K extends string> = Array<GroupByItemRegular<K> | GroupByItemRaw>;
6
+ export type GroupByItemRegular<K extends string> = FieldRegular<K>;
8
7
  export type GroupByItemRaw = FieldRaw;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export * from './condition';
1
+ export * from './operation';
2
+ export * from './error';
2
3
  export * from './field';
3
4
  export * from './group-by';
4
5
  export * from './order-by';
package/dist/index.js CHANGED
@@ -14,7 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./condition"), exports);
17
+ __exportStar(require("./operation"), exports);
18
+ __exportStar(require("./error"), exports);
18
19
  __exportStar(require("./field"), exports);
19
20
  __exportStar(require("./group-by"), exports);
20
21
  __exportStar(require("./order-by"), exports);
@@ -0,0 +1 @@
1
+ export * from './operation-type';
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./condition-type"), exports);
17
+ __exportStar(require("./operation-type"), exports);
@@ -0,0 +1,3 @@
1
+ export declare const ConditionTypeItems: readonly ["eq", "ne", "null", "!null", "missing", "!missing", "gt", "gte", "lt", "lte", "between", "!between", "in", "!in", "starts", "!starts", "ends", "!ends", "matches", "!matches", "contains", "!contains", "contained", "!contained", "true", "false", "includes", "!includes", "intersects", "!intersects", "exists", "!exists"];
2
+ export type OperationType = typeof ConditionTypeItems[number];
3
+ export declare const OperationTypeMap: Record<string, OperationType>;
@@ -1,26 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ConditionTypeMap = exports.ConditionTypeItems = void 0;
3
+ exports.OperationTypeMap = exports.ConditionTypeItems = void 0;
4
4
  exports.ConditionTypeItems = [
5
5
  // all
6
- '==',
7
- '!=',
6
+ 'eq',
7
+ 'ne',
8
8
  'null',
9
9
  '!null',
10
+ 'missing',
11
+ '!missing',
10
12
  // string, number
11
- '>',
12
- '>=',
13
- '<',
14
- '<=',
13
+ 'gt',
14
+ 'gte',
15
+ 'lt',
16
+ 'lte',
15
17
  'between',
16
18
  '!between',
17
19
  'in',
18
20
  '!in',
19
21
  // string
20
- '^',
21
- '!^',
22
- '$',
23
- '!$',
22
+ 'starts',
23
+ '!starts',
24
+ 'ends',
25
+ '!ends',
24
26
  'matches',
25
27
  '!matches',
26
28
  'contains', // left includes right
@@ -40,32 +42,41 @@ exports.ConditionTypeItems = [
40
42
  '!exists',
41
43
  ];
42
44
  // noinspection JSUnusedGlobalSymbols
43
- exports.ConditionTypeMap = {
45
+ exports.OperationTypeMap = {
44
46
  // all
45
- 'eq': '==',
46
- '=': '==',
47
- 'equals': '==',
48
- 'equal': '==',
49
- 'ne': '!=',
50
- '<>': '!=',
51
- 'not-equals': '!=',
52
- 'not-equal': '!=',
47
+ '=': 'eq',
48
+ '==': 'eq',
49
+ 'equals': 'eq',
50
+ 'equal': 'eq',
51
+ '!equals': 'ne',
52
+ '!equal': 'ne',
53
+ '!=': 'ne',
54
+ '<>': 'ne',
55
+ 'not-equals': 'ne',
56
+ 'not-equal': 'ne',
53
57
  'is-null': 'null',
54
58
  '!': 'null',
55
59
  'nil': 'null',
56
60
  '!!': '!null',
57
61
  'not-null': '!null',
62
+ 'is-missing': 'missing',
63
+ 'is-undefined': 'missing',
64
+ 'undefined': 'missing',
65
+ 'not-missing': '!missing',
66
+ 'not-undefined': '!missing',
67
+ 'defined': '!missing',
58
68
  // string, number
59
- 'greater-than': '>',
60
- 'gt': '>',
61
- 'greater-than-or-equals': '>=',
62
- 'gte': '>=',
63
- '=>': '>=',
64
- 'less-than': '<',
65
- 'lt': '<',
66
- 'less-than-or-equals': '<=',
67
- '=<': '<=',
68
- 'lte': '<=',
69
+ 'greater-than': 'gt',
70
+ '>': 'gt',
71
+ 'greater-than-or-equals': 'gte',
72
+ '>=': 'gte',
73
+ '=>': 'gte',
74
+ 'less-than': 'lt',
75
+ 'less': 'lt',
76
+ '<': 'lt',
77
+ 'less-than-or-equals': 'lte',
78
+ '=<': 'lte',
79
+ '<=': 'lte',
69
80
  '()': 'between',
70
81
  'not-between': '!between',
71
82
  ')(': '!between',
@@ -73,30 +84,29 @@ exports.ConditionTypeMap = {
73
84
  '][': '!in',
74
85
  'not-in': '!in',
75
86
  // string
76
- 'starts-with': '^',
77
- 'start-with': '^',
78
- 'starts': '^',
79
- 'start': '^',
80
- 'not-starts-with': '!^',
81
- 'not-start-with': '!^',
82
- 'not-starts': '!^',
83
- 'not-start': '!^',
84
- '!starts-with': '!^',
85
- '!start-with': '!^',
86
- '!starts': '!^',
87
- '!start': '!^',
88
- 'ends-with': '$',
89
- 'end-with': '$',
90
- 'ends': '$',
91
- 'end': '$',
92
- 'not-end-with': '!$',
93
- 'not-ends': '!$',
94
- 'not-end': '!$',
95
- '!$': '!$',
96
- '!ends-with': '!$',
97
- '!end-with': '!$',
98
- '!ends': '!$',
99
- '!end': '!$',
87
+ 'starts-with': 'starts',
88
+ 'start-with': 'starts',
89
+ '^': 'starts',
90
+ 'start': 'starts',
91
+ 'not-starts-with': '!starts',
92
+ 'not-start-with': '!starts',
93
+ 'not-starts': '!starts',
94
+ 'not-start': '!starts',
95
+ '!starts-with': '!starts',
96
+ '!start-with': '!starts',
97
+ '!^': '!starts',
98
+ '!start': '!starts',
99
+ 'ends-with': 'ends',
100
+ 'end-with': 'ends',
101
+ '$': 'ends',
102
+ 'end': 'ends',
103
+ 'not-end-with': '!ends',
104
+ 'not-ends': '!ends',
105
+ 'not-end': '!ends',
106
+ '!$': '!ends',
107
+ '!ends-with': '!ends',
108
+ '!end-with': '!ends',
109
+ '!end': '!ends',
100
110
  'match': 'matches',
101
111
  'not-matches': '!matches',
102
112
  'not-match': '!matches',
@@ -114,10 +124,10 @@ exports.ConditionTypeMap = {
114
124
  '!like': '!contains',
115
125
  // boolean
116
126
  'yes': 'true',
117
- 'on': 'true',
118
- 'ok': 'true',
119
127
  'no': 'false',
128
+ 'on': 'true',
120
129
  'off': 'false',
130
+ 'ok': 'true',
121
131
  'none': 'false',
122
132
  // array object
123
133
  'include': 'includes',
@@ -1,9 +1,8 @@
1
- import type { KeyOf } from "@leyyo/common";
2
1
  import type { FieldRaw, FieldRegular } from "../field";
3
2
  export type OrderType = 'asc' | 'desc';
4
- export type OrderByAny<T> = KeyOf<T> | Array<OrderByGiven<T> | KeyOf<T> | OrderByGivenRaw> | OrderByValue<T>;
5
- export type OrderByValue<T, K extends keyof T = keyof T> = {
6
- [P in K]: boolean;
3
+ export type OrderByAny<K extends string> = K | Array<OrderByGiven<K> | K | OrderByGivenRaw> | OrderByValue<K>;
4
+ export type OrderByValue<K extends string> = {
5
+ [field in K]: boolean | OrderType;
7
6
  };
8
7
  export interface OrderByGivenAsc {
9
8
  asc?: boolean | OrderType;
@@ -11,8 +10,8 @@ export interface OrderByGivenAsc {
11
10
  export interface OrderAscRegular {
12
11
  asc: boolean;
13
12
  }
14
- export type OrderByGiven<T> = FieldRegular<T> & OrderByGivenAsc;
13
+ export type OrderByGiven<K extends string> = FieldRegular<K> & OrderByGivenAsc;
15
14
  export type OrderByGivenRaw = FieldRaw & OrderByGivenAsc;
16
- export type OrderByItem<T> = FieldRegular<T> & OrderAscRegular;
15
+ export type OrderByItem<K extends string> = FieldRegular<K> & OrderAscRegular;
17
16
  export type OrderByRaw = FieldRaw & OrderAscRegular;
18
- export type OrderBy<T> = Array<OrderByItem<T> | OrderByRaw>;
17
+ export type OrderBy<K extends string> = Array<OrderByItem<K> | OrderByRaw>;
@@ -1,5 +1,6 @@
1
- import type { KeyOf } from "@leyyo/common";
2
1
  import type { QueryAny, QueryRegular } from "../query";
2
+ import { BasicType } from "@leyyo/common";
3
3
  export interface QueryParserLike {
4
- exec<T>(query: QueryAny<T>, availableFields: Array<KeyOf<T> | string>, name?: string): QueryRegular<T>;
4
+ exec<K extends string>(query: QueryAny<K>, availableFields: Array<K | string>, name?: string): QueryRegular<K>;
5
5
  }
6
+ export type QueryValueType = BasicType | 'array' | 'null' | 'integer' | '*';
@@ -1,75 +1,93 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.queryParser = void 0;
4
- const common_1 = require("@leyyo/common");
5
- const condition_1 = require("../condition");
4
+ const operation_1 = require("../operation");
5
+ const error_1 = require("../error");
6
+ const type_1 = require("@leyyo/type");
6
7
  class QueryParser {
7
8
  // region private
8
- _error(message, path) {
9
- return new Error(message + ', ' + path);
9
+ _error(code, message, path) {
10
+ return new error_1.InvalidQueryValueError(code, message, path);
11
+ }
12
+ _invalid(value, path, expected, code) {
13
+ const ex = Array.isArray(expected) ? `[${expected.join(', ')}]` : expected;
14
+ return this._error(code, `It's expected as ${ex}, but it's type: ${typeof value}`, path);
15
+ }
16
+ _emptyOrInvalid(value, path, expected, empty, invalid) {
17
+ if ((0, type_1.isEmpty)(value)) {
18
+ return this._error(empty, `It's empty`, path);
19
+ }
20
+ if (typeof value === 'string' && value.trim() === '') {
21
+ return this._error(empty, `It's empty`, path);
22
+ }
23
+ return this._invalid(value, path, expected, invalid);
10
24
  }
11
25
  _asc(value, path) {
12
- if (common_1.$is.empty(value)) {
26
+ if ((0, type_1.isEmpty)(value)) {
13
27
  return true;
14
28
  }
15
- if (common_1.$is.boolean(value)) {
29
+ if (typeof value === 'boolean') {
16
30
  return value;
17
31
  }
18
- else if (common_1.$is.text(value)) {
32
+ else if ((0, type_1.isText)(value)) {
19
33
  if (value.toLowerCase() === 'asc') {
20
34
  return true;
21
35
  }
22
36
  else if (value.toLowerCase() === 'desc') {
23
37
  return false;
24
38
  }
25
- throw this._error('Order asc error: invalid string', path);
39
+ throw this._error('asc:invalid-key', `It should be [asc, desc], but it's value: ${value}`, path);
26
40
  }
27
- throw this._error('Order asc error: invalid string', path);
41
+ throw this._invalid(value, path, ['boolean', 'string'], 'asc:invalid-type');
28
42
  }
29
43
  _field(value, path) {
30
- if (common_1.$is.text(value)) {
44
+ if ((0, type_1.isText)(value)) {
31
45
  return value;
32
46
  }
33
- throw this._error('Order asc error: invalid string', path);
47
+ throw this._emptyOrInvalid(value, path, 'string', 'field:empty', 'field:invalid');
34
48
  }
35
49
  _raw(value, path) {
36
- if (common_1.$is.text(value)) {
50
+ if ((0, type_1.isText)(value)) {
37
51
  return value;
38
52
  }
39
- throw this._error('Order asc error: invalid string', path);
53
+ throw this._emptyOrInvalid(value, path, 'string', 'raw:empty', 'raw:invalid');
40
54
  }
41
55
  _as(value, path) {
42
- if (common_1.$is.empty(value)) {
56
+ if ((0, type_1.isEmpty)(value)) {
43
57
  return undefined;
44
58
  }
45
- else if (common_1.$is.text(value)) {
59
+ else if ((0, type_1.isText)(value)) {
46
60
  return value;
47
61
  }
48
- throw this._error('Order asc error: invalid string', path);
62
+ throw this._invalid(value, path, 'string', 'as:invalid');
49
63
  }
50
- _condition(value, path) {
51
- if (common_1.$is.empty(value)) {
52
- return '==';
64
+ _operation(value, path) {
65
+ if ((0, type_1.isEmpty)(value)) {
66
+ return 'eq';
53
67
  }
54
- else if (common_1.$is.text(value)) {
68
+ else if ((0, type_1.isText)(value)) {
55
69
  const key = value;
56
- if (common_1.$is.literal(key, condition_1.ConditionTypeItems)) {
70
+ if ((0, type_1.isLiteral)(key, operation_1.ConditionTypeItems)) {
57
71
  return key;
58
72
  }
59
- if (condition_1.ConditionTypeMap[key] !== undefined) {
60
- return condition_1.ConditionTypeMap[key];
73
+ if (operation_1.OperationTypeMap[key] !== undefined) {
74
+ return operation_1.OperationTypeMap[key];
61
75
  }
62
- throw this._error('Order asc error: invalid string', path);
76
+ throw this._error('op:invalid-key', `It should be [@see operations], but it's value: ${value}`, path);
63
77
  }
64
- throw this._error('Order asc error: invalid string', path);
78
+ throw this._invalid(value, path, 'string', 'op:invalid-type');
65
79
  }
66
80
  _value(value, path) {
67
81
  if (value === undefined) {
68
- return [undefined];
82
+ return [];
69
83
  }
70
84
  switch (typeof value) {
71
85
  case "string":
72
- return [];
86
+ value = value.trim();
87
+ if (!value) {
88
+ throw this._error('value:invalid-type', `It should not be empty string`, path);
89
+ }
90
+ return [value];
73
91
  case "number":
74
92
  case "boolean":
75
93
  return [value];
@@ -77,193 +95,202 @@ class QueryParser {
77
95
  if (value === null) {
78
96
  return [null];
79
97
  }
80
- if (Array.isArray(value) && value.length > 0) {
98
+ if (Array.isArray(value)) {
99
+ let index = 0;
100
+ for (const item of value) {
101
+ if (!(0, type_1.isText)(item) && !(0, type_1.isNumberValid)(item) && typeof value !== 'boolean') {
102
+ throw this._invalid(item, `${path}[${index}]`, ['string', 'number', 'boolean', 'array', 'number'], 'value:invalid-item');
103
+ }
104
+ index++;
105
+ }
81
106
  return value;
82
107
  }
83
108
  break;
84
109
  }
85
- throw this._error('Order asc error: invalid string', path);
110
+ throw this._invalid(value, path, ['string', 'number', 'boolean', 'array', 'number'], 'value:invalid-type');
86
111
  }
87
112
  _num(value, path, min) {
88
- if (common_1.$is.empty(value)) {
113
+ if ((0, type_1.isEmpty)(value)) {
89
114
  return undefined;
90
115
  }
91
- else if (common_1.$is.integer(value) && value >= min) {
92
- return value;
116
+ else if ((0, type_1.isIntegerValid)(value)) {
117
+ if (value >= min) {
118
+ return value;
119
+ }
120
+ throw this._error('integer:min', `It should be gte ${min}`, path);
93
121
  }
94
- throw this._error('Order asc error: invalid string', path);
122
+ throw this._invalid(value, path, ['integer'], 'integer:invalid');
95
123
  }
96
124
  _fieldXorRaw(field, raw, path) {
97
125
  if (!raw && !field) {
98
- throw this._error('Order asc error: invalid string', path);
126
+ throw this._error('field:raw-none', `Field or raw are not provided, one of them should be`, path);
99
127
  }
100
128
  else if (raw && field) {
101
- throw this._error('Order asc error: invalid string', path);
129
+ throw this._error('field:raw-both', `Field and raw are provided together, Field or raw are not provided, only one of them should be`, path);
102
130
  }
103
131
  }
104
132
  // endregion private
105
133
  // region parts
106
- _select(given, _availableFields, name) {
107
- if (common_1.$is.empty(given)) {
108
- return true;
134
+ _select(given, _availableFields, _name) {
135
+ if ((0, type_1.isEmpty)(given)) {
136
+ return { all: true };
109
137
  }
110
138
  // Cases:
111
139
  // 1 - '*'
112
- // 2 - Array<KeyOf<T> | [KeyOf<T>, string] | SelectGiven<T> | SelectGivenRaw>
113
- // case 1: string as KeyOf<T>
140
+ // 2 - Array<K | [K, string] | SelectGiven<K> | SelectGivenRaw>
141
+ // case 1: string as K
114
142
  if (given === '*') {
115
- return true;
143
+ return { all: true };
116
144
  }
117
- const newSelect = [];
118
- // case 2: Array<KeyOf<T> | [KeyOf<T>, string] | SelectGiven<T> | SelectGivenRaw>
145
+ const newSelect = { fields: [] };
146
+ // case 2: Array<K | [K, string] | SelectGiven<K> | SelectGivenRaw>
119
147
  if (Array.isArray(given)) {
120
148
  if (given.length < 1) {
121
- return true;
149
+ return { all: true };
122
150
  }
123
151
  const arr = given;
124
152
  arr.forEach((item, index) => {
125
- // Case 2A: KeyOf<T>
126
- if (common_1.$is.text(item)) {
127
- newSelect.push({
153
+ // Case 2A: K
154
+ if ((0, type_1.isText)(item)) {
155
+ newSelect.fields.push({
128
156
  field: item,
129
157
  });
130
158
  }
131
- // Case 2B: [KeyOf<T>, string]
159
+ // Case 2B: [K, string]
132
160
  else if (Array.isArray(item)) {
133
161
  let [field, as] = item;
134
162
  field = this._field(field, `select[${index}][0]`);
135
163
  as = this._as(as, `select[${index}][1]`);
136
- newSelect.push({ field, as, });
164
+ newSelect.fields.push({ field, as, });
137
165
  }
138
- // Case 2C: SelectGiven<T> | SelectGivenRaw
139
- else if (common_1.$is.object(item)) {
166
+ // Case 2C: SelectGiven<K> | SelectGivenRaw
167
+ else if ((0, type_1.isObjectBare)(item)) {
140
168
  let as;
141
169
  let field;
142
170
  let raw;
143
171
  const obj = item;
144
- if (!common_1.$is.empty(obj.raw)) {
172
+ if (!(0, type_1.isEmpty)(obj.raw)) {
145
173
  raw = this._raw(obj.raw, `select[${index}].raw`);
146
174
  }
147
- if (!common_1.$is.empty(obj.field)) {
175
+ if (!(0, type_1.isEmpty)(obj.field)) {
148
176
  field = this._field(obj.field, `select[${index}].field`);
149
177
  }
150
178
  this._fieldXorRaw(field, raw, `select[${index}].field`);
151
179
  as = this._as(obj.as, `select[${index}].as`);
152
180
  if (field) {
153
- newSelect.push({ field, as });
181
+ newSelect.fields.push({ field, as });
154
182
  }
155
183
  else {
156
- newSelect.push({ raw, as });
184
+ newSelect.fields.push({ raw, as });
157
185
  }
158
186
  }
159
187
  // other
160
188
  else {
161
- throw this._error('Invalid select item', name);
189
+ throw this._invalid(item, `select[${index}]`, ['string', 'array', 'object'], 'select:item');
162
190
  }
163
191
  });
164
192
  }
165
193
  // case: other
166
194
  else {
167
- throw this._error('Invalid select item', name);
195
+ throw this._invalid(given, `select`, ['*', 'array'], 'select:body');
168
196
  }
169
197
  return newSelect;
170
198
  }
171
- _where(scope, given, _availableFields, name) {
172
- if (common_1.$is.empty(given)) {
199
+ _where(scope, given, _availableFields, _name) {
200
+ if ((0, type_1.isEmpty)(given)) {
173
201
  return [];
174
202
  }
175
203
  // Cases:
176
- // 1 - WhereValue<T>
177
- // 2 - Array<WhereGiven<T>|WhereGivenRaw|[KeyOf<T>, unknown]>
204
+ // 1 - WhereValue<K>
205
+ // 2 - Array<WhereGiven<K>|WhereGivenRaw|[K, unknown]>
178
206
  const newWhere = [];
179
- // case 1: WhereValue<T>
180
- if (common_1.$is.object(given)) {
207
+ // case 1: WhereValue<K>
208
+ if ((0, type_1.isObjectBare)(given)) {
181
209
  let index = 0;
182
210
  for (let [k, v] of Object.entries(given)) {
183
- const field = this._field(k, `where(key=${index})`);
184
- const value = this._value(v, `where.${field}`);
185
- newWhere.push({ field, value, condition: '==' });
211
+ const field = this._field(k, `${scope}(key=${index})`);
212
+ const value = this._value(v, `${scope}.${field}`);
213
+ newWhere.push({ field, value, op: 'eq' });
186
214
  index++;
187
215
  }
188
216
  }
189
- // case 2: array as Array<WhereGiven<T>|WhereGivenRaw|[KeyOf<T>, unknown]>
217
+ // case 2: array as Array<WhereGiven<K>|WhereGivenRaw|[K, unknown]>
190
218
  else if (Array.isArray(given)) {
191
219
  if (given.length < 1) {
192
220
  return [];
193
221
  }
194
222
  const arr = given;
195
223
  arr.forEach((item, index) => {
196
- var _a, _b;
197
- // Case 2A: WhereGiven<T>|WhereGivenRaw
198
- if (common_1.$is.object(item)) {
224
+ // Case 2A: WhereGiven<K>|WhereGivenRaw
225
+ if ((0, type_1.isObjectBare)(item)) {
199
226
  let field;
200
227
  let raw;
201
- let condition;
228
+ let op;
202
229
  let value;
203
230
  let fullRaw;
204
231
  const obj = item;
205
- if (!common_1.$is.empty(obj.raw)) {
206
- raw = this._raw(obj.raw, `select[${index}].raw`);
232
+ if (!(0, type_1.isEmpty)(obj.raw)) {
233
+ raw = this._raw(obj.raw, `${scope}[${index}].raw`);
207
234
  }
208
- if (!common_1.$is.empty(obj.field)) {
209
- field = this._field(obj.field, `select[${index}].field`);
235
+ if (!(0, type_1.isEmpty)(obj.field)) {
236
+ field = this._field(obj.field, `${scope}[${index}].field`);
210
237
  }
211
- this._fieldXorRaw(field, raw, `where[${index}].field`);
238
+ this._fieldXorRaw(field, raw, `${scope}[${index}].field`);
212
239
  const whereItem = obj;
213
- if (raw && common_1.$is.empty((_a = whereItem.eq) !== null && _a !== void 0 ? _a : whereItem.condition) && common_1.$is.empty(whereItem.value)) {
240
+ if (raw && (0, type_1.isEmpty)(whereItem.op) && (0, type_1.isEmpty)(whereItem.value)) {
214
241
  fullRaw = true;
215
242
  }
216
- condition = this._condition((_b = whereItem.eq) !== null && _b !== void 0 ? _b : whereItem.condition, `select[${index}].condition`);
217
- value = this._value(whereItem.value, `select[${index}].value`);
243
+ op = this._operation(whereItem.op, `${scope}[${index}].op`);
244
+ value = this._value(whereItem.value, `${scope}[${index}].value`);
218
245
  if (field) {
219
- newWhere.push({ field, condition, value });
246
+ newWhere.push({ field, op, value });
220
247
  }
221
248
  else {
222
- newWhere.push({ raw, condition, value, fullRaw });
249
+ newWhere.push({ raw, op, value, fullRaw });
223
250
  }
224
251
  }
225
- // Case 2B: |[KeyOf<T>, unknown]
252
+ // Case 2B: |[K, unknown]
226
253
  else if (Array.isArray(item) && item.length > 0) {
227
254
  let field;
228
255
  let value;
229
- field = this._field(item[0], `select[${index}][0]`);
230
- value = this._value(item[1], `select[${index}][1]`);
231
- newWhere.push({ field, value, condition: '==' });
256
+ field = this._field(item[0], `${scope}[${index}][0]`);
257
+ value = this._value(item[1], `${scope}[${index}][1]`);
258
+ newWhere.push({ field, value, op: 'eq' });
232
259
  }
233
260
  else {
234
- throw this._error('Invalid select item', name);
261
+ throw this._invalid(item, `${scope}[${index}]`, ['object', 'array'], (scope === 'where') ? 'where:item' : 'having:item');
235
262
  }
236
263
  });
237
264
  }
238
265
  // case: other
239
266
  else {
240
- throw this._error('Invalid select item', name);
267
+ throw this._invalid(given, scope, ['object', 'array'], (scope === 'where') ? 'where:body' : 'having:body');
241
268
  }
242
269
  return newWhere;
243
270
  }
244
- _groupBy(given, _availableFields, name) {
245
- if (common_1.$is.empty(given)) {
271
+ _groupBy(given, _availableFields, _name) {
272
+ if ((0, type_1.isEmpty)(given)) {
246
273
  return [];
247
274
  }
248
275
  // Cases:
249
- // 1 - Array<KeyOf<T> | GroupByGivenRegular<T> | GroupByGivenRaw>
276
+ // 1 - Array<K | GroupByGivenRegular<K> | GroupByGivenRaw>
250
277
  const newGroup = [];
251
- // case 1: Array<KeyOf<T> | GroupByGivenRegular<T> | GroupByGivenRaw>
278
+ // case 1: Array<K | GroupByGivenRegular<K> | GroupByGivenRaw>
252
279
  if (Array.isArray(given)) {
253
280
  if (given.length < 1) {
254
281
  return [];
255
282
  }
256
283
  const arr = given;
257
284
  arr.forEach((item, index) => {
258
- // Case 2A: GroupByGivenRegular<T> | GroupByGivenRaw
259
- if (common_1.$is.object(item)) {
285
+ // Case 2A: GroupByGivenRegular<K> | GroupByGivenRaw
286
+ if ((0, type_1.isObjectBare)(item)) {
260
287
  let field;
261
288
  let raw;
262
289
  const obj = item;
263
- if (!common_1.$is.empty(obj.raw)) {
290
+ if (!(0, type_1.isEmpty)(obj.raw)) {
264
291
  raw = this._raw(obj.raw, `groupBy[${index}].raw`);
265
292
  }
266
- if (!common_1.$is.empty(obj.field)) {
293
+ if (!(0, type_1.isEmpty)(obj.field)) {
267
294
  field = this._field(obj.field, `groupBy[${index}].field`);
268
295
  }
269
296
  this._fieldXorRaw(field, raw, `groupBy[${index}].field`);
@@ -274,51 +301,51 @@ class QueryParser {
274
301
  newGroup.push({ raw });
275
302
  }
276
303
  }
277
- // Case 2B: KeyOf<T>
278
- else if (common_1.$is.text(item)) {
304
+ // Case 2B: K
305
+ else if ((0, type_1.isText)(item)) {
279
306
  newGroup.push({ field: item });
280
307
  }
281
308
  else {
282
- throw this._error('Invalid select item', name);
309
+ throw this._invalid(item, `groupBy[${index}]`, ['string', 'object'], 'groupBy:item');
283
310
  }
284
311
  });
285
312
  }
286
313
  // case: other
287
314
  else {
288
- throw this._error('Invalid select item', name);
315
+ throw this._invalid(given, `groupBy`, ['array'], 'groupBy:body');
289
316
  }
290
317
  return newGroup;
291
318
  }
292
- _orderBy(given, _availableFields, name) {
293
- if (common_1.$is.empty(given)) {
319
+ _orderBy(given, _availableFields, _name) {
320
+ if ((0, type_1.isEmpty)(given)) {
294
321
  return [];
295
322
  }
296
323
  // Cases:
297
- // 1 - KeyOf<T>
298
- // 2 - Array<OrderByGiven<T>|KeyOf<T>|OrderByGivenRaw>
299
- // 3 - OrderByValue<T>
324
+ // 1 - K
325
+ // 2 - Array<OrderByGiven<K>|K|OrderByGivenRaw>
326
+ // 3 - OrderByValue<K>
300
327
  const newOrder = [];
301
- // case 1: string as KeyOf<T>
302
- if (common_1.$is.text(given)) {
328
+ // case 1: string as K
329
+ if ((0, type_1.isText)(given)) {
303
330
  newOrder.push({ field: given, asc: true });
304
331
  }
305
- // case 2: array as Array<OrderByGiven<T>|KeyOf<T>|OrderByGivenRaw>
332
+ // case 2: array as Array<OrderByGiven<K>|K|OrderByGivenRaw>
306
333
  else if (Array.isArray(given)) {
307
334
  if (given.length < 1) {
308
335
  return [];
309
336
  }
310
337
  const arr = given;
311
338
  arr.forEach((item, index) => {
312
- // Case 2A: OrderByGiven<T>|OrderByGivenRaw
313
- if (common_1.$is.object(item)) {
339
+ // Case 2A: OrderByGiven<K>|OrderByGivenRaw
340
+ if ((0, type_1.isObjectBare)(item)) {
314
341
  let asc;
315
342
  let field;
316
343
  let raw;
317
344
  const obj = item;
318
- if (!common_1.$is.empty(obj.raw)) {
345
+ if (!(0, type_1.isEmpty)(obj.raw)) {
319
346
  raw = this._raw(obj.raw, `orderBy[${index}].raw`);
320
347
  }
321
- if (!common_1.$is.empty(obj.field)) {
348
+ if (!(0, type_1.isEmpty)(obj.field)) {
322
349
  field = this._field(obj.field, `orderBy[${index}].field`);
323
350
  }
324
351
  this._fieldXorRaw(field, raw, `orderBy[${index}].field`);
@@ -330,18 +357,18 @@ class QueryParser {
330
357
  newOrder.push({ raw, asc });
331
358
  }
332
359
  }
333
- // Case 2B: KeyOf<T>
334
- else if (common_1.$is.text(item)) {
360
+ // Case 2B: K
361
+ else if ((0, type_1.isText)(item)) {
335
362
  newOrder.push({ field: this._field(item, ''), asc: true });
336
363
  }
337
364
  // other
338
365
  else {
339
- throw this._error('Invalid select item', name);
366
+ throw this._invalid(item, `orderBy[${index}]`, ['string', 'object'], 'orderBy:item');
340
367
  }
341
368
  });
342
369
  }
343
- // case 3: {'id': true, name: true, ...} as OrderByValue<T>
344
- else if (common_1.$is.object(given)) {
370
+ // case 3: {'id': true, name: true, ...} as OrderByValue<K>
371
+ else if ((0, type_1.isObjectBare)(given)) {
345
372
  let index = 0;
346
373
  for (let [k, v] of Object.entries(given)) {
347
374
  const field = this._field(k, `orderBy(key=${index})`);
@@ -352,13 +379,13 @@ class QueryParser {
352
379
  }
353
380
  // case: other
354
381
  else {
355
- throw this._error('Invalid select item', name);
382
+ throw this._invalid(given, `orderBy`, ['string', 'array', 'object'], 'orderBy:body');
356
383
  }
357
384
  return newOrder;
358
385
  }
359
- _pagination(given, name) {
386
+ _pagination(given, _name) {
360
387
  var _a;
361
- if (common_1.$is.empty(given)) {
388
+ if ((0, type_1.isEmpty)(given)) {
362
389
  return {};
363
390
  }
364
391
  // Case 1: PaginationLiteral
@@ -372,28 +399,28 @@ class QueryParser {
372
399
  };
373
400
  }
374
401
  // Case 2: PaginationPage | PaginationLimit
375
- else if (common_1.$is.object(given)) {
402
+ else if ((0, type_1.isObjectBare)(given)) {
376
403
  if (Object.keys(given).length < 1) {
377
404
  return {};
378
405
  }
379
406
  const obj = given;
380
- if (!common_1.$is.empty(obj.page)) {
407
+ if (!(0, type_1.isEmpty)(obj.page)) {
408
+ const page = this._num(obj.page, `pagination.page`, 1);
409
+ const size = (_a = this._num(obj.size, `pagination.size`, 1)) !== null && _a !== void 0 ? _a : 50;
381
410
  ['limit', 'offset'].forEach(f => {
382
- if (!common_1.$is.empty(given[f])) {
383
- throw this._error('Invalid select item', name);
411
+ if (!(0, type_1.isEmpty)(given[f])) {
412
+ throw this._error('page:conflict', 'If you give page; limit and offset can not be used anymore', `pagination.page`);
384
413
  }
385
414
  });
386
- const page = this._num(obj.page, `pagination.page`, 1);
387
- const size = (_a = this._num(obj.size, `pagination.size`, 1)) !== null && _a !== void 0 ? _a : 50;
388
415
  return {
389
416
  limit: size,
390
417
  offset: (page - 1) * size
391
418
  };
392
419
  }
393
- if (!common_1.$is.empty(obj.limit)) {
420
+ if (!(0, type_1.isEmpty)(obj.limit)) {
394
421
  ['page', 'size'].forEach(f => {
395
- if (!common_1.$is.empty(obj[f])) {
396
- throw this._error('Invalid select item', name);
422
+ if (!(0, type_1.isEmpty)(obj[f])) {
423
+ throw this._error('limit:conflict', 'If you give limit; page and size can not be used anymore', `pagination.limit`);
397
424
  }
398
425
  });
399
426
  return {
@@ -401,9 +428,9 @@ class QueryParser {
401
428
  offset: this._num(obj.offset, `pagination.offset`, 0)
402
429
  };
403
430
  }
404
- throw this._error('Invalid select item', name);
431
+ throw this._error('pagination:invalid-key', 'Pagination should have limit/offset or page/size keys', 'pagination');
405
432
  }
406
- throw this._error('Invalid select item', name);
433
+ throw this._invalid(given, 'pagination', ['array', 'object'], 'pagination:invalid-type');
407
434
  }
408
435
  // endregion parts
409
436
  exec(query, availableFields, name) {
@@ -3,19 +3,19 @@ import type { Where, WhereAny } from "../where";
3
3
  import type { GroupBy, GroupByAny } from "../group-by";
4
4
  import type { OrderBy, OrderByAny } from "../order-by";
5
5
  import type { PaginationAny, PaginationLimit } from "../pagination";
6
- export interface QueryAny<T = Record<string, unknown>> {
7
- select?: SelectAny<T>;
8
- where?: WhereAny<T>;
9
- having?: WhereAny<T>;
10
- groupBy?: GroupByAny<T>;
11
- orderBy?: OrderByAny<T>;
6
+ export interface QueryAny<K extends string> {
7
+ select?: SelectAny<K>;
8
+ where?: WhereAny<K>;
9
+ having?: WhereAny<K>;
10
+ groupBy?: GroupByAny<K>;
11
+ orderBy?: OrderByAny<K>;
12
12
  pagination?: PaginationAny;
13
13
  }
14
- export interface QueryRegular<T = Record<string, unknown>> {
15
- select: Select<T>;
16
- where: Where<T>;
17
- having: Where<T>;
18
- groupBy: GroupBy<T>;
19
- orderBy: OrderBy<T>;
14
+ export interface QueryRegular<K extends string> {
15
+ select: Select<K>;
16
+ where: Where<K>;
17
+ having: Where<K>;
18
+ groupBy: GroupBy<K>;
19
+ orderBy: OrderBy<K>;
20
20
  pagination: PaginationLimit;
21
21
  }
@@ -1,8 +1,10 @@
1
- import type { KeyOf } from "@leyyo/common";
2
1
  import type { FieldAs, FieldRaw, FieldRegular } from "../field";
3
- export type SelectAny<T> = '*' | Array<KeyOf<T> | [KeyOf<T>, string] | SelectGiven<T> | SelectGivenRaw>;
4
- export type SelectGiven<T> = FieldRegular<T> & FieldAs;
2
+ export type SelectAny<K extends string> = '*' | Array<K | [K, string] | SelectGiven<K> | SelectGivenRaw>;
3
+ export type SelectGiven<K extends string> = FieldRegular<K> & FieldAs;
5
4
  export type SelectGivenRaw = FieldRaw & FieldAs;
6
- export type Select<T> = true | Array<SelectItemRegular<T> | SelectItemRaw>;
7
- export type SelectItemRegular<T> = FieldRegular<T> & FieldAs;
5
+ export interface Select<K extends string> {
6
+ all?: true;
7
+ fields?: Array<SelectItemRegular<K> | SelectItemRaw>;
8
+ }
9
+ export type SelectItemRegular<K extends string> = FieldRegular<K> & FieldAs;
8
10
  export type SelectItemRaw = FieldRaw & FieldAs;
@@ -1,22 +1,20 @@
1
- import type { KeyOf } from "@leyyo/common";
2
- import type { ConditionType } from "../condition";
1
+ import type { OperationType } from "../operation";
3
2
  import type { FieldRaw, FieldRegular } from "../field";
4
- export type WhereValue<T, K extends keyof T = keyof T> = {
5
- [P in K]: T[P];
3
+ export type WhereValue<K extends string> = {
4
+ [P in K]: unknown;
6
5
  };
7
- export type WhereAny<T> = WhereValue<T> | Array<WhereGiven<T> | WhereGivenRaw | [KeyOf<T>, unknown]>;
6
+ export type WhereAny<K extends string> = WhereValue<K> | Array<WhereGiven<K> | WhereGivenRaw | [K, unknown]>;
8
7
  export interface WhereGivenCondition {
9
- eq?: string | ConditionType;
10
- condition?: string | ConditionType;
11
- value: unknown;
8
+ op: string | OperationType;
9
+ value?: unknown;
12
10
  }
13
- export type WhereGiven<T> = FieldRegular<T> & WhereGivenCondition;
11
+ export type WhereGiven<K extends string> = FieldRegular<K> & WhereGivenCondition;
14
12
  export type WhereGivenRaw = FieldRaw & WhereGivenCondition;
15
- export type Where<T> = Array<WhereItemRegular<T> | WhereItemRaw>;
16
- export type WhereItemRegular<T> = FieldRegular<T> & WhereCondition;
13
+ export type Where<K extends string> = Array<WhereItemRegular<K> | WhereItemRaw>;
14
+ export type WhereItemRegular<K extends string> = FieldRegular<K> & WhereCondition;
17
15
  export type WhereItemRaw = FieldRaw & WhereCondition;
18
16
  export interface WhereCondition {
19
17
  fullRaw?: true;
20
- condition?: ConditionType;
18
+ op?: OperationType;
21
19
  value?: unknown;
22
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leyyo/query",
3
- "version": "1.0.2",
3
+ "version": "1.2.1",
4
4
  "description": "Query common component",
5
5
  "keywords": [
6
6
  "Query"
@@ -66,6 +66,7 @@
66
66
  }
67
67
  },
68
68
  "dependencies": {
69
- "@leyyo/common": "^1.0.13"
69
+ "@leyyo/common": "^1.2.1",
70
+ "@leyyo/type": "^1.1.1"
70
71
  }
71
72
  }
@@ -1,8 +0,0 @@
1
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
2
- <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
3
- <rect width="24" height="24" rx="4" fill="#03a56f" />
4
- <g transform="scale(0.9)" transform-origin="12 12" stroke-width="2">
5
- <path stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
6
- d="M21 6H19M21 12H16M21 18H16M7 20V13.5612C7 13.3532 7 13.2492 6.97958 13.1497C6.96147 13.0615 6.93151 12.9761 6.89052 12.8958C6.84431 12.8054 6.77934 12.7242 6.64939 12.5617L3.35061 8.43826C3.22066 8.27583 3.15569 8.19461 3.10948 8.10417C3.06849 8.02393 3.03853 7.93852 3.02042 7.85026C3 7.75078 3 7.64677 3 7.43875V5.6C3 5.03995 3 4.75992 3.10899 4.54601C3.20487 4.35785 3.35785 4.20487 3.54601 4.10899C3.75992 4 4.03995 4 4.6 4H13.4C13.9601 4 14.2401 4 14.454 4.10899C14.6422 4.20487 14.7951 4.35785 14.891 4.54601C15 4.75992 15 5.03995 15 5.6V7.43875C15 7.64677 15 7.75078 14.9796 7.85026C14.9615 7.93852 14.9315 8.02393 14.8905 8.10417C14.8443 8.19461 14.7793 8.27583 14.6494 8.43826L11.3506 12.5617C11.2207 12.7242 11.1557 12.8054 11.1095 12.8958C11.0685 12.9761 11.0385 13.0615 11.0204 13.1497C11 13.2492 11 13.3532 11 13.5612V17L7 20Z"/>
7
- </g>
8
- </svg>
@@ -1,3 +0,0 @@
1
- export declare const ConditionTypeItems: readonly ["==", "!=", "null", "!null", ">", ">=", "<", "<=", "between", "!between", "in", "!in", "^", "!^", "$", "!$", "matches", "!matches", "contains", "!contains", "contained", "!contained", "true", "false", "includes", "!includes", "intersects", "!intersects", "exists", "!exists"];
2
- export type ConditionType = typeof ConditionTypeItems[number];
3
- export declare const ConditionTypeMap: Record<string, ConditionType>;
@@ -1 +0,0 @@
1
- export * from './condition-type';
File without changes
File without changes