Merge pull request #426 from buster-so/cursor/ensure-correct-types-for-integration-handler-fac1

Ensure correct types for integration handler
This commit is contained in:
dal 2025-07-07 14:37:32 -07:00 committed by GitHub
commit 35761e9dd0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 126 additions and 62 deletions

View File

@ -200,6 +200,10 @@ export class SlackOAuthService {
teamDomain?: string; teamDomain?: string;
installedAt: string; installedAt: string;
lastUsedAt?: string; lastUsedAt?: string;
defaultChannel?: {
id: string;
name: string;
};
}; };
}> { }> {
try { try {
@ -209,6 +213,19 @@ export class SlackOAuthService {
return { connected: false }; return { connected: false };
} }
// Cast defaultChannel to the expected type
const defaultChannel = integration.defaultChannel as
| { id: string; name: string }
| Record<string, never>
| null;
// Check if defaultChannel has content
const hasDefaultChannel =
defaultChannel &&
typeof defaultChannel === 'object' &&
'id' in defaultChannel &&
'name' in defaultChannel;
return { return {
connected: true, connected: true,
integration: { integration: {
@ -217,6 +234,12 @@ export class SlackOAuthService {
...(integration.teamDomain != null && { teamDomain: integration.teamDomain }), ...(integration.teamDomain != null && { teamDomain: integration.teamDomain }),
installedAt: integration.installedAt || integration.createdAt, installedAt: integration.installedAt || integration.createdAt,
...(integration.lastUsedAt != null && { lastUsedAt: integration.lastUsedAt }), ...(integration.lastUsedAt != null && { lastUsedAt: integration.lastUsedAt }),
...(hasDefaultChannel && {
defaultChannel: {
id: defaultChannel.id,
name: defaultChannel.name,
},
}),
}, },
}; };
} catch (error) { } catch (error) {

View File

@ -1,11 +1,4 @@
// Export all request types and schemas // Re-export all types, schemas, and utilities
export * from './requests.types';
export type * from './requests.types';
// Export all response types
export * from './responses.types';
export type * from './responses.types';
// Export error types and classes
export * from './errors.types'; export * from './errors.types';
export type * from './errors.types'; export * from './requests.types';
export * from './responses.types';

View File

@ -1,69 +1,117 @@
// Error response type import { z } from 'zod';
export interface SlackErrorResponse {
error: string; // Error response schema
code?: string; export const SlackErrorResponseSchema = z.object({
} error: z.string(),
code: z.string().optional(),
});
export type SlackErrorResponse = z.infer<typeof SlackErrorResponseSchema>;
// POST /api/v2/slack/auth/init // POST /api/v2/slack/auth/init
export interface InitiateOAuthResponse { export const InitiateOAuthResponseSchema = z.object({
auth_url: string; auth_url: z.string(),
state: string; state: z.string(),
} });
export type InitiateOAuthResponse = z.infer<typeof InitiateOAuthResponseSchema>;
// GET /api/v2/slack/auth/callback // GET /api/v2/slack/auth/callback
// This endpoint returns a redirect, not JSON // This endpoint returns a redirect, not JSON
// GET /api/v2/slack/integration // GET /api/v2/slack/integration
export interface GetIntegrationResponse { export const GetIntegrationResponseSchema = z.object({
connected: boolean; connected: z.boolean(),
integration?: { integration: z
id: string; .object({
team_name: string; id: z.string(),
team_domain?: string; team_name: z.string(),
installed_at: string; team_domain: z.string().optional(),
last_used_at?: string; installed_at: z.string(),
}; last_used_at: z.string().optional(),
} default_channel: z
.object({
id: z.string(),
name: z.string(),
})
.optional(),
})
.optional(),
});
export type GetIntegrationResponse = z.infer<typeof GetIntegrationResponseSchema>;
// DELETE /api/v2/slack/integration // DELETE /api/v2/slack/integration
export interface RemoveIntegrationResponse { export const RemoveIntegrationResponseSchema = z.object({
message: string; message: z.string(),
} });
export type RemoveIntegrationResponse = z.infer<typeof RemoveIntegrationResponseSchema>;
// PUT /api/v2/slack/integration // PUT /api/v2/slack/integration
export interface UpdateIntegrationResponse { export const UpdateIntegrationResponseSchema = z.object({
message: string; message: z.string(),
default_channel?: { default_channel: z
name: string; .object({
id: string; name: z.string(),
}; id: z.string(),
} })
.optional(),
});
export type UpdateIntegrationResponse = z.infer<typeof UpdateIntegrationResponseSchema>;
// GET /api/v2/slack/channels // GET /api/v2/slack/channels
export interface GetChannelsResponse { export const GetChannelsResponseSchema = z.object({
channels: Array<{ channels: z.array(
id: string; z.object({
name: string; id: z.string(),
}>; name: z.string(),
} })
),
});
export type GetChannelsResponse = z.infer<typeof GetChannelsResponseSchema>;
// OAuth callback result (used internally) // OAuth callback result (used internally)
export interface OAuthCallbackResult { export const OAuthCallbackResultSchema = z.object({
success: boolean; success: z.boolean(),
integration_id: string; integration_id: z.string(),
metadata?: { metadata: z
return_url?: string; .object({
source?: string; return_url: z.string().optional(),
project_id?: string; source: z.string().optional(),
initiated_at?: string; project_id: z.string().optional(),
ip_address?: string; initiated_at: z.string().optional(),
}; ip_address: z.string().optional(),
team_name?: string; })
error?: string; .optional(),
} team_name: z.string().optional(),
error: z.string().optional(),
});
export type OAuthCallbackResult = z.infer<typeof OAuthCallbackResultSchema>;
// Remove integration result (used internally) // Remove integration result (used internally)
export interface RemoveIntegrationResult { export const RemoveIntegrationResultSchema = z.object({
success: boolean; success: z.boolean(),
error?: string; error: z.string().optional(),
} });
export type RemoveIntegrationResult = z.infer<typeof RemoveIntegrationResultSchema>;
// Example usage for type validation:
// const response: GetIntegrationResponse = GetIntegrationResponseSchema.parse({
// connected: true,
// integration: {
// id: 'integration-123',
// team_name: 'My Team',
// team_domain: 'my-team',
// installed_at: '2025-01-01T00:00:00Z',
// last_used_at: '2025-01-02T00:00:00Z',
// default_channel: {
// id: 'C04RCNXL75J',
// name: 'general'
// }
// }
// });