UNPKG

n8n

Version:

n8n Workflow Automation Tool

679 lines • 31.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executeLinearContextQuery = executeLinearContextQuery; exports.executeLinearAction = executeLinearAction; exports.normalizeLinearIssue = normalizeLinearIssue; exports.normalizeLinearComment = normalizeLinearComment; const zod_1 = require("zod"); const integration_error_codes_1 = require("../integration-error-codes"); const integration_helpers_1 = require("../integration-helpers"); const PLATFORM = 'linear'; const getUserSchema = zod_1.z.object({ userId: zod_1.z.string().min(1) }); const searchUsersSchema = zod_1.z .object({ query: zod_1.z.string().min(1).optional(), email: zod_1.z.string().min(1).optional(), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), includeBots: zod_1.z.boolean().default(false), includeDeleted: zod_1.z.boolean().default(false), }) .refine((input) => input.query !== undefined || input.email !== undefined, { message: 'Provide query or email.', }); const getIssueSchema = zod_1.z.object({ issueId: zod_1.z.string().min(1), includeComments: zod_1.z.boolean().default(false), commentsLimit: zod_1.z.number().int().min(1).max(20).default(10), }); const searchIssuesSchema = zod_1.z.object({ query: zod_1.z.string().min(1), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), teamId: zod_1.z.string().min(1).optional(), includeArchived: zod_1.z.boolean().default(false), }); const getTeamSchema = zod_1.z.object({ teamId: zod_1.z.string().min(1), }); const searchTeamsSchema = zod_1.z.object({ query: zod_1.z.string().min(1).optional(), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), includeArchived: zod_1.z.boolean().default(false), }); const getProjectSchema = zod_1.z.object({ projectId: zod_1.z.string().min(1), }); const searchProjectsSchema = zod_1.z.object({ query: zod_1.z.string().min(1).optional(), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), teamId: zod_1.z.string().min(1).optional(), includeArchived: zod_1.z.boolean().default(false), }); const searchLabelsSchema = zod_1.z.object({ query: zod_1.z.string().min(1).optional(), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), teamId: zod_1.z.string().min(1).optional(), }); const searchIssueStatesSchema = zod_1.z.object({ query: zod_1.z.string().min(1).optional(), limit: zod_1.z.number().int().min(1).max(50).default(10), cursor: zod_1.z.string().min(1).optional(), teamId: zod_1.z.string().min(1).optional(), type: zod_1.z.enum(['backlog', 'unstarted', 'started', 'completed', 'canceled']).optional(), }); const createIssueSchema = zod_1.z.object({ teamId: zod_1.z.string().min(1), title: zod_1.z.string().min(1), description: zod_1.z.string().min(1).optional(), assigneeId: zod_1.z.string().min(1).optional(), projectId: zod_1.z.string().min(1).optional(), labelIds: zod_1.z.array(zod_1.z.string().min(1)).optional(), priority: zod_1.z.number().int().optional(), stateId: zod_1.z.string().min(1).optional(), parentId: zod_1.z.string().min(1).optional(), }); const nullableLinearIdSchema = zod_1.z.string().min(1).nullable(); const updateIssueSchema = zod_1.z .object({ issueId: zod_1.z.string().min(1), teamId: nullableLinearIdSchema.optional(), title: zod_1.z.string().min(1).optional(), description: zod_1.z.string().min(1).nullable().optional(), assigneeId: nullableLinearIdSchema.optional(), projectId: nullableLinearIdSchema.optional(), labelIds: zod_1.z.array(zod_1.z.string().min(1)).optional(), priority: zod_1.z.number().int().nullable().optional(), stateId: nullableLinearIdSchema.optional(), parentId: nullableLinearIdSchema.optional(), }) .refine(hasUpdateIssueField, { message: 'Provide at least one issue field to update.', }); const createCommentSchema = zod_1.z.object({ issueId: zod_1.z.string().min(1), body: zod_1.z.string().min(1), parentCommentId: zod_1.z.string().min(1).optional(), }); async function executeLinearContextQuery(params) { const adapter = getLinearAdapter(params.chat); if (!adapter) return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, params.query); if (params.query === 'get_user') { return await getLinearUser(adapter, getUserSchema.parse(params.input)); } if (params.query === 'search_users') { return await searchLinearUsers(adapter, searchUsersSchema.parse(params.input)); } if (params.query === 'get_team') { return await getLinearTeam(adapter, getTeamSchema.parse(params.input)); } if (params.query === 'search_teams') { return await searchLinearTeams(adapter, searchTeamsSchema.parse(params.input)); } if (params.query === 'get_project') { return await getLinearProject(adapter, getProjectSchema.parse(params.input)); } if (params.query === 'search_projects') { return await searchLinearProjects(adapter, searchProjectsSchema.parse(params.input)); } if (params.query === 'search_labels') { return await searchLinearLabels(adapter, searchLabelsSchema.parse(params.input)); } if (params.query === 'search_issue_states') { return await searchLinearIssueStates(adapter, searchIssueStatesSchema.parse(params.input)); } if (params.query === 'get_issue') { return await getLinearIssue(adapter, getIssueSchema.parse(params.input)); } if (params.query === 'search_issues') { return await searchLinearIssues(adapter, searchIssuesSchema.parse(params.input)); } return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, params.query); } async function executeLinearAction(params) { if (params.action === 'create_issue') { return await createLinearIssue(params.chat, params.descriptor, createIssueSchema.parse(params.input)); } if (params.action === 'update_issue') { return await updateLinearIssue(params.chat, params.descriptor, updateIssueSchema.parse(params.input)); } if (params.action === 'create_comment') { return await createLinearComment(params.chat, params.descriptor, createCommentSchema.parse(params.input)); } return undefined; } async function getLinearUser(adapter, input) { if (!hasMethod(adapter.client, 'user')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'get_user'); } const user = await adapter.client.user(input.userId); return { ok: true, user: normalizeLinearUser(user) ?? null }; } async function searchLinearUsers(adapter, input) { if (!hasMethod(adapter.client, 'users')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_users'); } const response = await adapter.client.users({ filter: buildLinearUserSearchFilter(input), first: input.limit, ...(input.cursor ? { after: input.cursor } : {}), includeArchived: input.includeDeleted, includeDisabled: input.includeDeleted, }); const users = linearNodes(response).map(normalizeLinearUser).filter(integration_helpers_1.isDefined); const nextCursor = extractLinearNextCursor(response); return { ok: true, users, resultCount: users.length, ...(nextCursor ? { nextCursor } : {}), }; } async function getLinearTeam(adapter, input) { if (!hasMethod(adapter.client, 'team')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'get_team'); } const team = await adapter.client.team(input.teamId); return { ok: true, team: normalizeLinearTeam(team) ?? null }; } async function searchLinearTeams(adapter, input) { if (!hasMethod(adapter.client, 'teams')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_teams'); } const response = await adapter.client.teams(buildLinearConnectionOptions(input, { includeArchived: true })); const teams = filterLinearRecords(linearNodes(response).map(normalizeLinearTeam).filter(integration_helpers_1.isDefined), input.query, ['teamId', 'key', 'name', 'description', 'url']); return linearSearchResult('teams', teams, response); } async function getLinearProject(adapter, input) { if (!hasMethod(adapter.client, 'project')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'get_project'); } const project = await adapter.client.project(input.projectId); return { ok: true, project: normalizeLinearProject(project) ?? null }; } async function searchLinearProjects(adapter, input) { const options = buildLinearConnectionOptions(input, { includeArchived: true }); const response = input.teamId ? await callLinearTeamConnection(adapter, input.teamId, ['projects'], options) : await callLinearProjectSearch(adapter, input, options); if (!response) return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_projects'); const projects = filterLinearRecords(linearNodes(response).map(normalizeLinearProject).filter(integration_helpers_1.isDefined), input.query, ['projectId', 'name', 'description', 'url', 'state']); return linearSearchResult('projects', projects, response); } async function searchLinearLabels(adapter, input) { const options = buildLinearConnectionOptions(input); const response = input.teamId ? await callLinearTeamConnection(adapter, input.teamId, ['labels'], options) : await callLinearIssueLabels(adapter, options); if (!response) return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_labels'); const labels = filterLinearRecords(linearNodes(response).map(normalizeLinearLabel).filter(integration_helpers_1.isDefined), input.query, ['labelId', 'name', 'description', 'color']); return linearSearchResult('labels', labels, response); } async function searchLinearIssueStates(adapter, input) { const options = buildLinearConnectionOptions(input); const response = input.teamId ? await callLinearTeamConnection(adapter, input.teamId, ['states', 'workflowStates'], options) : await callLinearWorkflowStates(adapter, options); if (!response) return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_issue_states'); const states = filterLinearIssueStates(linearNodes(response).map(normalizeLinearWorkflowState).filter(integration_helpers_1.isDefined), input); return linearSearchResult('states', states, response); } async function getLinearIssue(adapter, input) { if (!hasMethod(adapter.client, 'issue')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'get_issue'); } const issue = await adapter.client.issue(input.issueId); if (!issue) return { ok: true, issue: null }; return { ok: true, issue: await normalizeLinearIssue(issue, { includeComments: input.includeComments, commentsLimit: input.commentsLimit, }), }; } async function searchLinearIssues(adapter, input) { if (!hasMethod(adapter.client, 'searchIssues')) { return (0, integration_helpers_1.unsupportedQuery)(PLATFORM, 'search_issues'); } const response = await adapter.client.searchIssues(input.query, { first: input.limit, ...(input.cursor ? { after: input.cursor } : {}), ...(input.teamId ? { teamId: input.teamId } : {}), includeArchived: input.includeArchived, }); const issues = linearNodes(response).map(summarizeLinearIssue); const totalCount = (0, integration_helpers_1.numberProperty)(response, 'totalCount'); const nextCursor = extractLinearNextCursor(response); return { ok: true, issues, resultCount: issues.length, ...(totalCount !== undefined ? { totalCount } : {}), ...(nextCursor ? { nextCursor } : {}), }; } function extractLinearNextCursor(response) { if (!(0, integration_helpers_1.isRecord)(response)) return undefined; const pageInfo = response.pageInfo; if (!(0, integration_helpers_1.isRecord)(pageInfo)) return undefined; if (pageInfo.hasNextPage !== true) return undefined; return (0, integration_helpers_1.stringProperty)(pageInfo, 'endCursor'); } function buildLinearConnectionOptions(input, options = {}) { return (0, integration_helpers_1.removeUndefinedValues)({ first: input.limit, ...(input.cursor ? { after: input.cursor } : {}), ...(options.includeArchived ? { includeArchived: input.includeArchived ?? false } : {}), }); } async function callLinearProjectSearch(adapter, input, options) { if (input.query && hasMethod(adapter.client, 'searchProjects')) { return await adapter.client.searchProjects(input.query, options); } if (hasMethod(adapter.client, 'projects')) { return await adapter.client.projects(options); } return undefined; } async function callLinearIssueLabels(adapter, options) { if (!hasMethod(adapter.client, 'issueLabels')) return undefined; return await adapter.client.issueLabels(options); } async function callLinearWorkflowStates(adapter, options) { if (!hasMethod(adapter.client, 'workflowStates')) return undefined; return await adapter.client.workflowStates(options); } async function callLinearTeamConnection(adapter, teamId, keys, options) { if (!hasMethod(adapter.client, 'team')) return undefined; const team = await adapter.client.team(teamId); if (!(0, integration_helpers_1.isRecord)(team)) return undefined; for (const key of keys) { const response = await callLinearConnection(team, key, options); if (response !== undefined) return response; } return undefined; } function linearSearchResult(key, records, response) { const nextCursor = extractLinearNextCursor(response); const totalCount = (0, integration_helpers_1.numberProperty)(response, 'totalCount'); return { ok: true, [key]: records, resultCount: records.length, ...(totalCount !== undefined ? { totalCount } : {}), ...(nextCursor ? { nextCursor } : {}), }; } function filterLinearRecords(records, query, keys) { const term = query?.trim().toLowerCase(); if (!term) return records; return records.filter((record) => keys.some((key) => { const value = (0, integration_helpers_1.stringProperty)(record, key); return value !== undefined && value.toLowerCase().includes(term); })); } function filterLinearIssueStates(states, input) { const queryFilteredStates = filterLinearRecords(states, input.query, [ 'stateId', 'name', 'type', 'color', ]); if (!input.type) return queryFilteredStates; return queryFilteredStates.filter((state) => (0, integration_helpers_1.stringProperty)(state, 'type') === input.type); } async function createLinearIssue(chat, descriptor, input) { const adapter = getLinearAdapter(chat); if (!adapter || !hasMethod(adapter.client, 'createIssue')) { return (0, integration_helpers_1.unsupportedAction)(PLATFORM, 'create_issue'); } const payload = await adapter.client.createIssue((0, integration_helpers_1.removeUndefinedValues)({ ...input })); const rawIssue = await awaitableProperty(payload, 'issue'); const normalizedIssue = await normalizeLinearIssue(rawIssue ?? payload); const issueId = (0, integration_helpers_1.stringProperty)(normalizedIssue, 'issueId') ?? (0, integration_helpers_1.stringProperty)(payload, 'issueId') ?? (0, integration_helpers_1.stringProperty)(normalizedIssue, 'identifier'); if (!issueId) { return (0, integration_helpers_1.integrationError)(integration_error_codes_1.INTEGRATION_ERROR_CODES.ACTION_FAILED, 'Linear did not return an issue ID for the created issue.'); } return { ok: true, issue: normalizedIssue, messageContext: { integrationConnectionId: descriptor.integrationConnectionId, platform: descriptor.integration.type, target: { type: 'thread', threadId: `linear:${issueId}` }, subject: buildLinearIssueSubject(normalizedIssue, issueId), updatedAt: new Date().toISOString(), }, }; } async function updateLinearIssue(chat, descriptor, input) { const adapter = getLinearAdapter(chat); if (!adapter || !hasMethod(adapter.client, 'updateIssue')) { return (0, integration_helpers_1.unsupportedAction)(PLATFORM, 'update_issue'); } const payload = await adapter.client.updateIssue(input.issueId, buildLinearIssueUpdatePayload(input)); const rawIssue = await awaitableProperty(payload, 'issue'); const normalizedIssue = await normalizeLinearIssue(rawIssue ?? payload); const issueId = (0, integration_helpers_1.stringProperty)(normalizedIssue, 'issueId') ?? input.issueId; return { ok: true, issue: normalizedIssue, messageContext: { integrationConnectionId: descriptor.integrationConnectionId, platform: descriptor.integration.type, target: { type: 'thread', threadId: `linear:${issueId}` }, subject: buildLinearIssueSubject(normalizedIssue, issueId), updatedAt: new Date().toISOString(), }, }; } async function createLinearComment(chat, descriptor, input) { const adapter = getLinearAdapter(chat); if (!adapter || !hasMethod(adapter.client, 'createComment')) { return (0, integration_helpers_1.unsupportedAction)(PLATFORM, 'create_comment'); } const payload = await adapter.client.createComment((0, integration_helpers_1.removeUndefinedValues)({ issueId: input.issueId, body: input.body, parentId: input.parentCommentId, })); const rawComment = await awaitableProperty(payload, 'comment'); const normalizedComment = await normalizeLinearComment(rawComment ?? payload); const commentId = (0, integration_helpers_1.stringProperty)(normalizedComment, 'commentId') ?? (0, integration_helpers_1.stringProperty)(payload, 'commentId'); return { ok: true, comment: normalizedComment, messageContext: { integrationConnectionId: descriptor.integrationConnectionId, platform: descriptor.integration.type, target: { type: 'thread', threadId: input.parentCommentId ? `linear:${input.issueId}:c:${input.parentCommentId}` : `linear:${input.issueId}`, }, ...(commentId ? { messageId: commentId } : {}), subject: { type: 'issue', id: input.issueId }, updatedAt: new Date().toISOString(), }, }; } function buildLinearIssueUpdatePayload(input) { return (0, integration_helpers_1.removeUndefinedValues)({ teamId: input.teamId, title: input.title, description: input.description, assigneeId: input.assigneeId, projectId: input.projectId, labelIds: input.labelIds, priority: input.priority, stateId: input.stateId, parentId: input.parentId, }); } function getLinearAdapter(chat) { const adapter = chat.getAdapter('linear'); if (!(0, integration_helpers_1.isRecord)(adapter) || !(0, integration_helpers_1.isRecord)(adapter.client)) return undefined; return { client: adapter.client }; } function hasMethod(client, key) { return typeof client[key] === 'function'; } function buildLinearUserSearchFilter(input) { const term = buildLinearUserSearchTermFilter(input); if (input.includeBots) return term; return { and: [term, { app: { eq: false } }] }; } function buildLinearUserSearchTermFilter(input) { if (input.email) { return { email: { eqIgnoreCase: input.email.trim() } }; } const query = input.query?.trim() ?? ''; return { or: [ { name: { containsIgnoreCase: query } }, { displayName: { containsIgnoreCase: query } }, { email: { containsIgnoreCase: query } }, ], }; } function hasUpdateIssueField(input) { return (input.teamId !== undefined || input.title !== undefined || input.description !== undefined || input.assigneeId !== undefined || input.projectId !== undefined || input.labelIds !== undefined || input.priority !== undefined || input.stateId !== undefined || input.parentId !== undefined); } async function normalizeLinearIssue(value, options = {}) { const issue = (0, integration_helpers_1.isRecord)(value) ? value : {}; const [state, assignee, creator, team, project, labelsConnection] = await Promise.all([ awaitableProperty(issue, 'state'), awaitableProperty(issue, 'assignee'), awaitableProperty(issue, 'creator'), awaitableProperty(issue, 'team'), awaitableProperty(issue, 'project'), callLinearConnection(issue, 'labels', { first: 50 }), ]); const priority = normalizeLinearPriority(issue); const comments = options.includeComments ? await normalizeLinearComments(issue, options.commentsLimit ?? 10) : undefined; return (0, integration_helpers_1.removeUndefinedValues)({ issueId: (0, integration_helpers_1.stringProperty)(issue, 'id'), identifier: (0, integration_helpers_1.stringProperty)(issue, 'identifier'), title: (0, integration_helpers_1.stringProperty)(issue, 'title'), description: (0, integration_helpers_1.stringProperty)(issue, 'description'), url: (0, integration_helpers_1.stringProperty)(issue, 'url'), priority, state: normalizeLinearState(state), assignee: normalizeLinearUser(assignee), creator: normalizeLinearUser(creator), team: normalizeLinearTeam(team), project: normalizeLinearProject(project), labels: linearNodes(labelsConnection).map(normalizeLinearLabel).filter(integration_helpers_1.isDefined), createdAt: (0, integration_helpers_1.isoDateProperty)(issue, 'createdAt'), updatedAt: (0, integration_helpers_1.isoDateProperty)(issue, 'updatedAt'), ...(comments ? { comments } : {}), }); } function summarizeLinearIssue(value) { const issue = (0, integration_helpers_1.isRecord)(value) ? value : {}; return (0, integration_helpers_1.removeUndefinedValues)({ issueId: (0, integration_helpers_1.stringProperty)(issue, 'id'), identifier: (0, integration_helpers_1.stringProperty)(issue, 'identifier'), title: (0, integration_helpers_1.stringProperty)(issue, 'title'), url: (0, integration_helpers_1.stringProperty)(issue, 'url'), priority: normalizeLinearPriority(issue), createdAt: (0, integration_helpers_1.isoDateProperty)(issue, 'createdAt'), updatedAt: (0, integration_helpers_1.isoDateProperty)(issue, 'updatedAt'), }); } async function normalizeLinearComments(issue, commentsLimit) { const commentsConnection = await callLinearConnection(issue, 'comments', { first: commentsLimit, }); if (!commentsConnection) return undefined; return await Promise.all(linearNodes(commentsConnection).map(async (comment) => await normalizeLinearComment(comment))); } async function normalizeLinearComment(value) { const comment = (0, integration_helpers_1.isRecord)(value) ? value : {}; const author = await awaitableProperty(comment, 'user'); return (0, integration_helpers_1.removeUndefinedValues)({ commentId: (0, integration_helpers_1.stringProperty)(comment, 'id'), body: (0, integration_helpers_1.stringProperty)(comment, 'body'), url: (0, integration_helpers_1.stringProperty)(comment, 'url'), createdAt: (0, integration_helpers_1.isoDateProperty)(comment, 'createdAt'), updatedAt: (0, integration_helpers_1.isoDateProperty)(comment, 'updatedAt'), author: normalizeLinearUser(author), }); } function normalizeLinearUser(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; const userId = (0, integration_helpers_1.stringProperty)(value, 'id'); if (!userId) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ userId, name: (0, integration_helpers_1.stringProperty)(value, 'name') ?? userId, displayName: (0, integration_helpers_1.stringProperty)(value, 'displayName'), email: (0, integration_helpers_1.stringProperty)(value, 'email'), avatarUrl: (0, integration_helpers_1.stringProperty)(value, 'avatarUrl'), active: (0, integration_helpers_1.booleanProperty)(value, 'active'), isBot: (0, integration_helpers_1.booleanProperty)(value, 'app') ?? false, isAssignable: (0, integration_helpers_1.booleanProperty)(value, 'isAssignable'), isMentionable: (0, integration_helpers_1.booleanProperty)(value, 'isMentionable'), url: (0, integration_helpers_1.stringProperty)(value, 'url'), }); } function normalizeLinearState(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ id: (0, integration_helpers_1.stringProperty)(value, 'id'), name: (0, integration_helpers_1.stringProperty)(value, 'name'), type: (0, integration_helpers_1.stringProperty)(value, 'type'), }); } function normalizeLinearTeam(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ teamId: (0, integration_helpers_1.stringProperty)(value, 'id'), key: (0, integration_helpers_1.stringProperty)(value, 'key'), name: (0, integration_helpers_1.stringProperty)(value, 'name'), description: (0, integration_helpers_1.stringProperty)(value, 'description'), url: (0, integration_helpers_1.stringProperty)(value, 'url'), isPrivate: (0, integration_helpers_1.booleanProperty)(value, 'private'), isArchived: (0, integration_helpers_1.booleanProperty)(value, 'archived') ?? ((0, integration_helpers_1.stringProperty)(value, 'archivedAt') ? true : undefined), }); } function normalizeLinearProject(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ projectId: (0, integration_helpers_1.stringProperty)(value, 'id'), name: (0, integration_helpers_1.stringProperty)(value, 'name'), description: (0, integration_helpers_1.stringProperty)(value, 'description'), url: (0, integration_helpers_1.stringProperty)(value, 'url'), state: (0, integration_helpers_1.stringProperty)(value, 'state'), color: (0, integration_helpers_1.stringProperty)(value, 'color'), }); } function normalizeLinearLabel(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; const labelId = (0, integration_helpers_1.stringProperty)(value, 'id'); const name = (0, integration_helpers_1.stringProperty)(value, 'name'); if (!labelId || !name) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ labelId, name, color: (0, integration_helpers_1.stringProperty)(value, 'color'), description: (0, integration_helpers_1.stringProperty)(value, 'description'), }); } function normalizeLinearWorkflowState(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; const stateId = (0, integration_helpers_1.stringProperty)(value, 'id'); if (!stateId) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ stateId, name: (0, integration_helpers_1.stringProperty)(value, 'name'), type: (0, integration_helpers_1.stringProperty)(value, 'type'), color: (0, integration_helpers_1.stringProperty)(value, 'color'), position: (0, integration_helpers_1.numberProperty)(value, 'position'), }); } function normalizeLinearPriority(issue) { const value = (0, integration_helpers_1.numberProperty)(issue, 'priority'); const label = (0, integration_helpers_1.stringProperty)(issue, 'priorityLabel'); if (value === undefined && !label) return undefined; return (0, integration_helpers_1.removeUndefinedValues)({ value, label }); } function buildLinearIssueSubject(issue, fallbackIssueId) { const identifier = (0, integration_helpers_1.stringProperty)(issue, 'identifier'); const title = (0, integration_helpers_1.stringProperty)(issue, 'title'); const description = (0, integration_helpers_1.stringProperty)(issue, 'description'); const url = (0, integration_helpers_1.stringProperty)(issue, 'url'); const status = (0, integration_helpers_1.stringProperty)((0, integration_helpers_1.isRecord)(issue.state) ? issue.state : undefined, 'name'); const labels = linearLabelNames(issue); const assignee = linearSubjectPerson(issue.assignee); return { type: 'issue', id: identifier ?? fallbackIssueId, ...(title ? { title } : {}), ...(description ? { description } : {}), ...(url ? { url } : {}), ...(status ? { status } : {}), ...(labels.length > 0 ? { labels } : {}), ...(assignee ? { assignee } : {}), }; } function linearLabelNames(issue) { const labels = issue.labels; if (!Array.isArray(labels)) return []; return labels .map((label) => (0, integration_helpers_1.stringProperty)(label, 'name')) .filter((label) => label !== undefined); } function linearSubjectPerson(value) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; const id = (0, integration_helpers_1.stringProperty)(value, 'userId') ?? (0, integration_helpers_1.stringProperty)(value, 'id'); const name = (0, integration_helpers_1.stringProperty)(value, 'name') ?? (0, integration_helpers_1.stringProperty)(value, 'displayName'); if (!id || !name) return undefined; return { id, name }; } async function awaitableProperty(value, key) { if (!(0, integration_helpers_1.isRecord)(value)) return undefined; return await Promise.resolve(value[key]); } async function callLinearConnection(record, key, options) { const fn = record[key]; if (typeof fn !== 'function') return undefined; return await fn.call(record, options); } function linearNodes(value) { if (!(0, integration_helpers_1.isRecord)(value) || !Array.isArray(value.nodes)) return []; return value.nodes; } //# sourceMappingURL=linear-operations.js.map