@based/db 0.0.12 → 0.0.14

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 (30) hide show
  1. package/dist/lib/darwin_aarch64/libnode-v20.11.1.node +0 -0
  2. package/dist/lib/darwin_aarch64/libnode-v20.18.1.node +0 -0
  3. package/dist/lib/darwin_aarch64/libnode-v22.13.0.node +0 -0
  4. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  5. package/dist/lib/linux_aarch64/libnode-v20.11.1.node +0 -0
  6. package/dist/lib/linux_aarch64/libnode-v20.18.1.node +0 -0
  7. package/dist/lib/linux_aarch64/libnode-v22.13.0.node +0 -0
  8. package/dist/lib/linux_aarch64/libselva.so +0 -0
  9. package/dist/lib/linux_x86_64/libnode-v20.11.1.node +0 -0
  10. package/dist/lib/linux_x86_64/libnode-v20.18.1.node +0 -0
  11. package/dist/lib/linux_x86_64/libnode-v22.13.0.node +0 -0
  12. package/dist/lib/linux_x86_64/libselva.so +0 -0
  13. package/dist/src/client/query/BasedDbQuery.js +2 -2
  14. package/dist/src/client/query/filter/FilterBranch.js +2 -2
  15. package/dist/src/client/query/filter/filter.d.ts +1 -1
  16. package/dist/src/client/query/filter/filter.js +22 -12
  17. package/dist/src/client/query/filter/types.d.ts +2 -1
  18. package/dist/src/client/query/filter/types.js +3 -2
  19. package/dist/src/client/query/include/props.js +1 -1
  20. package/dist/src/client/query/include/toBuffer.js +19 -15
  21. package/dist/src/client/query/include/walk.js +12 -7
  22. package/dist/src/client/query/queryDef.js +5 -2
  23. package/dist/src/client/query/read/read.js +1 -1
  24. package/dist/src/client/query/subscription/markers.js +2 -2
  25. package/dist/src/client/query/toBuffer.js +15 -44
  26. package/dist/src/client/query/types.d.ts +9 -2
  27. package/dist/src/client/query/types.js +4 -1
  28. package/dist/src/client/query/validation.d.ts +22 -2
  29. package/dist/src/client/query/validation.js +79 -2
  30. package/package.json +1 -1
Binary file
Binary file
@@ -21,7 +21,7 @@ export class QueryBranch {
21
21
  return this;
22
22
  }
23
23
  filter(field, operator, value, opts) {
24
- const f = convertFilter(field, operator, value, opts);
24
+ const f = convertFilter(this.def, field, operator, value, opts);
25
25
  filter(this.db, this.def, f, this.def.filter);
26
26
  // @ts-ignore
27
27
  return this;
@@ -93,7 +93,7 @@ export class QueryBranch {
93
93
  this.def.filter.size += f.filterBranch.size;
94
94
  }
95
95
  else {
96
- const f = convertFilter(field, operator, value, opts);
96
+ const f = convertFilter(this.def, field, operator, value, opts);
97
97
  filterOr(this.db, this.def, f, this.def.filter);
98
98
  }
99
99
  // @ts-ignore
@@ -15,13 +15,13 @@ export class FilterBranch {
15
15
  this.def.filter.size += f.filterBranch.size;
16
16
  }
17
17
  else {
18
- const f = convertFilter(field, operator, value, opts);
18
+ const f = convertFilter(this.def, field, operator, value, opts);
19
19
  filterOr(this.db, this.def, f, this.filterBranch);
20
20
  }
21
21
  return this;
22
22
  }
23
23
  filter(field, operator, value) {
24
- const f = convertFilter(field, operator, value);
24
+ const f = convertFilter(this.def, field, operator, value);
25
25
  filter(this.db, this.def, f, this.filterBranch);
26
26
  return this;
27
27
  }
@@ -7,4 +7,4 @@ export { Operator, Filter };
7
7
  export declare const filterRaw: (db: DbClient, filter: Filter, schema: SchemaTypeDef, conditions: QueryDefFilter, def: QueryDef) => number;
8
8
  export declare const filter: (db: DbClient, def: QueryDef, filterAst: FilterAst, conditions: QueryDefFilter) => void;
