Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kentcdodds/google

src/accounts.ts

98 lines · 3.1 KB · TypeScript
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<GoogleAccountAlias, GoogleAccountInfo> = {
	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] }
}