Skip to content

Commit c81474c

Browse files
authored
Merge pull request #546 from objectstack-ai/copilot/fix-zod-schema-audit-report
2 parents c54a06a + 9a70e79 commit c81474c

8 files changed

Lines changed: 208 additions & 226 deletions

File tree

packages/spec/ZOD_SCHEMA_AUDIT_REPORT.md

Lines changed: 158 additions & 158 deletions
Large diffs are not rendered by default.

packages/spec/src/api/metadata.zod.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ export const ConceptListResponseSchema = BaseResponseSchema.extend({
4242
description: z.string().optional(),
4343
})).describe('List of available concepts (Objects, Apps, Flows)'),
4444
});
45+
46+
export type ObjectDefinitionResponse = z.infer<typeof ObjectDefinitionResponseSchema>;
47+
export type AppDefinitionResponse = z.infer<typeof AppDefinitionResponseSchema>;
48+
export type ConceptListResponse = z.infer<typeof ConceptListResponseSchema>;

packages/spec/src/hub/plugin-security.zod.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,12 @@ export type DependencyGraph = z.infer<typeof DependencyGraphSchema>;
410410

411411
/**
412412
* Dependency Conflict
413+
*
414+
* Hub-level dependency conflict detected during plugin resolution.
415+
* Focuses on package version conflicts across the marketplace/registry.
416+
*
417+
* @see kernel/plugin-versioning.zod.ts DependencyConflictSchema for kernel-level plugin conflicts
418+
* which models plugin-to-plugin conflicts with richer resolution strategies.
413419
*/
414420
export const DependencyConflictSchema = z.object({
415421
/**

packages/spec/src/integration/connector.test.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { z } from 'zod';
33
import {
44
// Field Mapping
55
FieldMappingSchema,
6-
FieldTransformSchema,
76

87
// Data Sync
98
DataSyncConfigSchema,
@@ -22,14 +21,12 @@ import {
2221
ConnectorSchema,
2322
ConnectorTypeSchema,
2423
ConnectorStatusSchema,
25-
AuthenticationSchema,
2624

2725
// Types
2826
type Connector,
2927
type FieldMapping,
3028
type DataSyncConfig,
3129
type WebhookConfig,
32-
type Authentication,
3330
} from './connector.zod';
3431

3532
// Import shared auth schemas from canonical source
@@ -128,7 +125,7 @@ describe('OAuth2Schema', () => {
128125
});
129126
});
130127

131-
describe('AuthenticationSchema', () => {
128+
describe('ConnectorAuthConfigSchema (Authentication)', () => {
132129
it('should accept all authentication types via discriminated union', () => {
133130
const keyAuth = { type: 'api-key' as const, key: 'key' };
134131
const oauth2Auth = {
@@ -141,10 +138,10 @@ describe('AuthenticationSchema', () => {
141138
const basicAuth = { type: 'basic' as const, username: 'user', password: 'pass' };
142139
const noAuth = { type: 'none' as const };
143140

144-
expect(() => AuthenticationSchema.parse(keyAuth)).not.toThrow();
145-
expect(() => AuthenticationSchema.parse(oauth2Auth)).not.toThrow();
146-
expect(() => AuthenticationSchema.parse(basicAuth)).not.toThrow();
147-
expect(() => AuthenticationSchema.parse(noAuth)).not.toThrow();
141+
expect(() => AuthConfigSchema.parse(keyAuth)).not.toThrow();
142+
expect(() => AuthConfigSchema.parse(oauth2Auth)).not.toThrow();
143+
expect(() => AuthConfigSchema.parse(basicAuth)).not.toThrow();
144+
expect(() => AuthConfigSchema.parse(noAuth)).not.toThrow();
148145
});
149146
});
150147

packages/spec/src/integration/connector.zod.ts

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,44 +67,15 @@ import { FieldMappingSchema as BaseFieldMappingSchema } from '../shared/mapping.
6767

6868
// ============================================================================
6969
// Authentication Schemas - IMPORTED FROM CANONICAL SOURCE
70-
// For backward compatibility, we re-export the auth types from auth/config.zod.ts
70+
// Use ConnectorAuthConfigSchema from shared/connector-auth.zod.ts
7171
// ============================================================================
7272

73-
/**
74-
* @deprecated Use ConnectorAuthConfigSchema from auth/config.zod instead
75-
* Kept for backward compatibility
76-
*/
77-
export const AuthenticationSchema = ConnectorAuthConfigSchema;
78-
export type Authentication = z.infer<typeof ConnectorAuthConfigSchema>;
79-
8073
// ============================================================================
8174
// Field Mapping Schema
8275
// Uses the canonical field mapping protocol from shared/mapping.zod.ts
8376
// Extended with connector-specific features
8477
// ============================================================================
8578

86-
/**
87-
* Field Transformation Function (Connector-specific)
88-
*
89-
* @deprecated Use TransformTypeSchema from shared/mapping.zod.ts instead
90-
*/
91-
export const FieldTransformSchema = z.object({
92-
type: z.enum([
93-
'uppercase',
94-
'lowercase',
95-
'trim',
96-
'date_format',
97-
'number_format',
98-
'custom',
99-
]).describe('Transformation type'),
100-
101-
params: z.record(z.string(), z.unknown()).optional().describe('Transformation parameters'),
102-
103-
function: z.string().optional().describe('Custom JavaScript function for transformation'),
104-
});
105-
106-
export type FieldTransform = z.infer<typeof FieldTransformSchema>;
107-
10879
/**
10980
* Connector Field Mapping Configuration
11081
*
@@ -483,7 +454,7 @@ export const ConnectorSchema = z.object({
483454
/**
484455
* Authentication configuration
485456
*/
486-
authentication: AuthenticationSchema.describe('Authentication configuration'),
457+
authentication: ConnectorAuthConfigSchema.describe('Authentication configuration'),
487458

488459
/** Zapier-style Capabilities */
489460
actions: z.array(ConnectorActionSchema).optional(),

packages/spec/src/kernel/plugin-versioning.zod.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,11 @@ export const PluginCompatibilityMatrixSchema = z.object({
236236

237237
/**
238238
* Dependency Conflict
239-
* Represents a conflict in plugin dependencies
239+
* Represents a conflict in plugin dependencies at the kernel level.
240+
* Models plugin-to-plugin dependency conflicts with typed conflict categories.
241+
*
242+
* @see hub/plugin-security.zod.ts DependencyConflictSchema for hub-level package version conflicts
243+
* which focuses on marketplace registry resolution.
240244
*/
241245
export const DependencyConflictSchema = z.object({
242246
/**

packages/spec/src/qa/testing.zod.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ export const TestActionTypeSchema = z.enum([
1414
'api_call',
1515
'run_script',
1616
'wait' // Testing async processes
17-
]);
17+
]).describe('Type of test action to perform');
1818

1919
export const TestActionSchema = z.object({
20-
type: TestActionTypeSchema,
20+
type: TestActionTypeSchema.describe('The action type to execute'),
2121
target: z.string().describe('Target Object, API Endpoint, or Function Name'),
2222
payload: z.record(z.string(), z.unknown()).optional().describe('Data to send or use'),
23-
user: z.string().optional().describe('Run as specific user/role') // Impersonation
24-
});
23+
user: z.string().optional().describe('Run as specific user/role for impersonation testing')
24+
}).describe('A single test action to execute against the system');
2525

2626
// Assertion Types
2727
export const TestAssertionTypeSchema = z.enum([
@@ -36,46 +36,46 @@ export const TestAssertionTypeSchema = z.enum([
3636
'lt',
3737
'lte',
3838
'error' // Expecting an error
39-
]);
39+
]).describe('Comparison operator for test assertions');
4040

4141
export const TestAssertionSchema = z.object({
4242
field: z.string().describe('Field path in the result to check (e.g. "body.data.0.status")'),
43-
operator: TestAssertionTypeSchema,
44-
expectedValue: z.unknown()
45-
});
43+
operator: TestAssertionTypeSchema.describe('Comparison operator to use'),
44+
expectedValue: z.unknown().describe('Expected value to compare against')
45+
}).describe('A test assertion that validates the result of a test action');
4646

4747
// --- Test Structure ---
4848

4949
export const TestStepSchema = z.object({
50-
name: z.string(),
51-
description: z.string().optional(),
52-
action: TestActionSchema,
53-
assertions: z.array(TestAssertionSchema).optional(),
50+
name: z.string().describe('Step name for identification in test reports'),
51+
description: z.string().optional().describe('Human-readable description of what this step tests'),
52+
action: TestActionSchema.describe('The action to execute in this step'),
53+
assertions: z.array(TestAssertionSchema).optional().describe('Assertions to validate after the action completes'),
5454
// Capture outputs to variables for subsequent steps
5555
capture: z.record(z.string(), z.string()).optional().describe('Map result fields to context variables: { "newId": "body._id" }')
56-
});
56+
}).describe('A single step in a test scenario, consisting of an action and optional assertions');
5757

5858
export const TestScenarioSchema = z.object({
59-
id: z.string(),
60-
name: z.string(),
61-
description: z.string().optional(),
62-
tags: z.array(z.string()).optional(), // e.g. "critical", "regression", "crm"
59+
id: z.string().describe('Unique scenario identifier'),
60+
name: z.string().describe('Scenario name for test reports'),
61+
description: z.string().optional().describe('Detailed description of the test scenario'),
62+
tags: z.array(z.string()).optional().describe('Tags for filtering and categorization (e.g. "critical", "regression", "crm")'),
6363

64-
setup: z.array(TestStepSchema).optional().describe('Steps to run before main test'),
65-
steps: z.array(TestStepSchema).describe('Main test sequence'),
66-
teardown: z.array(TestStepSchema).optional().describe('Steps to cleanup'),
64+
setup: z.array(TestStepSchema).optional().describe('Steps to run before main test (preconditions)'),
65+
steps: z.array(TestStepSchema).describe('Main test sequence to execute'),
66+
teardown: z.array(TestStepSchema).optional().describe('Steps to cleanup after test execution'),
6767

6868
// Environment requirements
6969
requires: z.object({
70-
params: z.array(z.string()).optional(), // Required env vars or params
71-
plugins: z.array(z.string()).optional()
72-
}).optional()
73-
});
70+
params: z.array(z.string()).optional().describe('Required environment variables or parameters'),
71+
plugins: z.array(z.string()).optional().describe('Required plugins that must be loaded')
72+
}).optional().describe('Environment requirements for this scenario')
73+
}).describe('A complete test scenario with setup, execution steps, and teardown');
7474

7575
export const TestSuiteSchema = z.object({
76-
name: z.string(),
77-
scenarios: z.array(TestScenarioSchema)
78-
});
76+
name: z.string().describe('Test suite name'),
77+
scenarios: z.array(TestScenarioSchema).describe('List of test scenarios in this suite')
78+
}).describe('A collection of test scenarios grouped into a test suite');
7979

8080
export type TestSuite = z.infer<typeof TestSuiteSchema>;
8181
export type TestScenario = z.infer<typeof TestScenarioSchema>;

packages/spec/src/security/sharing.zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const OwnerSharingRuleSchema = BaseSharingRuleSchema.extend({
9090
/**
9191
* Master Sharing Rule Schema
9292
*/
93-
export const SharingRuleSchema: z.ZodType<any> = z.discriminatedUnion('type', [
93+
export const SharingRuleSchema = z.discriminatedUnion('type', [
9494
CriteriaSharingRuleSchema,
9595
OwnerSharingRuleSchema
9696
]);

0 commit comments

Comments
 (0)