9
9
  export declare const filterOr: (db: DbClient, def: QueryDef, filterAst: FilterAst[], conditions: QueryDefFilter) => QueryDefFilter;
10
- export declare const convertFilter: (field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts) => FilterAst;
10
+ export declare const convertFilter: (def: QueryDef, field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts) => FilterAst;
@@ -1,8 +1,9 @@
1
- import { isPropDef, ID_FIELD_DEF, TEXT, } from '../../../server/schema/schema.js';
1
+ import { isPropDef, ID_FIELD_DEF, TEXT, REFERENCE, } from '../../../server/schema/schema.js';
2
2
  import { primitiveFilter } from './primitiveFilter.js';
3
3
  import { toFilterCtx } from './types.js';
4
4
  import { IsFilter } from './types.js';
5
5
  import { langCodesMap } from '@based/schema';
6
+ import { filterFieldDoesNotExist, filterInvalidLang } from '../validation.js';
6
7
  const referencesFilter = (db, filter, schema, conditions, def) => {
7
8
  const [fieldStr, ctx, value] = filter;
8
9
  var size = 0;
@@ -25,9 +26,13 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
25
26
  }
26
27
  }
27
28
  }
29
+ else {
30
+ filterFieldDoesNotExist(def, fieldStr);
31
+ return 0;
32
+ }
28
33
  return size;
29
34
  }
30
- if (isPropDef(t) && t.typeIndex === 13) {
35
+ if (isPropDef(t) && t.typeIndex === REFERENCE) {
31
36
  conditions.references ??= new Map();
32
37
  let refConditions = conditions.references.get(t.prop);
33
38
  if (!refConditions) {
@@ -46,7 +51,10 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
46
51
  return size;
47
52
  }
48
53
  }
49
- throw new Error(`Query: field "${fieldStr}" does not exist on type ${schema.type}`);
54
+ if (!def) {
55
+ filterFieldDoesNotExist(def, fieldStr);
56
+ return 0;
57
+ }
50
58
  };
