@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.
- package/README.md +61 -0
- package/dist/auth-types.d.ts +138 -0
- package/dist/auth-types.d.ts.map +1 -0
- package/dist/auth-types.js +4 -0
- package/dist/auth-types.js.map +1 -0
- package/dist/constants.d.ts +123 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +144 -0
- package/dist/constants.js.map +1 -0
- package/dist/filter/compiler.d.ts +14 -0
- package/dist/filter/compiler.d.ts.map +1 -0
- package/dist/filter/compiler.js +93 -0
- package/dist/filter/compiler.js.map +1 -0
- package/dist/filter/parser.d.ts +15 -0
- package/dist/filter/parser.d.ts.map +1 -0
- package/dist/filter/parser.js +134 -0
- package/dist/filter/parser.js.map +1 -0
- package/dist/filter/query.d.ts +13 -0
- package/dist/filter/query.d.ts.map +1 -0
- package/dist/filter/query.js +20 -0
- package/dist/filter/query.js.map +1 -0
- package/dist/filter/tokenizer.d.ts +17 -0
- package/dist/filter/tokenizer.d.ts.map +1 -0
- package/dist/filter/tokenizer.js +133 -0
- package/dist/filter/tokenizer.js.map +1 -0
- package/dist/filter/types.d.ts +24 -0
- package/dist/filter/types.d.ts.map +1 -0
- package/dist/filter/types.js +3 -0
- package/dist/filter/types.js.map +1 -0
- package/dist/filter.d.ts +7 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +12 -0
- package/dist/filter.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/realtime-types.d.ts +90 -0
- package/dist/realtime-types.d.ts.map +1 -0
- package/dist/realtime-types.js +4 -0
- package/dist/realtime-types.js.map +1 -0
- package/dist/schema.d.ts +612 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +209 -0
- package/dist/schema.js.map +1 -0
- package/dist/storage-types.d.ts +117 -0
- package/dist/storage-types.d.ts.map +1 -0
- package/dist/storage-types.js +4 -0
- package/dist/storage-types.js.map +1 -0
- package/dist/sync-types.d.ts +136 -0
- package/dist/sync-types.d.ts.map +1 -0
- package/dist/sync-types.js +4 -0
- package/dist/sync-types.js.map +1 -0
- package/dist/types.d.ts +164 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +30 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +259 -0
- package/dist/validation.js.map +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/filter/types.ts"],"names":[],"mappings":"AAAA,qBAAqB"}
|
package/dist/filter.d.ts
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-types.js","sourceRoot":"","sources":["../src/realtime-types.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,wDAAwD"}
|