chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1420 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: issues
|
|
3
|
+
description: "Jira JavaScript/TypeScript SDK Coding Guidelines for writing code using the Jira API with official libraries and SDKs"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "5.2.2"
|
|
7
|
+
updated-on: "2026-03-02"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "jira,issues,atlassian,project-management,agile"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Jira JavaScript/TypeScript SDK Coding Guidelines
|
|
13
|
+
|
|
14
|
+
You are a Jira API coding expert. Help me with writing code using the Jira API calling the official libraries and SDKs.
|
|
15
|
+
|
|
16
|
+
You can find the official Jira API documentation and code samples here:
|
|
17
|
+
https://developer.atlassian.com/cloud/jira/platform/rest/v3/
|
|
18
|
+
https://mrrefactoring.github.io/jira.js/
|
|
19
|
+
|
|
20
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
21
|
+
|
|
22
|
+
Always use the jira.js library to interact with the Jira Cloud, Jira Agile, and Jira Service Desk REST APIs. This is the most comprehensive and actively maintained JavaScript/TypeScript wrapper for Jira APIs.
|
|
23
|
+
|
|
24
|
+
- **Library Name:** jira.js
|
|
25
|
+
- **NPM Package:** `jira.js`
|
|
26
|
+
- **Minimum Node.js Version:** 20.0.0 or newer
|
|
27
|
+
- **Legacy Libraries**: `jira-connector`, `jira-client`, and other unofficial packages are not recommended
|
|
28
|
+
|
|
29
|
+
**Installation:**
|
|
30
|
+
|
|
31
|
+
- **Correct:** `npm install jira.js`
|
|
32
|
+
- **Correct:** `yarn add jira.js`
|
|
33
|
+
- **Correct:** `pnpm add jira.js`
|
|
34
|
+
|
|
35
|
+
**APIs and Usage:**
|
|
36
|
+
|
|
37
|
+
- **Correct:** `import { Version3Client } from 'jira.js'`
|
|
38
|
+
- **Correct:** `const client = new Version3Client({ host, authentication })`
|
|
39
|
+
- **Correct:** `await client.issues.createIssue(...)`
|
|
40
|
+
- **Correct:** `await client.issueSearch.searchForIssuesUsingJql(...)`
|
|
41
|
+
- **Incorrect:** `JiraClient`, `JiraApi`, or `JiraConnector`
|
|
42
|
+
- **Incorrect:** Using REST API endpoints directly without the SDK
|
|
43
|
+
- **Incorrect:** Using deprecated v1 or v2 API versions
|
|
44
|
+
|
|
45
|
+
## Authentication
|
|
46
|
+
|
|
47
|
+
The jira.js library supports multiple authentication methods. Always obtain API credentials from your Jira Cloud instance.
|
|
48
|
+
|
|
49
|
+
### Basic Authentication (Recommended for Jira Cloud)
|
|
50
|
+
|
|
51
|
+
Generate an API token at: https://id.atlassian.com/manage-profile/security/api-tokens
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
import { Version3Client } from 'jira.js';
|
|
55
|
+
|
|
56
|
+
const client = new Version3Client({
|
|
57
|
+
host: 'https://your-domain.atlassian.net',
|
|
58
|
+
authentication: {
|
|
59
|
+
basic: {
|
|
60
|
+
email: 'your@email.com',
|
|
61
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### OAuth 2.0 Authentication
|
|
68
|
+
|
|
69
|
+
OAuth 2.0 uses an access token obtained through the OAuth flow:
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
import { Version3Client } from 'jira.js';
|
|
73
|
+
|
|
74
|
+
const client = new Version3Client({
|
|
75
|
+
host: 'https://your-domain.atlassian.net',
|
|
76
|
+
authentication: {
|
|
77
|
+
oauth2: {
|
|
78
|
+
accessToken: process.env.JIRA_ACCESS_TOKEN,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### OAuth 1.0a Authentication (Legacy)
|
|
85
|
+
|
|
86
|
+
For Jira Server instances or legacy integrations:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
import { Version3Client } from 'jira.js';
|
|
90
|
+
|
|
91
|
+
const client = new Version3Client({
|
|
92
|
+
host: 'https://your-domain.atlassian.net',
|
|
93
|
+
authentication: {
|
|
94
|
+
oauth: {
|
|
95
|
+
consumerKey: process.env.JIRA_CONSUMER_KEY,
|
|
96
|
+
consumerSecret: process.env.JIRA_CONSUMER_SECRET,
|
|
97
|
+
accessToken: process.env.JIRA_ACCESS_TOKEN,
|
|
98
|
+
tokenSecret: process.env.JIRA_TOKEN_SECRET,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Environment Variables Setup
|
|
105
|
+
|
|
106
|
+
Create a `.env` file in your project root:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
JIRA_HOST=https://your-domain.atlassian.net
|
|
110
|
+
JIRA_EMAIL=your@email.com
|
|
111
|
+
JIRA_API_TOKEN=your_api_token_here
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Load environment variables in your code:
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
import 'dotenv/config';
|
|
118
|
+
import { Version3Client } from 'jira.js';
|
|
119
|
+
|
|
120
|
+
const client = new Version3Client({
|
|
121
|
+
host: process.env.JIRA_HOST,
|
|
122
|
+
authentication: {
|
|
123
|
+
basic: {
|
|
124
|
+
email: process.env.JIRA_EMAIL,
|
|
125
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Initialization
|
|
132
|
+
|
|
133
|
+
Create a client instance for all API interactions:
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
import { Version3Client } from 'jira.js';
|
|
137
|
+
|
|
138
|
+
// Basic initialization
|
|
139
|
+
const client = new Version3Client({
|
|
140
|
+
host: 'https://your-domain.atlassian.net',
|
|
141
|
+
authentication: {
|
|
142
|
+
basic: {
|
|
143
|
+
email: 'your@email.com',
|
|
144
|
+
apiToken: 'your_api_token',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// With custom timeout and other options
|
|
150
|
+
const clientWithOptions = new Version3Client({
|
|
151
|
+
host: 'https://your-domain.atlassian.net',
|
|
152
|
+
authentication: {
|
|
153
|
+
basic: {
|
|
154
|
+
email: 'your@email.com',
|
|
155
|
+
apiToken: 'your_api_token',
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
timeout: 30000, // 30 seconds
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Error Handling
|
|
163
|
+
|
|
164
|
+
The library provides two error types for comprehensive error handling:
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
import { Version3Client } from 'jira.js';
|
|
168
|
+
import { AxiosError } from 'axios';
|
|
169
|
+
|
|
170
|
+
const client = new Version3Client({
|
|
171
|
+
host: 'https://your-domain.atlassian.net',
|
|
172
|
+
authentication: {
|
|
173
|
+
basic: {
|
|
174
|
+
email: process.env.JIRA_EMAIL,
|
|
175
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const issue = await client.issues.getIssue({ issueIdOrKey: 'PROJECT-123' });
|
|
182
|
+
console.log(issue);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (error.name === 'HttpException') {
|
|
185
|
+
// Server errors with parsed details
|
|
186
|
+
console.error('HTTP Error:', error.statusCode, error.message);
|
|
187
|
+
console.error('Error details:', error.data);
|
|
188
|
+
} else if (error instanceof AxiosError) {
|
|
189
|
+
// Network or configuration errors
|
|
190
|
+
console.error('Network Error:', error.code, error.message);
|
|
191
|
+
} else {
|
|
192
|
+
console.error('Unexpected error:', error);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Core API Surfaces
|
|
198
|
+
|
|
199
|
+
### Projects
|
|
200
|
+
|
|
201
|
+
#### Get Project
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// Minimal example
|
|
205
|
+
const project = await client.projects.getProject({
|
|
206
|
+
projectIdOrKey: 'PROJ',
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
console.log(project.name);
|
|
210
|
+
console.log(project.key);
|
|
211
|
+
console.log(project.id);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Advanced: Get Project with Expanded Properties
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
// Advanced example with expand options
|
|
218
|
+
const project = await client.projects.getProject({
|
|
219
|
+
projectIdOrKey: 'PROJ',
|
|
220
|
+
expand: 'description,lead,issueTypes,url,projectKeys',
|
|
221
|
+
properties: '*all',
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
console.log('Project Name:', project.name);
|
|
225
|
+
console.log('Project Lead:', project.lead.displayName);
|
|
226
|
+
console.log('Description:', project.description);
|
|
227
|
+
console.log('Issue Types:', project.issueTypes);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### Search Projects
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
// Search for projects
|
|
234
|
+
const projects = await client.projects.searchProjects({
|
|
235
|
+
startAt: 0,
|
|
236
|
+
maxResults: 50,
|
|
237
|
+
orderBy: 'name',
|
|
238
|
+
query: 'development',
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
console.log('Total projects:', projects.total);
|
|
242
|
+
projects.values.forEach(project => {
|
|
243
|
+
console.log(`${project.key}: ${project.name}`);
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### Create Project
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
// Create a new project
|
|
251
|
+
const newProject = await client.projects.createProject({
|
|
252
|
+
key: 'NEWP',
|
|
253
|
+
name: 'New Project',
|
|
254
|
+
projectTypeKey: 'software',
|
|
255
|
+
projectTemplateKey: 'com.atlassian.jira-core-project-templates:jira-core-simplified-project-management',
|
|
256
|
+
description: 'This is a new project',
|
|
257
|
+
leadAccountId: '5b10a2844c20165700ede21g',
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
console.log('Created project:', newProject.key);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Issues
|
|
264
|
+
|
|
265
|
+
#### Create Issue
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
// Minimal example
|
|
269
|
+
const issue = await client.issues.createIssue({
|
|
270
|
+
fields: {
|
|
271
|
+
project: {
|
|
272
|
+
key: 'PROJ',
|
|
273
|
+
},
|
|
274
|
+
summary: 'New issue from API',
|
|
275
|
+
issuetype: {
|
|
276
|
+
name: 'Task',
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
console.log('Created issue:', issue.key);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### Advanced: Create Issue with All Fields
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
// Advanced example with multiple fields
|
|
288
|
+
const issue = await client.issues.createIssue({
|
|
289
|
+
fields: {
|
|
290
|
+
project: {
|
|
291
|
+
key: 'PROJ',
|
|
292
|
+
},
|
|
293
|
+
summary: 'Implement user authentication',
|
|
294
|
+
description: {
|
|
295
|
+
type: 'doc',
|
|
296
|
+
version: 1,
|
|
297
|
+
content: [
|
|
298
|
+
{
|
|
299
|
+
type: 'paragraph',
|
|
300
|
+
content: [
|
|
301
|
+
{
|
|
302
|
+
type: 'text',
|
|
303
|
+
text: 'Need to implement OAuth 2.0 authentication for the API.',
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
},
|
|
309
|
+
issuetype: {
|
|
310
|
+
name: 'Story',
|
|
311
|
+
},
|
|
312
|
+
priority: {
|
|
313
|
+
name: 'High',
|
|
314
|
+
},
|
|
315
|
+
labels: ['security', 'authentication'],
|
|
316
|
+
assignee: {
|
|
317
|
+
accountId: '5b10a2844c20165700ede21g',
|
|
318
|
+
},
|
|
319
|
+
duedate: '2025-12-31',
|
|
320
|
+
customfield_10001: 'Custom field value',
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
console.log('Created issue:', issue.key, issue.id);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### Get Issue
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
// Get an issue with all fields
|
|
331
|
+
const issue = await client.issues.getIssue({
|
|
332
|
+
issueIdOrKey: 'PROJ-123',
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
console.log('Summary:', issue.fields.summary);
|
|
336
|
+
console.log('Status:', issue.fields.status.name);
|
|
337
|
+
console.log('Assignee:', issue.fields.assignee?.displayName);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Advanced: Get Issue with Specific Fields
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
// Get specific fields and expand certain properties
|
|
344
|
+
const issue = await client.issues.getIssue({
|
|
345
|
+
issueIdOrKey: 'PROJ-123',
|
|
346
|
+
fields: ['summary', 'status', 'assignee', 'priority', 'created', 'updated'],
|
|
347
|
+
expand: 'changelog,renderedFields',
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log('Issue:', issue.key);
|
|
351
|
+
console.log('Summary:', issue.fields.summary);
|
|
352
|
+
console.log('Created:', issue.fields.created);
|
|
353
|
+
console.log('Change History:', issue.changelog);
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### Update Issue
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
// Update issue fields
|
|
360
|
+
await client.issues.editIssue({
|
|
361
|
+
issueIdOrKey: 'PROJ-123',
|
|
362
|
+
fields: {
|
|
363
|
+
summary: 'Updated summary',
|
|
364
|
+
description: {
|
|
365
|
+
type: 'doc',
|
|
366
|
+
version: 1,
|
|
367
|
+
content: [
|
|
368
|
+
{
|
|
369
|
+
type: 'paragraph',
|
|
370
|
+
content: [
|
|
371
|
+
{
|
|
372
|
+
type: 'text',
|
|
373
|
+
text: 'Updated description',
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
},
|
|
379
|
+
priority: {
|
|
380
|
+
name: 'Critical',
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
console.log('Issue updated successfully');
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Assign Issue
|
|
389
|
+
|
|
390
|
+
```javascript
|
|
391
|
+
// Assign issue to a user
|
|
392
|
+
await client.issues.assignIssue({
|
|
393
|
+
issueIdOrKey: 'PROJ-123',
|
|
394
|
+
accountId: '5b10a2844c20165700ede21g',
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### Add Comment
|
|
399
|
+
|
|
400
|
+
```javascript
|
|
401
|
+
// Add a comment to an issue
|
|
402
|
+
const comment = await client.issueComments.addComment({
|
|
403
|
+
issueIdOrKey: 'PROJ-123',
|
|
404
|
+
body: {
|
|
405
|
+
type: 'doc',
|
|
406
|
+
version: 1,
|
|
407
|
+
content: [
|
|
408
|
+
{
|
|
409
|
+
type: 'paragraph',
|
|
410
|
+
content: [
|
|
411
|
+
{
|
|
412
|
+
type: 'text',
|
|
413
|
+
text: 'This is a comment from the API',
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
console.log('Comment added:', comment.id);
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
#### Transition Issue
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
// Get available transitions
|
|
428
|
+
const transitions = await client.issues.getTransitions({
|
|
429
|
+
issueIdOrKey: 'PROJ-123',
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
console.log('Available transitions:');
|
|
433
|
+
transitions.transitions.forEach(t => {
|
|
434
|
+
console.log(`${t.id}: ${t.name}`);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Transition issue to a new status
|
|
438
|
+
await client.issues.doTransition({
|
|
439
|
+
issueIdOrKey: 'PROJ-123',
|
|
440
|
+
transition: {
|
|
441
|
+
id: '21', // ID from getTransitions
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
console.log('Issue transitioned successfully');
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
#### Delete Issue
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// Delete an issue
|
|
452
|
+
await client.issues.deleteIssue({
|
|
453
|
+
issueIdOrKey: 'PROJ-123',
|
|
454
|
+
deleteSubtasks: 'true',
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
console.log('Issue deleted successfully');
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Issue Search
|
|
461
|
+
|
|
462
|
+
#### Search with JQL (Jira Query Language)
|
|
463
|
+
|
|
464
|
+
```javascript
|
|
465
|
+
// Basic JQL search
|
|
466
|
+
const searchResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
467
|
+
jql: 'project = PROJ AND status = "In Progress"',
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
console.log('Total issues:', searchResults.total);
|
|
471
|
+
searchResults.issues.forEach(issue => {
|
|
472
|
+
console.log(`${issue.key}: ${issue.fields.summary}`);
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
#### Advanced: Search with Pagination and Sorting
|
|
477
|
+
|
|
478
|
+
```javascript
|
|
479
|
+
// Advanced search with pagination, sorting, and field selection
|
|
480
|
+
const searchResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
481
|
+
jql: 'project = PROJ AND assignee = currentUser() ORDER BY created DESC',
|
|
482
|
+
startAt: 0,
|
|
483
|
+
maxResults: 50,
|
|
484
|
+
fields: ['summary', 'status', 'assignee', 'priority', 'created'],
|
|
485
|
+
expand: ['changelog'],
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
console.log(`Showing ${searchResults.issues.length} of ${searchResults.total} issues`);
|
|
489
|
+
|
|
490
|
+
searchResults.issues.forEach(issue => {
|
|
491
|
+
console.log(`${issue.key}: ${issue.fields.summary}`);
|
|
492
|
+
console.log(` Status: ${issue.fields.status.name}`);
|
|
493
|
+
console.log(` Priority: ${issue.fields.priority.name}`);
|
|
494
|
+
console.log(` Created: ${issue.fields.created}`);
|
|
495
|
+
});
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
#### Pagination Example
|
|
499
|
+
|
|
500
|
+
```javascript
|
|
501
|
+
// Fetch all issues with pagination
|
|
502
|
+
async function getAllIssues(jql) {
|
|
503
|
+
const allIssues = [];
|
|
504
|
+
let startAt = 0;
|
|
505
|
+
const maxResults = 100;
|
|
506
|
+
let total = 0;
|
|
507
|
+
|
|
508
|
+
do {
|
|
509
|
+
const searchResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
510
|
+
jql,
|
|
511
|
+
startAt,
|
|
512
|
+
maxResults,
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
allIssues.push(...searchResults.issues);
|
|
516
|
+
total = searchResults.total;
|
|
517
|
+
startAt += maxResults;
|
|
518
|
+
|
|
519
|
+
console.log(`Fetched ${allIssues.length} of ${total} issues`);
|
|
520
|
+
} while (allIssues.length < total);
|
|
521
|
+
|
|
522
|
+
return allIssues;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Usage
|
|
526
|
+
const allProjectIssues = await getAllIssues('project = PROJ');
|
|
527
|
+
console.log('Total issues fetched:', allProjectIssues.length);
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
#### Complex JQL Queries
|
|
531
|
+
|
|
532
|
+
```javascript
|
|
533
|
+
// Complex JQL with multiple conditions
|
|
534
|
+
const jql = `
|
|
535
|
+
project = PROJ AND
|
|
536
|
+
status IN ("To Do", "In Progress") AND
|
|
537
|
+
priority IN (High, Critical) AND
|
|
538
|
+
assignee = currentUser() AND
|
|
539
|
+
created >= -30d
|
|
540
|
+
ORDER BY priority DESC, created ASC
|
|
541
|
+
`;
|
|
542
|
+
|
|
543
|
+
const issues = await client.issueSearch.searchForIssuesUsingJql({
|
|
544
|
+
jql: jql.trim(),
|
|
545
|
+
maxResults: 100,
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
console.log('High priority issues:', issues.total);
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Agile - Boards
|
|
552
|
+
|
|
553
|
+
#### Get All Boards
|
|
554
|
+
|
|
555
|
+
```javascript
|
|
556
|
+
// Minimal example
|
|
557
|
+
import { AgileClient } from 'jira.js';
|
|
558
|
+
|
|
559
|
+
const agileClient = new AgileClient({
|
|
560
|
+
host: 'https://your-domain.atlassian.net',
|
|
561
|
+
authentication: {
|
|
562
|
+
basic: {
|
|
563
|
+
email: process.env.JIRA_EMAIL,
|
|
564
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
const boards = await agileClient.board.getAllBoards();
|
|
570
|
+
|
|
571
|
+
boards.values.forEach(board => {
|
|
572
|
+
console.log(`${board.id}: ${board.name} (${board.type})`);
|
|
573
|
+
});
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
#### Advanced: Get Boards with Filters
|
|
577
|
+
|
|
578
|
+
```javascript
|
|
579
|
+
// Filter boards by project and type
|
|
580
|
+
const scrumBoards = await agileClient.board.getAllBoards({
|
|
581
|
+
projectKeyOrId: 'PROJ',
|
|
582
|
+
type: 'scrum',
|
|
583
|
+
startAt: 0,
|
|
584
|
+
maxResults: 50,
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
console.log('Scrum boards:');
|
|
588
|
+
scrumBoards.values.forEach(board => {
|
|
589
|
+
console.log(`${board.id}: ${board.name}`);
|
|
590
|
+
});
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
#### Get Board
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
// Get a specific board
|
|
597
|
+
const board = await agileClient.board.getBoard({
|
|
598
|
+
boardId: 1,
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
console.log('Board name:', board.name);
|
|
602
|
+
console.log('Board type:', board.type);
|
|
603
|
+
console.log('Board location:', board.location);
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
#### Get Issues for Board
|
|
607
|
+
|
|
608
|
+
```javascript
|
|
609
|
+
// Get all issues on a board
|
|
610
|
+
const boardIssues = await agileClient.board.getIssuesForBoard({
|
|
611
|
+
boardId: 1,
|
|
612
|
+
startAt: 0,
|
|
613
|
+
maxResults: 50,
|
|
614
|
+
jql: 'status != Done',
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
console.log('Issues on board:', boardIssues.total);
|
|
618
|
+
boardIssues.issues.forEach(issue => {
|
|
619
|
+
console.log(`${issue.key}: ${issue.fields.summary}`);
|
|
620
|
+
});
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### Agile - Sprints
|
|
624
|
+
|
|
625
|
+
#### Create Sprint
|
|
626
|
+
|
|
627
|
+
```javascript
|
|
628
|
+
// Create a new sprint
|
|
629
|
+
const sprint = await agileClient.sprint.createSprint({
|
|
630
|
+
name: 'Sprint 23',
|
|
631
|
+
startDate: '2025-11-15T10:00:00.000Z',
|
|
632
|
+
endDate: '2025-11-29T18:00:00.000Z',
|
|
633
|
+
originBoardId: 1,
|
|
634
|
+
goal: 'Complete user authentication feature',
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
console.log('Created sprint:', sprint.id, sprint.name);
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
#### Advanced: Create Sprint with Minimal Fields
|
|
641
|
+
|
|
642
|
+
```javascript
|
|
643
|
+
// Create a future sprint (only name and board required)
|
|
644
|
+
const futureSprint = await agileClient.sprint.createSprint({
|
|
645
|
+
name: 'Q1 Sprint 1',
|
|
646
|
+
originBoardId: 1,
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
console.log('Created future sprint:', futureSprint.id);
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
#### Get Sprint
|
|
653
|
+
|
|
654
|
+
```javascript
|
|
655
|
+
// Get sprint details
|
|
656
|
+
const sprint = await agileClient.sprint.getSprint({
|
|
657
|
+
sprintId: 123,
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
console.log('Sprint:', sprint.name);
|
|
661
|
+
console.log('State:', sprint.state);
|
|
662
|
+
console.log('Start Date:', sprint.startDate);
|
|
663
|
+
console.log('End Date:', sprint.endDate);
|
|
664
|
+
console.log('Goal:', sprint.goal);
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
#### Update Sprint
|
|
668
|
+
|
|
669
|
+
```javascript
|
|
670
|
+
// Update sprint details
|
|
671
|
+
await agileClient.sprint.updateSprint({
|
|
672
|
+
sprintId: 123,
|
|
673
|
+
name: 'Updated Sprint Name',
|
|
674
|
+
goal: 'Updated sprint goal',
|
|
675
|
+
startDate: '2025-11-15T10:00:00.000Z',
|
|
676
|
+
endDate: '2025-11-29T18:00:00.000Z',
|
|
677
|
+
state: 'active',
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
console.log('Sprint updated successfully');
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
#### Get Issues for Sprint
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
// Get all issues in a sprint
|
|
687
|
+
const sprintIssues = await agileClient.sprint.getIssuesForSprint({
|
|
688
|
+
sprintId: 123,
|
|
689
|
+
startAt: 0,
|
|
690
|
+
maxResults: 50,
|
|
691
|
+
jql: 'status != Done',
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
console.log('Issues in sprint:', sprintIssues.total);
|
|
695
|
+
sprintIssues.issues.forEach(issue => {
|
|
696
|
+
console.log(`${issue.key}: ${issue.fields.summary}`);
|
|
697
|
+
});
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
#### Move Issues to Sprint
|
|
701
|
+
|
|
702
|
+
```javascript
|
|
703
|
+
// Move issues to a sprint (max 50 issues per operation)
|
|
704
|
+
await agileClient.sprint.moveIssuesToSprintAndRank({
|
|
705
|
+
sprintId: 123,
|
|
706
|
+
issues: ['PROJ-123', 'PROJ-124', 'PROJ-125'],
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
console.log('Issues moved to sprint successfully');
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
#### Delete Sprint
|
|
713
|
+
|
|
714
|
+
```javascript
|
|
715
|
+
// Delete a sprint
|
|
716
|
+
await agileClient.sprint.deleteSprint({
|
|
717
|
+
sprintId: 123,
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
console.log('Sprint deleted successfully');
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### Users
|
|
724
|
+
|
|
725
|
+
#### Get Current User
|
|
726
|
+
|
|
727
|
+
```javascript
|
|
728
|
+
// Get currently authenticated user
|
|
729
|
+
const currentUser = await client.myself.getCurrentUser();
|
|
730
|
+
|
|
731
|
+
console.log('User:', currentUser.displayName);
|
|
732
|
+
console.log('Email:', currentUser.emailAddress);
|
|
733
|
+
console.log('Account ID:', currentUser.accountId);
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
#### Find Users
|
|
737
|
+
|
|
738
|
+
```javascript
|
|
739
|
+
// Search for users by query
|
|
740
|
+
const users = await client.userSearch.findUsers({
|
|
741
|
+
query: 'john',
|
|
742
|
+
maxResults: 50,
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
users.forEach(user => {
|
|
746
|
+
console.log(`${user.displayName} (${user.emailAddress})`);
|
|
747
|
+
});
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
#### Get User
|
|
751
|
+
|
|
752
|
+
```javascript
|
|
753
|
+
// Get a specific user by account ID
|
|
754
|
+
const user = await client.users.getUser({
|
|
755
|
+
accountId: '5b10a2844c20165700ede21g',
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
console.log('User:', user.displayName);
|
|
759
|
+
console.log('Active:', user.active);
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
### Filters
|
|
763
|
+
|
|
764
|
+
#### Get Filters
|
|
765
|
+
|
|
766
|
+
```javascript
|
|
767
|
+
// Get all filters for the current user
|
|
768
|
+
const filters = await client.filters.getFavouriteFilters();
|
|
769
|
+
|
|
770
|
+
filters.forEach(filter => {
|
|
771
|
+
console.log(`${filter.id}: ${filter.name}`);
|
|
772
|
+
console.log(` JQL: ${filter.jql}`);
|
|
773
|
+
});
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
#### Create Filter
|
|
777
|
+
|
|
778
|
+
```javascript
|
|
779
|
+
// Create a new filter
|
|
780
|
+
const filter = await client.filters.createFilter({
|
|
781
|
+
name: 'My High Priority Issues',
|
|
782
|
+
description: 'All high priority issues assigned to me',
|
|
783
|
+
jql: 'assignee = currentUser() AND priority = High',
|
|
784
|
+
favourite: true,
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
console.log('Created filter:', filter.id, filter.name);
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
#### Get Filter
|
|
791
|
+
|
|
792
|
+
```javascript
|
|
793
|
+
// Get a specific filter
|
|
794
|
+
const filter = await client.filters.getFilter({
|
|
795
|
+
id: 10000,
|
|
796
|
+
expand: 'subscriptions,owner',
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
console.log('Filter:', filter.name);
|
|
800
|
+
console.log('JQL:', filter.jql);
|
|
801
|
+
console.log('Owner:', filter.owner.displayName);
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
#### Search with Filter
|
|
805
|
+
|
|
806
|
+
```javascript
|
|
807
|
+
// Execute a saved filter
|
|
808
|
+
const filterResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
809
|
+
jql: `filter = ${filterId}`,
|
|
810
|
+
maxResults: 100,
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
console.log('Filter results:', filterResults.total);
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Workflows
|
|
817
|
+
|
|
818
|
+
#### Get All Workflows
|
|
819
|
+
|
|
820
|
+
```javascript
|
|
821
|
+
// Get all workflows
|
|
822
|
+
const workflows = await client.workflows.getAllWorkflows({
|
|
823
|
+
workflowName: undefined,
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
workflows.forEach(workflow => {
|
|
827
|
+
console.log(`${workflow.id}: ${workflow.name}`);
|
|
828
|
+
});
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
#### Get Issue Transitions
|
|
832
|
+
|
|
833
|
+
```javascript
|
|
834
|
+
// Get available transitions for an issue
|
|
835
|
+
const transitions = await client.issues.getTransitions({
|
|
836
|
+
issueIdOrKey: 'PROJ-123',
|
|
837
|
+
expand: 'transitions.fields',
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
console.log('Available transitions:');
|
|
841
|
+
transitions.transitions.forEach(transition => {
|
|
842
|
+
console.log(`${transition.id}: ${transition.name}`);
|
|
843
|
+
console.log(` To status: ${transition.to.name}`);
|
|
844
|
+
});
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
### Custom Fields
|
|
848
|
+
|
|
849
|
+
#### Get All Fields
|
|
850
|
+
|
|
851
|
+
```javascript
|
|
852
|
+
// Get all fields in Jira
|
|
853
|
+
const fields = await client.issueFields.getFields();
|
|
854
|
+
|
|
855
|
+
fields.forEach(field => {
|
|
856
|
+
if (field.custom) {
|
|
857
|
+
console.log(`Custom Field: ${field.id} - ${field.name}`);
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
#### Get Custom Field Options
|
|
863
|
+
|
|
864
|
+
```javascript
|
|
865
|
+
// Get options for a custom field
|
|
866
|
+
const customFieldId = 'customfield_10001';
|
|
867
|
+
const issue = await client.issues.getIssue({
|
|
868
|
+
issueIdOrKey: 'PROJ-123',
|
|
869
|
+
fields: [customFieldId],
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
console.log('Custom field value:', issue.fields[customFieldId]);
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
### Versions (Releases)
|
|
876
|
+
|
|
877
|
+
#### Create Version
|
|
878
|
+
|
|
879
|
+
```javascript
|
|
880
|
+
// Create a new version/release
|
|
881
|
+
const version = await client.projectVersions.createVersion({
|
|
882
|
+
name: 'v1.2.0',
|
|
883
|
+
description: 'Q4 2025 Release',
|
|
884
|
+
projectId: 10000,
|
|
885
|
+
releaseDate: '2025-12-15',
|
|
886
|
+
archived: false,
|
|
887
|
+
released: false,
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
console.log('Created version:', version.id, version.name);
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
#### Get Version
|
|
894
|
+
|
|
895
|
+
```javascript
|
|
896
|
+
// Get a specific version
|
|
897
|
+
const version = await client.projectVersions.getVersion({
|
|
898
|
+
id: '10001',
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
console.log('Version:', version.name);
|
|
902
|
+
console.log('Released:', version.released);
|
|
903
|
+
console.log('Release Date:', version.releaseDate);
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
#### Update Version
|
|
907
|
+
|
|
908
|
+
```javascript
|
|
909
|
+
// Update a version
|
|
910
|
+
await client.projectVersions.updateVersion({
|
|
911
|
+
id: '10001',
|
|
912
|
+
name: 'v1.2.1',
|
|
913
|
+
description: 'Updated release',
|
|
914
|
+
released: true,
|
|
915
|
+
releaseDate: '2025-12-20',
|
|
916
|
+
});
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
### Labels
|
|
920
|
+
|
|
921
|
+
#### Add Labels to Issue
|
|
922
|
+
|
|
923
|
+
```javascript
|
|
924
|
+
// Add labels to an issue
|
|
925
|
+
await client.issues.editIssue({
|
|
926
|
+
issueIdOrKey: 'PROJ-123',
|
|
927
|
+
fields: {
|
|
928
|
+
labels: ['backend', 'api', 'urgent'],
|
|
929
|
+
},
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
console.log('Labels added successfully');
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
#### Get All Labels
|
|
936
|
+
|
|
937
|
+
```javascript
|
|
938
|
+
// Search for labels
|
|
939
|
+
const labels = await client.labels.getAllLabels({
|
|
940
|
+
startAt: 0,
|
|
941
|
+
maxResults: 1000,
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
console.log('Total labels:', labels.total);
|
|
945
|
+
labels.values.forEach(label => {
|
|
946
|
+
console.log(label);
|
|
947
|
+
});
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
### Components
|
|
951
|
+
|
|
952
|
+
#### Get Project Components
|
|
953
|
+
|
|
954
|
+
```javascript
|
|
955
|
+
// Get all components for a project
|
|
956
|
+
const components = await client.projectComponents.getProjectComponents({
|
|
957
|
+
projectIdOrKey: 'PROJ',
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
components.forEach(component => {
|
|
961
|
+
console.log(`${component.id}: ${component.name}`);
|
|
962
|
+
console.log(` Description: ${component.description}`);
|
|
963
|
+
console.log(` Lead: ${component.lead?.displayName}`);
|
|
964
|
+
});
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
#### Create Component
|
|
968
|
+
|
|
969
|
+
```javascript
|
|
970
|
+
// Create a new component
|
|
971
|
+
const component = await client.projectComponents.createComponent({
|
|
972
|
+
name: 'Frontend',
|
|
973
|
+
description: 'Frontend components and pages',
|
|
974
|
+
project: 'PROJ',
|
|
975
|
+
leadAccountId: '5b10a2844c20165700ede21g',
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
console.log('Created component:', component.id, component.name);
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
### Attachments
|
|
982
|
+
|
|
983
|
+
#### Add Attachment
|
|
984
|
+
|
|
985
|
+
```javascript
|
|
986
|
+
import fs from 'fs';
|
|
987
|
+
import FormData from 'form-data';
|
|
988
|
+
|
|
989
|
+
// Add attachment to an issue
|
|
990
|
+
const formData = new FormData();
|
|
991
|
+
formData.append('file', fs.createReadStream('/path/to/file.pdf'));
|
|
992
|
+
|
|
993
|
+
const attachments = await client.issueAttachments.addAttachment({
|
|
994
|
+
issueIdOrKey: 'PROJ-123',
|
|
995
|
+
attachment: formData,
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
console.log('Attachment added:', attachments[0].filename);
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
#### Get Attachment
|
|
1002
|
+
|
|
1003
|
+
```javascript
|
|
1004
|
+
// Get attachment metadata
|
|
1005
|
+
const issue = await client.issues.getIssue({
|
|
1006
|
+
issueIdOrKey: 'PROJ-123',
|
|
1007
|
+
fields: ['attachment'],
|
|
1008
|
+
});
|
|
1009
|
+
|
|
1010
|
+
issue.fields.attachment.forEach(attachment => {
|
|
1011
|
+
console.log(`${attachment.filename} - ${attachment.size} bytes`);
|
|
1012
|
+
console.log(` Download: ${attachment.content}`);
|
|
1013
|
+
});
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
### Webhooks
|
|
1017
|
+
|
|
1018
|
+
#### Create Webhook
|
|
1019
|
+
|
|
1020
|
+
```javascript
|
|
1021
|
+
// Create a webhook
|
|
1022
|
+
const webhook = await client.webhooks.registerDynamicWebhooks({
|
|
1023
|
+
url: 'https://your-domain.com/webhook',
|
|
1024
|
+
webhooks: [
|
|
1025
|
+
{
|
|
1026
|
+
events: ['jira:issue_created', 'jira:issue_updated'],
|
|
1027
|
+
jqlFilter: 'project = PROJ',
|
|
1028
|
+
},
|
|
1029
|
+
],
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
console.log('Webhook created:', webhook);
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
#### Get Webhooks
|
|
1036
|
+
|
|
1037
|
+
```javascript
|
|
1038
|
+
// Get all registered webhooks
|
|
1039
|
+
const webhooks = await client.webhooks.getDynamicWebhooksForApp();
|
|
1040
|
+
|
|
1041
|
+
webhooks.forEach(webhook => {
|
|
1042
|
+
console.log(`Webhook ${webhook.id}:`);
|
|
1043
|
+
console.log(` URL: ${webhook.url}`);
|
|
1044
|
+
console.log(` Events: ${webhook.events.join(', ')}`);
|
|
1045
|
+
});
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
### Permissions
|
|
1049
|
+
|
|
1050
|
+
#### Get My Permissions
|
|
1051
|
+
|
|
1052
|
+
```javascript
|
|
1053
|
+
// Get current user permissions
|
|
1054
|
+
const permissions = await client.permissions.getMyPermissions({
|
|
1055
|
+
projectKey: 'PROJ',
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
console.log('Permissions for project PROJ:');
|
|
1059
|
+
Object.entries(permissions.permissions).forEach(([key, permission]) => {
|
|
1060
|
+
console.log(`${key}: ${permission.havePermission}`);
|
|
1061
|
+
});
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
#### Get Bulk Permissions
|
|
1065
|
+
|
|
1066
|
+
```javascript
|
|
1067
|
+
// Get permissions for multiple projects
|
|
1068
|
+
const bulkPermissions = await client.permissions.getBulkPermissions({
|
|
1069
|
+
projectKey: ['PROJ1', 'PROJ2', 'PROJ3'],
|
|
1070
|
+
permissions: ['BROWSE_PROJECTS', 'CREATE_ISSUES', 'EDIT_ISSUES'],
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
console.log('Bulk permissions:', bulkPermissions);
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
## API Client Optimization
|
|
1077
|
+
|
|
1078
|
+
### Using Version 2 Client
|
|
1079
|
+
|
|
1080
|
+
For legacy Jira instances or when you need v2 endpoints:
|
|
1081
|
+
|
|
1082
|
+
```javascript
|
|
1083
|
+
import { Version2Client } from 'jira.js';
|
|
1084
|
+
|
|
1085
|
+
const v2Client = new Version2Client({
|
|
1086
|
+
host: 'https://your-domain.atlassian.net',
|
|
1087
|
+
authentication: {
|
|
1088
|
+
basic: {
|
|
1089
|
+
email: process.env.JIRA_EMAIL,
|
|
1090
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
});
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
### Using Agile Client
|
|
1097
|
+
|
|
1098
|
+
For dedicated Agile/Scrum operations:
|
|
1099
|
+
|
|
1100
|
+
```javascript
|
|
1101
|
+
import { AgileClient } from 'jira.js';
|
|
1102
|
+
|
|
1103
|
+
const agileClient = new AgileClient({
|
|
1104
|
+
host: 'https://your-domain.atlassian.net',
|
|
1105
|
+
authentication: {
|
|
1106
|
+
basic: {
|
|
1107
|
+
email: process.env.JIRA_EMAIL,
|
|
1108
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
1109
|
+
},
|
|
1110
|
+
},
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
// Agile client provides specialized methods for boards, sprints, and backlogs
|
|
1114
|
+
const boards = await agileClient.board.getAllBoards();
|
|
1115
|
+
const sprints = await agileClient.sprint.getAllSprints({ boardId: 1 });
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
### Bundle Size Optimization
|
|
1119
|
+
|
|
1120
|
+
Import only what you need to reduce bundle size:
|
|
1121
|
+
|
|
1122
|
+
```javascript
|
|
1123
|
+
// Instead of importing the full client
|
|
1124
|
+
import { Board } from 'jira.js/agile';
|
|
1125
|
+
import { Issues } from 'jira.js/version3';
|
|
1126
|
+
|
|
1127
|
+
// Use specific modules
|
|
1128
|
+
const board = new Board({
|
|
1129
|
+
host: 'https://your-domain.atlassian.net',
|
|
1130
|
+
authentication: { /* ... */ },
|
|
1131
|
+
});
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
## Common Patterns
|
|
1135
|
+
|
|
1136
|
+
### Batch Operations
|
|
1137
|
+
|
|
1138
|
+
```javascript
|
|
1139
|
+
// Create multiple issues in batch
|
|
1140
|
+
async function createMultipleIssues(issuesData) {
|
|
1141
|
+
const promises = issuesData.map(issueData =>
|
|
1142
|
+
client.issues.createIssue({
|
|
1143
|
+
fields: issueData,
|
|
1144
|
+
})
|
|
1145
|
+
);
|
|
1146
|
+
|
|
1147
|
+
const results = await Promise.all(promises);
|
|
1148
|
+
return results;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
// Usage
|
|
1152
|
+
const issues = await createMultipleIssues([
|
|
1153
|
+
{
|
|
1154
|
+
project: { key: 'PROJ' },
|
|
1155
|
+
summary: 'Task 1',
|
|
1156
|
+
issuetype: { name: 'Task' },
|
|
1157
|
+
},
|
|
1158
|
+
{
|
|
1159
|
+
project: { key: 'PROJ' },
|
|
1160
|
+
summary: 'Task 2',
|
|
1161
|
+
issuetype: { name: 'Task' },
|
|
1162
|
+
},
|
|
1163
|
+
]);
|
|
1164
|
+
|
|
1165
|
+
console.log('Created issues:', issues.map(i => i.key));
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
### Rate Limiting
|
|
1169
|
+
|
|
1170
|
+
```javascript
|
|
1171
|
+
// Implement rate limiting for bulk operations
|
|
1172
|
+
async function rateLimitedOperation(items, operation, rateLimit = 10) {
|
|
1173
|
+
const results = [];
|
|
1174
|
+
|
|
1175
|
+
for (let i = 0; i < items.length; i += rateLimit) {
|
|
1176
|
+
const batch = items.slice(i, i + rateLimit);
|
|
1177
|
+
const batchResults = await Promise.all(
|
|
1178
|
+
batch.map(item => operation(item))
|
|
1179
|
+
);
|
|
1180
|
+
results.push(...batchResults);
|
|
1181
|
+
|
|
1182
|
+
// Wait before next batch (optional)
|
|
1183
|
+
if (i + rateLimit < items.length) {
|
|
1184
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
return results;
|
|
1189
|
+
}
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
### Retry Logic
|
|
1193
|
+
|
|
1194
|
+
```javascript
|
|
1195
|
+
// Implement retry logic for failed requests
|
|
1196
|
+
async function withRetry(operation, maxRetries = 3, delay = 1000) {
|
|
1197
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
1198
|
+
try {
|
|
1199
|
+
return await operation();
|
|
1200
|
+
} catch (error) {
|
|
1201
|
+
if (attempt === maxRetries) throw error;
|
|
1202
|
+
|
|
1203
|
+
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
|
|
1204
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
1205
|
+
delay *= 2; // Exponential backoff
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
// Usage
|
|
1211
|
+
const issue = await withRetry(() =>
|
|
1212
|
+
client.issues.getIssue({ issueIdOrKey: 'PROJ-123' })
|
|
1213
|
+
);
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
## Complete Application Example
|
|
1217
|
+
|
|
1218
|
+
```javascript
|
|
1219
|
+
import 'dotenv/config';
|
|
1220
|
+
import { Version3Client } from 'jira.js';
|
|
1221
|
+
|
|
1222
|
+
// Initialize client
|
|
1223
|
+
const client = new Version3Client({
|
|
1224
|
+
host: process.env.JIRA_HOST,
|
|
1225
|
+
authentication: {
|
|
1226
|
+
basic: {
|
|
1227
|
+
email: process.env.JIRA_EMAIL,
|
|
1228
|
+
apiToken: process.env.JIRA_API_TOKEN,
|
|
1229
|
+
},
|
|
1230
|
+
},
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
async function main() {
|
|
1234
|
+
try {
|
|
1235
|
+
// Get current user
|
|
1236
|
+
const user = await client.myself.getCurrentUser();
|
|
1237
|
+
console.log(`Logged in as: ${user.displayName}`);
|
|
1238
|
+
|
|
1239
|
+
// Create a new issue
|
|
1240
|
+
const newIssue = await client.issues.createIssue({
|
|
1241
|
+
fields: {
|
|
1242
|
+
project: { key: 'PROJ' },
|
|
1243
|
+
summary: 'Implement new feature',
|
|
1244
|
+
description: {
|
|
1245
|
+
type: 'doc',
|
|
1246
|
+
version: 1,
|
|
1247
|
+
content: [
|
|
1248
|
+
{
|
|
1249
|
+
type: 'paragraph',
|
|
1250
|
+
content: [
|
|
1251
|
+
{
|
|
1252
|
+
type: 'text',
|
|
1253
|
+
text: 'This is a new feature request from the API',
|
|
1254
|
+
},
|
|
1255
|
+
],
|
|
1256
|
+
},
|
|
1257
|
+
],
|
|
1258
|
+
},
|
|
1259
|
+
issuetype: { name: 'Story' },
|
|
1260
|
+
priority: { name: 'High' },
|
|
1261
|
+
},
|
|
1262
|
+
});
|
|
1263
|
+
|
|
1264
|
+
console.log(`Created issue: ${newIssue.key}`);
|
|
1265
|
+
|
|
1266
|
+
// Add a comment
|
|
1267
|
+
await client.issueComments.addComment({
|
|
1268
|
+
issueIdOrKey: newIssue.key,
|
|
1269
|
+
body: {
|
|
1270
|
+
type: 'doc',
|
|
1271
|
+
version: 1,
|
|
1272
|
+
content: [
|
|
1273
|
+
{
|
|
1274
|
+
type: 'paragraph',
|
|
1275
|
+
content: [
|
|
1276
|
+
{
|
|
1277
|
+
type: 'text',
|
|
1278
|
+
text: 'Starting work on this issue',
|
|
1279
|
+
},
|
|
1280
|
+
],
|
|
1281
|
+
},
|
|
1282
|
+
],
|
|
1283
|
+
},
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
console.log('Comment added');
|
|
1287
|
+
|
|
1288
|
+
// Search for issues
|
|
1289
|
+
const searchResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
1290
|
+
jql: 'project = PROJ AND status = "To Do" ORDER BY created DESC',
|
|
1291
|
+
maxResults: 10,
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
console.log(`Found ${searchResults.total} issues`);
|
|
1295
|
+
searchResults.issues.forEach(issue => {
|
|
1296
|
+
console.log(` ${issue.key}: ${issue.fields.summary}`);
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
} catch (error) {
|
|
1300
|
+
console.error('Error:', error.message);
|
|
1301
|
+
if (error.data) {
|
|
1302
|
+
console.error('Error details:', error.data);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
main();
|
|
1308
|
+
```
|
|
1309
|
+
|
|
1310
|
+
## TypeScript Support
|
|
1311
|
+
|
|
1312
|
+
jira.js is written in TypeScript and provides full type definitions:
|
|
1313
|
+
|
|
1314
|
+
```typescript
|
|
1315
|
+
import { Version3Client } from 'jira.js';
|
|
1316
|
+
import type { Issue, IssueBean, SearchResults } from 'jira.js/out/version3/models';
|
|
1317
|
+
|
|
1318
|
+
const client = new Version3Client({
|
|
1319
|
+
host: process.env.JIRA_HOST!,
|
|
1320
|
+
authentication: {
|
|
1321
|
+
basic: {
|
|
1322
|
+
email: process.env.JIRA_EMAIL!,
|
|
1323
|
+
apiToken: process.env.JIRA_API_TOKEN!,
|
|
1324
|
+
},
|
|
1325
|
+
},
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1328
|
+
async function getIssues(projectKey: string): Promise<Issue[]> {
|
|
1329
|
+
const results: SearchResults = await client.issueSearch.searchForIssuesUsingJql({
|
|
1330
|
+
jql: `project = ${projectKey}`,
|
|
1331
|
+
maxResults: 100,
|
|
1332
|
+
});
|
|
1333
|
+
|
|
1334
|
+
return results.issues || [];
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
async function createIssue(summary: string, projectKey: string): Promise<IssueBean> {
|
|
1338
|
+
return await client.issues.createIssue({
|
|
1339
|
+
fields: {
|
|
1340
|
+
project: { key: projectKey },
|
|
1341
|
+
summary,
|
|
1342
|
+
issuetype: { name: 'Task' },
|
|
1343
|
+
},
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
## Common JQL Patterns
|
|
1349
|
+
|
|
1350
|
+
```javascript
|
|
1351
|
+
// Issues assigned to current user
|
|
1352
|
+
const jql1 = 'assignee = currentUser()';
|
|
1353
|
+
|
|
1354
|
+
// Issues created in the last 7 days
|
|
1355
|
+
const jql2 = 'created >= -7d';
|
|
1356
|
+
|
|
1357
|
+
// High priority bugs not resolved
|
|
1358
|
+
const jql3 = 'type = Bug AND priority = High AND status != Resolved';
|
|
1359
|
+
|
|
1360
|
+
// Issues in specific sprint
|
|
1361
|
+
const jql4 = 'sprint = 123';
|
|
1362
|
+
|
|
1363
|
+
// Issues with specific labels
|
|
1364
|
+
const jql5 = 'labels IN (urgent, critical)';
|
|
1365
|
+
|
|
1366
|
+
// Issues due this week
|
|
1367
|
+
const jql6 = 'duedate >= startOfWeek() AND duedate <= endOfWeek()';
|
|
1368
|
+
|
|
1369
|
+
// Combining multiple conditions
|
|
1370
|
+
const jql7 = `
|
|
1371
|
+
project = PROJ AND
|
|
1372
|
+
status IN ("To Do", "In Progress") AND
|
|
1373
|
+
assignee IN (currentUser(), "john.doe") AND
|
|
1374
|
+
created >= -30d
|
|
1375
|
+
ORDER BY priority DESC, created ASC
|
|
1376
|
+
`;
|
|
1377
|
+
```
|
|
1378
|
+
|
|
1379
|
+
## Response Format Examples
|
|
1380
|
+
|
|
1381
|
+
### Issue Response
|
|
1382
|
+
|
|
1383
|
+
```javascript
|
|
1384
|
+
{
|
|
1385
|
+
"id": "10002",
|
|
1386
|
+
"key": "PROJ-123",
|
|
1387
|
+
"self": "https://your-domain.atlassian.net/rest/api/3/issue/10002",
|
|
1388
|
+
"fields": {
|
|
1389
|
+
"summary": "Issue summary",
|
|
1390
|
+
"description": { /* ADF format */ },
|
|
1391
|
+
"status": {
|
|
1392
|
+
"name": "In Progress",
|
|
1393
|
+
"statusCategory": { "key": "indeterminate" }
|
|
1394
|
+
},
|
|
1395
|
+
"priority": { "name": "High" },
|
|
1396
|
+
"assignee": {
|
|
1397
|
+
"accountId": "5b10a2844c20165700ede21g",
|
|
1398
|
+
"displayName": "John Doe",
|
|
1399
|
+
"emailAddress": "john@example.com"
|
|
1400
|
+
},
|
|
1401
|
+
"created": "2025-11-01T10:00:00.000+0000",
|
|
1402
|
+
"updated": "2025-11-07T15:30:00.000+0000",
|
|
1403
|
+
"labels": ["backend", "api"]
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
```
|
|
1407
|
+
|
|
1408
|
+
### Search Results Response
|
|
1409
|
+
|
|
1410
|
+
```javascript
|
|
1411
|
+
{
|
|
1412
|
+
"startAt": 0,
|
|
1413
|
+
"maxResults": 50,
|
|
1414
|
+
"total": 127,
|
|
1415
|
+
"issues": [
|
|
1416
|
+
{ /* issue object */ },
|
|
1417
|
+
{ /* issue object */ }
|
|
1418
|
+
]
|
|
1419
|
+
}
|
|
1420
|
+
```
|