import { accounts } from './accounts.ts'
import { createBoard } from './boards.ts'
import { createCard } from './cards.ts'
import { addComment } from './comments.ts'
import { createList } from './lists.ts'
import { getViewer } from './viewer.ts'
import { listBoards } from './boards.ts'
import { parseAuthInput } from './auth.ts'
import {
API_KEY_SETUP_URL,
OAUTH_CONNECT_URL,
TOKEN_SETUP_URL,
TRELLO_CALLBACK_URL,
TRELLO_REQUIRED_HOSTS,
} from './setup.ts'
import { isDryRunResult, mutationPreview } from './client.ts'
import type { TrelloAuthInput } from './types.ts'
import { requireRecord } from './types.ts'
export type SmokeTestInput = TrelloAuthInput & {
/** When true, skip the live member/board query even if credentials exist. */
setupOnly?: boolean
}
/**
* Local dry-run self-check plus an optional live member + board list.
* Never creates boards, lists, cards, or comments.
* @example
* import trello from 'kody:@kody/trello'
* const result = await trello({ action: 'smoke-test' })
*/
export async function smokeTest(input: SmokeTestInput = {}) {
const boardPreview = await createBoard({
name: 'Kody Trello smoke',
dryRun: true,
})
if (!isDryRunResult(boardPreview)) {
throw new Error('createBoard dryRun self-check failed.')
}
const listPreview = await createList({
boardId: 'board-id-from-caller',
name: 'Ready',
dryRun: true,
})
if (!isDryRunResult(listPreview)) {
throw new Error('createList dryRun self-check failed.')
}
const cardPreview = await createCard({
listId: 'list-id-from-caller',
name: 'Draft card',
dryRun: true,
})
if (!isDryRunResult(cardPreview)) {
throw new Error('createCard dryRun self-check failed.')
}
const commentPreview = await addComment({
cardId: 'card-id-from-caller',
text: 'Dry run only',
dryRun: true,
})
if (!isDryRunResult(commentPreview)) {
throw new Error('addComment dryRun self-check failed.')
}
let confirmRequired = false
try {
mutationPreview({}, { method: 'POST', path: '/cards', body: { name: 'Nope' } })
} catch {
confirmRequired = true
}
if (!confirmRequired) throw new Error('confirm rejection self-check failed.')
const info = await accounts(input)
const canLive = Boolean(info.preferredAuth) && input.setupOnly !== true
const selfCheck = {
dryRunCreateBoard: true,
dryRunCreateList: true,
dryRunCreateCard: true,
dryRunAddComment: true,
confirmRequired,
connectUrlUsesTrelloHost: info.connectUrl.includes('api.trello.com'),
apiKeyUrlUsesTrelloHost: info.apiKeyUrl.includes('api.trello.com'),
tokenUrlUsesTrelloHost: info.tokenUrl.includes('api.trello.com'),
callbackUrl: info.callbackUrl === TRELLO_CALLBACK_URL,
}
if (!canLive) {
return {
ok: true,
live: false,
selfCheck,
authMode: info.preferredAuth,
integrationName: info.integrationName,
apiKeySecretName: info.apiKeySecretName,
tokenSecretName: info.tokenSecretName,
oauthConnected: info.oauthConnected,
keyTokenSaved: info.keyTokenSaved,
setup: {
connectUrl: info.connectUrl,
reconnectUrl: info.reconnectUrl,
apiKeyUrl: info.apiKeyUrl,
tokenUrl: info.tokenUrl,
authorizeUrl: info.authorizeUrl,
callbackUrl: info.callbackUrl,
requiredHosts: info.requiredHosts,
nextSteps: [
`Save the Trello API key (do not paste it in chat): ${info.apiKeyUrl}`,
`Authorize a user token, then save it: ${info.authorizeUrl} then ${info.tokenUrl}`,
`Or reconnect a saved OAuth integration: ${info.reconnectUrl}`,
`Approve host ${TRELLO_REQUIRED_HOSTS.join(', ')}.`,
],
},
}
}
const [viewer, boards] = await Promise.all([
getViewer(input),
listBoards({ ...input, limit: 5 }),
])
return {
ok: true,
live: true,
selfCheck,
authMode: info.preferredAuth,
integrationName: info.integrationName,
apiKeySecretName: info.apiKeySecretName,
tokenSecretName: info.tokenSecretName,
oauthConnected: info.oauthConnected,
keyTokenSaved: info.keyTokenSaved,
viewer: {
id: viewer.id,
username: viewer.username,
fullName: viewer.fullName,
},
boardCount: boards.length,
sampleBoard: boards[0]
? { id: boards[0].id, name: boards[0].name, url: boards[0].url }
: null,
setup: {
connectUrl: OAUTH_CONNECT_URL,
apiKeyUrl: API_KEY_SETUP_URL,
tokenUrl: TOKEN_SETUP_URL,
requiredHosts: [...TRELLO_REQUIRED_HOSTS],
},
}
}
/**
* Local dry-run self-check plus an optional live member read.
* @example
* import smokeTest from 'kody:@kody/trello/smoke-test'
* const result = await smokeTest()
*/
export default async function smokeTestEntrypoint(
params: SmokeTestInput & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'smoke-test')
return smokeTest({
...parseAuthInput(input),
setupOnly: input.setupOnly === true,
})
}