Skip to content

Commit a0d5772

Browse files
authored
Merge pull request #370 from objectstack-ai/copilot/update-kernel-to-latest-version
2 parents 0859ed0 + 210b295 commit a0d5772

File tree

19 files changed

+260
-76
lines changed

19 files changed

+260
-76
lines changed

apps/console/src/__tests__/BrowserSimulation.test.tsx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ const mocks = vi.hoisted(() => {
3030
}
3131
return { data: [] };
3232
}
33+
async findOne(objectName: string, id: string) {
34+
if (objectName === 'kitchen_sink') {
35+
return { id, name: 'Test Sink', amount: 100 };
36+
}
37+
return null;
38+
}
3339
async getObjectSchema(name: string) {
3440
if (name === 'kitchen_sink') {
3541
return {
@@ -147,6 +153,14 @@ describe('Console Application Simulation', () => {
147153
});
148154

149155
it('Scenario 4: Object Create Form (All Field Types)', async () => {
156+
// Helper function to check if a label exists in the form
157+
const expectLabelToExist = (label: string) => {
158+
const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
159+
const regex = new RegExp(escaped, 'i');
160+
const elements = screen.queryAllByText(regex);
161+
expect(elements.length).toBeGreaterThan(0);
162+
};
163+
150164
renderApp('/kitchen_sink');
151165

152166
// 1. Wait for Object View
@@ -164,10 +178,10 @@ describe('Console Application Simulation', () => {
164178
});
165179

166180
// 4. Verify Field Inputs
167-
// Wait for at least one field to appear to ensure form is loaded
181+
// Wait for form to finish loading and first field to appear
168182
await waitFor(() => {
169183
expect(screen.getByText(/Text \(Name\)/i)).toBeInTheDocument();
170-
}, { timeout: 5000 });
184+
}, { timeout: 10000 });
171185

172186
const fieldLabels = [
173187
'Text (Name)',
@@ -178,17 +192,12 @@ describe('Console Application Simulation', () => {
178192
'Boolean (Switch)',
179193
];
180194

181-
// Check each label exists
182-
for (const label of fieldLabels) {
183-
const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
184-
const regex = new RegExp(escaped, 'i');
185-
const elements = screen.queryAllByText(regex);
186-
if (elements.length === 0) {
187-
console.log(`Failed to find label: ${label}`);
188-
// console.log(document.body.innerHTML); // Too large, but useful if localized
189-
}
190-
expect(elements.length).toBeGreaterThan(0);
191-
}
195+
// Check all labels exist concurrently using Promise.all for faster execution
196+
await Promise.all(
197+
fieldLabels.map(label =>
198+
waitFor(() => expectLabelToExist(label), { timeout: 5000 })
199+
)
200+
);
192201

193202
// 5. Test specific interaction (e.g. typing in name)
194203
// Note: Shadcn/Form labels might be associated via ID, so getByLabelText is safer usually,

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@
5959
"devDependencies": {
6060
"@changesets/cli": "^2.29.8",
6161
"@eslint/js": "^9.39.1",
62-
"@objectstack/cli": "^0.9.0",
63-
"@objectstack/core": "^0.9.0",
64-
"@objectstack/driver-memory": "^0.9.0",
65-
"@objectstack/objectql": "^0.9.0",
66-
"@objectstack/plugin-msw": "^0.9.0",
67-
"@objectstack/runtime": "^0.9.0",
62+
"@objectstack/cli": "^0.9.1",
63+
"@objectstack/core": "^0.9.1",
64+
"@objectstack/driver-memory": "^0.9.1",
65+
"@objectstack/objectql": "^0.9.1",
66+
"@objectstack/plugin-msw": "^0.9.1",
67+
"@objectstack/runtime": "^0.9.1",
6868
"@storybook/addon-essentials": "^8.6.14",
6969
"@storybook/addon-interactions": "^8.6.14",
7070
"@storybook/addon-links": "^8.6.15",
@@ -117,7 +117,7 @@
117117
},
118118
"dependencies": {
119119
"@hono/node-server": "^1.19.9",
120-
"@objectstack/plugin-hono-server": "^0.9.0",
120+
"@objectstack/plugin-hono-server": "^0.9.1",
121121
"coverage-v8": "0.0.1-security",
122122
"hono": "^4.11.7",
123123
"pino": "^8.21.0",

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
"dependencies": {
3232
"@object-ui/types": "workspace:*",
33-
"@objectstack/spec": "^0.9.0",
33+
"@objectstack/spec": "^0.9.1",
3434
"lodash": "^4.17.23",
3535
"zod": "^4.3.6"
3636
},

packages/data-objectstack/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"dependencies": {
3131
"@object-ui/core": "workspace:*",
3232
"@object-ui/types": "workspace:*",
33-
"@objectstack/client": "^0.9.0"
33+
"@objectstack/client": "^0.9.1"
3434
},
3535
"devDependencies": {
3636
"tsup": "^8.0.1",

packages/fields/src/widgets/BooleanField.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ export function BooleanField({ value, onChange, field, readonly, ...props }: Fie
1515
return <span className="text-sm">{value ? 'Yes' : 'No'}</span>;
1616
}
1717

18+
// Filter out non-DOM props
19+
const { inputType, ...domProps } = props as any;
20+
1821
if (widget === 'checkbox') {
1922
return (
2023
<div className="flex items-center space-x-2">
2124
<Checkbox
22-
{...props}
25+
{...domProps}
2326
id={id}
2427
checked={!!value}
2528
onCheckedChange={(checked) => onChange(!!checked)}
26-
disabled={readonly || props.disabled}
29+
disabled={readonly || domProps.disabled}
2730
/>
2831
<Label htmlFor={id}>{label}</Label>
2932
</div>
@@ -33,11 +36,11 @@ export function BooleanField({ value, onChange, field, readonly, ...props }: Fie
3336
return (
3437
<div className="flex items-center space-x-2">
3538
<Switch
36-
{...props}
39+
{...domProps}
3740
id={id}
3841
checked={!!value}
3942
onCheckedChange={onChange}
40-
disabled={readonly || props.disabled}
43+
disabled={readonly || domProps.disabled}
4144
/>
4245
<Label htmlFor={id}>{label}</Label>
4346
</div>

packages/fields/src/widgets/DateField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ export function DateField({ value, onChange, field, readonly, ...props }: FieldW
77
return <span className="text-sm">{value ? new Date(value).toLocaleDateString() : '-'}</span>;
88
}
99

10+
// Filter out non-DOM props
11+
const { inputType, ...domProps } = props as any;
12+
1013
return (
1114
<Input
12-
{...props}
15+
{...domProps}
1316
type="date"
1417
value={value || ''}
1518
onChange={(e) => onChange(e.target.value)}
16-
disabled={readonly || props.disabled}
19+
disabled={readonly || domProps.disabled}
1720
/>
1821
);
1922
}

packages/fields/src/widgets/DateTimeField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ export function DateTimeField({ value, onChange, field, readonly, ...props }: Fi
1313
);
1414
}
1515

16+
// Filter out non-DOM props
17+
const { inputType, ...domProps } = props as any;
18+
1619
return (
1720
<Input
18-
{...props}
21+
{...domProps}
1922
type="datetime-local"
2023
value={value || ''}
2124
onChange={(e) => onChange(e.target.value)}
22-
disabled={readonly || props.disabled}
25+
disabled={readonly || domProps.disabled}
2326
/>
2427
);
2528
}

packages/fields/src/widgets/EmailField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ export function EmailField({ value, onChange, field, readonly, errorMessage, ...
1616
);
1717
}
1818

19+
// Filter out non-DOM props
20+
const { inputType, ...domProps } = props as any;
21+
1922
return (
2023
<Input
21-
{...props}
24+
{...domProps}
2225
type="email"
2326
value={value || ''}
2427
onChange={(e) => onChange(e.target.value)}
2528
placeholder={config?.placeholder || 'email@example.com'}
26-
disabled={readonly || props.disabled}
29+
disabled={readonly || domProps.disabled}
2730
aria-invalid={!!errorMessage}
2831
/>
2932
);

packages/fields/src/widgets/NumberField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ export function NumberField({ value, onChange, field, readonly, ...props }: Fiel
1111
const numberField = (field || (props as any).schema) as NumberFieldMetadata;
1212
const precision = numberField?.precision;
1313

14+
// Filter out non-DOM props
15+
const { inputType, ...domProps } = props as any;
16+
1417
return (
1518
<Input
16-
{...props}
19+
{...domProps}
1720
type="number"
1821
value={value ?? ''}
1922
onChange={(e) => {
2023
const val = e.target.value;
2124
onChange(val === '' ? (null as any) : Number(val));
2225
}}
2326
placeholder={numberField?.placeholder}
24-
disabled={readonly || props.disabled}
27+
disabled={readonly || domProps.disabled}
2528
step={precision ? Math.pow(10, -precision) : 'any'}
2629
/>
2730
);

packages/fields/src/widgets/PasswordField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ export function PasswordField({ value, onChange, field, readonly, className, ...
1212
return <span className="text-sm">••••••••</span>;
1313
}
1414

15+
// Filter out non-DOM props
16+
const { inputType, ...domProps } = props as any;
17+
1518
return (
1619
<div className="relative">
1720
<Input
18-
{...props}
21+
{...domProps}
1922
type={showPassword ? 'text' : 'password'}
2023
value={value || ''}
2124
onChange={(e) => onChange(e.target.value)}
2225
placeholder={config?.placeholder}
23-
disabled={readonly || props.disabled}
26+
disabled={readonly || domProps.disabled}
2427
className={`pr-10 ${className || ''}`}
2528
/>
2629
<Button

0 commit comments

Comments
 (0)