jiradc-cli 1.0.18 → 1.0.20
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 +42 -6
- package/dist/index.js +235 -28
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,6 +15,12 @@ export JIRA_URL="https://jira.example.com" # Base URL of your Jira instance
|
|
|
15
15
|
export JIRA_TOKEN="your-personal-access-token" # HTTP Access Token from Jira
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## Breaking changes in this release
|
|
19
|
+
|
|
20
|
+
- `issue transitions` now returns a bare JSON array of transitions (previously wrapped in `{ transitions: [...] }`). Each transition is reduced to `{ id, name, to, fields? }` — verbose fields like `to.iconUrl`, `to.statusCategory`, `isGlobal`, `isInitial`, `isConditional`, `hasScreen` are stripped.
|
|
21
|
+
- `component list` now requires `--project <key>` instead of a positional `<projectKey>` argument.
|
|
22
|
+
- `issue link-epic` is now variadic on the issue argument: `link-epic <issueKey...> --epic <epicKey>`. Single-issue calls keep working.
|
|
23
|
+
|
|
18
24
|
## Commands
|
|
19
25
|
|
|
20
26
|
All commands output JSON. Add `--pretty` to pretty-print.
|
|
@@ -26,16 +32,17 @@ All commands output JSON. Add `--pretty` to pretty-print.
|
|
|
26
32
|
| `jiradc issue get <key>` | Get issue details (`--fields` to select, `--expand` for changelog/transitions) |
|
|
27
33
|
| `jiradc issue search <jql>` | Search issues with JQL |
|
|
28
34
|
| `jiradc issue create` | Create an issue (`--project`, `--type`, `--summary`, `--description`, `--custom-fields`) |
|
|
29
|
-
| `jiradc issue update <key>` | Update an issue |
|
|
35
|
+
| `jiradc issue update <key>` | Update an issue (`--summary`, `--description`, `--priority`, `--assignee`, `--labels`, `--components`, `--fix-versions`, or `--fields` JSON) |
|
|
30
36
|
| `jiradc issue delete <key>` | Delete an issue |
|
|
31
|
-
| `jiradc issue
|
|
37
|
+
| `jiradc issue assign <key> <user>` | Assign issue (user can be a username, `me`, or `none` to unassign) |
|
|
38
|
+
| `jiradc issue transition <key>` | Transition issue to a new status (`--to` accepts ID or status name, `--comment` to add a note) |
|
|
32
39
|
| `jiradc issue transitions <key>` | List available transitions |
|
|
33
40
|
| `jiradc issue comment <key>` | Add a comment |
|
|
34
41
|
| `jiradc issue comment-edit <key> <commentId>` | Edit a comment |
|
|
35
42
|
| `jiradc issue link <key> <targetKey>` | Link two issues (`--type` link type name) |
|
|
36
43
|
| `jiradc issue unlink <linkId>` | Remove a link |
|
|
37
44
|
| `jiradc issue link-types` | List available link types |
|
|
38
|
-
| `jiradc issue link-epic <
|
|
45
|
+
| `jiradc issue link-epic <keys...>` | Link one or more issues to an epic (`--epic <epicKey>`) |
|
|
39
46
|
| `jiradc issue worklog <key>` | Add a work log entry |
|
|
40
47
|
| `jiradc issue get-worklog <key>` | Get work log entries |
|
|
41
48
|
| `jiradc issue changelog <key>` | Get issue changelog |
|
|
@@ -60,7 +67,16 @@ All commands output JSON. Add `--pretty` to pretty-print.
|
|
|
60
67
|
|---------|-------------|
|
|
61
68
|
| `jiradc project list` | List projects |
|
|
62
69
|
| `jiradc project versions <key>` | List versions for a project |
|
|
63
|
-
|
|
70
|
+
|
|
71
|
+
### component
|
|
72
|
+
|
|
73
|
+
| Command | Description |
|
|
74
|
+
|---------|-------------|
|
|
75
|
+
| `jiradc component list` | List components for a project (`--project <key>`) |
|
|
76
|
+
| `jiradc component get <id>` | Get a component by ID |
|
|
77
|
+
| `jiradc component create` | Create a component (`--project`, `--name`, `--description`, `--lead`) |
|
|
78
|
+
| `jiradc component update <id>` | Update a component |
|
|
79
|
+
| `jiradc component issue-count <id>` | Get the number of issues using a component |
|
|
64
80
|
|
|
65
81
|
### board
|
|
66
82
|
|
|
@@ -113,9 +129,26 @@ jiradc issue create --project AI --type Task --summary "Implement feature X" --d
|
|
|
113
129
|
# Create with custom fields
|
|
114
130
|
jiradc issue create --project AI --type Story --summary "User login" --custom-fields '{"customfield_10100": "value"}'
|
|
115
131
|
|
|
116
|
-
# Transition
|
|
132
|
+
# Transition by ID or by status name
|
|
117
133
|
jiradc issue transitions AI-123
|
|
118
|
-
jiradc issue transition AI-123 31
|
|
134
|
+
jiradc issue transition AI-123 --to 31
|
|
135
|
+
jiradc issue transition AI-123 --to "In Review" --comment "Ready for review"
|
|
136
|
+
|
|
137
|
+
# Assign
|
|
138
|
+
jiradc issue assign AI-123 me
|
|
139
|
+
jiradc issue assign AI-123 jsmith
|
|
140
|
+
jiradc issue assign AI-123 none
|
|
141
|
+
|
|
142
|
+
# Update with shortcuts (instead of --fields JSON)
|
|
143
|
+
jiradc issue update AI-123 --summary "New title" --priority High
|
|
144
|
+
jiradc issue update AI-123 --assignee me
|
|
145
|
+
jiradc issue update AI-123 --labels backend,urgent # set mode
|
|
146
|
+
jiradc issue update AI-123 --labels +urgent,-backend # mutate mode
|
|
147
|
+
jiradc issue update AI-123 --components +Frontend
|
|
148
|
+
jiradc issue update AI-123 --fix-versions 1.0,2.0
|
|
149
|
+
|
|
150
|
+
# Link multiple issues to an epic in one call
|
|
151
|
+
jiradc issue link-epic AI-456 AI-457 AI-458 --epic AI-100
|
|
119
152
|
|
|
120
153
|
# Add a comment
|
|
121
154
|
jiradc issue comment AI-123 --body "Fixed in commit abc123"
|
|
@@ -140,4 +173,7 @@ jiradc issue clone AI-123
|
|
|
140
173
|
|
|
141
174
|
# Get dev status (linked branches, PRs)
|
|
142
175
|
jiradc issue dev-status AI-123
|
|
176
|
+
|
|
177
|
+
# List components for a project
|
|
178
|
+
jiradc component list --project AI
|
|
143
179
|
```
|
package/dist/index.js
CHANGED
|
@@ -432,6 +432,49 @@ function transformIssueFields(fields) {
|
|
|
432
432
|
};
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
// src/utils/transformers/transition.ts
|
|
436
|
+
function slimAllowedValue(raw) {
|
|
437
|
+
if (!raw || typeof raw !== "object") return {};
|
|
438
|
+
const av = raw;
|
|
439
|
+
const slim = {};
|
|
440
|
+
if (typeof av.id === "string") slim.id = av.id;
|
|
441
|
+
if (typeof av.name === "string") slim.name = av.name;
|
|
442
|
+
if (typeof av.value === "string") slim.value = av.value;
|
|
443
|
+
return slim;
|
|
444
|
+
}
|
|
445
|
+
function slimField(raw) {
|
|
446
|
+
if (!raw || typeof raw !== "object") return {};
|
|
447
|
+
const field = raw;
|
|
448
|
+
const out = {};
|
|
449
|
+
if (typeof field.required === "boolean") out.required = field.required;
|
|
450
|
+
if (typeof field.name === "string") out.name = field.name;
|
|
451
|
+
if (Array.isArray(field.allowedValues)) {
|
|
452
|
+
out.allowedValues = field.allowedValues.map(slimAllowedValue);
|
|
453
|
+
}
|
|
454
|
+
return out;
|
|
455
|
+
}
|
|
456
|
+
function slimFields(fields) {
|
|
457
|
+
const out = {};
|
|
458
|
+
for (const [key, raw] of Object.entries(fields)) {
|
|
459
|
+
out[key] = slimField(raw);
|
|
460
|
+
}
|
|
461
|
+
return out;
|
|
462
|
+
}
|
|
463
|
+
function transformTransition(t) {
|
|
464
|
+
const out = {
|
|
465
|
+
id: t.id,
|
|
466
|
+
name: t.name,
|
|
467
|
+
to: t.to.name
|
|
468
|
+
};
|
|
469
|
+
if (t.fields && Object.keys(t.fields).length > 0) {
|
|
470
|
+
out.fields = slimFields(t.fields);
|
|
471
|
+
}
|
|
472
|
+
return out;
|
|
473
|
+
}
|
|
474
|
+
function transformTransitions(response) {
|
|
475
|
+
return response.transitions.map(transformTransition);
|
|
476
|
+
}
|
|
477
|
+
|
|
435
478
|
// src/commands/board/issues.ts
|
|
436
479
|
function issues(parent) {
|
|
437
480
|
parent.command("issues").description("Get issues for a board").addArgument(new Argument("<id>", "Board ID").argParser(positiveInt)).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated field names to return").option("--jql <jql>", "Additional JQL filter within the board").addHelpText(
|
|
@@ -550,9 +593,9 @@ function issueCount(parent) {
|
|
|
550
593
|
|
|
551
594
|
// src/commands/component/list.ts
|
|
552
595
|
function list2(parent) {
|
|
553
|
-
parent.command("list
|
|
596
|
+
parent.command("list").description("List all components for a project").requiredOption("--project <key>", "Project key (e.g., AI)").addHelpText("after", "\nExamples:\n jiradc component list --project AI").action(async (opts) => {
|
|
554
597
|
const client = getClient();
|
|
555
|
-
const result = await client.components.list({ projectKeyOrId:
|
|
598
|
+
const result = await client.components.list({ projectKeyOrId: opts.project });
|
|
556
599
|
output(result.map(transformComponent));
|
|
557
600
|
});
|
|
558
601
|
}
|
|
@@ -597,7 +640,7 @@ function registerComponentCommands(program2) {
|
|
|
597
640
|
"after",
|
|
598
641
|
`
|
|
599
642
|
Examples:
|
|
600
|
-
$ jiradc component list AI
|
|
643
|
+
$ jiradc component list --project AI
|
|
601
644
|
$ jiradc component get 11289
|
|
602
645
|
$ jiradc component create --project AI --name Backend
|
|
603
646
|
$ jiradc component update 11289 --name Backend
|
|
@@ -657,6 +700,42 @@ Examples:
|
|
|
657
700
|
options(field);
|
|
658
701
|
}
|
|
659
702
|
|
|
703
|
+
// src/utils/resolve-user.ts
|
|
704
|
+
var cachedMe;
|
|
705
|
+
async function resolveUserToken(token) {
|
|
706
|
+
if (token === "none") return null;
|
|
707
|
+
if (token === "me") {
|
|
708
|
+
if (cachedMe !== void 0) return cachedMe;
|
|
709
|
+
const me2 = await getClient().users.getMyself();
|
|
710
|
+
if (!me2.name) {
|
|
711
|
+
throw new Error('Could not resolve "me": authenticated user has no name field');
|
|
712
|
+
}
|
|
713
|
+
cachedMe = me2.name;
|
|
714
|
+
return cachedMe;
|
|
715
|
+
}
|
|
716
|
+
return token;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// src/commands/issue/assign.ts
|
|
720
|
+
function assign(parent) {
|
|
721
|
+
parent.command("assign <key> <user>").description('Assign an issue. <user> is a username, "me", or "none" to unassign.').addHelpText(
|
|
722
|
+
"after",
|
|
723
|
+
`
|
|
724
|
+
Examples:
|
|
725
|
+
jiradc issue assign PROJ-123 jsmith
|
|
726
|
+
jiradc issue assign PROJ-123 me
|
|
727
|
+
jiradc issue assign PROJ-123 none`
|
|
728
|
+
).action(async (key, user) => {
|
|
729
|
+
const resolved = await resolveUserToken(user);
|
|
730
|
+
const client = getClient();
|
|
731
|
+
await client.issues.update({
|
|
732
|
+
issueKeyOrId: key,
|
|
733
|
+
fields: { assignee: resolved === null ? null : { name: resolved } }
|
|
734
|
+
});
|
|
735
|
+
output({ assigned: true, issue: transformIssueRef(key), assignee: resolved });
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
|
|
660
739
|
// src/commands/issue/attachment/delete.ts
|
|
661
740
|
function deleteAttachment(parent) {
|
|
662
741
|
parent.command("delete").description("Delete an attachment by ID").requiredOption("--id <attachmentId>", "Attachment ID to delete").addHelpText("after", "\nExamples:\n jiradc issue attachment delete --id 12345").action(async (opts) => {
|
|
@@ -1185,17 +1264,37 @@ function get2(parent) {
|
|
|
1185
1264
|
|
|
1186
1265
|
// src/commands/issue/link-epic.ts
|
|
1187
1266
|
function linkEpic(parent) {
|
|
1188
|
-
parent.command("link-epic <
|
|
1267
|
+
parent.command("link-epic <keys...>").description("Link one or more issues to an epic").requiredOption("--epic <epicKey>", "Epic issue key").addHelpText(
|
|
1268
|
+
"after",
|
|
1269
|
+
`
|
|
1270
|
+
Examples:
|
|
1271
|
+
jiradc issue link-epic PROJ-456 --epic PROJ-123
|
|
1272
|
+
jiradc issue link-epic PROJ-456 PROJ-457 PROJ-458 --epic PROJ-123`
|
|
1273
|
+
).action(async (keys, opts) => {
|
|
1189
1274
|
const client = getClient();
|
|
1190
|
-
await
|
|
1191
|
-
|
|
1192
|
-
|
|
1275
|
+
const results = await Promise.allSettled(
|
|
1276
|
+
keys.map(
|
|
1277
|
+
(key) => client.issues.update({ issueKeyOrId: key, fields: { customfield_10100: opts.epic } }).then(() => key)
|
|
1278
|
+
)
|
|
1279
|
+
);
|
|
1280
|
+
const linked = [];
|
|
1281
|
+
const failed = [];
|
|
1282
|
+
results.forEach((r, i) => {
|
|
1283
|
+
if (r.status === "fulfilled") {
|
|
1284
|
+
linked.push({ key: r.value });
|
|
1285
|
+
} else {
|
|
1286
|
+
const message = r.reason instanceof Error ? r.reason.message : String(r.reason);
|
|
1287
|
+
failed.push({ key: keys[i], error: message });
|
|
1288
|
+
}
|
|
1193
1289
|
});
|
|
1194
1290
|
output({
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1291
|
+
epic: transformIssueRef(opts.epic),
|
|
1292
|
+
linked,
|
|
1293
|
+
...failed.length > 0 && { failed }
|
|
1198
1294
|
});
|
|
1295
|
+
if (failed.length > 0) {
|
|
1296
|
+
process.exitCode = 1;
|
|
1297
|
+
}
|
|
1199
1298
|
});
|
|
1200
1299
|
}
|
|
1201
1300
|
|
|
@@ -1250,12 +1349,37 @@ function search2(parent) {
|
|
|
1250
1349
|
|
|
1251
1350
|
// src/commands/issue/transition.ts
|
|
1252
1351
|
function transition(parent) {
|
|
1253
|
-
parent.command("transition <key>").description("Transition issue to a new status").requiredOption("--to <
|
|
1352
|
+
parent.command("transition <key>").description("Transition issue to a new status").requiredOption("--to <idOrName>", "Transition ID, or status name (case-insensitive)").option("--comment <text>", "Comment to add during transition").addHelpText(
|
|
1254
1353
|
"after",
|
|
1255
|
-
|
|
1354
|
+
`
|
|
1355
|
+
Examples:
|
|
1356
|
+
jiradc issue transition PROJ-123 --to 31
|
|
1357
|
+
jiradc issue transition PROJ-123 --to "In Review"
|
|
1358
|
+
jiradc issue transition PROJ-123 --to Done --comment "Verified in staging"`
|
|
1256
1359
|
).action(async (key, opts) => {
|
|
1257
1360
|
const client = getClient();
|
|
1258
|
-
|
|
1361
|
+
let transitionId;
|
|
1362
|
+
if (/^\d+$/.test(opts.to)) {
|
|
1363
|
+
transitionId = opts.to;
|
|
1364
|
+
} else {
|
|
1365
|
+
const raw = await client.issues.getTransitions({
|
|
1366
|
+
issueKeyOrId: key,
|
|
1367
|
+
expand: "transitions.fields"
|
|
1368
|
+
});
|
|
1369
|
+
const transitions2 = transformTransitions(raw);
|
|
1370
|
+
const target = opts.to.toLowerCase();
|
|
1371
|
+
const matches = transitions2.filter((t) => t.name.toLowerCase() === target);
|
|
1372
|
+
if (matches.length === 0) {
|
|
1373
|
+
const names = transitions2.map((t) => `"${t.name}"`).join(", ");
|
|
1374
|
+
throw new Error(`Transition "${opts.to}" not available from current status. Available: ${names || "(none)"}`);
|
|
1375
|
+
}
|
|
1376
|
+
if (matches.length > 1) {
|
|
1377
|
+
const ids = matches.map((t) => t.id).join(", ");
|
|
1378
|
+
throw new Error(`Multiple transitions named "${opts.to}". Use --to <id> with one of: ${ids}`);
|
|
1379
|
+
}
|
|
1380
|
+
transitionId = matches[0].id;
|
|
1381
|
+
}
|
|
1382
|
+
await client.issues.transition({ issueKeyOrId: key, transitionId, comment: opts.comment });
|
|
1259
1383
|
output({ transitioned: true, issue: transformIssueRef(key) });
|
|
1260
1384
|
});
|
|
1261
1385
|
}
|
|
@@ -1264,8 +1388,11 @@ function transition(parent) {
|
|
|
1264
1388
|
function transitions(parent) {
|
|
1265
1389
|
parent.command("transitions <key>").description("Get available transitions for an issue").addHelpText("after", "\nExamples:\n jiradc issue transitions PROJ-123").action(async (key) => {
|
|
1266
1390
|
const client = getClient();
|
|
1267
|
-
const result = await client.issues.getTransitions({
|
|
1268
|
-
|
|
1391
|
+
const result = await client.issues.getTransitions({
|
|
1392
|
+
issueKeyOrId: key,
|
|
1393
|
+
expand: "transitions.fields"
|
|
1394
|
+
});
|
|
1395
|
+
output(transformTransitions(result));
|
|
1269
1396
|
});
|
|
1270
1397
|
}
|
|
1271
1398
|
|
|
@@ -1278,24 +1405,103 @@ function unlink2(parent) {
|
|
|
1278
1405
|
});
|
|
1279
1406
|
}
|
|
1280
1407
|
|
|
1408
|
+
// src/utils/multi-value.ts
|
|
1409
|
+
import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
1410
|
+
function parseMultiValue(flagName, raw) {
|
|
1411
|
+
const items = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
1412
|
+
if (items.length === 0) {
|
|
1413
|
+
throw new InvalidArgumentError2(`${flagName} cannot be empty`);
|
|
1414
|
+
}
|
|
1415
|
+
const lonePrefix = items.find((s) => s === "+" || s === "-");
|
|
1416
|
+
if (lonePrefix !== void 0) {
|
|
1417
|
+
throw new InvalidArgumentError2(`${flagName} has an empty value after '${lonePrefix}' prefix`);
|
|
1418
|
+
}
|
|
1419
|
+
const prefixed = items.filter((s) => s.startsWith("+") || s.startsWith("-"));
|
|
1420
|
+
const bare = items.filter((s) => !s.startsWith("+") && !s.startsWith("-"));
|
|
1421
|
+
if (prefixed.length > 0 && bare.length > 0) {
|
|
1422
|
+
throw new InvalidArgumentError2(
|
|
1423
|
+
`${flagName} mixes set and mutate syntax. Either all values have +/- prefix, or none do.`
|
|
1424
|
+
);
|
|
1425
|
+
}
|
|
1426
|
+
if (bare.length > 0) {
|
|
1427
|
+
return { mode: "set", values: bare };
|
|
1428
|
+
}
|
|
1429
|
+
const adds = prefixed.filter((s) => s.startsWith("+")).map((s) => s.slice(1));
|
|
1430
|
+
const removes = prefixed.filter((s) => s.startsWith("-")).map((s) => s.slice(1));
|
|
1431
|
+
return { mode: "mutate", adds, removes };
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1281
1434
|
// src/commands/issue/update.ts
|
|
1435
|
+
function buildUpdateOps(parsed, wrap) {
|
|
1436
|
+
if (parsed.mode !== "mutate") return void 0;
|
|
1437
|
+
return [...parsed.adds.map((v) => ({ add: wrap(v) })), ...parsed.removes.map((v) => ({ remove: wrap(v) }))];
|
|
1438
|
+
}
|
|
1439
|
+
function buildSetValue(parsed, wrap) {
|
|
1440
|
+
if (parsed.mode !== "set") return void 0;
|
|
1441
|
+
return parsed.values.map(wrap);
|
|
1442
|
+
}
|
|
1282
1443
|
function update2(parent) {
|
|
1283
|
-
parent.command("update <key>").description("Update issue fields").option("--fields <json>", "JSON string of fields to update").option("--notify-users", "
|
|
1444
|
+
parent.command("update <key>").description("Update issue fields").option("--fields <json>", "JSON string of fields to update (advanced; merges with shortcuts, wins on conflict)").option("--no-notify-users", "Suppress notification emails (default: notify)").option("--attachments <paths>", "Comma-separated local file paths to attach").option("--summary <text>", "Set the issue summary").option("--description <text>", "Set the issue description (wiki markup)").option("--priority <name>", "Set the priority by name (e.g. High)").option("--assignee <user>", 'Set the assignee. Username, "me", or "none" to unassign.').option("--labels <list>", 'Set labels ("a,b,c") or mutate ("+add,-remove")').option("--components <list>", 'Set components ("a,b") or mutate ("+add,-remove")').option("--fix-versions <list>", 'Set fix versions ("1.0,2.0") or mutate ("+1.0,-0.9")').addHelpText(
|
|
1284
1445
|
"after",
|
|
1285
1446
|
`
|
|
1286
1447
|
Examples:
|
|
1287
|
-
jiradc issue update PROJ-123 --
|
|
1288
|
-
jiradc issue update PROJ-123 --
|
|
1289
|
-
jiradc issue update PROJ-123 --
|
|
1290
|
-
jiradc issue update PROJ-123 --
|
|
1448
|
+
jiradc issue update PROJ-123 --summary "New title"
|
|
1449
|
+
jiradc issue update PROJ-123 --priority High --assignee me
|
|
1450
|
+
jiradc issue update PROJ-123 --labels backend,urgent
|
|
1451
|
+
jiradc issue update PROJ-123 --labels +urgent,-backend
|
|
1452
|
+
jiradc issue update PROJ-123 --components +Frontend
|
|
1453
|
+
jiradc issue update PROJ-123 --fields '{"customfield_10100": "EPIC-1"}' --priority High
|
|
1454
|
+
jiradc issue update PROJ-123 --attachments /path/to/file.pdf,/path/to/image.png`
|
|
1291
1455
|
).action(async (key, opts) => {
|
|
1292
|
-
|
|
1293
|
-
|
|
1456
|
+
const hasShortcut = opts.summary !== void 0 || opts.description !== void 0 || opts.priority !== void 0 || opts.assignee !== void 0 || opts.labels !== void 0 || opts.components !== void 0 || opts.fixVersions !== void 0;
|
|
1457
|
+
if (!opts.fields && !opts.attachments && !hasShortcut) {
|
|
1458
|
+
throw new Error(
|
|
1459
|
+
"Provide at least one of --fields, --attachments, or a shortcut flag (--summary, --priority, --labels, ...)"
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
const fields = {};
|
|
1463
|
+
const updateOps = {};
|
|
1464
|
+
if (opts.summary !== void 0) fields.summary = opts.summary;
|
|
1465
|
+
if (opts.description !== void 0) fields.description = opts.description;
|
|
1466
|
+
if (opts.priority !== void 0) fields.priority = { name: opts.priority };
|
|
1467
|
+
if (opts.assignee !== void 0) {
|
|
1468
|
+
const resolved = await resolveUserToken(opts.assignee);
|
|
1469
|
+
fields.assignee = resolved === null ? null : { name: resolved };
|
|
1470
|
+
}
|
|
1471
|
+
if (opts.labels !== void 0) {
|
|
1472
|
+
const parsed = parseMultiValue("--labels", opts.labels);
|
|
1473
|
+
const setVal = buildSetValue(parsed, (v) => v);
|
|
1474
|
+
const ops = buildUpdateOps(parsed, (v) => v);
|
|
1475
|
+
if (setVal) fields.labels = setVal;
|
|
1476
|
+
if (ops) updateOps.labels = ops;
|
|
1477
|
+
}
|
|
1478
|
+
if (opts.components !== void 0) {
|
|
1479
|
+
const parsed = parseMultiValue("--components", opts.components);
|
|
1480
|
+
const setVal = buildSetValue(parsed, (v) => ({ name: v }));
|
|
1481
|
+
const ops = buildUpdateOps(parsed, (v) => ({ name: v }));
|
|
1482
|
+
if (setVal) fields.components = setVal;
|
|
1483
|
+
if (ops) updateOps.components = ops;
|
|
1484
|
+
}
|
|
1485
|
+
if (opts.fixVersions !== void 0) {
|
|
1486
|
+
const parsed = parseMultiValue("--fix-versions", opts.fixVersions);
|
|
1487
|
+
const setVal = buildSetValue(parsed, (v) => ({ name: v }));
|
|
1488
|
+
const ops = buildUpdateOps(parsed, (v) => ({ name: v }));
|
|
1489
|
+
if (setVal) fields.fixVersions = setVal;
|
|
1490
|
+
if (ops) updateOps.fixVersions = ops;
|
|
1294
1491
|
}
|
|
1295
|
-
const client = getClient();
|
|
1296
1492
|
if (opts.fields) {
|
|
1297
|
-
const
|
|
1298
|
-
|
|
1493
|
+
const parsedFields = JSON.parse(opts.fields);
|
|
1494
|
+
Object.assign(fields, parsedFields);
|
|
1495
|
+
}
|
|
1496
|
+
const client = getClient();
|
|
1497
|
+
const didFieldUpdate = Object.keys(fields).length > 0 || Object.keys(updateOps).length > 0;
|
|
1498
|
+
if (didFieldUpdate) {
|
|
1499
|
+
await client.issues.update({
|
|
1500
|
+
issueKeyOrId: key,
|
|
1501
|
+
fields: Object.keys(fields).length > 0 ? fields : void 0,
|
|
1502
|
+
update: Object.keys(updateOps).length > 0 ? updateOps : void 0,
|
|
1503
|
+
notifyUsers: opts.notifyUsers
|
|
1504
|
+
});
|
|
1299
1505
|
}
|
|
1300
1506
|
const uploaded = [];
|
|
1301
1507
|
if (opts.attachments) {
|
|
@@ -1308,9 +1514,9 @@ Examples:
|
|
|
1308
1514
|
}
|
|
1309
1515
|
}
|
|
1310
1516
|
output({
|
|
1311
|
-
updated: true,
|
|
1312
|
-
|
|
1313
|
-
|
|
1517
|
+
...didFieldUpdate && { updated: true },
|
|
1518
|
+
...uploaded.length > 0 && { attached: true, attachments: uploaded },
|
|
1519
|
+
issue: transformIssueRef(key)
|
|
1314
1520
|
});
|
|
1315
1521
|
});
|
|
1316
1522
|
}
|
|
@@ -1353,6 +1559,7 @@ Examples:
|
|
|
1353
1559
|
deleteIssue(issue);
|
|
1354
1560
|
transition(issue);
|
|
1355
1561
|
transitions(issue);
|
|
1562
|
+
assign(issue);
|
|
1356
1563
|
comment(issue);
|
|
1357
1564
|
commentEdit(issue);
|
|
1358
1565
|
worklog(issue);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jiradc-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"publish": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"commander": "^13.1.0",
|
|
15
|
-
"jira-data-center-client": "1.0.
|
|
15
|
+
"jira-data-center-client": "1.0.36"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/node": "24.10.4",
|