@revealui/core 0.5.2 → 0.5.4

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 CHANGED
@@ -145,6 +145,20 @@ pnpm test
145
145
  pnpm dev
146
146
  ```
147
147
 
148
+ ## When to Use This
149
+
150
+ - You're building a content-driven app and need collections, admin UI, and CRUD out of the box
151
+ - You need RBAC/ABAC access control, GDPR compliance, or feature gating by license tier
152
+ - You want a rich text editor (Lexical) integrated with your CMS
153
+ - **Not** for standalone UI components — use `@revealui/presentation`
154
+ - **Not** for raw database queries — use `@revealui/db` directly
155
+
156
+ ## JOSHUA Alignment
157
+
158
+ - **Sovereign**: Self-hosted CMS engine — no SaaS dependency for content management, auth, or storage
159
+ - **Unified**: One `buildConfig()` call wires collections, globals, plugins, security, and feature gates into a single configuration
160
+ - **Adaptive**: Plugin system and tier-based feature gating let the platform evolve without breaking existing deployments
161
+
148
162
  ## Related
149
163
 
150
164
  - [Contracts Package](../contracts/README.md) — Zod schemas and TypeScript types
@@ -1 +1 @@
1
- {"version":3,"file":"query-cache.d.ts","sourceRoot":"","sources":["../../src/cache/query-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-cache.d.ts","sourceRoot":"","sources":["../../src/cache/query-cache.ts"],"names":[],"mappings":"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"}
@@ -50,8 +50,18 @@ class QueryCache {
50
50
  return deleted;
51
51
  }
52
52
  keys(pattern) {
53
- const regex = new RegExp(pattern.replace('*', '.*'));
54
- return Array.from(this.cache.keys()).filter((key) => regex.test(key));
53
+ const startsWild = pattern.startsWith('*');
54
+ const endsWild = pattern.endsWith('*');
55
+ const core = pattern.slice(startsWild ? 1 : 0, endsWild ? -1 : undefined);
56
+ return Array.from(this.cache.keys()).filter((key) => {
57
+ if (startsWild && endsWild)
58
+ return key.includes(core);
59
+ if (startsWild)
60
+ return key.endsWith(core);
61
+ if (endsWild)
62
+ return key.startsWith(core);
63
+ return key === core;
64
+ });
55
65
  }
56
66
  clear() {
57
67
  this.cache.clear();
@@ -3,5 +3,5 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import Head from 'next/head';
4
4
  import { ServerFunctionProvider } from './context/ServerFunctionContext.js';
5
5
  export function RootLayout({ children, serverFunction }) {
6
- return (_jsxs("html", { lang: "en", children: [_jsxs(Head, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "RevealUI Admin" })] }), _jsx("body", { className: "antialiased", children: _jsx(ServerFunctionProvider, { serverFunction: serverFunction, children: _jsx("div", { id: "revealui-admin", className: "min-h-screen", children: children }) }) })] }));
6
+ return (_jsxs("html", { lang: "en", children: [_jsxs(Head, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "RevealUI Admin" })] }), _jsx("body", { className: "antialiased", children: _jsx(ServerFunctionProvider, { serverFunction: serverFunction, children: _jsx("main", { id: "revealui-admin", className: "min-h-screen", children: children }) }) })] }));
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sqlAdapter.d.ts","sourceRoot":"","sources":["../../../src/collections/operations/sqlAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACvE,CAAC;AAgBF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/C;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAIpF;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAKjF;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAKrF"}
1
+ {"version":3,"file":"sqlAdapter.d.ts","sourceRoot":"","sources":["../../../src/collections/operations/sqlAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACvE,CAAC;AA6BF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/C;AAkBD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAIpF;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAKjF;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAKrF"}
@@ -9,21 +9,53 @@
9
9
  * redesign the collection storage layer toward typed tables instead.
10
10
  */
11
11
  /** Only lowercase alphanumeric, hyphens, and underscores (1-63 chars, PostgreSQL identifier limit). */
12
- const VALID_SLUG = /^[a-z][a-z0-9_-]{0,62}$/;
12
+ function isValidSlug(s) {
13
+ if (s.length < 1 || s.length > 63)
14
+ return false;
15
+ // First char must be lowercase letter
16
+ const first = s.charCodeAt(0);
17
+ if (first < 97 || first > 122)
18
+ return false;
19
+ for (let i = 1; i < s.length; i++) {
20
+ const c = s.charCodeAt(i);
21
+ const isLower = c >= 97 && c <= 122;
22
+ const isDigit = c >= 48 && c <= 57;
23
+ // underscore = 95, hyphen = 45
24
+ if (!(isLower || isDigit || c === 95 || c === 45))
25
+ return false;
26
+ }
27
+ return true;
28
+ }
13
29
  export function validateSlug(slug) {
14
- if (!VALID_SLUG.test(slug)) {
30
+ if (!isValidSlug(slug)) {
15
31
  throw new Error(`Invalid collection slug: "${slug}". Slugs must start with a lowercase letter and contain only lowercase alphanumeric characters, hyphens, and underscores (max 63 chars).`);
16
32
  }
17
33
  }
18
34
  /** Only lowercase alphanumeric and underscores (PostgreSQL column name safe). */
19
- const VALID_COLUMN = /^[a-z_][a-z0-9_]{0,62}$/;
35
+ function isValidColumnName(s) {
36
+ if (s.length < 1 || s.length > 63)
37
+ return false;
38
+ // First char must be lowercase letter or underscore
39
+ const first = s.charCodeAt(0);
40
+ const firstIsLower = first >= 97 && first <= 122;
41
+ if (!(firstIsLower || first === 95))
42
+ return false;
43
+ for (let i = 1; i < s.length; i++) {
44
+ const c = s.charCodeAt(i);
45
+ const isLower = c >= 97 && c <= 122;
46
+ const isDigit = c >= 48 && c <= 57;
47
+ if (!(isLower || isDigit || c === 95))
48
+ return false;
49
+ }
50
+ return true;
51
+ }
20
52
  export function validateColumnName(column) {
21
- if (!VALID_COLUMN.test(column)) {
53
+ if (!isValidColumnName(column)) {
22
54
  throw new Error(`Invalid column name: "${column}". Column names must start with a lowercase letter or underscore and contain only lowercase alphanumeric characters and underscores.`);
23
55
  }
24
56
  }
25
57
  export function escapeIdentifier(identifier) {
26
- return identifier.replace(/"/g, '""');
58
+ return identifier.split('"').join('""');
27
59
  }
28
60
  export function collectionTable(configSlug) {
29
61
  validateSlug(configSlug);
@@ -11,9 +11,9 @@
11
11
  import { type LicenseTier } from './license.js';
12
12
  /** All gated features in RevealUI */
13
13
  export interface FeatureFlags {
14
- /** Local AI inference via BitNet — available at all tiers (no API key needed) */
14
+ /** Local AI inference via Inference Snaps or BitNet — available at all tiers (no API key needed) */
15
15
  aiLocal: boolean;
16
- /** Cloud AI agent system (Pro: 1 provider, Enterprise: all providers) */
16
+ /** AI agent system local + cloud via RevealUI harness (Pro+) */
17
17
  ai: boolean;
18
18
  /** AI memory system — working + episodic + vector (Max: basic, Enterprise: full) */
19
19
  aiMemory: boolean;
@@ -27,14 +27,10 @@ export interface FeatureFlags {
27
27
  whiteLabel: boolean;
28
28
  /** SSO/SAML authentication (planned — not yet implemented) */
29
29
  sso: boolean;
30
- /** BYOK server-side key storage (Max+) */
31
- byokServerSide: boolean;
32
- /** Multi-provider AI (Max+: 2 providers, Enterprise: all providers) */
33
- aiMultiProvider: boolean;
30
+ /** Open-model inference configuration — snaps, BitNet, harness (Max+) */
31
+ aiInference: boolean;
34
32
  /** Audit logging and compliance trail */
35
33
  auditLog: boolean;
36
- /** AI sampling for free users — limited cloud tasks via platform key */
37
- aiSampling: boolean;
38
34
  /** Full real-time sync with conflict resolution */
39
35
  advancedSync: boolean;
40
36
  /** Monitoring dashboard */
@@ -43,7 +39,7 @@ export interface FeatureFlags {
43
39
  customDomain: boolean;
44
40
  /** Analytics and conversion tracking */
45
41
  analytics: boolean;
46
- /** RevVault desktop app — Tauri companion for encrypted secret management (Pro+) */
42
+ /** RevVault desktop app — Tauri native AI experience for encrypted secret management (Pro+) */
47
43
  vaultDesktop: boolean;
48
44
  /** RevVault rotation engine — automated credential lifecycle (Pro+) */
49
45
  vaultRotation: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,EAAE,EAAE,OAAO,CAAC;IACZ,oFAAoF;IACpF,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,GAAG,EAAE,OAAO,CAAC;IACb,0CAA0C;IAC1C,cAAc,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,oFAAoF;IACpF,YAAY,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,cAAc,EAAE,OAAO,CAAC;CACzB;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,YAAY,CAY1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,OAAO,CAMrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAmBlE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,WAAW,CAExE;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,oGAAoG;IACpG,OAAO,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,EAAE,EAAE,OAAO,CAAC;IACZ,oFAAoF;IACpF,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,GAAG,EAAE,OAAO,CAAC;IACb,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,+FAA+F;IAC/F,YAAY,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,cAAc,EAAE,OAAO,CAAC;CACzB;AA0BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,YAAY,CAY1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,OAAO,CAMrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAmBlE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,WAAW,CAExE;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/features.js CHANGED
@@ -13,7 +13,6 @@ import { isLicensed } from './license.js';
13
13
  const featureTierMap = {
14
14
  aiLocal: 'free',
15
15
  ai: 'pro',
16
- aiSampling: 'free',
17
16
  mcp: 'pro',
18
17
  payments: 'pro',
19
18
  advancedSync: 'pro',
@@ -21,8 +20,7 @@ const featureTierMap = {
21
20
  customDomain: 'pro',
22
21
  analytics: 'pro',
23
22
  aiMemory: 'max',
24
- byokServerSide: 'max',
25
- aiMultiProvider: 'max',
23
+ aiInference: 'max',
26
24
  auditLog: 'max',
27
25
  multiTenant: 'enterprise',
28
26
  // NOTE: whiteLabel and sso are planned but not yet implemented.
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalOperations.d.ts","sourceRoot":"","sources":["../../src/globals/GlobalOperations.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EAEd,MAAM,mBAAmB,CAAC;AAG3B;;;;GAIG;AACH,qBAAa,cAAc;IACzB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,EAAE,EAAE;QACF,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;KACvE,GAAG,IAAI,CAAC;gBAGP,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE;QACF,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;KACvE,GAAG,IAAI;IAMJ,IAAI,CACR,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,mBAAmB,EAAE,YAAY,CAAC;QACpD,GAAG,CAAC,EAAE,aAAa,CAAC;KAChB,GACL,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsG3B,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CAqElF"}
1
+ {"version":3,"file":"GlobalOperations.d.ts","sourceRoot":"","sources":["../../src/globals/GlobalOperations.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EAEd,MAAM,mBAAmB,CAAC;AAG3B;;;;GAIG;AACH,qBAAa,cAAc;IACzB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,EAAE,EAAE;QACF,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;KACvE,GAAG,IAAI,CAAC;gBAGP,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE;QACF,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;KACvE,GAAG,IAAI;IAMJ,IAAI,CACR,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,mBAAmB,EAAE,YAAY,CAAC;QACpD,GAAG,CAAC,EAAE,aAAa,CAAC;KAChB,GACL,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAwG3B,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CAqElF"}
@@ -1,4 +1,4 @@
1
- import { validateColumnName, validateSlug } from '../collections/operations/sqlAdapter.js';
1
+ import { escapeIdentifier, validateColumnName, validateSlug, } from '../collections/operations/sqlAdapter.js';
2
2
  import { afterRead } from '../fields/hooks/afterRead/index.js';
3
3
  import { getRelationshipFields } from '../relationships/analyzer.js';
4
4
  import { flattenResult } from '../utils/flattenResult.js';
@@ -22,7 +22,10 @@ export class RevealUIGlobal {
22
22
  }
23
23
  if (this.db?.query) {
24
24
  const slug = this.config.slug;
25
- if (!/^[a-z][a-z0-9_-]{0,62}$/.test(slug)) {
25
+ try {
26
+ validateSlug(slug);
27
+ }
28
+ catch {
26
29
  throw new Error(`Invalid global slug: "${slug}". Must be lowercase alphanumeric with hyphens/underscores.`);
27
30
  }
28
31
  const tableName = `global_${slug}`;
@@ -101,7 +104,10 @@ export class RevealUIGlobal {
101
104
  const { data } = options;
102
105
  if (this.db?.query) {
103
106
  const slug = this.config.slug;
104
- if (!/^[a-z][a-z0-9_-]{0,62}$/.test(slug)) {
107
+ try {
108
+ validateSlug(slug);
109
+ }
110
+ catch {
105
111
  throw new Error(`Invalid global slug: "${slug}". Must be lowercase alphanumeric with hyphens/underscores.`);
106
112
  }
107
113
  const tableName = `global_${slug}`;
@@ -114,9 +120,7 @@ export class RevealUIGlobal {
114
120
  const keys = Object.keys(data);
115
121
  for (const key of keys)
116
122
  validateColumnName(key);
117
- const setClause = keys
118
- .map((key, i) => `"${key.replace(/"/g, '""')}" = $${i + 1}`)
119
- .join(', ');
123
+ const setClause = keys.map((key, i) => `"${escapeIdentifier(key)}" = $${i + 1}`).join(', ');
120
124
  const values = keys.map((key) => {
121
125
  const value = data[key];
122
126
  // Serialize non-primitive values to JSON strings for SQLite compatibility
@@ -147,7 +151,7 @@ export class RevealUIGlobal {
147
151
  }
148
152
  return value;
149
153
  });
