import { PRODUCTHUNT_ACCESS_TOKEN_SECRET, PRODUCTHUNT_APPLICATIONS_URL, PRODUCTHUNT_AUTHORIZE_URL, PRODUCTHUNT_CLIENT_SECRET_SECRET, PRODUCTHUNT_GRAPHQL_URL, PRODUCTHUNT_INTEGRATION, PRODUCTHUNT_TOKEN_URL, } from './request.ts' /** Default Kody deployment origin used when none is provided. */ export const DEFAULT_KODY_ORIGIN = 'https://kody.codes' /** * Builds the hosted Kody OAuth connect URL for the saved `producthunt` integration. * * Pass your own deployment origin when this package runs somewhere other than * the default deployment. */ export function getConnectUrl(origin = DEFAULT_KODY_ORIGIN) { const params = new URLSearchParams({ provider: PRODUCTHUNT_INTEGRATION, authorizeUrl: PRODUCTHUNT_AUTHORIZE_URL, tokenUrl: PRODUCTHUNT_TOKEN_URL, apiBaseUrl: PRODUCTHUNT_GRAPHQL_URL, allowedHosts: 'api.producthunt.com', flow: 'confidential', scopes: 'public private', dashboardUrl: PRODUCTHUNT_APPLICATIONS_URL, providerSetupInstructions: 'Create a Confidential Product Hunt OAuth app. Register the exact redirect URI shown in the connect wizard (https://kody.codes/connect/oauth on the default deployment). Paste the client ID and client secret into the Kody form. Public clients cannot store the secret Kody needs.', }) return `${origin}/connect/oauth?${params.toString()}` } /** * Returns setup guidance for agents and humans. */ export function getSetupGuide(origin = DEFAULT_KODY_ORIGIN) { return { integration: PRODUCTHUNT_INTEGRATION, connectUrl: getConnectUrl(origin), redirectUri: `${origin}/connect/oauth`, applicationUrl: PRODUCTHUNT_APPLICATIONS_URL, clientType: 'confidential', scopes: ['public', 'private'], requiredSecrets: [PRODUCTHUNT_ACCESS_TOKEN_SECRET, PRODUCTHUNT_CLIENT_SECRET_SECRET], recommendedApprovedHosts: ['api.producthunt.com'], notes: [ 'Choose Confidential when creating the Product Hunt app. Kody stores the client secret server-side.', 'Register the redirect URI exactly as shown. A truncated URI will fail the callback.', 'Private scope is required for viewer.user. Public is enough for featured posts.', `Reconnect any time with ${origin}/connect/oauth?provider=producthunt after the integration is saved.`, 'Use request() for uncommon GraphQL queries or mutations. Write mutations need Product Hunt approval plus the write scope.', ], } } /** * Return Product Hunt OAuth setup guidance and connect URL for this deployment. * @returns Integration metadata, redirect URI, required secrets, and setup notes. * @example * import guide from 'kody:@kentcdodds/producthunt/guide' * const info = await guide({ origin: 'https://kody.codes' }) * // => { integration: 'producthunt', connectUrl: 'https://.../connect/oauth?...', requiredSecrets: ['producthuntAccessToken', 'producthuntClientSecret'] } */ export default async function guideEntrypoint(params: { origin?: string } = {}) { return getSetupGuide(params.origin ?? DEFAULT_KODY_ORIGIN) }