import type {
JsonRecord,
LinearCommentSummary,
LinearIssueSummary,
LinearNamedRef,
LinearPageInfo,
LinearProjectSummary,
LinearTeamSummary,
LinearWorkflowStateSummary,
} from './types.ts'
export const ISSUE_FIELDS = `
id
identifier
title
url
priority
createdAt
updatedAt
state { id name type }
team { id name key }
assignee { id name }
project { id name }
`
export const COMMENT_FIELDS = `
id
body
url
createdAt
updatedAt
user { id name }
`
export const PROJECT_FIELDS = `
id
name
url
description
status { id name type }
startDate
targetDate
progress
`
export const TEAM_FIELDS = `
id
name
key
description
`
export const WORKFLOW_STATE_FIELDS = `
id
name
type
team { id name key }
`
export const PAGE_INFO_FIELDS = `
pageInfo { hasNextPage endCursor }
`
export function namedRef(value: unknown): LinearNamedRef | null {
if (!value || typeof value !== 'object') return null
const record = value as JsonRecord
if (typeof record.id !== 'string' || record.id.length === 0) return null
return {
id: record.id,
name: typeof record.name === 'string' ? record.name : '',
key: typeof record.key === 'string' ? record.key : undefined,
type: typeof record.type === 'string' ? record.type : undefined,
}
}
export function mapIssue(value: unknown): LinearIssueSummary {
const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
return {
id: String(record.id || ''),
identifier: String(record.identifier || ''),
title: String(record.title || ''),
url: typeof record.url === 'string' ? record.url : null,
priority: typeof record.priority === 'number' ? record.priority : null,
createdAt: typeof record.createdAt === 'string' ? record.createdAt : null,
updatedAt: typeof record.updatedAt === 'string' ? record.updatedAt : null,
state: namedRef(record.state),
team: namedRef(record.team),
assignee: namedRef(record.assignee),
project: namedRef(record.project),
}
}
export function mapComment(value: unknown): LinearCommentSummary {
const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
return {
id: String(record.id || ''),
body: typeof record.body === 'string' ? record.body : null,
url: typeof record.url === 'string' ? record.url : null,
createdAt: typeof record.createdAt === 'string' ? record.createdAt : null,
updatedAt: typeof record.updatedAt === 'string' ? record.updatedAt : null,
user: namedRef(record.user),
}
}
export function mapProject(value: unknown): LinearProjectSummary {
const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
const state =
typeof record.state === 'string'
? record.state
: namedRef(record.status)?.name ?? namedRef(record.state)?.name ?? null
return {
id: String(record.id || ''),
name: String(record.name || ''),
url: typeof record.url === 'string' ? record.url : null,
description: typeof record.description === 'string' ? record.description : null,
state,
startDate: typeof record.startDate === 'string' ? record.startDate : null,
targetDate: typeof record.targetDate === 'string' ? record.targetDate : null,
progress: typeof record.progress === 'number' ? record.progress : null,
}
}
export function mapTeam(value: unknown): LinearTeamSummary {
const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
return {
id: String(record.id || ''),
name: String(record.name || ''),
key: String(record.key || ''),
description: typeof record.description === 'string' ? record.description : null,
}
}
export function mapWorkflowState(value: unknown): LinearWorkflowStateSummary {
const record = (value && typeof value === 'object' ? value : {}) as JsonRecord
return {
id: String(record.id || ''),
name: String(record.name || ''),
type: String(record.type || ''),
team: namedRef(record.team),
}
}
export function nodesFromConnection<T>(value: unknown): Array<T> {
if (!value || typeof value !== 'object') return []
const record = value as { nodes?: unknown }
return Array.isArray(record.nodes) ? (record.nodes as Array<T>) : []
}
export function pageInfoFromConnection(value: unknown): LinearPageInfo {
const info =
value && typeof value === 'object'
? ((value as { pageInfo?: Record<string, unknown> }).pageInfo ?? {})
: {}
return {
hasNextPage: Boolean(info.hasNextPage),
endCursor: typeof info.endCursor === 'string' ? info.endCursor : null,
}
}