150
- const query = `INSERT INTO "${tableName}" (id, ${columns.map((c) => `"${c.replace(/"/g, '""')}"`).join(', ')}) VALUES ($1, ${placeholders})`;
154
+ const query = `INSERT INTO "${tableName}" (id, ${columns.map((c) => `"${escapeIdentifier(c)}"`).join(', ')}) VALUES ($1, ${placeholders})`;
151
155
  await this.db.query(query, [id, ...values]);
152
156
  }
153
157
  const updatedDoc = await this.find();
package/dist/license.d.ts CHANGED
@@ -11,8 +11,8 @@ export type LicenseTier = 'free' | 'pro' | 'max' | 'enterprise';
11
11
  /** Decoded license payload schema */
12
12
  declare const licensePayloadSchema: z.ZodObject<{
13
13
  tier: z.ZodEnum<{
14
- max: "max";
15
14
  pro: "pro";
15
+ max: "max";
16
16
  enterprise: "enterprise";
17
17
  }>;
18
18
  customerId: z.ZodString;
@@ -78,12 +78,6 @@ export declare function getMaxUsers(): number;
78
78
  * Track B metering: free=1K, pro=10K, max=50K, enterprise=unlimited.
79
79
  */
80
80
  export declare function getMaxAgentTasks(): number;
81
- /**
82
- * Returns the maximum free-tier AI sampling tasks per billing cycle.
83
- * Free users get 50 cloud AI tasks/month via platform Groq key.
84
- * Paid users return 0 (they use full quota via getMaxAgentTasks instead).
85
- */
86
- export declare function getMaxFreemiumTasks(): number;
87
81
  /**
88
82
  * Generates a signed license key JWT.
89
83
  * This is a server-only function — requires the private key.
@@ -1 +1 @@
1
- {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;AAEhE,qCAAqC;AACrC,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;iBAqBxB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AASD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAElF;AAoCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAkC9D;AAaD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAG5C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAGzD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,WAAW,GAAG,OAAO,CAqB7D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,KAAK,CAAC,EAC5C,UAAU,EAAE,MAAM,EAClB,gBAAgB,GAAE,MAAM,GAAG,IAAyB,EACpD,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
1
+ {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;AAEhE,qCAAqC;AACrC,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;iBAqBxB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AASD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAElF;AAoCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAkC9D;AAaD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAG5C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAGzD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,WAAW,GAAG,OAAO,CAqB7D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,KAAK,CAAC,EAC5C,UAAU,EAAE,MAAM,EAClB,gBAAgB,GAAE,MAAM,GAAG,IAAyB,EACpD,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
package/dist/license.js CHANGED
@@ -228,17 +228,6 @@ export function getMaxAgentTasks() {
228
228
  return 10_000;
229
229
  return 1_000;
230
230
  }
231
- /**
232
- * Returns the maximum free-tier AI sampling tasks per billing cycle.
233
- * Free users get 50 cloud AI tasks/month via platform Groq key.
234
- * Paid users return 0 (they use full quota via getMaxAgentTasks instead).
235
- */
236
- export function getMaxFreemiumTasks() {
237
- evictStaleCache();
238
- if (cachedState.tier === 'free')
239
- return 50;
240
- return 0;
241
- }
242
231
  /**
243
232
  * Generates a signed license key JWT.
244
233
  * This is a server-only function — requires the private key.
@@ -1 +1 @@
1
- {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/observability/health-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,SAAS,CAAsB;IAEvC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIlC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAoD1C;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACH,SAAS,IAAI,MAAM;CAGpB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,mBAA0B,CAAC;AAEnD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CA4BnF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,gBAAgB,GAAE,MAAW,GAAG,WAAW,CAwClF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,GAAE,MAAW,GAAG,WAAW,CA4ChF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,GAAE,MAAY,GAAG,WAAW,CAuC3F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,EACzC,QAAQ,GAAE,OAAe,GACxB,WAAW,CAMb;AAED;;GAEG;AACH,wBAAgB,oBAAoB,UACjB,OAAO,CAAC,QAAQ,CAAC,CAanC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,UACpB,OAAO,CAAC,QAAQ,CAAC,CA2BnC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,UACzB,QAAQ,CAqBpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,GAAE,MAAc,EAC1B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC9C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAsBzB"}
1
+ {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/observability/health-check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,SAAS,CAAsB;IAEvC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIlC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAoD1C;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACH,SAAS,IAAI,MAAM;CAGpB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,mBAA0B,CAAC;AAEnD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAmCnF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,gBAAgB,GAAE,MAAW,GAAG,WAAW,CAwClF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,GAAE,MAAW,GAAG,WAAW,CA4ChF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,GAAE,MAAY,GAAG,WAAW,CAuC3F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,EACzC,QAAQ,GAAE,OAAe,GACxB,WAAW,CAMb;AAED;;GAEG;AACH,wBAAgB,oBAAoB,UACjB,OAAO,CAAC,QAAQ,CAAC,CAanC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,UACpB,OAAO,CAAC,QAAQ,CAAC,CA2BnC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,UACzB,QAAQ,CAqBpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,GAAE,MAAc,EAC1B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC9C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAsBzB"}
@@ -115,9 +115,15 @@ export function createDatabaseHealthCheck(queryFn) {
115
115
  };
116
116
  }
117
117
  catch (error) {
118
+ // Surface the root cause — Drizzle wraps Neon errors with "Failed query: ..."
119
+ // but the actual HTTP/connection error is in .cause
120
+ let message = error instanceof Error ? error.message : 'Database connection failed';
121
+ if (error instanceof Error && error.cause instanceof Error) {
122
+ message = `${message} | cause: ${error.cause.message}`;
123
+ }
118
124
  return {
119
125
  status: 'unhealthy',
120
- message: error instanceof Error ? error.message : 'Database connection failed',
126
+ message,
121
127
  };
122
128
  }
123
129
  },
@@ -1 +1 @@
1
- {"version":3,"file":"queryBuilder.d.ts","sourceRoot":"","sources":["../../src/queries/queryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAExE;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,SAAS,EAC3D,MAAM,EAAE,OAAO,EAAE,EACjB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA0NR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,EAAE,CAoEjE"}
1
+ {"version":3,"file":"queryBuilder.d.ts","sourceRoot":"","sources":["../../src/queries/queryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAExE;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAevD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,SAAS,EAC3D,MAAM,EAAE,OAAO,EAAE,EACjB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA0NR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,EAAE,CAoEjE"}
@@ -1,3 +1,16 @@
1
+ /** Escape SQL LIKE wildcards (%, _, \) in user input */
2
+ function escapeLikeWildcards(value) {
3
+ let result = '';
4
+ for (const ch of value) {
5
+ if (ch === '%' || ch === '_' || ch === '\\') {
6
+ result += `\\${ch}`;
7
+ }
8
+ else {
9
+ result += ch;
10
+ }
11
+ }
12
+ return result;
13
+ }
1
14
  /**
2
15
  * Builds a WHERE clause from a RevealWhere query object.
3
16
  * Supports nested AND/OR conditions and various operators.
@@ -27,7 +40,7 @@ export function buildWhereClause(where, params, options = {}) {
27
40
  if (!quoteFields)
28
41
  return field;
29
42
  // Escape embedded double quotes to prevent SQL injection via identifier breakout
30
- const escaped = field.replace(/"/g, '""');
43
+ const escaped = field.split('"').join('""');
31
44
  return `"${escaped}"`;
32
45
  };
33
46
  const whereWithGroups = where;
@@ -149,7 +162,7 @@ export function buildWhereClause(where, params, options = {}) {
149
162
  if ('contains' in condition && typeof condition.contains === 'string') {
150
163
  const placeholder = getPlaceholder();
151
164
  // Escape LIKE wildcards (% and _) in user input to prevent wildcard injection
152
- const escaped = condition.contains.replace(/[%_\\]/g, '\\$&');
165
+ const escaped = escapeLikeWildcards(condition.contains);
153
166
  params.push(`%${escaped}%`);
154
167
  conditions.push(`${quotedField} LIKE ${placeholder} ESCAPE '\\'`);
155
168
  }
@@ -168,7 +181,7 @@ export function buildWhereClause(where, params, options = {}) {
168
181
  // like (escape wildcards to prevent blind LIKE probing)
169
182
  if ('like' in condition && typeof condition.like === 'string') {
170
183
  const placeholder = getPlaceholder();
171
- const escaped = condition.like.replace(/[%_\\]/g, '\\$&');
184
+ const escaped = escapeLikeWildcards(condition.like);
172
185
  params.push(escaped);
173
186
  conditions.push(`${quotedField} LIKE ${placeholder} ESCAPE '\\'`);
174
187
  }
@@ -219,7 +232,7 @@ export function extractWhereValues(where) {
219
232
  break;
220
233
  case 'contains':
221
234
  if (typeof value === 'string') {
222
- const escaped = value.replace(/[%_\\]/g, '\\$&');
235
+ const escaped = escapeLikeWildcards(value);
223
236
  values.push(`%${escaped}%`);
224
237
  }
225
238
  break;
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@revealui/core",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
+ "description": "CMS engine, REST API, auth, rich text, admin UI, and plugins for RevealUI",
4
5
  "license": "MIT",
5
6
  "dependencies": {
6
7
  "@electric-sql/pglite": "^0.4.2",
@@ -23,11 +24,11 @@
23
24
  "pg": "^8.18.0",
24
25
  "yjs": "^13.6.29",
25
26
  "zod": "^4.3.6",
26
- "@revealui/security": "0.2.3",
27
- "@revealui/utils": "0.3.0",
28
- "@revealui/contracts": "1.3.3",
29
- "@revealui/resilience": "0.2.0",
30
- "@revealui/cache": "0.1.0"
27
+ "@revealui/cache": "0.1.2",
28
+ "@revealui/contracts": "1.3.5",
29
+ "@revealui/resilience": "0.2.2",
30
+ "@revealui/security": "0.2.5",
31
+ "@revealui/utils": "0.3.2"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/json-schema": "^7.0.15",
@@ -212,6 +213,10 @@
212
213
  "types": "./dist/observability/logger.d.ts",
213
214
  "import": "./dist/observability/logger.js"
214
215
  },
216
+ "./observability/alerts": {
217
+ "types": "./dist/observability/alerts.d.ts",
218
+ "import": "./dist/observability/alerts.js"
219
+ },
215
220
  "./utils/cache": {
216
221
  "types": "./dist/utils/cache.d.ts",
217
222
  "import": "./dist/utils/cache.js"