export type GoogleAccountAlias = 'personal' | 'business' | 'youtube-brand' | 'youtube-plus' export type GoogleAccountInfo = { account: GoogleAccountAlias integrationName: string label: string emailHint: string | null products: string[] useWhen: string } export const GOOGLE_ACCOUNTS: Record = { personal: { account: 'personal', integrationName: 'google', label: 'Personal Google', emailHint: 'kent.c.dodds@gmail.com', products: ['gmail', 'drive', 'youtube'], useWhen: 'Use for personal Gmail, personal Drive, and personal YouTube channel reads unless the user specifies the Workspace account.', }, business: { account: 'business', integrationName: 'google-business', label: 'Business Google', emailHint: 'me@kentcdodds.com', products: ['calendar', 'gmail'], useWhen: 'Use for Workspace Calendar and me@kentcdodds.com Gmail (inbox, drafts, send) workflows.', }, 'youtube-brand': { account: 'youtube-brand', integrationName: 'google-youtube-brand', label: 'YouTube Brand Google', emailHint: null, products: ['youtube', 'youtube-analytics'], useWhen: 'Use for the main Kent C. Dodds YouTube channel (Better with Kent, workshops, curated dev content). See google/youtube-channels key "main".', }, 'youtube-plus': { account: 'youtube-plus', integrationName: 'google-youtube-plus', label: 'YouTube Plus Google', emailHint: null, products: ['youtube', 'youtube-analytics'], useWhen: 'Use for the kentcdodds-plus YouTube channel (Become an Epic Product Engineer, legacy Chats with Kent archive). See google/youtube-channels key "plus". Connect via /connect/oauth before first use.', }, } export const GOOGLE_ACCOUNT_ALIASES = [ 'personal', 'business', 'youtube-brand', 'youtube-plus', ] as const function cloneAccount(account: GoogleAccountInfo): GoogleAccountInfo { return { ...account, products: [...account.products] } } export function listGoogleAccounts(): GoogleAccountInfo[] { return GOOGLE_ACCOUNT_ALIASES.map((alias) => cloneAccount(GOOGLE_ACCOUNTS[alias])) } export function resolveGoogleAccount( input: { account?: string } | string = {}, ): GoogleAccountInfo { const account = typeof input === 'string' ? input : input.account if (!account) { throw new Error( 'Missing required Google account. Pass one of: ' + GOOGLE_ACCOUNT_ALIASES.join(', '), ) } const fromAlias = GOOGLE_ACCOUNTS[account as GoogleAccountAlias] if (fromAlias) return cloneAccount(fromAlias) const fromIntegration = GOOGLE_ACCOUNT_ALIASES.map((alias) => GOOGLE_ACCOUNTS[alias]).find( (candidate) => candidate.integrationName === account, ) if (fromIntegration) return cloneAccount(fromIntegration) throw new Error( 'Unknown Google account "' + account + '". Pass one of: ' + GOOGLE_ACCOUNT_ALIASES.join(', '), ) } /** * Return Kent's Google account registry and supported aliases. * @example * import accounts from 'kody:@kentcdodds/google/accounts' * const { accounts: list } = accounts() * // => [{ account: 'personal', integrationName: 'google', ... }, ...] */ export default function accounts() { return { accounts: listGoogleAccounts(), aliases: [...GOOGLE_ACCOUNT_ALIASES] } }