@object-ui/core 0.3.0 → 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 (90) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +8 -0
  3. package/dist/actions/ActionRunner.d.ts +40 -0
  4. package/dist/actions/ActionRunner.js +160 -0
  5. package/dist/actions/index.d.ts +8 -0
  6. package/dist/actions/index.js +8 -0
  7. package/dist/adapters/index.d.ts +7 -0
  8. package/dist/adapters/index.js +10 -0
  9. package/dist/builder/schema-builder.d.ts +7 -0
  10. package/dist/builder/schema-builder.js +4 -6
  11. package/dist/evaluator/ExpressionCache.d.ts +101 -0
  12. package/dist/evaluator/ExpressionCache.js +135 -0
  13. package/dist/evaluator/ExpressionContext.d.ts +51 -0
  14. package/dist/evaluator/ExpressionContext.js +110 -0
  15. package/dist/evaluator/ExpressionEvaluator.d.ts +117 -0
  16. package/dist/evaluator/ExpressionEvaluator.js +220 -0
  17. package/dist/evaluator/index.d.ts +10 -0
  18. package/dist/evaluator/index.js +10 -0
  19. package/dist/index.d.ts +17 -4
  20. package/dist/index.js +16 -5
  21. package/dist/query/index.d.ts +6 -0
  22. package/dist/query/index.js +6 -0
  23. package/dist/query/query-ast.d.ts +32 -0
  24. package/dist/query/query-ast.js +268 -0
  25. package/dist/registry/PluginScopeImpl.d.ts +80 -0
  26. package/dist/registry/PluginScopeImpl.js +243 -0
  27. package/dist/registry/PluginSystem.d.ts +66 -0
  28. package/dist/registry/PluginSystem.js +142 -0
  29. package/dist/registry/Registry.d.ts +80 -4
  30. package/dist/registry/Registry.js +119 -7
  31. package/dist/types/index.d.ts +7 -0
  32. package/dist/types/index.js +7 -0
  33. package/dist/utils/filter-converter.d.ts +57 -0
  34. package/dist/utils/filter-converter.js +100 -0
  35. package/dist/validation/index.d.ts +9 -0
  36. package/dist/validation/index.js +9 -0
  37. package/dist/validation/schema-validator.d.ts +7 -0
  38. package/dist/validation/schema-validator.js +4 -6
  39. package/dist/validation/validation-engine.d.ts +70 -0
  40. package/dist/validation/validation-engine.js +363 -0
  41. package/dist/validation/validators/index.d.ts +16 -0
  42. package/dist/validation/validators/index.js +16 -0
  43. package/dist/validation/validators/object-validation-engine.d.ts +118 -0
  44. package/dist/validation/validators/object-validation-engine.js +538 -0
  45. package/package.json +26 -7
  46. package/src/actions/ActionRunner.ts +195 -0
  47. package/src/actions/index.ts +9 -0
  48. package/src/adapters/README.md +180 -0
  49. package/src/adapters/index.ts +10 -0
  50. package/src/builder/schema-builder.ts +8 -0
  51. package/src/evaluator/ExpressionCache.ts +192 -0
  52. package/src/evaluator/ExpressionContext.ts +118 -0
  53. package/src/evaluator/ExpressionEvaluator.ts +267 -0
  54. package/src/evaluator/__tests__/ExpressionCache.test.ts +135 -0
  55. package/src/evaluator/__tests__/ExpressionEvaluator.test.ts +101 -0
  56. package/src/evaluator/index.ts +11 -0
  57. package/src/index.test.ts +8 -0
  58. package/src/index.ts +18 -5
  59. package/src/query/__tests__/query-ast.test.ts +211 -0
  60. package/src/query/__tests__/window-functions.test.ts +275 -0
  61. package/src/query/index.ts +7 -0
  62. package/src/query/query-ast.ts +341 -0
  63. package/src/registry/PluginScopeImpl.ts +259 -0
  64. package/src/registry/PluginSystem.ts +161 -0
  65. package/src/registry/Registry.ts +133 -8
  66. package/src/registry/__tests__/PluginSystem.test.ts +226 -0
  67. package/src/registry/__tests__/Registry.test.ts +293 -0
  68. package/src/registry/__tests__/plugin-scope-integration.test.ts +283 -0
  69. package/src/types/index.ts +8 -0
  70. package/src/utils/__tests__/filter-converter.test.ts +118 -0
  71. package/src/utils/filter-converter.ts +133 -0
  72. package/src/validation/__tests__/object-validation-engine.test.ts +567 -0
  73. package/src/validation/__tests__/validation-engine.test.ts +102 -0
  74. package/src/validation/index.ts +10 -0
  75. package/src/validation/schema-validator.ts +8 -0
  76. package/src/validation/validation-engine.ts +461 -0
  77. package/src/validation/validators/index.ts +25 -0
  78. package/src/validation/validators/object-validation-engine.ts +722 -0
  79. package/tsconfig.tsbuildinfo +1 -1
  80. package/vitest.config.ts +2 -0
  81. package/src/builder/schema-builder.d.ts +0 -287
  82. package/src/builder/schema-builder.js +0 -505
  83. package/src/index.d.ts +0 -4
  84. package/src/index.js +0 -7
  85. package/src/registry/Registry.d.ts +0 -49
  86. package/src/registry/Registry.js +0 -36
  87. package/src/types/index.d.ts +0 -12
  88. package/src/types/index.js +0 -1
  89. package/src/validation/schema-validator.d.ts +0 -87
  90. package/src/validation/schema-validator.js +0 -280
