Skip to content

Commit 32769da

Browse files
waleedlatif1claude
andcommitted
feat(jira): support raw ADF document objects in description and environment fields
Add toAdf() helper that passes through ADF objects as-is or wraps plain text in a single-paragraph ADF doc. Update write and update routes to use it, replacing inline ADF wrapping. Update Zod schema to accept string or object for description. Fully backward compatible — plain text still works, but callers can now pass rich ADF with expand nodes, tables, code blocks, etc. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7028e0d commit 32769da

5 files changed

Lines changed: 31 additions & 65 deletions

File tree

apps/sim/app/api/tools/jira/update/route.ts

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
33
import { z } from 'zod'
44
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
55
import { validateJiraCloudId, validateJiraIssueKey } from '@/lib/core/security/input-validation'
6-
import { getJiraCloudId, parseAtlassianErrorMessage } from '@/tools/jira/utils'
6+
import { getJiraCloudId, parseAtlassianErrorMessage, toAdf } from '@/tools/jira/utils'
77

88
export const dynamic = 'force-dynamic'
99

@@ -15,7 +15,7 @@ const jiraUpdateSchema = z.object({
1515
issueKey: z.string().min(1, 'Issue key is required'),
1616
summary: z.string().optional(),
1717
title: z.string().optional(),
18-
description: z.string().optional(),
18+
description: z.union([z.string(), z.record(z.unknown())]).optional(),
1919
priority: z.string().optional(),
2020
assignee: z.string().optional(),
2121
labels: z.array(z.string()).optional(),
@@ -91,21 +91,7 @@ export async function PUT(request: NextRequest) {
9191
}
9292

9393
if (description !== undefined && description !== null && description !== '') {
94-
fields.description = {
95-
type: 'doc',
96-
version: 1,
97-
content: [
98-
{
99-
type: 'paragraph',
100-
content: [
101-
{
102-
type: 'text',
103-
text: description,
104-
},
105-
],
106-
},
107-
],
108-
}
94+
fields.description = toAdf(description)
10995
}
11096

11197
if (priority !== undefined && priority !== null && priority !== '') {
@@ -136,21 +122,7 @@ export async function PUT(request: NextRequest) {
136122
}
137123

138124
if (environment !== undefined && environment !== null && environment !== '') {
139-
fields.environment = {
140-
type: 'doc',
141-
version: 1,
142-
content: [
143-
{
144-
type: 'paragraph',
145-
content: [
146-
{
147-
type: 'text',
148-
text: environment,
149-
},
150-
],
151-
},
152-
],
153-
}
125+
fields.environment = toAdf(environment)
154126
}
155127

156128
if (

apps/sim/app/api/tools/jira/write/route.ts

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createLogger } from '@sim/logger'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
44
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
5-
import { getJiraCloudId, parseAtlassianErrorMessage } from '@/tools/jira/utils'
5+
import { getJiraCloudId, parseAtlassianErrorMessage, toAdf } from '@/tools/jira/utils'
66

77
export const dynamic = 'force-dynamic'
88

@@ -85,21 +85,7 @@ export async function POST(request: NextRequest) {
8585
}
8686

8787
if (description !== undefined && description !== null && description !== '') {
88-
fields.description = {
89-
type: 'doc',
90-
version: 1,
91-
content: [
92-
{
93-
type: 'paragraph',
94-
content: [
95-
{
96-
type: 'text',
97-
text: description,
98-
},
99-
],
100-
},
101-
],
102-
}
88+
fields.description = toAdf(description)
10389
}
10490

10591
if (parent !== undefined && parent !== null && parent !== '') {
@@ -144,21 +130,7 @@ export async function POST(request: NextRequest) {
144130
}
145131

146132
if (environment !== undefined && environment !== null && environment !== '') {
147-
fields.environment = {
148-
type: 'doc',
149-
version: 1,
150-
content: [
151-
{
152-
type: 'paragraph',
153-
content: [
154-
{
155-
type: 'text',
156-
text: environment,
157-
},
158-
],
159-
},
160-
],
161-
}
133+
fields.environment = toAdf(environment)
162134
}
163135

164136
if (

apps/sim/tools/jira/update.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export const jiraUpdateTool: ToolConfig<JiraUpdateParams, JiraUpdateResponse> =
4242
type: 'string',
4343
required: false,
4444
visibility: 'user-or-llm',
45-
description: 'New description for the issue',
45+
description:
46+
'New description for the issue. Accepts plain text (auto-wrapped in ADF) or a raw ADF document object',
4647
},
4748
priority: {
4849
type: 'string',

apps/sim/tools/jira/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ const logger = createLogger('JiraUtils')
55

66
const MAX_ATTACHMENT_SIZE = 50 * 1024 * 1024
77

8+
/**
9+
* Converts a value to ADF format. If the value is already an ADF document object,
10+
* it is returned as-is. If it is a plain string, it is wrapped in a single-paragraph ADF doc.
11+
*/
12+
export function toAdf(value: string | Record<string, unknown>): Record<string, unknown> {
13+
if (typeof value === 'object' && value.type === 'doc') {
14+
return value
15+
}
16+
return {
17+
type: 'doc',
18+
version: 1,
19+
content: [
20+
{
21+
type: 'paragraph',
22+
content: [{ type: 'text', text: String(value) }],
23+
},
24+
],
25+
}
26+
}
27+
828
/**
929
* Extracts plain text from Atlassian Document Format (ADF) content.
1030
* Returns null if content is falsy.

apps/sim/tools/jira/write.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export const jiraWriteTool: ToolConfig<JiraWriteParams, JiraWriteResponse> = {
4242
type: 'string',
4343
required: false,
4444
visibility: 'user-or-llm',
45-
description: 'Description for the issue',
45+
description:
46+
'Description for the issue. Accepts plain text (auto-wrapped in ADF) or a raw ADF document object',
4647
},
4748
priority: {
4849
type: 'string',

0 commit comments

Comments
 (0)