Skip to content

Commit 753d278

Browse files
committed
Enhance TypeScript generator for stricter field typing
Updated FieldDef to use FieldType and expanded support for field options, multiple values, and enable flags. Improved type mapping for various field types, including select, references, calculated fields, and geolocation. Added standard system fields to generated interfaces for consistency.
1 parent 4b8bb62 commit 753d278

File tree

1 file changed

+74
-21
lines changed

1 file changed

+74
-21
lines changed

packages/ai-bridge/src/generator/ts-generator.ts

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
// Define a simplified version of ObjectSchema to rely on,
2-
// avoiding direct dependency on @objectstack/spec to keep this package lightweight/portable if needed,
3-
// or we can treat inputs as 'any' or generic structures that match the shape.
4-
// For now, let's assume the input is the JSON structure compatible with what we saw in `object.zod.ts`.
1+
import { FieldType } from '@objectstack/spec/data';
2+
3+
// Determine if we can import ObjectSchema directly or if we treat inputs as generic JSON
4+
// For utility purposes, we often process JSON objects that might not be fully instantiated ObjectSchema types yet.
5+
// However, we should strictly align with the FieldType values.
56

67
export interface FieldDef {
7-
type: string;
8+
type: FieldType; // Strict alignment with Protocol
89
label?: string;
910
required?: boolean;
10-
options?: string[];
11+
multiple?: boolean;
12+
options?: Array<{ label: string; value: string } | string>;
1113
reference?: string;
1214
}
1315

1416
export interface ObjectDef {
1517
name: string;
1618
fields: Record<string, FieldDef>;
1719
description?: string;
20+
enable?: {
21+
files?: boolean;
22+
audit?: boolean;
23+
trash?: boolean;
24+
};
1825
}
1926

2027
/**
@@ -28,33 +35,75 @@ export function generateTypeScriptDefinition(objects: ObjectDef[]): string {
2835
switch (field.type) {
2936
case 'text':
3037
case 'textarea':
31-
case 'select':
3238
case 'email':
3339
case 'url':
3440
case 'phone':
35-
tsType = field.options ? field.options.map(o => `'${o}'`).join(' | ') : 'string';
36-
break;
41+
case 'password':
42+
case 'markdown':
43+
case 'html':
44+
case 'richtext':
45+
case 'image':
46+
case 'file':
47+
case 'avatar':
48+
tsType = 'string';
49+
break;
50+
51+
case 'select':
52+
if (field.options && field.options.length > 0) {
53+
// Handle both string[] and {label, value}[]
54+
const options = field.options.map(opt => typeof opt === 'string' ? opt : opt.value);
55+
tsType = options.map(o => `'${o}'`).join(' | ');
56+
} else {
57+
tsType = 'string';
58+
}
59+
break;
60+
3761
case 'number':
3862
case 'currency':
3963
case 'percent':
40-
tsType = 'number';
41-
break;
64+
case 'rating':
65+
case 'slider':
66+
tsType = 'number';
67+
break;
68+
4269
case 'boolean':
43-
tsType = 'boolean';
44-
break;
70+
tsType = 'boolean';
71+
break;
72+
4573
case 'date':
4674
case 'datetime':
47-
tsType = 'string'; // ISO string
48-
break;
75+
case 'time':
76+
tsType = 'string'; // ISO 8601
77+
break;
78+
4979
case 'lookup':
5080
case 'master_detail':
51-
tsType = field.reference ? `string | ${toPascalCase(field.reference)}` : 'string';
52-
break;
53-
case 'json':
54-
tsType = 'Record<string, any>';
55-
break;
81+
// For references, we allow the ID string OR the expanded object (if populated)
82+
// To be safe for write operations, we focus on the ID string
83+
// But strict AI typing might benefit from `string`
84+
tsType = field.reference ? `string | ${toPascalCase(field.reference)}` : 'string';
85+
break;
86+
87+
case 'formula':
88+
case 'summary':
89+
case 'autonumber':
90+
// Read-only calculated fields
91+
// Usually number or string depending on return type. Defaulting to any or union for safety
92+
tsType = 'string | number';
93+
break;
94+
95+
case 'location':
96+
case 'geolocation':
97+
case 'address':
98+
tsType = '{ latitude: number; longitude: number; } | any';
99+
break;
100+
56101
default:
57-
tsType = 'any';
102+
tsType = 'any';
103+
}
104+
105+
if (field.multiple) {
106+
tsType = `(${tsType})[]`;
58107
}
59108

60109
const optionalMark = field.required ? '' : '?';
@@ -72,6 +121,10 @@ export function generateTypeScriptDefinition(objects: ObjectDef[]): string {
72121
export interface ${pascalName} {
73122
_id: string;
74123
${fields}
124+
// Standard System Fields
125+
created_on?: string;
126+
modified_on?: string;
127+
owner?: string;
75128
}`;
76129

77130
// Generate ObjectQL Query Helper Types

0 commit comments

Comments
 (0)