@boltstore/utils 0.5.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 (62) hide show
  1. package/README.md +61 -0
  2. package/dist/auth-types.d.ts +138 -0
  3. package/dist/auth-types.d.ts.map +1 -0
  4. package/dist/auth-types.js +4 -0
  5. package/dist/auth-types.js.map +1 -0
  6. package/dist/constants.d.ts +123 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +144 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/filter/compiler.d.ts +14 -0
  11. package/dist/filter/compiler.d.ts.map +1 -0
  12. package/dist/filter/compiler.js +93 -0
  13. package/dist/filter/compiler.js.map +1 -0
  14. package/dist/filter/parser.d.ts +15 -0
  15. package/dist/filter/parser.d.ts.map +1 -0
  16. package/dist/filter/parser.js +134 -0
  17. package/dist/filter/parser.js.map +1 -0
  18. package/dist/filter/query.d.ts +13 -0
  19. package/dist/filter/query.d.ts.map +1 -0
  20. package/dist/filter/query.js +20 -0
  21. package/dist/filter/query.js.map +1 -0
  22. package/dist/filter/tokenizer.d.ts +17 -0
  23. package/dist/filter/tokenizer.d.ts.map +1 -0
  24. package/dist/filter/tokenizer.js +133 -0
  25. package/dist/filter/tokenizer.js.map +1 -0
  26. package/dist/filter/types.d.ts +24 -0
  27. package/dist/filter/types.d.ts.map +1 -0
  28. package/dist/filter/types.js +3 -0
  29. package/dist/filter/types.js.map +1 -0
  30. package/dist/filter.d.ts +7 -0
  31. package/dist/filter.d.ts.map +1 -0
  32. package/dist/filter.js +12 -0
  33. package/dist/filter.js.map +1 -0
  34. package/dist/index.d.ts +13 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +16 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/realtime-types.d.ts +90 -0
  39. package/dist/realtime-types.d.ts.map +1 -0
  40. package/dist/realtime-types.js +4 -0
  41. package/dist/realtime-types.js.map +1 -0
  42. package/dist/schema.d.ts +612 -0
  43. package/dist/schema.d.ts.map +1 -0
  44. package/dist/schema.js +209 -0
  45. package/dist/schema.js.map +1 -0
  46. package/dist/storage-types.d.ts +117 -0
  47. package/dist/storage-types.d.ts.map +1 -0
  48. package/dist/storage-types.js +4 -0
  49. package/dist/storage-types.js.map +1 -0
  50. package/dist/sync-types.d.ts +136 -0
  51. package/dist/sync-types.d.ts.map +1 -0
  52. package/dist/sync-types.js +4 -0
  53. package/dist/sync-types.js.map +1 -0
  54. package/dist/types.d.ts +164 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +3 -0
  57. package/dist/types.js.map +1 -0
  58. package/dist/validation.d.ts +30 -0
  59. package/dist/validation.d.ts.map +1 -0
  60. package/dist/validation.js +259 -0
  61. package/dist/validation.js.map +1 -0
  62. package/package.json +74 -0
