Skip to content

Commit ecc82db

Browse files
Copilothotlong
andcommitted
Phase 1: Add object-level validation engine and window function builder
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent c3f396b commit ecc82db

4 files changed

Lines changed: 647 additions & 1 deletion

File tree

packages/core/src/query/query-ast.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* ObjectUI - Query AST Builder
33
* Phase 3.3: QuerySchema AST implementation
4+
* ObjectStack Spec v0.7.1: Window functions support
45
*/
56

67
import type {
@@ -15,6 +16,9 @@ import type {
1516
LimitNode,
1617
OffsetNode,
1718
AggregateNode,
19+
WindowNode,
20+
WindowFunction,
21+
WindowFrame,
1822
FieldNode,
1923
LiteralNode,
2024
OperatorNode,
@@ -64,7 +68,7 @@ export class QueryASTBuilder {
6468
}
6569

6670
private buildSelect(query: QuerySchema): SelectNode {
67-
const fields: (FieldNode | AggregateNode)[] = [];
71+
const fields: (FieldNode | AggregateNode | WindowNode)[] = [];
6872

6973
if (query.fields && query.fields.length > 0) {
7074
fields.push(...query.fields.map(field => this.buildField(field)));
@@ -77,6 +81,9 @@ export class QueryASTBuilder {
7781
fields.push(...query.aggregations.map(agg => this.buildAggregation(agg)));
7882
}
7983

84+
// Add window functions if they exist (future extension point)
85+
// query.windows?.forEach(win => fields.push(this.buildWindow(win)));
86+
8087
return {
8188
type: 'select',
8289
fields,
@@ -279,6 +286,55 @@ export class QueryASTBuilder {
279286
};
280287
}
281288

289+
/**
290+
* Build window function node (ObjectStack Spec v0.7.1)
291+
*/
292+
private buildWindow(config: {
293+
function: WindowFunction;
294+
field?: string;
295+
alias: string;
296+
partitionBy?: string[];
297+
orderBy?: Array<{ field: string; direction: 'asc' | 'desc' }>;
298+
frame?: WindowFrame;
299+
offset?: number;
300+
defaultValue?: any;
301+
}): WindowNode {
302+
const node: WindowNode = {
303+
type: 'window',
304+
function: config.function,
305+
alias: config.alias,
306+
};
307+
308+
if (config.field) {
309+
node.field = this.buildField(config.field);
310+
}
311+
312+
if (config.partitionBy && config.partitionBy.length > 0) {
313+
node.partitionBy = config.partitionBy.map(field => this.buildField(field));
314+
}
315+
316+
if (config.orderBy && config.orderBy.length > 0) {
317+
node.orderBy = config.orderBy.map(sort => ({
318+
field: this.buildField(sort.field),
319+
direction: sort.direction,
320+
}));
321+
}
322+
323+
if (config.frame) {
324+
node.frame = config.frame;
325+
}
326+
327+
if (config.offset !== undefined) {
328+
node.offset = config.offset;
329+
}
330+
331+
if (config.defaultValue !== undefined) {
332+
node.defaultValue = this.buildLiteral(config.defaultValue);
333+
}
334+
335+
return node;
336+
}
337+
282338
optimize(ast: QueryAST): QueryAST {
283339
return ast;
284340
}

packages/core/src/validation/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* @object-ui/core - Validation Module
33
*
44
* Phase 3.5: Validation engine
5+
* ObjectStack Spec v0.7.1: Object-level validation
56
*/
67

78
export * from './validation-engine';
89
export * from './schema-validator';
10+
export * from './validators';
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
/**
10+
* @object-ui/core - Validators
11+
*
12+
* ObjectStack Spec v0.7.1 compliant validators
13+
*
14+
* @module validators
15+
* @packageDocumentation
16+
*/
17+
18+
export {
19+
ObjectValidationEngine,
20+
defaultObjectValidationEngine,
21+
validateRecord,
22+
type ObjectValidationContext,
23+
type ObjectValidationResult,
24+
type ValidationExpressionEvaluator,
25+
} from './object-validation-engine';

0 commit comments

Comments
 (0)