51
59
  export const filterRaw = (db, filter, schema, conditions, def) => {
52
60
  const field = filter[0];
@@ -57,9 +65,11 @@ export const filterRaw = (db, filter, schema, conditions, def) => {
57
65
  const f = s.slice(0, -1).join();
58
66
  fieldDef = schema.props[f];
59
67
  if (fieldDef && fieldDef.typeIndex === TEXT) {
60
- const code = langCodesMap.get(s[s.length - 1]);
61
- if (!code) {
62
- throw new Error(`Invalid value for filter on ${field}: expected a valid locale`);
68
+ const lang = s[s.length - 1];
69
+ const code = langCodesMap.get(lang);
70
+ if (!code || !schema.locales[lang]) {
71
+ filterInvalidLang(def, field);
72
+ return 0;
63
73
  }
64
74
  return primitiveFilter(fieldDef, filter, conditions, code);
65
75
  }
@@ -101,7 +111,7 @@ const normalizeNeedle = (s) => {
101
111
  .filter((ch) => ch.charCodeAt(0) <= 127)
102
112
  .join('');
103
113
  };
104
- export const convertFilter = (field, operator, value, opts) => {
114
+ export const convertFilter = (def, field, operator, value, opts) => {
105
115
  if (operator === undefined) {
106
116
  operator = '=';
107
117
  value = true;
@@ -112,14 +122,14 @@ export const convertFilter = (field, operator, value, opts) => {
112
122
  }
113
123
  if (operator === '!..') {
114
124
  return [
115
- [field, toFilterCtx('>', opts), value[1]],
116
- [field, toFilterCtx('<', opts), value[0]],
125
+ [field, toFilterCtx(def, '>', opts), value[1]],
126
+ [field, toFilterCtx(def, '<', opts), value[0]],
117
127
  ];
118
128
  }
119
129
  else if (operator === '..') {
120
130
  return [
121
- [field, toFilterCtx('>', opts), value[0]],
122
- [field, toFilterCtx('<', opts), value[1]],
131
+ [field, toFilterCtx(def, '>', opts), value[0]],
132
+ [field, toFilterCtx(def, '<', opts), value[1]],
123
133
  ];
124
134
  }
125
135
  else {
@@ -142,7 +152,7 @@ export const convertFilter = (field, operator, value, opts) => {
142
152
  value = value.buffer;
143
153
  }
144
154
  }
145
- return [[field, toFilterCtx(operator, opts), value]];
155
+ return [[field, toFilterCtx(def, operator, opts), value]];
146
156
  }
147
157
  };
148
158
  //# sourceMappingURL=filter.js.map
@@ -1,3 +1,4 @@
1
+ import { QueryDef } from '../types.js';
1
2
  import { FilterBranch } from './FilterBranch.js';
2
3
  export type Filter = [fieldStr: string, ctx: FilterCtx, value: any];
3
4
  export type FilterBranchFn = (filterBranch: FilterBranch) => void;
@@ -52,4 +53,4 @@ export declare const VECTOR_MANHATTAN_DIST = 1;
52
53
  export declare const VECTOR_COSTINE_SIMILARITY = 2;
53
54
  export declare const VECTOR_EUCLIDEAN_DIST = 3;
54
55
  export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) => 0 | 1 | 2 | 3;
55
- export declare const toFilterCtx: (op: Operator, opts?: FilterOpts) => FilterCtx;
56
+ export declare const toFilterCtx: (def: QueryDef, op: Operator, opts?: FilterOpts) => FilterCtx;
@@ -1,3 +1,4 @@
1
+ import { filterOperatorDoesNotExist } from '../validation.js';
1
2
  export const IsFilter = (f) => {
2
3
  if (typeof f[0] === 'string') {
3
4
  return true;
@@ -86,7 +87,7 @@ export const getVectorFn = (optsFn) => {
86
87
  return VECTOR_MANHATTAN_DIST;
87
88
  }
88
89
  };
89
- export const toFilterCtx = (op, opts = {}) => {
90
+ export const toFilterCtx = (def, op, opts = {}) => {
90
91
  if (op === '=' || op === '!=') {
91
92
  return {
92
93
  operation: EQUAL,
@@ -116,6 +117,6 @@ export const toFilterCtx = (op, opts = {}) => {
116
117
  if (op === 'like') {
117
118
  return { operation: LIKE, opts, type: TYPE_DEFAULT };
118
119
  }
119
- throw new Error('Invalid filter operator');
120
+ filterOperatorDoesNotExist(def, op);
120
121
  };
121
122
  //# sourceMappingURL=types.js.map
@@ -51,7 +51,7 @@ export const includeProp = (def, prop) => {
51
51
  return false;
52
52
  }
53
53
  if (prop.separate) {
54
- def.include.props.add(prop.prop);
54
+ def.include.props.set(prop.prop, prop);
55
55
  }
56
56
  else {
57
57
  def.include.main.len += prop.len;
@@ -48,19 +48,21 @@ export const includeToBuffer = (db, def) => {
48
48
  }
49
49
  }
50
50
  if (def.include.langTextFields.size) {
51
- for (const [prop, langCode] of def.include.langTextFields.entries()) {
51
+ for (const [prop, { codes, def: propDef },] of def.include.langTextFields.entries()) {
52
52
  def.include.propsRead[prop] = 0;
53
- if (langCode.has(0)) {
54
- const b = Buffer.allocUnsafe(2);
53
+ if (codes.has(0)) {
54
+ const b = Buffer.allocUnsafe(3);
55
55
  b[0] = prop;
56
- b[1] = 0;
56
+ b[1] = propDef.typeIndex;
57
+ b[2] = 0;
57
58
  result.push(b);
58
59
  }
59
60
  else {
60
- for (const code of langCode) {
61
- const b = Buffer.allocUnsafe(2);
61
+ for (const code of codes) {
62
+ const b = Buffer.allocUnsafe(3);
62
63
  b[0] = prop;
63
- b[1] = code;
64
+ b[1] = propDef.typeIndex;
65
+ b[2] = code;
64
66
  result.push(b);
65
67
  }
66
68
  }
@@ -68,7 +70,7 @@ export const includeToBuffer = (db, def) => {
68
70
  }
69
71
  const propSize = def.include.props.size ?? 0;
70
72
  if (mainBuffer) {
71
- len = mainBuffer.byteLength + 3 + propSize;
73
+ len = mainBuffer.byteLength + 3 + propSize * 2;
72
74
  includeBuffer = Buffer.allocUnsafe(len);
73
75
  includeBuffer[0] = 0;
74
76
  includeBuffer.writeInt16LE(mainBuffer.byteLength, 1);
@@ -76,24 +78,26 @@ export const includeToBuffer = (db, def) => {
76
78
  mainBuffer.copy(includeBuffer, 3);
77
79
  if (propSize) {
78
80
  let i = 0;
79
- for (const prop of def.include.props) {
81
+ for (const [prop, propDef] of def.include.props.entries()) {
80
82
  includeBuffer[i + offset] = prop;
81
- i++;
83
+ includeBuffer[i + offset + 1] = propDef.typeIndex;
84
+ i += 2;
82
85
  }
83
86
  }
84
87
  }
85
88
  else if (propSize) {
86
- const buf = Buffer.allocUnsafe(propSize);
89
+ const buf = Buffer.allocUnsafe(propSize * 2);
87
90
  let i = 0;
88
- for (const prop of def.include.props) {
91
+ for (const [prop, propDef] of def.include.props.entries()) {
89
92
  buf[i] = prop;
90
- i++;
93
+ buf[i + 1] = propDef.typeIndex;
94
+ i += 2;
91
95
  }
92
96
  includeBuffer = buf;
93
97
  }
94
98
  if (includeBuffer) {
95
- def.include.props.forEach((v) => {
96
- def.include.propsRead[v] = 0;
99
+ def.include.props.forEach((v, k) => {
100
+ def.include.propsRead[k] = 0;
97
101
  });
98
102
  result.push(includeBuffer);
99
103
  }
@@ -4,7 +4,7 @@ import { isRefDef, QueryDefType } from '../types.js';
4
4
  import { getAllFieldFromObject, createOrGetRefQueryDef } from './utils.js';
5
5
  import { includeProp, includeAllProps, includeField } from './props.js';
6
6
  import { langCodesMap } from '@based/schema';
7
- import { includeDoesNotExist } from '../validation.js';
7
+ import { includeDoesNotExist, includeLangDoesNotExist } from '../validation.js';
8
8
  export const walkDefs = (db, def, f) => {
9
9
  const prop = def.props[f];
10
10
  const path = f.split('.');
@@ -35,7 +35,7 @@ export const walkDefs = (db, def, f) => {
35
35
  }
36
36
  }
37
37
  else {
38
- def.edges.include.props.add(edgeProp.prop);
38
+ def.edges.include.props.set(edgeProp.prop, edgeProp);
39
39
  }
40
40
  return;
41
41
  }
@@ -47,11 +47,16 @@ export const walkDefs = (db, def, f) => {
47
47
  return;
48
48
  }
49
49
  if (isPropDef(t) && t.typeIndex === TEXT) {
50
- const langCode = langCodesMap.get(path[path.length - 1]);
50
+ const lang = path[path.length - 1];
51
+ const langCode = langCodesMap.get(lang);
52
+ if (!langCode || !db.schema.locales[lang]) {
53
+ includeLangDoesNotExist(def, f);
54
+ return;
55
+ }
51
56
  if (!def.include.langTextFields.has(t.prop)) {
52
- def.include.langTextFields.set(t.prop, new Set());
57
+ def.include.langTextFields.set(t.prop, { def: t, codes: new Set() });
53
58
  }
54
- def.include.langTextFields.get(t.prop).add(langCode);
59
+ def.include.langTextFields.get(t.prop).codes.add(langCode);
55
60
  return;
56
61
  }
57
62
  else if (isPropDef(t) &&
@@ -79,9 +84,9 @@ export const walkDefs = (db, def, f) => {
79
84
  }
80
85
  else if (prop.typeIndex === TEXT) {
81
86
  if (!def.include.langTextFields.has(prop.prop)) {
82
- def.include.langTextFields.set(prop.prop, new Set());
87
+ def.include.langTextFields.set(prop.prop, { def: prop, codes: new Set() });
83
88
  }
84
- def.include.langTextFields.get(prop.prop).add(def.lang ?? 0);
89
+ def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
85
90
  }
86
91
  else {
87
92
  includeProp(def, prop);
@@ -1,7 +1,7 @@
1
1
  import { langCodesMap } from '@based/schema';
2
2
  import { DEF_RANGE_PROP_LIMIT, DEF_RANGE_REF_LIMIT } from './thresholds.js';
3
3
  import { QueryDefType, } from './types.js';
4
- import { validateId, validateIds, validateType } from './validation.js';
4
+ import { validateAlias, validateId, validateIds, validateType, } from './validation.js';
5
5
  const createEmptySharedDef = () => {
6
6
  const q = {
7
7
  errors: [],
@@ -11,7 +11,7 @@ const createEmptySharedDef = () => {
11
11
  include: {
12
12
  langTextFields: new Map(),
13
13
  stringFields: new Set(),
14
- props: new Set(),
14
+ props: new Map(),
15
15
  propsRead: {},
16
16
  main: {
17
17
  len: 0,
@@ -49,6 +49,9 @@ export const createQueryDef = (db, type, target) => {
49
49
  t.ids = validateIds(q, t.ids);
50
50
  q.range.limit = t.ids.length;
51
51
  }
52
+ else if (t.alias) {
53
+ t.resolvedAlias = validateAlias(t.alias, [], q);
54
+ }
52
55
  else {
53
56
  q.range.limit = DEF_RANGE_PROP_LIMIT;
54
57
  }
@@ -145,7 +145,7 @@ const handleUndefinedProps = (id, q, item) => {
145
145
  const prop = q.schema.reverseProps[k];
146
146
  if (prop.typeIndex === TEXT && q.lang == 0) {
147
147
  const lan = getEmptyField(prop, item);
148
- const lang = q.include.langTextFields.get(prop.prop);
148
+ const lang = q.include.langTextFields.get(prop.prop).codes;
149
149
  if (lang.has(0)) {
150
150
  for (const locale in q.schema.locales) {
151
151
  if (!lan[locale]) {
@@ -132,7 +132,7 @@ export const addSubscriptionMarkers = (q, subscription) => {
132
132
  const marker = markerType.ids.get(id);
133
133
  const props = q.def.include.props;
134
134
  const main = q.def.include.main;
135
- for (const p of props) {
135
+ for (const [p] of props.entries()) {
136
136
  if (!(p in marker.props)) {
137
137
  marker.props[p] = [];
138
138
  }
@@ -154,7 +154,7 @@ export const addSubscriptionMarkers = (q, subscription) => {
154
154
  const props = q.def.include.props;
155
155
  const main = q.def.include.main;
156
156
  const marker = markerType.collection;
157
- for (const p of props) {
157
+ for (const [p] of props.entries()) {
158
158
  if (!(p in marker.props)) {
159
159
  marker.props[p] = [];
160
160
  }
@@ -3,30 +3,11 @@ import { QueryDefType } from './types.js';
3
3
  import { includeToBuffer } from './include/toBuffer.js';
4
4
  import { filterToBuffer } from './query.js';
5
5
  import { searchToBuffer } from './search/index.js';
6
- import { ALIAS } from '../../server/schema/types.js';
7
6
  const byteSize = (arr) => {
8
7
  return arr.reduce((a, b) => {
9
8
  return a + b.byteLength;
10
9
  }, 0);
11
10
  };
12
- const getAliasPropdef = (alias, path, def) => {
13
- const schema = def.schema;
14
- for (const k in alias) {
15
- if (typeof alias[k] === 'string') {
16
- const p = path.join('.') + k;
17
- const prop = schema.props[p];
18
- if (prop.typeIndex === ALIAS) {
19
- return { def: prop, value: alias[k] };
20
- }
21
- }
22
- else if (typeof alias[k] === 'object') {
23
- const propDef = getAliasPropdef(alias[k], [...path, k], def);
24
- if (propDef) {
25
- return propDef;
26
- }
27
- }
28
- }
29
- };
30
11
  export function defToBuffer(db, def) {
31
12
  // if (def.errors.length) {
32
13
  // return []
@@ -67,33 +48,23 @@ export function defToBuffer(db, def) {
67
48
  }
68
49
  // [type,type]
69
50
  // [q type] 0 == id, 1 === ids, 2 === type only
70
- if (def.target.alias) {
51
+ if (def.target.resolvedAlias) {
71
52
  // put this somehwere else at some point
72
- try {
73
- const alias = getAliasPropdef(def.target.alias, [], def);
74
- if (!alias) {
75
- throw new Error(`Cannot find valid alias type in "${JSON.stringify(def.target.alias)}"`);
76
- }
77
- else {
78
- const s = Buffer.byteLength(alias.value);
79
- // filter is nice for things like access
80
- const buf = Buffer.allocUnsafe(8 + filterSize + s);
81
- buf[0] = 3;
82
- buf[1] = def.schema.idUint8[0];
83
- buf[2] = def.schema.idUint8[1];
84
- buf[3] = alias.def.prop;
85
- buf.writeUint16LE(s, 4);
86
- buf.write(alias.value, 6);
87
- buf.writeUint16LE(filterSize, s + 6);
88
- if (filterSize) {
89
- buf.set(filter, 8 + s);
90
- }
91
- result.push(buf);
92
- }
93
- }
94
- catch (err) {
95
- throw new Error(`Cannot parse alias object query for type ${def.schema.type}`);
53
+ const alias = def.target.resolvedAlias;
54
+ const s = Buffer.byteLength(alias.value);
55
+ // filter is nice for things like access
56
+ const buf = Buffer.allocUnsafe(8 + filterSize + s);
57
+ buf[0] = 3;
58
+ buf[1] = def.schema.idUint8[0];
59
+ buf[2] = def.schema.idUint8[1];
60
+ buf[3] = alias.def.prop;
61
+ buf.writeUint16LE(s, 4);
62
+ buf.write(alias.value, 6);
63
+ buf.writeUint16LE(filterSize, s + 6);
64
+ if (filterSize) {
65
+ buf.set(filter, 8 + s);
96
66
  }
67
+ result.push(buf);
97
68
  }
98
69
  else if (def.target.id) {
99
70
  // type 0
@@ -21,6 +21,10 @@ export type Target = {
21
21
  ids?: Uint32Array | void;
22
22
  propDef?: PropDef | PropDefEdge;
23
23
  alias?: QueryByAliasObj;
24
+ resolvedAlias?: {
25
+ def: PropDef;
26
+ value: string;
27
+ };
24
28
  };
25
29
  export declare const isRefDef: (def: QueryDef) => def is QueryDefRest;
26
30
  export type QueryDefFilter = {
@@ -66,9 +70,12 @@ export type QueryDefShared = {
66
70
  limit: number;
67
71
  };
68
72
  include: {
69
- langTextFields: Map<number, Set<LangCode>>;
73
+ langTextFields: Map<number, {
74
+ def: PropDef | PropDefEdge;
75
+ codes: Set<LangCode>;
76
+ }>;
70
77
  stringFields: Set<string>;
71
- props: Set<number>;
78
+ props: Map<number, PropDef | PropDefEdge>;
72
79
  propsRead: {
73
80
  [propName: number]: number;
74
81
  };
@@ -13,6 +13,9 @@ export const isAlias = (id) => {
13
13
  if (id instanceof Uint32Array) {
14
14
  return false;
15
15
  }
16
- return typeof id === 'object' && id !== null && !Array.isArray(id);
16
+ return (typeof id === 'object' &&
17
+ id !== null &&
18
+ !Array.isArray(id) &&
19
+ !ArrayBuffer.isView(id));
17
20
  };
18
21
  //# sourceMappingURL=types.js.map
@@ -1,6 +1,6 @@
1
- import { SchemaTypeDef } from '../../server/schema/types.js';
1
+ import { PropDef, SchemaTypeDef } from '../../server/schema/types.js';
2
2
  import { DbClient } from '../index.js';
3
- import { QueryDef } from './types.js';
3
+ import { QueryByAliasObj, QueryDef } from './types.js';
4
4
  export type QueryError = {
5
5
  code: number;
6
6
  payload: any;
@@ -11,6 +11,13 @@ export declare const ERR_TARGET_EXCEED_MAX_IDS = 3;
11
11
  export declare const ERR_TARGET_INVAL_IDS = 4;
12
12
  export declare const ERR_TARGET_INVAL_ID = 5;
13
13
  export declare const ERR_INCLUDE_ENOENT = 6;
14
+ export declare const ERR_FILTER_ENOENT = 7;
15
+ export declare const ERR_FILTER_OP_FIELD = 8;
16
+ export declare const ERR_FILTER_OP_ENOENT = 9;
17
+ export declare const ERR_FILTER_INVALID_VAL = 10;
18
+ export declare const ERR_FILTER_INVALID_OPTS = 11;
19
+ export declare const ERR_FILTER_INVALID_LANG = 12;
20
+ export declare const ERR_INCLUDE_INVALID_LANG = 13;
14
21
  declare const messages: {
15
22
  1: (p: any) => string;
16
23
  2: (p: any) => string;
@@ -18,12 +25,25 @@ declare const messages: {
18
25
  4: (p: any) => string;
19
26
  5: (p: any) => string;
20
27
  6: (p: any) => string;
28
+ 13: (p: any) => string;
29
+ 7: (p: any) => string;
30
+ 12: (p: any) => string;
31
+ 9: (p: any) => string;
21
32
  };
22
33
  export type ErrorCode = keyof typeof messages;
23
34
  export declare const validateType: (db: DbClient, def: QueryDef, type: string) => SchemaTypeDef;
35
+ export declare const filterOperatorDoesNotExist: (def: QueryDef, field: string) => void;
36
+ export declare const filterInvalidLang: (def: QueryDef, field: string) => void;
37
+ export declare const filterFieldDoesNotExist: (def: QueryDef, field: string) => void;
24
38
  export declare const includeDoesNotExist: (def: QueryDef, field: string) => void;
39
+ export declare const includeLangDoesNotExist: (def: QueryDef, field: string) => void;
40
+ export declare const validateAlias: (alias: QueryByAliasObj, path: string[], def: QueryDef) => {
41
+ def: PropDef;
42
+ value: string;
43
+ };
25
44
  export declare const validateId: (def: QueryDef, id: any) => number;
26
45
  export declare const validateIds: (def: QueryDef, ids: any) => Uint32Array;
27
46
  export declare const handleErrors: (def: QueryDef) => void;
47
+ export declare const EMPTY_ALIAS_PROP_DEF: PropDef;
28
48
  export declare const EMPTY_SCHEMA_DEF: SchemaTypeDef;
29
49
  export {};
@@ -1,3 +1,4 @@
1
+ import { ALIAS } from '../../server/schema/types.js';
1
2
  import { MAX_ID, MAX_IDS_PER_QUERY } from './thresholds.js';
2
3
  export const ERR_TARGET_INVAL_TYPE = 1;
3
4
  export const ERR_TARGET_INVAL_ALIAS = 2;
@@ -5,13 +6,33 @@ export const ERR_TARGET_EXCEED_MAX_IDS = 3;
5
6
  export const ERR_TARGET_INVAL_IDS = 4;
6
7
  export const ERR_TARGET_INVAL_ID = 5;
7
8
  export const ERR_INCLUDE_ENOENT = 6;
9
+ export const ERR_FILTER_ENOENT = 7;
10
+ export const ERR_FILTER_OP_FIELD = 8;
11
+ export const ERR_FILTER_OP_ENOENT = 9;
12
+ export const ERR_FILTER_INVALID_VAL = 10;
13
+ export const ERR_FILTER_INVALID_OPTS = 11;
14
+ export const ERR_FILTER_INVALID_LANG = 12;
15
+ export const ERR_INCLUDE_INVALID_LANG = 13;
8
16
  const messages = {
9
17
  [ERR_TARGET_INVAL_TYPE]: (p) => `Type "${p}" does not exist`,
10
- [ERR_TARGET_INVAL_ALIAS]: (p) => `Invalid alias "${p}"`,
18
+ [ERR_TARGET_INVAL_ALIAS]: (p) => {
19
+ var v;
20
+ try {
21
+ v = JSON.stringify(p).replace(/"/g, '');
22
+ }
23
+ catch (err) {
24
+ v = '';
25
+ }
26
+ return `Invalid alias prodived to query "${v}"`;
27
+ },
11
28
  [ERR_TARGET_EXCEED_MAX_IDS]: (p) => `Exceeds max ids ${~~(p.length / 1e3)}k (max ${MAX_IDS_PER_QUERY / 1e3}k)`,
12
29
  [ERR_TARGET_INVAL_IDS]: (p) => `Ids should be of type array or Uint32Array with valid ids`,
13
30
  [ERR_TARGET_INVAL_ID]: (p) => `Invalid id should be a number larger then 0 "${p}"`,
14
- [ERR_INCLUDE_ENOENT]: (p) => `Included field does not exist "${p}"`,
31
+ [ERR_INCLUDE_ENOENT]: (p) => `Include: field does not exist "${p}"`,
32
+ [ERR_INCLUDE_INVALID_LANG]: (p) => `Include: invalid lang "${p}"`,
33
+ [ERR_FILTER_ENOENT]: (p) => `Filter: field does not exist "${p}"`,
34
+ [ERR_FILTER_INVALID_LANG]: (p) => `Filter: invalid lang "${p}"`,
35
+ [ERR_FILTER_OP_ENOENT]: (p) => `Filter: invalid operator "${p}"`,
15
36
  };
16
37
  export const validateType = (db, def, type) => {
17
38
  const r = db.schemaTypesParsed[type];
@@ -25,12 +46,59 @@ export const validateType = (db, def, type) => {
25
46
  }
26
47
  return r;
27
48
  };
49
+ export const filterOperatorDoesNotExist = (def, field) => {
50
+ def.errors.push({
51
+ code: ERR_FILTER_OP_ENOENT,
52
+ payload: field,
53
+ });
54
+ };
55
+ export const filterInvalidLang = (def, field) => {
56
+ def.errors.push({
57
+ code: ERR_FILTER_INVALID_LANG,
58
+ payload: field,
59
+ });
60
+ };
61
+ export const filterFieldDoesNotExist = (def, field) => {
62
+ def.errors.push({
63
+ code: ERR_FILTER_ENOENT,
64
+ payload: field,
65
+ });
66
+ };
28
67
  export const includeDoesNotExist = (def, field) => {
29
68
  def.errors.push({
30
69
  code: ERR_INCLUDE_ENOENT,
31
70
  payload: field,
32
71
  });
33
72
  };
73
+ export const includeLangDoesNotExist = (def, field) => {
74
+ def.errors.push({
75
+ code: ERR_INCLUDE_INVALID_LANG,
76
+ payload: field,
77
+ });
78
+ };
79
+ export const validateAlias = (alias, path, def) => {
80
+ const schema = def.schema;
81
+ for (const k in alias) {
82
+ if (typeof alias[k] === 'string') {
83
+ const p = path.join('.') + k;
84
+ const prop = schema.props[p];
85
+ if (prop.typeIndex === ALIAS) {
86
+ return { def: prop, value: alias[k] };
87
+ }
88
+ }
89
+ else if (typeof alias[k] === 'object') {
90
+ const propDef = validateAlias(alias[k], [...path, k], def);
91
+ if (propDef) {
92
+ return propDef;
93
+ }
94
+ }
95
+ }
96
+ def.errors.push({
97
+ code: ERR_TARGET_INVAL_ALIAS,
98
+ payload: alias,
99
+ });
100
+ return { value: '', def: EMPTY_ALIAS_PROP_DEF };
101
+ };
34
102
  export const validateId = (def, id) => {
35
103
  if (typeof id != 'number' || id == 0 || id > MAX_ID) {
36
104
  def.errors.push({
@@ -92,6 +160,15 @@ export const handleErrors = (def) => {
92
160
  throw err;
93
161
  }
94
162
  };
163
+ export const EMPTY_ALIAS_PROP_DEF = {
164
+ prop: 1,
165
+ typeIndex: ALIAS,
166
+ __isPropDef: true,
167
+ separate: true,
168
+ len: 0,
169
+ start: 0,
170
+ path: ['ERROR_ALIAS'],
171
+ };
95
172
  export const EMPTY_SCHEMA_DEF = {
96
173
  type: '_error',
97
174
  cnt: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/db",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",