import { kody } from 'kody:runtime' import { smokeTest, tryDefaultHandle } from './client.ts' import { APP_PASSWORD_DOCS_URL, APP_PASSWORD_SECRET, APP_PASSWORD_SETUP_URL, AUTH_HOST, DEFAULT_AUTH_SERVICE, DEFAULT_PUBLIC_APPVIEW, HANDLE_STORAGE_KEY, PDS_HOST_PATTERN, } from './setup.ts' function secretEntries(result: unknown): Array<{ name?: string; scope?: string }> { if (result && typeof result === 'object' && Array.isArray((result as { secrets?: unknown }).secrets)) { return (result as { secrets: Array<{ name?: string; scope?: string }> }).secrets } return Array.isArray(result) ? result : [] } /** * Verify Bluesky auth and read the default profile without returning session tokens. * Without a saved app password or handle this still returns `{ ok: true, live: false }` * plus the prefilled secret URL so the package is forkable before anyone connects. * @example * import smokeTest from 'kody:@kody/bluesky/smoke-test' * const result = await smokeTest() * // => { ok: true, live: false, setup: { ... } } */ export default async function smokeTestEntrypoint(params: Record = {}) { const listed = await kody.secretList({ scope: 'user' }) const names = new Set() for (const entry of secretEntries(listed)) { if (entry?.name && (entry.scope === 'user' || !entry.scope)) { names.add(entry.name) } } const identifier = (typeof params.identifier === 'string' && params.identifier.trim()) || (typeof params.handle === 'string' && params.handle.trim()) || (await tryDefaultHandle()) const hasSecret = names.has(APP_PASSWORD_SECRET) const setup = { secretUrl: APP_PASSWORD_SETUP_URL, appPasswordDocs: APP_PASSWORD_DOCS_URL, hosts: [AUTH_HOST, PDS_HOST_PATTERN], handleStorageKey: HANDLE_STORAGE_KEY, defaultAuthService: DEFAULT_AUTH_SERVICE, defaultPublicAppview: DEFAULT_PUBLIC_APPVIEW, secrets: { [APP_PASSWORD_SECRET]: hasSecret }, hasHandle: Boolean(identifier), nextSteps: [ 'Create an app password at ' + APP_PASSWORD_DOCS_URL + '. Do not paste it into chat.', APP_PASSWORD_SETUP_URL, 'Approve hosts bsky.social and *.bsky.network after the secret is saved.', 'Fork this package, then packageStorage().set("blueskyHandle", "yourhandle.bsky.social").', ], } if (!hasSecret || !identifier || params.setupOnly === true) { return { ok: true, live: false, method: 'com.atproto.server.createSession', host: AUTH_HOST, handle: identifier || null, setup, } } const live = await smokeTest({ ...params, identifier }) return { ...live, setup: { ...setup, nextSteps: [] } } }