import { z } from 'zod'; import { AuthedUser, authedUser, authedUserRequest, authedUserResponse } from './authed-user.js'; import { Enterprise, enterprise, enterpriseRequest, enterpriseResponse } from './enterprise.js'; import { IncomingWebhook, incomingWebhook, incomingWebhookRequest, incomingWebhookResponse, } from './incoming-webhook.js'; import { Team, team, teamRequest, teamResponse } from './team.js'; /** * Zod schema for the SlackInstallation model. * Defines the structure and validation rules for this data type. * This is the shape used in application code - what developers interact with. */ export const slackInstallation = z.lazy(() => { return z.object({ accessToken: z.string(), appId: z.string(), authedUser: authedUser, botUserId: z.string().optional(), enterprise: enterprise.optional(), expiresIn: z.number().optional(), id: z .string() .regex(/^[A-Z0-9]+-.*$/) .optional(), incomingWebhook: incomingWebhook.optional(), isEnterpriseInstall: z.boolean().optional(), refreshToken: z.string().optional(), scope: z.string().optional(), team: team, tokenType: z.string().optional(), }); }); /** * * @typedef {SlackInstallation} slackInstallation * @property {string} - Bot token returned from the Slack OAuth exchange. * @property {string} - Slack app identifier for the installed app. * @property {AuthedUser} * @property {string} - Slack user ID of the installed bot. * @property {Enterprise} * @property {number} - Seconds until the bot access token expires. * @property {string} - Unique identifier MagicBell assigns to the Slack installation. * @property {IncomingWebhook} * @property {boolean} - Indicates whether the installation occurred on an enterprise grid. * @property {string} - Refresh token for regenerating the bot access token. * @property {string} - Space-delimited OAuth scopes granted to the bot token. * @property {Team} * @property {string} - Type of bot token returned by Slack. */ export type SlackInstallation = z.infer; /** * Zod schema for mapping API responses to the SlackInstallation application shape. * Handles any property name transformations from the API schema. * If property names match the API schema exactly, this is identical to the application shape. */ export const slackInstallationResponse = z.lazy(() => { return z .object({ access_token: z.string(), app_id: z.string(), authed_user: authedUserResponse, bot_user_id: z.string().optional(), enterprise: enterpriseResponse.optional(), expires_in: z.number().optional(), id: z .string() .regex(/^[A-Z0-9]+-.*$/) .optional(), incoming_webhook: incomingWebhookResponse.optional(), is_enterprise_install: z.boolean().optional(), refresh_token: z.string().optional(), scope: z.string().optional(), team: teamResponse, token_type: z.string().optional(), }) .transform((data) => ({ accessToken: data['access_token'], appId: data['app_id'], authedUser: data['authed_user'], botUserId: data['bot_user_id'], enterprise: data['enterprise'], expiresIn: data['expires_in'], id: data['id'], incomingWebhook: data['incoming_webhook'], isEnterpriseInstall: data['is_enterprise_install'], refreshToken: data['refresh_token'], scope: data['scope'], team: data['team'], tokenType: data['token_type'], })); }); /** * Zod schema for mapping the SlackInstallation application shape to API requests. * Handles any property name transformations required by the API schema. * If property names match the API schema exactly, this is identical to the application shape. */ export const slackInstallationRequest = z.lazy(() => { return z .object({ accessToken: z.string(), appId: z.string(), authedUser: authedUserRequest, botUserId: z.string().optional(), enterprise: enterpriseRequest.optional(), expiresIn: z.number().optional(), id: z .string() .regex(/^[A-Z0-9]+-.*$/) .optional(), incomingWebhook: incomingWebhookRequest.optional(), isEnterpriseInstall: z.boolean().optional(), refreshToken: z.string().optional(), scope: z.string().optional(), team: teamRequest, tokenType: z.string().optional(), }) .transform((data) => ({ access_token: data['accessToken'], app_id: data['appId'], authed_user: data['authedUser'], bot_user_id: data['botUserId'], enterprise: data['enterprise'], expires_in: data['expiresIn'], id: data['id'], incoming_webhook: data['incomingWebhook'], is_enterprise_install: data['isEnterpriseInstall'], refresh_token: data['refreshToken'], scope: data['scope'], team: data['team'], token_type: data['tokenType'], })); });