@@ -0,0 +1,134 @@
1
+ // ── Filter Parser ──
2
+ // Turns a token stream into a structured filter expression tree.
3
+ import { OPERATOR_MAP, parseFilterValue, tokenize } from "./tokenizer";
4
+ class FilterParser {
5
+ tokens;
6
+ pos;
7
+ constructor(tokens) {
8
+ this.tokens = tokens;
9
+ this.pos = 0;
10
+ }
11
+ peek() {
12
+ return this.tokens[this.pos];
13
+ }
14
+ consume() {
15
+ return this.tokens[this.pos++];
16
+ }
17
+ expect(type) {
18
+ const token = this.consume();
19
+ if (!token || token.type !== type) {
20
+ throw new Error(`Expected token type "${type}" but got "${token?.type}" (${token?.value})`);
21
+ }
22
+ return token;
23
+ }
24
+ parse() {
25
+ if (this.tokens.length === 0)
26
+ return undefined;
27
+ return this.parseGroup();
28
+ }
29
+ parseGroup() {
30
+ const conditions = [];
31
+ let operator = "and";
32
+ while (this.pos < this.tokens.length) {
33
+ const token = this.peek();
34
+ if (!token)
35
+ break;
36
+ if (token.type === "paren_close") {
37
+ this.consume();
38
+ break;
39
+ }
40
+ if (token.type === "paren_open") {
41
+ this.consume(); // skip '('
42
+ const subgroup = this.parseGroup();
43
+ conditions.push(subgroup);
44
+ continue;
45
+ }
46
+ if (token.type === "logical") {
47
+ operator = token.value.toLowerCase();
48
+ this.consume();
49
+ continue;
50
+ }
51
+ if (token.type === "field") {
52
+ const condition = this.parseCondition();
53
+ if (condition) {
54
+ conditions.push(condition);
55
+ continue;
56
+ }
57
+ }
58
+ this.consume();
59
+ }
60
+ return { operator, conditions };
61
+ }
62
+ parseCondition() {
63
+ const field = this.consume();
64
+ const opToken = this.peek();
65
+ if (!field || !opToken || opToken.type !== "operator")
66
+ return null;
67
+ this.consume(); // consume operator
68
+ let valueToken = this.peek();
69
+ // Handle IN operator with parens: field ?= (val1, val2, ...)
70
+ if ((opToken.value === "?=" || opToken.value === "?!=") &&
71
+ valueToken?.type === "paren_open") {
72
+ this.consume(); // skip '('
73
+ const values = [];
74
+ while (this.pos < this.tokens.length) {
75
+ const t = this.peek();
76
+ if (t?.type === "paren_close") {
77
+ this.consume();
78
+ break;
79
+ }
80
+ if (t?.type === "value" || t?.type === "field") {
81
+ values.push(t.value);
82
+ }
83
+ this.consume();
84
+ }
85
+ return {
86
+ field: field.value,
87
+ operator: OPERATOR_MAP[opToken.value] ?? "eq",
88
+ value: values,
89
+ };
90
+ }
91
+ if (!valueToken || (valueToken.type !== "value" && valueToken.type !== "field")) {
92
+ return null;
93
+ }
94
+ this.consume(); // consume value
95
+ return {
96
+ field: field.value,
97
+ operator: OPERATOR_MAP[opToken.value] ?? "eq",
98
+ value: parseFilterValue(valueToken.value),
99
+ };
100
+ }
101
+ }
102
+ export function parseSort(sortStr) {
103
+ if (!sortStr)
104
+ return [];
105
+ return sortStr.split(",").map((s) => {
106
+ const trimmed = s.trim();
107
+ if (trimmed.startsWith("-")) {
108
+ return { field: trimmed.slice(1), direction: "desc" };
109
+ }
110
+ if (trimmed.startsWith("+")) {
111
+ return { field: trimmed.slice(1), direction: "asc" };
112
+ }
113
+ return { field: trimmed, direction: "asc" };
114
+ });
115
+ }
116
+ // ── Main Entry ──
117
+ /**
118
+ * Parse a filter string into a structured filter expression.
119
+ *
120
+ * @example
121
+ * parseFilter("status = 'active' && priority > 3")
122
+ * // => { operator: "and", conditions: [
123
+ * // { field: "status", operator: "eq", value: "active" },
124
+ * // { field: "priority", operator: "gt", value: 3 }
125
+ * // ]}
126
+ */
127
+ export function parseFilter(filterStr) {
128
+ if (!filterStr || !filterStr.trim())
129
+ return undefined;
130
+ const tokens = tokenize(filterStr.trim());
131
+ const parser = new FilterParser(tokens);
132
+ return parser.parse();
133
+ }
134
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/filter/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ParsedQuery } from "./types";
2
+ /**
3
+ * Parse URL query parameters into a structured query.
4
+ */
5
+ export declare function parseQuery(params: {
6
+ filter?: string;
7
+ sort?: string;
8
+ page?: string;
9
+ perPage?: string;
10
+ expand?: string;
11
+ search?: string;
12
+ }): ParsedQuery;
13
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/filter/query.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,WAAW,CAYd"}
@@ -0,0 +1,20 @@
1
+ // ── Query Parser ──
2
+ // Parses URL query parameters into a structured query object.
3
+ import { parseFilter } from "./parser";
4
+ import { parseSort } from "./parser";
5
+ /**
6
+ * Parse URL query parameters into a structured query.
7
+ */
8
+ export function parseQuery(params) {
9
+ const perPageRaw = params.perPage?.trim();
10
+ const perPageNum = perPageRaw ? parseInt(perPageRaw, 10) : 30;
11
+ return {
12
+ filter: params.filter ? parseFilter(params.filter) : undefined,
13
+ sort: parseSort(params.sort ?? ""),
14
+ page: Math.max(1, parseInt(params.page ?? "1", 10) || 1),
15
+ perPage: Math.min(200, Math.max(1, Number.isNaN(perPageNum) ? 30 : perPageNum)),
16
+ expand: params.expand ? params.expand.split(",").map((e) => e.trim()) : [],
17
+ search: params.search || undefined,
18
+ };
19
+ }
20
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/filter/query.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,8DAA8D;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAO1B;IACC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9D,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9D,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAClC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACxD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC/E,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1E,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,SAAS;KACnC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { FilterOperator } from "./types";
2
+ type TokenType = "paren_open" | "paren_close" | "operator" | "value" | "field" | "logical";
3
+ export interface Token {
4
+ type: TokenType;
5
+ value: string;
6
+ }
7
+ export declare const OPERATOR_MAP: Record<string, FilterOperator>;
8
+ /**
9
+ * Break a filter string into typed tokens.
10
+ */
11
+ export declare function tokenize(input: string): Token[];
12
+ /**
13
+ * Convert a raw token value to its typed equivalent.
14
+ */
15
+ export declare function parseFilterValue(raw: string): unknown;
16
+ export {};
17
+ //# sourceMappingURL=tokenizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/filter/tokenizer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,KAAK,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3F,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAWvD,CAAC;AAEF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAsG/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOrD"}
@@ -0,0 +1,133 @@
1
+ // ── Filter Tokenizer ──
2
+ // Converts a raw filter string into a sequence of typed tokens.
3
+ export const OPERATOR_MAP = {
4
+ "=": "eq",
5
+ "!=": "neq",
6
+ ">": "gt",
7
+ ">=": "gte",
8
+ "<": "lt",
9
+ "<=": "lte",
10
+ "~": "like",
11
+ "!~": "not_like",
12
+ "?=": "in",
13
+ "?!=": "not_in",
14
+ };
15
+ /**
16
+ * Break a filter string into typed tokens.
17
+ */
18
+ export function tokenize(input) {
19
+ const tokens = [];
20
+ let i = 0;
21
+ const len = input.length;
22
+ while (i < len) {
23
+ // Skip whitespace
24
+ if (/\s/.test(input[i])) {
25
+ i++;
26
+ continue;
27
+ }
28
+ // Parentheses
29
+ if (input[i] === "(") {
30
+ tokens.push({ type: "paren_open", value: "(" });
31
+ i++;
32
+ continue;
33
+ }
34
+ if (input[i] === ")") {
35
+ tokens.push({ type: "paren_close", value: ")" });
36
+ i++;
37
+ continue;
38
+ }
39
+ // Logical operators
40
+ if (input.slice(i, i + 3).toLowerCase() === "and") {
41
+ tokens.push({ type: "logical", value: "and" });
42
+ i += 3;
43
+ continue;
44
+ }
45
+ if (input.slice(i, i + 2).toLowerCase() === "or") {
46
+ tokens.push({ type: "logical", value: "or" });
47
+ i += 2;
48
+ continue;
49
+ }
50
+ if (input.slice(i, i + 2) === "&&") {
51
+ tokens.push({ type: "logical", value: "and" });
52
+ i += 2;
53
+ continue;
54
+ }
55
+ if (input.slice(i, i + 2) === "||") {
56
+ tokens.push({ type: "logical", value: "or" });
57
+ i += 2;
58
+ continue;
59
+ }
60
+ // Operators (multi-char first)
61
+ const multiCharOps = ["!=", ">=", "<=", "!~", "?=", "?!!="];
62
+ let matched = false;
63
+ for (const op of multiCharOps) {
64
+ if (input.slice(i, i + op.length) === op) {
65
+ tokens.push({ type: "operator", value: op });
66
+ i += op.length;
67
+ matched = true;
68
+ break;
69
+ }
70
+ }
71
+ if (matched)
72
+ continue;
73
+ // Single-char operators
74
+ if (["=", ">", "<", "~"].includes(input[i])) {
75
+ tokens.push({ type: "operator", value: input[i] });
76
+ i++;
77
+ continue;
78
+ }
79
+ // Single-quoted strings
80
+ if (input[i] === "'") {
81
+ i++; // skip opening quote
82
+ let val = "";
83
+ while (i < len && input[i] !== "'") {
84
+ if (input[i] === "\\" && i + 1 < len) {
85
+ i++;
86
+ val += input[i];
87
+ }
88
+ else {
89
+ val += input[i];
90
+ }
91
+ i++;
92
+ }
93
+ i++; // skip closing quote
94
+ tokens.push({ type: "value", value: val });
95
+ continue;
96
+ }
97
+ // Identifiers (field names) and unquoted values
98
+ let ident = "";
99
+ while (i < len && !/[\s()=!><~]/.test(input[i]) && input[i] !== "'") {
100
+ ident += input[i];
101
+ i++;
102
+ }
103
+ if (ident) {
104
+ if (/^-?\d+(\.\d+)?$/.test(ident)) {
105
+ tokens.push({ type: "value", value: ident });
106
+ }
107
+ else if (ident === "true" || ident === "false" || ident === "null") {
108
+ tokens.push({ type: "value", value: ident });
109
+ }
110
+ else {
111
+ tokens.push({ type: "field", value: ident });
112
+ }
113
+ }
114
+ }
115
+ return tokens;
116
+ }
117
+ /**
118
+ * Convert a raw token value to its typed equivalent.
119
+ */
120
+ export function parseFilterValue(raw) {
121
+ if (raw === "true")
122
+ return true;
123
+ if (raw === "false")
124
+ return false;
125
+ if (raw === "null")
126
+ return null;
127
+ if (/^-?\d+$/.test(raw))
128
+ return parseInt(raw, 10);
129
+ if (/^-?\d+\.\d+$/.test(raw))
130
+ return parseFloat(raw);
131
+ return raw;
132
+ }
133
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/filter/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type FilterOperator = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "like" | "not_like" | "in" | "not_in" | "between";
2
+ export type LogicalOperator = "and" | "or";
3
+ export interface FilterCondition {
4
+ field: string;
5
+ operator: FilterOperator;
6
+ value: unknown;
7
+ }
8
+ export interface FilterGroup {
9
+ operator: LogicalOperator;
10
+ conditions: Array<FilterCondition | FilterGroup>;
11
+ }
12
+ export interface SortClause {
13
+ field: string;
14
+ direction: "asc" | "desc";
15
+ }
16
+ export interface ParsedQuery {
17
+ filter?: FilterGroup;
18
+ sort: SortClause[];
19
+ page: number;
20
+ perPage: number;
21
+ expand: string[];
22
+ search?: string;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/filter/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,MAAM,GACN,UAAU,GACV,IAAI,GACJ,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,IAAI,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,KAAK,CAAC,eAAe,GAAG,WAAW,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,3 @@
1
+ // ── Filter Types ──
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/filter/types.ts"],"names":[],"mappings":"AAAA,qBAAqB"}
@@ -0,0 +1,7 @@
1
+ export type { FilterOperator, LogicalOperator, FilterCondition, FilterGroup, SortClause, ParsedQuery, } from "./filter/types";
2
+ export { parseFilter, parseSort } from "./filter/parser";
3
+ export { parseQuery } from "./filter/query";
4
+ export { filterToSQL, type CompiledSQL } from "./filter/compiler";
5
+ export { tokenize, parseFilterValue, OPERATOR_MAP } from "./filter/tokenizer";
6
+ export type { Token } from "./filter/tokenizer";
7
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAOA,YAAY,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGlE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/filter.js ADDED
@@ -0,0 +1,12 @@
1
+ // ── @boltstore/utils/filter ──
2
+ // Barrel re-export. Internal modules are split by responsibility:
3
+ // types.ts — AST node types
4
+ // tokenizer.ts — string → token stream
5
+ // parser.ts — token stream → AST
6
+ // compiler.ts — AST → SQL + params
7
+ export { parseFilter, parseSort } from "./filter/parser";
8
+ export { parseQuery } from "./filter/query";
9
+ export { filterToSQL } from "./filter/compiler";
10
+ // Re-export token internals for advanced use
11
+ export { tokenize, parseFilterValue, OPERATOR_MAP } from "./filter/tokenizer";
12
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,kEAAkE;AAClE,kCAAkC;AAClC,yCAAyC;AACzC,sCAAsC;AACtC,sCAAsC;AAWtC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAElE,6CAA6C;AAC7C,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,13 @@
1
+ export * from "./types";
2
+ export * from "./constants";
3
+ export * from "./auth-types";
4
+ export * from "./sync-types";
5
+ export * from "./realtime-types";
6
+ export * from "./storage-types";
7
+ export { validateField, validateRecord, isValidType, applyDefaults } from "./validation";
8
+ export type { ValidationError, ValidationResult } from "./validation";
9
+ export { parseFilter, parseQuery, filterToSQL } from "./filter";
10
+ export type { FilterOperator, LogicalOperator, FilterCondition, FilterGroup, SortClause, ParsedQuery, } from "./filter";
11
+ export { RecordSchema, CollectionSchema, UserSchema, JwtPayloadSchema, ApiResponseSchema, ErrorCodesSchema, allSchemas, } from "./schema";
12
+ export type { SchemaName } from "./schema";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAGhC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzF,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAChE,YAAY,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ // ── @boltstore/utils ──
2
+ // Convenience barrel export. For tree-shaking, import from submodules directly:
3
+ // import { JwtPayload } from "@boltstore/utils/auth-types";
4
+ export * from "./types";
5
+ export * from "./constants";
6
+ export * from "./auth-types";
7
+ export * from "./sync-types";
8
+ export * from "./realtime-types";
9
+ export * from "./storage-types";
10
+ // Validation (tree-shakeable if imported separately)
11
+ export { validateField, validateRecord, isValidType, applyDefaults } from "./validation";
12
+ // Filter parser (tree-shakeable if imported separately)
13
+ export { parseFilter, parseQuery, filterToSQL } from "./filter";
14
+ // JSON Schema exports
15
+ export { RecordSchema, CollectionSchema, UserSchema, JwtPayloadSchema, ApiResponseSchema, ErrorCodesSchema, allSchemas, } from "./schema";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,gFAAgF;AAChF,8DAA8D;AAE9D,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,qDAAqD;AACrD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGzF,wDAAwD;AACxD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAUhE,sBAAsB;AACtB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,GACX,MAAM,UAAU,CAAC"}
@@ -0,0 +1,90 @@
1
+ export type TopicType = "table" | "row" | "filter";
2
+ export interface RealtimeTopic {
3
+ type: TopicType;
4
+ applicationId: string;
5
+ collection: string;
6
+ /** For "row" type: the record ID */
7
+ rowId?: string;
8
+ /** For "filter" type: the filter hash */
9
+ filterHash?: string;
10
+ }
11
+ export type RealtimeEventType = "insert" | "update" | "delete";
12
+ export interface RealtimeEvent {
13
+ type: RealtimeEventType;
14
+ /** Collection the event is for */
15
+ collection: string;
16
+ /** The affected record */
17
+ record: Record<string, unknown>;
18
+ /** Server timestamp */
19
+ timestamp: string;
20
+ }
21
+ export type ClientMessageType = "subscribe" | "unsubscribe" | "catchup" | "ping";
22
+ export interface SubscribeMessage {
23
+ type: "subscribe";
24
+ /** Topic to subscribe to (e.g., "table:proj_123:todos") */
25
+ topic: string;
26
+ }
27
+ export interface UnsubscribeMessage {
28
+ type: "unsubscribe";
29
+ /** Topic to unsubscribe from */
30
+ topic: string;
31
+ }
32
+ export interface CatchupRequest {
33
+ type: "catchup";
34
+ /** Replay events since this ISO 8601 timestamp */
35
+ since: string;
36
+ }
37
+ export interface PingMessage {
38
+ type: "ping";
39
+ }
40
+ export type ServerMessageType = "event" | "subscribed" | "unsubscribed" | "error" | "pong" | "catchup_batch";
41
+ export interface SubscribedAck {
42
+ type: "subscribed";
43
+ topic: string;
44
+ }
45
+ export interface UnsubscribedAck {
46
+ type: "unsubscribed";
47
+ topic: string;
48
+ }
49
+ export interface RealtimeErrorMessage {
50
+ type: "error";
51
+ code: string;
52
+ message: string;
53
+ }
54
+ export interface PongMessage {
55
+ type: "pong";
56
+ }
57
+ export interface CatchupBatchMessage {
58
+ type: "catchup_batch";
59
+ events: RealtimeEvent[];
60
+ /** Server timestamp — client should use this as its new "since" value */
61
+ serverTimestamp: string;
62
+ }
63
+ export type ClientMessage = SubscribeMessage | UnsubscribeMessage | CatchupRequest | PingMessage;
64
+ export type ServerMessage = RealtimeEvent | SubscribedAck | UnsubscribedAck | RealtimeErrorMessage | PongMessage | CatchupBatchMessage;
65
+ export interface ActiveSubscription {
66
+ /** The WebSocket connection */
67
+ connectionId: string;
68
+ topic: string;
69
+ /** Parsed topic parts */
70
+ parsedTopic: RealtimeTopic;
71
+ /** Authenticated user context for RLS */
72
+ userId?: string;
73
+ userRole?: string;
74
+ /** JWT claims for RLS evaluation */
75
+ jwtClaims?: Record<string, unknown>;
76
+ subscribedAt: string;
77
+ }
78
+ export interface RealtimeConfig {
79
+ /** Maximum subscriptions per connection */
80
+ maxSubscriptions: number;
81
+ /** Heartbeat interval in seconds */
82
+ heartbeatInterval: number;
83
+ /** Idle timeout in seconds */
84
+ idleTimeout: number;
85
+ /** Maximum message payload size in bytes */
86
+ maxPayloadSize: number;
87
+ /** Enable per-message deflate compression */
88
+ compression: boolean;
89
+ }
90
+ //# sourceMappingURL=realtime-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-types.d.ts","sourceRoot":"","sources":["../src/realtime-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // ── Realtime / WebSocket Types ──
2
+ // Shared between server realtime engine and client SDK.
3
+ export {};
4
+ //# sourceMappingURL=realtime-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-types.js","sourceRoot":"","sources":["../src/realtime-types.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,wDAAwD"}