@@ -0,0 +1,117 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * @object-ui/core - Expression Evaluator
10
+ *
11
+ * Evaluates template string expressions like ${data.amount > 1000} for dynamic UI behavior.
12
+ * Supports variable substitution, comparison operators, and basic JavaScript expressions.
13
+ *
14
+ * @module evaluator
15
+ * @packageDocumentation
16
+ */
17
+ import { ExpressionContext } from './ExpressionContext.js';
18
+ import { ExpressionCache } from './ExpressionCache.js';
19
+ /**
20
+ * Options for expression evaluation
21
+ */
22
+ export interface EvaluationOptions {
23
+ /**
24
+ * Default value to return if evaluation fails
25
+ */
26
+ defaultValue?: any;
27
+ /**
28
+ * Whether to throw errors on evaluation failure
29
+ * @default false
30
+ */
31
+ throwOnError?: boolean;
32
+ /**
33
+ * Whether to sanitize the expression before evaluation
34
+ * @default true
35
+ */
36
+ sanitize?: boolean;
37
+ }
38
+ /**
39
+ * Expression evaluator for dynamic UI expressions
40
+ */
41
+ export declare class ExpressionEvaluator {
42
+ private context;
43
+ private cache;
44
+ constructor(context?: ExpressionContext | Record<string, any>, cache?: ExpressionCache);
45
+ /**
46
+ * Evaluate a string that may contain template expressions like ${...}
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const evaluator = new ExpressionEvaluator({ data: { amount: 1500 } });
51
+ * evaluator.evaluate('${data.amount > 1000}'); // Returns: true
52
+ * evaluator.evaluate('Amount is ${data.amount}'); // Returns: "Amount is 1500"
53
+ * ```
54
+ */
55
+ evaluate(expression: string | boolean | number | null | undefined, options?: EvaluationOptions): any;
56
+ /**
57
+ * Evaluate a single expression (without ${} wrapper)
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * evaluator.evaluateExpression('data.amount > 1000'); // Returns: true
62
+ * evaluator.evaluateExpression('data.user.name'); // Returns: "John"
63
+ * ```
64
+ */
65
+ evaluateExpression(expression: string, options?: {
66
+ sanitize?: boolean;
67
+ }): any;
68
+ /**
69
+ * Check if expression contains potentially dangerous code
70
+ */
71
+ private isDangerous;
72
+ /**
73
+ * Evaluate a conditional expression and return boolean
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * evaluator.evaluateCondition('${data.age >= 18}'); // Returns: true/false
78
+ * ```
79
+ */
80
+ evaluateCondition(condition: string | boolean | undefined, options?: EvaluationOptions): boolean;
81
+ /**
82
+ * Update the context with new data
83
+ */
84
+ updateContext(data: Record<string, any>): void;
85
+ /**
86
+ * Get the current context
87
+ */
88
+ getContext(): ExpressionContext;
89
+ /**
90
+ * Create a new evaluator with additional context data
91
+ */
92
+ withContext(data: Record<string, any>): ExpressionEvaluator;
93
+ /**
94
+ * Get cache statistics (useful for debugging and optimization)
95
+ */
96
+ getCacheStats(): {
97
+ size: number;
98
+ maxSize: number;
99
+ totalHits: number;
100
+ entries: Array<{
101
+ expression: string;
102
+ hitCount: number;
103
+ }>;
104
+ };
105
+ /**
106
+ * Clear the expression cache
107
+ */
108
+ clearCache(): void;
109
+ }
110
+ /**
111
+ * Convenience function to quickly evaluate an expression
112
+ */
113
+ export declare function evaluateExpression(expression: string | boolean | number | null | undefined, context?: Record<string, any>, options?: EvaluationOptions): any;
114
+ /**
115
+ * Convenience function to evaluate a condition
116
+ */
117
+ export declare function evaluateCondition(condition: string | boolean | undefined, context?: Record<string, any>): boolean;
@@ -0,0 +1,220 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * @object-ui/core - Expression Evaluator
10
+ *
11
+ * Evaluates template string expressions like ${data.amount > 1000} for dynamic UI behavior.
12
+ * Supports variable substitution, comparison operators, and basic JavaScript expressions.
13
+ *
14
+ * @module evaluator
15
+ * @packageDocumentation
16
+ */
17
+ import { ExpressionContext } from './ExpressionContext.js';
18
+ import { ExpressionCache } from './ExpressionCache.js';
19
+ /**
20
+ * Expression evaluator for dynamic UI expressions
21
+ */
22
+ export class ExpressionEvaluator {
23
+ constructor(context, cache) {
24
+ Object.defineProperty(this, "context", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: void 0
29
+ });
30
+ Object.defineProperty(this, "cache", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: void 0
35
+ });
36
+ if (context instanceof ExpressionContext) {
37
+ this.context = context;
38
+ }
39
+ else {
40
+ this.context = new ExpressionContext(context || {});
41
+ }
42
+ // Use provided cache or create a new one
43
+ this.cache = cache || new ExpressionCache();
44
+ }
45
+ /**
46
+ * Evaluate a string that may contain template expressions like ${...}
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const evaluator = new ExpressionEvaluator({ data: { amount: 1500 } });
51
+ * evaluator.evaluate('${data.amount > 1000}'); // Returns: true
52
+ * evaluator.evaluate('Amount is ${data.amount}'); // Returns: "Amount is 1500"
53
+ * ```
54
+ */
55
+ evaluate(expression, options = {}) {
56
+ // Handle non-string primitives
57
+ if (typeof expression !== 'string') {
58
+ return expression;
59
+ }
60
+ const { defaultValue, throwOnError = false, sanitize = true } = options;
61
+ try {
62
+ // Check if string contains template expressions
63
+ const hasTemplates = expression.includes('${');
64
+ if (!hasTemplates) {
65
+ // No templates, return as-is
66
+ return expression;
67
+ }
68
+ // Special case: if the entire string is a single template expression, return the value directly
69
+ const singleTemplateMatch = expression.match(/^\$\{([^}]+)\}$/);
70
+ if (singleTemplateMatch) {
71
+ return this.evaluateExpression(singleTemplateMatch[1].trim(), { sanitize });
72
+ }
73
+ // Replace all ${...} expressions in a string with multiple parts
74
+ return expression.replace(/\$\{([^}]+)\}/g, (match, expr) => {
75
+ try {
76
+ const result = this.evaluateExpression(expr.trim(), { sanitize });
77
+ return String(result ?? '');
78
+ }
79
+ catch (error) {
80
+ if (throwOnError) {
81
+ throw error;
82
+ }
83
+ console.warn(`Expression evaluation failed for: ${expr}`, error);
84
+ return match; // Return original if evaluation fails
85
+ }
86
+ });
87
+ }
88
+ catch (error) {
89
+ if (throwOnError) {
90
+ throw error;
91
+ }
92
+ console.warn(`Failed to evaluate expression: ${expression}`, error);
93
+ return defaultValue ?? expression;
94
+ }
95
+ }
96
+ /**
97
+ * Evaluate a single expression (without ${} wrapper)
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * evaluator.evaluateExpression('data.amount > 1000'); // Returns: true
102
+ * evaluator.evaluateExpression('data.user.name'); // Returns: "John"
103
+ * ```
104
+ */
105
+ evaluateExpression(expression, options = {}) {
106
+ const { sanitize = true } = options;
107
+ if (!expression || expression.trim() === '') {
108
+ return undefined;
109
+ }
110
+ // Sanitize expression to prevent dangerous code execution
111
+ if (sanitize && this.isDangerous(expression)) {
112
+ throw new Error(`Potentially dangerous expression detected: ${expression}`);
113
+ }
114
+ try {
115
+ // Create a safe evaluation function
116
+ const contextObj = this.context.toObject();
117
+ // Build safe function with context variables
118
+ const varNames = Object.keys(contextObj);
119
+ const varValues = Object.values(contextObj);
120
+ // Use cached compilation
121
+ const compiled = this.cache.compile(expression, varNames);
122
+ // Execute with context values
123
+ return compiled.fn(...varValues);
124
+ }
125
+ catch (error) {
126
+ throw new Error(`Failed to evaluate expression "${expression}": ${error.message}`);
127
+ }
128
+ }
129
+ /**
130
+ * Check if expression contains potentially dangerous code
131
+ */
132
+ isDangerous(expression) {
133
+ const dangerousPatterns = [
134
+ /eval\s*\(/i,
135
+ /Function\s*\(/i,
136
+ /setTimeout\s*\(/i,
137
+ /setInterval\s*\(/i,
138
+ /import\s*\(/i,
139
+ /require\s*\(/i,
140
+ /process\./i,
141
+ /global\./i,
142
+ /window\./i,
143
+ /document\./i,
144
+ /__proto__/i,
145
+ /constructor\s*\(/i,
146
+ /prototype\./i,
147
+ ];
148
+ return dangerousPatterns.some(pattern => pattern.test(expression));
149
+ }
150
+ /**
151
+ * Evaluate a conditional expression and return boolean
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * evaluator.evaluateCondition('${data.age >= 18}'); // Returns: true/false
156
+ * ```
157
+ */
158
+ evaluateCondition(condition, options = {}) {
159
+ if (typeof condition === 'boolean') {
160
+ return condition;
161
+ }
162
+ if (!condition) {
163
+ return true; // Default to visible/enabled if no condition
164
+ }
165
+ const result = this.evaluate(condition, options);
166
+ // Convert result to boolean
167
+ return Boolean(result);
168
+ }
169
+ /**
170
+ * Update the context with new data
171
+ */
172
+ updateContext(data) {
173
+ Object.entries(data).forEach(([key, value]) => {
174
+ this.context.set(key, value);
175
+ });
176
+ }
177
+ /**
178
+ * Get the current context
179
+ */
180
+ getContext() {
181
+ return this.context;
182
+ }
183
+ /**
184
+ * Create a new evaluator with additional context data
185
+ */
186
+ withContext(data) {
187
+ // Share the cache with the new evaluator for maximum efficiency
188
+ return new ExpressionEvaluator(this.context.createChild(data), this.cache);
189
+ }
190
+ /**
191
+ * Get cache statistics (useful for debugging and optimization)
192
+ */
193
+ getCacheStats() {
194
+ return this.cache.getStats();
195
+ }
196
+ /**
197
+ * Clear the expression cache
198
+ */
199
+ clearCache() {
200
+ this.cache.clear();
201
+ }
202
+ }
203
+ /**
204
+ * Shared global cache for convenience functions
205
+ */
206
+ const globalCache = new ExpressionCache();
207
+ /**
208
+ * Convenience function to quickly evaluate an expression
209
+ */
210
+ export function evaluateExpression(expression, context = {}, options = {}) {
211
+ const evaluator = new ExpressionEvaluator(context, globalCache);
212
+ return evaluator.evaluate(expression, options);
213
+ }
214
+ /**
215
+ * Convenience function to evaluate a condition
216
+ */
217
+ export function evaluateCondition(condition, context = {}) {
218
+ const evaluator = new ExpressionEvaluator(context, globalCache);
219
+ return evaluator.evaluateCondition(condition);
220
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ export * from './ExpressionContext.js';
9
+ export * from './ExpressionEvaluator.js';
10
+ export * from './ExpressionCache.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ export * from './ExpressionContext.js';
9
+ export * from './ExpressionEvaluator.js';
10
+ export * from './ExpressionCache.js';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,17 @@
1
- export * from './types';
2
- export * from './registry/Registry';
3
- export * from './validation/schema-validator';
4
- export * from './builder/schema-builder';
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ export type { SchemaNode, ComponentRendererProps } from './types/index.js';
9
+ export * from './registry/Registry.js';
10
+ export * from './registry/PluginSystem.js';
11
+ export * from './registry/PluginScopeImpl.js';
12
+ export * from './validation/index.js';
13
+ export * from './builder/schema-builder.js';
14
+ export * from './utils/filter-converter.js';
15
+ export * from './evaluator/index.js';
16
+ export * from './actions/index.js';
17
+ export * from './query/index.js';
package/dist/index.js CHANGED
@@ -1,7 +1,18 @@
1
- export * from './types';
2
- export * from './registry/Registry';
3
- export * from './validation/schema-validator';
4
- export * from './builder/schema-builder';
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ export * from './registry/Registry.js';
9
+ export * from './registry/PluginSystem.js';
10
+ export * from './registry/PluginScopeImpl.js';
11
+ export * from './validation/index.js';
12
+ export * from './builder/schema-builder.js';
13
+ export * from './utils/filter-converter.js';
14
+ export * from './evaluator/index.js';
15
+ export * from './actions/index.js';
16
+ export * from './query/index.js';
5
17
  // export * from './data-scope'; // TODO
6
- // export * from './evaluator'; // TODO
7
18
  // export * from './validators'; // TODO
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @object-ui/core - Query Module
3
+ *
4
+ * Phase 3.3: Query AST builder and utilities
5
+ */
6
+ export * from './query-ast.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @object-ui/core - Query Module
3
+ *
4
+ * Phase 3.3: Query AST builder and utilities
5
+ */
6
+ export * from './query-ast.js';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ObjectUI - Query AST Builder
3
+ * Phase 3.3: QuerySchema AST implementation
4
+ * ObjectStack Spec v0.7.1: Window functions support
5
+ */
6
+ import type { QueryAST, QuerySchema } from '@object-ui/types';
7
+ /**
8
+ * Query AST Builder - Converts QuerySchema to AST
9
+ */
10
+ export declare class QueryASTBuilder {
11
+ build(query: QuerySchema): QueryAST;
12
+ private buildSelect;
13
+ private buildFrom;
14
+ private buildWhere;
15
+ private buildFilterCondition;
16
+ private buildCondition;
17
+ private buildJoin;
18
+ private buildGroupBy;
19
+ private buildOrderBy;
20
+ private buildLimit;
21
+ private buildOffset;
22
+ private buildField;
23
+ private buildLiteral;
24
+ private buildAggregation;
25
+ /**
26
+ * Build window function node (ObjectStack Spec v0.7.1)
27
+ */
28
+ private buildWindow;
29
+ optimize(ast: QueryAST): QueryAST;
30
+ }
31
+ export declare const defaultQueryASTBuilder: QueryASTBuilder;
32
+ export declare function buildQueryAST(query: QuerySchema): QueryAST;