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<LinearRequestInput> & Record<string, unknown> = {},
) {
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'),
})
}