@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
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @boltstore/shared
2
+
3
+ Shared TypeScript types, validation, and utilities for Boltstore. Zero dependencies. Tree-shakeable.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @boltstore/shared
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Tree-shakeable imports (recommended)
14
+
15
+ ```ts
16
+ // Only auth types are bundled
17
+ import { JwtPayload, ApiKeyClaims } from "@boltstore/shared/auth-types";
18
+
19
+ // Only validation functions are bundled
20
+ import { validateField, validateRecord } from "@boltstore/shared/validation";
21
+
22
+ // Only filter parser is bundled
23
+ import { parseFilter, parseQuery } from "@boltstore/shared/filter";
24
+
25
+ // Only sync types
26
+ import { VersionVector, MergeResult } from "@boltstore/shared/sync-types";
27
+
28
+ // Only constants
29
+ import { ErrorCodes, Limits } from "@boltstore/shared/constants";
30
+ ```
31
+
32
+ ### Convenience barrel (imports everything)
33
+
34
+ ```ts
35
+ import {
36
+ JwtPayload,
37
+ MergeResult,
38
+ validateField,
39
+ parseFilter,
40
+ ErrorCodes,
41
+ } from "@boltstore/shared";
42
+ ```
43
+
44
+ ## Exports
45
+
46
+ | Entrypoint | Contents |
47
+ |-------------------------|----------------------------------------------------|
48
+ | `@boltstore/shared` | Barrel (all exports) |
49
+ | `./types` | Record, Collection, User, Application, ApiKey types |
50
+ | `./validation` | Field validators (email, url, required, etc.) |
51
+ | `./filter` | Filter expression parser & SQL compiler |
52
+ | `./sync-types` | Sync protocol types (VersionVector, LamportClock) |
53
+ | `./realtime-types` | Realtime/WebSocket message types |
54
+ | `./auth-types` | JWT, OAuth2, API key types |
55
+ | `./storage-types` | File storage types (FileInfo, S3Config) |
56
+ | `./constants` | Error codes, limits, defaults |
57
+ | `./schema` | JSON Schema exports for cross-language SDKs |
58
+
59
+ ## License
60
+
61
+ MIT
@@ -0,0 +1,138 @@
1
+ import type { UserRole, ApiKeyScope } from "./types";
2
+ export interface JwtHeader {
3
+ alg: "HS256";
4
+ typ: "JWT";
5
+ }
6
+ export interface JwtPayload {
7
+ /** Subject — user ID */
8
+ sub: string;
9
+ /** Issuer — always "boltstore" */
10
+ iss: string;
11
+ /** Audience — the application ID (or "system" for admin tokens) */
12
+ aud: string;
13
+ /** Issued at (Unix timestamp) */
14
+ iat: number;
15
+ /** Expiration (Unix timestamp) */
16
+ exp: number;
17
+ /** User role — default "user" for end users, custom roles allowed */
18
+ role: UserRole;
19
+ /** User email */
20
+ email?: string;
21
+ /** Application ID this token is scoped to */
22
+ application: string;
23
+ /** Token type */
24
+ type: "access" | "refresh";
25
+ /** Unique token ID (jti) */
26
+ jti: string;
27
+ /** Whether this is an admin token or a user token */
28
+ userType: "admin" | "user";
29
+ }
30
+ export interface RefreshToken {
31
+ id: string;
32
+ userId: string;
33
+ /** SHA-256 hash of the token */
34
+ tokenHash: string;
35
+ applicationId: string;
36
+ expiresAt: string;
37
+ createdAt: string;
38
+ /** Track token family for rotation detection */
39
+ family: string;
40
+ /** Incremented on each rotation */
41
+ rotationCount: number;
42
+ /** "admin" or "user" — determines which table to validate against */
43
+ userType: "admin" | "user";
44
+ }
45
+ export interface ApiKeyClaims {
46
+ /** API key record ID */
47
+ sub: string;
48
+ /** "apikey" */
49
+ type: "apikey";
50
+ scope: ApiKeyScope;
51
+ applicationId: string;
52
+ /** API key name (for audit logging) */
53
+ name: string;
54
+ }
55
+ export interface AuthResult {
56
+ type: "jwt" | "apikey";
57
+ /** Authenticated user ID (for JWT auth) */
58
+ userId?: string;
59
+ /** JWT claims */
60
+ jwt?: JwtPayload;
61
+ /** API key claims */
62
+ apiKey?: ApiKeyClaims;
63
+ }
64
+ export interface LoginRequest {
65
+ email: string;
66
+ password: string;
67
+ /** Duration in seconds for the session */
68
+ sessionDuration?: number;
69
+ }
70
+ export interface LoginResponse {
71
+ accessToken: string;
72
+ refreshToken: string;
73
+ user: {
74
+ id: string;
75
+ email: string;
76
+ role: UserRole;
77
+ name?: string;
78
+ };
79
+ expiresAt: number;
80
+ }
81
+ export interface RegisterRequest {
82
+ email: string;
83
+ password: string;
84
+ passwordConfirm: string;
85
+ name?: string;
86
+ }
87
+ export interface RefreshRequest {
88
+ refreshToken: string;
89
+ }
90
+ export interface RefreshResponse {
91
+ accessToken: string;
92
+ refreshToken: string;
93
+ expiresAt: number;
94
+ }
95
+ export type OAuth2Provider = "google" | "github";
96
+ export interface OAuth2Config {
97
+ provider: OAuth2Provider;
98
+ clientId: string;
99
+ clientSecret: string;
100
+ redirectUri: string;
101
+ /** URL to the provider's authorization endpoint */
102
+ authUrl: string;
103
+ /** URL to the provider's token endpoint */
104
+ tokenUrl: string;
105
+ /** URL to the provider's userinfo endpoint */
106
+ userInfoUrl: string;
107
+ /** Additional scopes to request */
108
+ scopes?: string[];
109
+ }
110
+ export interface OAuth2TokenResponse {
111
+ access_token: string;
112
+ token_type: string;
113
+ expires_in?: number;
114
+ refresh_token?: string;
115
+ scope?: string;
116
+ }
117
+ export interface OAuth2UserInfo {
118
+ id: string;
119
+ email: string;
120
+ name?: string;
121
+ avatar?: string;
122
+ }
123
+ export interface EmailVerification {
124
+ id: string;
125
+ userId: string;
126
+ token: string;
127
+ expiresAt: string;
128
+ createdAt: string;
129
+ }
130
+ export interface PasswordReset {
131
+ id: string;
132
+ userId: string;
133
+ token: string;
134
+ expiresAt: string;
135
+ createdAt: string;
136
+ used: boolean;
137
+ }
138
+ //# sourceMappingURL=auth-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-types.d.ts","sourceRoot":"","sources":["../src/auth-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // ── Authentication & Authorization Types ──
2
+ // Shared between server and client.
3
+ export {};
4
+ //# sourceMappingURL=auth-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-types.js","sourceRoot":"","sources":["../src/auth-types.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,oCAAoC"}
@@ -0,0 +1,123 @@
1
+ export declare const ErrorCodes: {
2
+ readonly UNAUTHORIZED: "unauthorized";
3
+ readonly FORBIDDEN: "forbidden";
4
+ readonly TOKEN_EXPIRED: "token_expired";
5
+ readonly INVALID_TOKEN: "invalid_token";
6
+ readonly INVALID_CREDENTIALS: "invalid_credentials";
7
+ readonly EMAIL_NOT_VERIFIED: "email_not_verified";
8
+ readonly EMAIL_ALREADY_EXISTS: "email_already_exists";
9
+ readonly COLLECTION_NOT_FOUND: "collection_not_found";
10
+ readonly RECORD_NOT_FOUND: "record_not_found";
11
+ readonly VALIDATION_ERROR: "validation_error";
12
+ readonly DUPLICATE_ENTRY: "duplicate_entry";
13
+ readonly RLS_FORBIDDEN: "rls_forbidden";
14
+ readonly RLS_NO_POLICY: "rls_no_policy";
15
+ readonly FILE_TOO_LARGE: "file_too_large";
16
+ readonly INVALID_FILE_TYPE: "invalid_file_type";
17
+ readonly FILE_NOT_FOUND: "file_not_found";
18
+ readonly STORAGE_ERROR: "storage_error";
19
+ readonly RATE_LIMITED: "rate_limited";
20
+ readonly INTERNAL_ERROR: "internal_error";
21
+ readonly NOT_IMPLEMENTED: "not_implemented";
22
+ readonly SERVICE_UNAVAILABLE: "service_unavailable";
23
+ readonly SYNC_CONFLICT: "sync_conflict";
24
+ readonly SYNC_REJECTED: "sync_rejected";
25
+ readonly SYNC_CLOCK_SKEW: "sync_clock_skew";
26
+ readonly APPLICATION_NOT_FOUND: "application_not_found";
27
+ readonly APPLICATION_LIMIT_REACHED: "application_limit_reached";
28
+ readonly BACKUP_FAILED: "backup_failed";
29
+ readonly BACKUP_NOT_FOUND: "backup_not_found";
30
+ readonly RESTORE_FAILED: "restore_failed";
31
+ };
32
+ export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
33
+ export declare const FieldTypes: {
34
+ readonly TEXT: "text";
35
+ readonly NUMBER: "number";
36
+ readonly BOOL: "bool";
37
+ readonly DATE: "date";
38
+ readonly JSON: "json";
39
+ readonly FILE: "file";
40
+ readonly RELATION: "relation";
41
+ readonly EMAIL: "email";
42
+ readonly URL: "url";
43
+ readonly SELECT: "select";
44
+ };
45
+ export declare const UserRoles: {
46
+ readonly USER: "user";
47
+ };
48
+ export declare const AdminRoles: {
49
+ readonly ADMIN: "admin";
50
+ };
51
+ export declare const ApiKeyScopes: {
52
+ readonly READ_ONLY: "read-only";
53
+ readonly READ_WRITE: "read-write";
54
+ readonly ADMIN: "admin";
55
+ };
56
+ export declare const SyncStrategies: {
57
+ readonly SERVER_WINS: "server-wins";
58
+ readonly LAST_WRITE_WINS: "last-write-wins";
59
+ readonly CLIENT_WINS: "client-wins";
60
+ readonly CUSTOM: "custom";
61
+ };
62
+ export declare const Limits: {
63
+ /** Maximum records per page */
64
+ readonly MAX_PER_PAGE: 200;
65
+ /** Default records per page */
66
+ readonly DEFAULT_PER_PAGE: 30;
67
+ /** Maximum filter query length */
68
+ readonly MAX_FILTER_LENGTH: 1000;
69
+ /** Maximum collection name length */
70
+ readonly MAX_COLLECTION_NAME: 64;
71
+ /** Maximum field name length */
72
+ readonly MAX_FIELD_NAME: 64;
73
+ /** Maximum fields per collection */
74
+ readonly MAX_FIELDS_PER_COLLECTION: 100;
75
+ /** Maximum file upload size (50MB) */
76
+ readonly MAX_FILE_SIZE: number;
77
+ /** Multipart upload threshold (5MB) */
78
+ readonly MULTIPART_THRESHOLD: number;
79
+ /** Maximum WebSocket message size (16MB) */
80
+ readonly MAX_WS_MESSAGE_SIZE: number;
81
+ };
82
+ export declare const Auth: {
83
+ /** Access token TTL in seconds (15 minutes) */
84
+ readonly ACCESS_TOKEN_TTL: number;
85
+ /** Refresh token TTL in seconds (7 days) */
86
+ readonly REFRESH_TOKEN_TTL: number;
87
+ /** API key prefix for identification */
88
+ readonly API_KEY_PREFIX: "bs_";
89
+ /** bcrypt cost factor */
90
+ readonly BCRYPT_COST: 12;
91
+ };
92
+ export declare const ServerDefaults: {
93
+ readonly DEFAULT_PORT: 8090;
94
+ readonly DEFAULT_HOST: "127.0.0.1";
95
+ /** Graceful shutdown timeout in ms */
96
+ readonly SHUTDOWN_TIMEOUT: 10000;
97
+ /** WebSocket idle timeout in seconds */
98
+ readonly WS_IDLE_TIMEOUT: 120;
99
+ /** Rate limit window in seconds */
100
+ readonly RATE_LIMIT_WINDOW: 60;
101
+ /** Default rate limit per window */
102
+ readonly RATE_LIMIT_MAX: 300;
103
+ /** Backup interval in hours */
104
+ readonly BACKUP_INTERVAL_HOURS: 6;
105
+ /** Full backup interval in days */
106
+ readonly FULL_BACKUP_INTERVAL_DAYS: 1;
107
+ /** Log retention in days */
108
+ readonly LOG_RETENTION_DAYS: 30;
109
+ };
110
+ export declare const HttpStatus: {
111
+ readonly OK: 200;
112
+ readonly CREATED: 201;
113
+ readonly NO_CONTENT: 204;
114
+ readonly BAD_REQUEST: 400;
115
+ readonly UNAUTHORIZED: 401;
116
+ readonly FORBIDDEN: 403;
117
+ readonly NOT_FOUND: 404;
118
+ readonly CONFLICT: 409;
119
+ readonly TOO_MANY_REQUESTS: 429;
120
+ readonly INTERNAL_ERROR: 500;
121
+ readonly SERVICE_UNAVAILABLE: 503;
122
+ };
123
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Cb,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAIrE,eAAO,MAAM,UAAU;;;;;;;;;;;CAWb,CAAC;AAKX,eAAO,MAAM,SAAS;;CAEZ,CAAC;AAIX,eAAO,MAAM,UAAU;;CAEb,CAAC;AAIX,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AAIX,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAIX,eAAO,MAAM,MAAM;IACjB,+BAA+B;;IAE/B,+BAA+B;;IAE/B,kCAAkC;;IAElC,qCAAqC;;IAErC,gCAAgC;;IAEhC,oCAAoC;;IAEpC,sCAAsC;;IAEtC,uCAAuC;;IAEvC,4CAA4C;;CAEpC,CAAC;AAIX,eAAO,MAAM,IAAI;IACf,+CAA+C;;IAE/C,4CAA4C;;IAE5C,wCAAwC;;IAExC,yBAAyB;;CAEjB,CAAC;AAIX,eAAO,MAAM,cAAc;;;IAGzB,sCAAsC;;IAEtC,wCAAwC;;IAExC,mCAAmC;;IAEnC,oCAAoC;;IAEpC,+BAA+B;;IAE/B,mCAAmC;;IAEnC,4BAA4B;;CAEpB,CAAC;AAIX,eAAO,MAAM,UAAU;;;;;;;;;;;;CAYb,CAAC"}
@@ -0,0 +1,144 @@
1
+ // ── Boltstore Constants ──
2
+ // Shared between server and client. Zero dependencies.
3
+ // ── Error Codes ──
4
+ export const ErrorCodes = {
5
+ // Auth
6
+ UNAUTHORIZED: "unauthorized",
7
+ FORBIDDEN: "forbidden",
8
+ TOKEN_EXPIRED: "token_expired",
9
+ INVALID_TOKEN: "invalid_token",
10
+ INVALID_CREDENTIALS: "invalid_credentials",
11
+ EMAIL_NOT_VERIFIED: "email_not_verified",
12
+ EMAIL_ALREADY_EXISTS: "email_already_exists",
13
+ // Collections & Records
14
+ COLLECTION_NOT_FOUND: "collection_not_found",
15
+ RECORD_NOT_FOUND: "record_not_found",
16
+ VALIDATION_ERROR: "validation_error",
17
+ DUPLICATE_ENTRY: "duplicate_entry",
18
+ // RLS
19
+ RLS_FORBIDDEN: "rls_forbidden",
20
+ RLS_NO_POLICY: "rls_no_policy",
21
+ // Storage
22
+ FILE_TOO_LARGE: "file_too_large",
23
+ INVALID_FILE_TYPE: "invalid_file_type",
24
+ FILE_NOT_FOUND: "file_not_found",
25
+ STORAGE_ERROR: "storage_error",
26
+ // Rate Limiting
27
+ RATE_LIMITED: "rate_limited",
28
+ // Server
29
+ INTERNAL_ERROR: "internal_error",
30
+ NOT_IMPLEMENTED: "not_implemented",
31
+ SERVICE_UNAVAILABLE: "service_unavailable",
32
+ // Sync
33
+ SYNC_CONFLICT: "sync_conflict",
34
+ SYNC_REJECTED: "sync_rejected",
35
+ SYNC_CLOCK_SKEW: "sync_clock_skew",
36
+ // Application
37
+ APPLICATION_NOT_FOUND: "application_not_found",
38
+ APPLICATION_LIMIT_REACHED: "application_limit_reached",
39
+ // Backup
40
+ BACKUP_FAILED: "backup_failed",
41
+ BACKUP_NOT_FOUND: "backup_not_found",
42
+ RESTORE_FAILED: "restore_failed",
43
+ };
44
+ // ── Field Type Enum ──
45
+ export const FieldTypes = {
46
+ TEXT: "text",
47
+ NUMBER: "number",
48
+ BOOL: "bool",
49
+ DATE: "date",
50
+ JSON: "json",
51
+ FILE: "file",
52
+ RELATION: "relation",
53
+ EMAIL: "email",
54
+ URL: "url",
55
+ SELECT: "select",
56
+ };
57
+ // ── User Roles ──
58
+ // End-user default role. Developers define custom roles via RLS policies.
59
+ export const UserRoles = {
60
+ USER: "user",
61
+ };
62
+ // ── Admin Roles ──
63
+ export const AdminRoles = {
64
+ ADMIN: "admin",
65
+ };
66
+ // ── API Key Scopes ──
67
+ export const ApiKeyScopes = {
68
+ READ_ONLY: "read-only",
69
+ READ_WRITE: "read-write",
70
+ ADMIN: "admin",
71
+ };
72
+ // ── Sync Strategies ──
73
+ export const SyncStrategies = {
74
+ SERVER_WINS: "server-wins",
75
+ LAST_WRITE_WINS: "last-write-wins",
76
+ CLIENT_WINS: "client-wins",
77
+ CUSTOM: "custom",
78
+ };
79
+ // ── Limits ──
80
+ export const Limits = {
81
+ /** Maximum records per page */
82
+ MAX_PER_PAGE: 200,
83
+ /** Default records per page */
84
+ DEFAULT_PER_PAGE: 30,
85
+ /** Maximum filter query length */
86
+ MAX_FILTER_LENGTH: 1000,
87
+ /** Maximum collection name length */
88
+ MAX_COLLECTION_NAME: 64,
89
+ /** Maximum field name length */
90
+ MAX_FIELD_NAME: 64,
91
+ /** Maximum fields per collection */
92
+ MAX_FIELDS_PER_COLLECTION: 100,
93
+ /** Maximum file upload size (50MB) */
94
+ MAX_FILE_SIZE: 50 * 1024 * 1024,
95
+ /** Multipart upload threshold (5MB) */
96
+ MULTIPART_THRESHOLD: 5 * 1024 * 1024,
97
+ /** Maximum WebSocket message size (16MB) */
98
+ MAX_WS_MESSAGE_SIZE: 16 * 1024 * 1024,
99
+ };
100
+ // ── Auth ──
101
+ export const Auth = {
102
+ /** Access token TTL in seconds (15 minutes) */
103
+ ACCESS_TOKEN_TTL: 15 * 60,
104
+ /** Refresh token TTL in seconds (7 days) */
105
+ REFRESH_TOKEN_TTL: 7 * 24 * 60 * 60,
106
+ /** API key prefix for identification */
107
+ API_KEY_PREFIX: "bs_",
108
+ /** bcrypt cost factor */
109
+ BCRYPT_COST: 12,
110
+ };
111
+ // ── Server ──
112
+ export const ServerDefaults = {
113
+ DEFAULT_PORT: 8090,
114
+ DEFAULT_HOST: "127.0.0.1",
115
+ /** Graceful shutdown timeout in ms */
116
+ SHUTDOWN_TIMEOUT: 10_000,
117
+ /** WebSocket idle timeout in seconds */
118
+ WS_IDLE_TIMEOUT: 120,
119
+ /** Rate limit window in seconds */
120
+ RATE_LIMIT_WINDOW: 60,
121
+ /** Default rate limit per window */
122
+ RATE_LIMIT_MAX: 300,
123
+ /** Backup interval in hours */
124
+ BACKUP_INTERVAL_HOURS: 6,
125
+ /** Full backup interval in days */
126
+ FULL_BACKUP_INTERVAL_DAYS: 1,
127
+ /** Log retention in days */
128
+ LOG_RETENTION_DAYS: 30,
129
+ };
130
+ // ── HTTP Status Codes ──
131
+ export const HttpStatus = {
132
+ OK: 200,
133
+ CREATED: 201,
134
+ NO_CONTENT: 204,
135
+ BAD_REQUEST: 400,
136
+ UNAUTHORIZED: 401,
137
+ FORBIDDEN: 403,
138
+ NOT_FOUND: 404,
139
+ CONFLICT: 409,
140
+ TOO_MANY_REQUESTS: 429,
141
+ INTERNAL_ERROR: 500,
142
+ SERVICE_UNAVAILABLE: 503,
143
+ };
144
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FilterCondition, FilterGroup } from "./types";
2
+ export interface CompiledSQL {
3
+ sql: string;
4
+ params: unknown[];
5
+ }
6
+ /**
7
+ * Compile a filter expression into a SQL WHERE clause with parameters.
8
+ *
9
+ * @example
10
+ * filterToSQL(parseFilter("status = 'active'"))
11
+ * // => { sql: "status = $0", params: ["active"] }
12
+ */
13
+ export declare function filterToSQL(filter: FilterGroup | FilterCondition | undefined, paramPrefix?: string): CompiledSQL;
14
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/filter/compiler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,WAAW,GAAG,eAAe,GAAG,SAAS,EACjD,WAAW,CAAC,EAAE,MAAM,GACnB,WAAW,CAiFb"}
@@ -0,0 +1,93 @@
1
+ // ── Filter → SQL Compiler ──
2
+ // Converts a parsed filter expression tree into a SQL WHERE clause.
3
+ // Uses parameterized queries — callers must handle value binding.
4
+ /**
5
+ * Compile a filter expression into a SQL WHERE clause with parameters.
6
+ *
7
+ * @example
8
+ * filterToSQL(parseFilter("status = 'active'"))
9
+ * // => { sql: "status = $0", params: ["active"] }
10
+ */
11
+ export function filterToSQL(filter, paramPrefix) {
12
+ if (!filter)
13
+ return { sql: "1=1", params: [] };
14
+ const params = [];
15
+ let counter = 0;
16
+ const p = () => `${paramPrefix ?? "$"}${counter++}`;
17
+ function buildCondition(c) {
18
+ const { field, operator, value } = c;
19
+ switch (operator) {
20
+ case "eq": {
21
+ if (value === null)
22
+ return `${field} IS NULL`;
23
+ params.push(value);
24
+ return `${field} = ${p()}`;
25
+ }
26
+ case "neq": {
27
+ if (value === null)
28
+ return `${field} IS NOT NULL`;
29
+ params.push(value);
30
+ return `${field} != ${p()}`;
31
+ }
32
+ case "gt":
33
+ params.push(value);
34
+ return `${field} > ${p()}`;
35
+ case "gte":
36
+ params.push(value);
37
+ return `${field} >= ${p()}`;
38
+ case "lt":
39
+ params.push(value);
40
+ return `${field} < ${p()}`;
41
+ case "lte":
42
+ params.push(value);
43
+ return `${field} <= ${p()}`;
44
+ case "like":
45
+ params.push(value);
46
+ return `${field} LIKE ${p()}`;
47
+ case "not_like":
48
+ params.push(value);
49
+ return `${field} NOT LIKE ${p()}`;
50
+ case "in": {
51
+ const values = Array.isArray(value) ? value : [value];
52
+ const placeholders = values.map((v, i) => {
53
+ params.push(values[i]);
54
+ return p();
55
+ });
56
+ return `${field} IN (${placeholders.join(", ")})`;
57
+ }
58
+ case "not_in": {
59
+ const values = Array.isArray(value) ? value : [value];
60
+ const placeholders = values.map((v, i) => {
61
+ params.push(values[i]);
62
+ return p();
63
+ });
64
+ return `${field} NOT IN (${placeholders.join(", ")})`;
65
+ }
66
+ default:
67
+ params.push(value);
68
+ return `${field} = ${p()}`;
69
+ }
70
+ }
71
+ function buildGroup(g) {
72
+ if (g.conditions.length === 0)
73
+ return "1=1";
74
+ const parts = g.conditions.map((c) => {
75
+ if ("operator" in c && ("field" in c || "conditions" in c)) {
76
+ if ("conditions" in c)
77
+ return buildGroup(c);
78
+ return buildCondition(c);
79
+ }
80
+ return "1=1";
81
+ });
82
+ return `(${parts.join(` ${g.operator.toUpperCase()} `)})`;
83
+ }
84
+ let sql;
85
+ if ("conditions" in filter) {
86
+ sql = buildGroup(filter);
87
+ }
88
+ else {
89
+ sql = buildCondition(filter);
90
+ }
91
+ return { sql, params };
92
+ }
93
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/filter/compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { FilterGroup } from "./types";
2
+ import type { SortClause } from "./types";
3
+ export declare function parseSort(sortStr: string): SortClause[];
4
+ /**
5
+ * Parse a filter string into a structured filter expression.
6
+ *
7
+ * @example
8
+ * parseFilter("status = 'active' && priority > 3")
9
+ * // => { operator: "and", conditions: [
10
+ * // { field: "status", operator: "eq", value: "active" },
11
+ * // { field: "priority", operator: "gt", value: 3 }
12
+ * // ]}
13
+ */
14
+ export declare function parseFilter(filterStr: string): FilterGroup | undefined;
15
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/filter/parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,WAAW,EAAmB,MAAM,SAAS,CAAC;AA8H7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAYvD;AAID;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAKtE"}