import { inferOperation, isReadOnlyQuery, linearGraphql } from './client.ts' import { LINEAR_GRAPHQL_URL } from './setup.ts' import type { JsonRecord, LinearAuthInput } from './types.ts' import { optionalBoolean, optionalString, requireRecord, requireString, } from './types.ts' import { requireAuthMode } from './auth.ts' export type LinearRequestInput = LinearAuthInput & { query: string variables?: JsonRecord confirm?: boolean dryRun?: boolean } /** * Call Linear GraphQL with a saved OAuth integration or personal API key. * Unknown and mutating operations require `confirm: true`; use `dryRun: true` * to preview. * @example * import request from 'kody:@kody/linear/request' * const result = await request({ * query: 'query { viewer { id } }', * }) */ export async function request(input: LinearRequestInput) { const query = requireString(input.query, 'query') const operation = inferOperation(query) const integrationName = optionalString(input.integrationName, 'integrationName') ?? optionalString(input.integration, 'integration') const secretName = optionalString(input.secretName, 'secretName') const account = optionalString(input.account, 'account') if (input.dryRun) { return { dryRun: true, url: LINEAR_GRAPHQL_URL, operation, query, variables: input.variables ?? {}, integrationName: integrationName ?? null, secretName: secretName ?? null, account: account ?? null, readOnly: isReadOnlyQuery(query, operation), } } if (!isReadOnlyQuery(query, operation) && input.confirm !== true) { throw new Error( 'This Linear GraphQL request may mutate data. Pass confirm: true only after explicit user approval, or use dryRun: true.', ) } return linearGraphql({ query, variables: input.variables, operation, integrationName, integration: input.integration, account, secretName, auth: input.auth, }) } /** * Call Linear GraphQL with a saved OAuth integration or personal API key. * Mutating documents require `confirm: true`; use `dryRun: true` to preview. * @example * import request from 'kody:@kody/linear/request' * const result = await request({ query: 'query { teams { nodes { id key } } }' }) */ export default async function requestEntrypoint( params: Partial & Record = {}, ) { const input = requireRecord(params, 'request') return request({ query: requireString(input.query, 'query'), variables: input.variables as JsonRecord | undefined, integrationName: optionalString(input.integrationName, 'integrationName'), integration: optionalString(input.integration, 'integration'), account: optionalString(input.account, 'account'), secretName: optionalString(input.secretName, 'secretName'), auth: requireAuthMode(input.auth), confirm: optionalBoolean(input.confirm, 'confirm'), dryRun: optionalBoolean(input.dryRun, 'dryRun'), }) }