jiradc-cli 1.0.10 → 1.0.12-g39f1036.1
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 +143 -0
- package/dist/index.js +342 -48
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# jiradc-cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for [Jira Data Center](https://developer.atlassian.com/server/jira/platform/rest-apis/). 35 commands across 6 domains — issues, projects, boards, sprints, fields, and users.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g jiradc-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
export JIRA_URL="https://jira.example.com" # Base URL of your Jira instance
|
|
15
|
+
export JIRA_TOKEN="your-personal-access-token" # HTTP Access Token from Jira
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
All commands output JSON. Add `--pretty` to pretty-print.
|
|
21
|
+
|
|
22
|
+
### issue
|
|
23
|
+
|
|
24
|
+
| Command | Description |
|
|
25
|
+
|---------|-------------|
|
|
26
|
+
| `jiradc issue get <key>` | Get issue details (`--fields` to select, `--expand` for changelog/transitions) |
|
|
27
|
+
| `jiradc issue search <jql>` | Search issues with JQL |
|
|
28
|
+
| `jiradc issue create` | Create an issue (`--project`, `--type`, `--summary`, `--description`, `--custom-fields`) |
|
|
29
|
+
| `jiradc issue update <key>` | Update an issue |
|
|
30
|
+
| `jiradc issue delete <key>` | Delete an issue |
|
|
31
|
+
| `jiradc issue transition <key> <transitionId>` | Transition issue to a new status |
|
|
32
|
+
| `jiradc issue transitions <key>` | List available transitions |
|
|
33
|
+
| `jiradc issue comment <key>` | Add a comment |
|
|
34
|
+
| `jiradc issue comment-edit <key> <commentId>` | Edit a comment |
|
|
35
|
+
| `jiradc issue link <key> <targetKey>` | Link two issues (`--type` link type name) |
|
|
36
|
+
| `jiradc issue unlink <linkId>` | Remove a link |
|
|
37
|
+
| `jiradc issue link-types` | List available link types |
|
|
38
|
+
| `jiradc issue link-epic <epicKey> <issueKey>` | Link an issue to an epic |
|
|
39
|
+
| `jiradc issue worklog <key>` | Add a work log entry |
|
|
40
|
+
| `jiradc issue get-worklog <key>` | Get work log entries |
|
|
41
|
+
| `jiradc issue changelog <key>` | Get issue changelog |
|
|
42
|
+
| `jiradc issue batch-changelog` | Get changelog for multiple issues (`--keys`) |
|
|
43
|
+
| `jiradc issue clone <key>` | Clone an issue with subtasks |
|
|
44
|
+
| `jiradc issue batch-create` | Create multiple issues from JSON |
|
|
45
|
+
| `jiradc issue dev-status <key>` | Get development status (branches, PRs, commits) |
|
|
46
|
+
|
|
47
|
+
#### issue attachment
|
|
48
|
+
|
|
49
|
+
| Command | Description |
|
|
50
|
+
|---------|-------------|
|
|
51
|
+
| `jiradc issue attachment list <key>` | List attachments |
|
|
52
|
+
| `jiradc issue attachment download <key> <attachmentId>` | Download a specific attachment |
|
|
53
|
+
| `jiradc issue attachment download-all <key>` | Download all attachments |
|
|
54
|
+
| `jiradc issue attachment upload <key> <files...>` | Upload files |
|
|
55
|
+
| `jiradc issue attachment delete <attachmentId>` | Delete an attachment |
|
|
56
|
+
|
|
57
|
+
### project
|
|
58
|
+
|
|
59
|
+
| Command | Description |
|
|
60
|
+
|---------|-------------|
|
|
61
|
+
| `jiradc project list` | List projects |
|
|
62
|
+
| `jiradc project versions <key>` | List versions for a project |
|
|
63
|
+
| `jiradc project components <key>` | List components for a project |
|
|
64
|
+
|
|
65
|
+
### board
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `jiradc board list` | List boards (`--project`, `--type`: scrum/kanban/simple, `--name`) |
|
|
70
|
+
| `jiradc board issues <boardId>` | Get issues on a board |
|
|
71
|
+
|
|
72
|
+
### sprint
|
|
73
|
+
|
|
74
|
+
| Command | Description |
|
|
75
|
+
|---------|-------------|
|
|
76
|
+
| `jiradc sprint list <boardId>` | List sprints (`--state`: future/active/closed) |
|
|
77
|
+
| `jiradc sprint issues <boardId> <sprintId>` | Get issues in a sprint |
|
|
78
|
+
| `jiradc sprint create <boardId>` | Create a sprint |
|
|
79
|
+
| `jiradc sprint update <sprintId>` | Update a sprint |
|
|
80
|
+
|
|
81
|
+
### field
|
|
82
|
+
|
|
83
|
+
| Command | Description |
|
|
84
|
+
|---------|-------------|
|
|
85
|
+
| `jiradc field search` | Search for fields (`--query`, `--type`: custom/system) |
|
|
86
|
+
| `jiradc field options <fieldKey>` | Get allowed values for a field (`--project`, `--issue-type`) |
|
|
87
|
+
|
|
88
|
+
### user
|
|
89
|
+
|
|
90
|
+
| Command | Description |
|
|
91
|
+
|---------|-------------|
|
|
92
|
+
| `jiradc user me` | Get current user info |
|
|
93
|
+
|
|
94
|
+
## Pagination
|
|
95
|
+
|
|
96
|
+
Search and list commands accept `--max` to control page size (Jira DC caps at 50 for agile endpoints). Responses include `nextPage` — pass it back as `--start-at` to fetch the next page. When `nextPage` is `null`, there are no more results.
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Get an issue with default fields
|
|
102
|
+
jiradc issue get AI-123
|
|
103
|
+
|
|
104
|
+
# Get an issue with specific fields
|
|
105
|
+
jiradc issue get AI-123 --fields summary,status,assignee,customfield_10100
|
|
106
|
+
|
|
107
|
+
# Search with JQL
|
|
108
|
+
jiradc issue search 'project = AI AND status = "In Development" ORDER BY updated DESC'
|
|
109
|
+
|
|
110
|
+
# Create an issue
|
|
111
|
+
jiradc issue create --project AI --type Task --summary "Implement feature X" --description "Details here"
|
|
112
|
+
|
|
113
|
+
# Create with custom fields
|
|
114
|
+
jiradc issue create --project AI --type Story --summary "User login" --custom-fields '{"customfield_10100": "value"}'
|
|
115
|
+
|
|
116
|
+
# Transition an issue (find transition ID first)
|
|
117
|
+
jiradc issue transitions AI-123
|
|
118
|
+
jiradc issue transition AI-123 31
|
|
119
|
+
|
|
120
|
+
# Add a comment
|
|
121
|
+
jiradc issue comment AI-123 --body "Fixed in commit abc123"
|
|
122
|
+
|
|
123
|
+
# Link two issues
|
|
124
|
+
jiradc issue link AI-123 AI-456 --type "blocks"
|
|
125
|
+
|
|
126
|
+
# Log work
|
|
127
|
+
jiradc issue worklog AI-123 --time "2h 30m" --comment "Code review"
|
|
128
|
+
|
|
129
|
+
# List active sprints
|
|
130
|
+
jiradc sprint list 42 --state active
|
|
131
|
+
|
|
132
|
+
# Get sprint issues
|
|
133
|
+
jiradc sprint issues 42 100
|
|
134
|
+
|
|
135
|
+
# Find a custom field key
|
|
136
|
+
jiradc field search --query "story points"
|
|
137
|
+
|
|
138
|
+
# Clone an issue with subtasks
|
|
139
|
+
jiradc issue clone AI-123
|
|
140
|
+
|
|
141
|
+
# Get dev status (linked branches, PRs)
|
|
142
|
+
jiradc issue dev-status AI-123
|
|
143
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { readFileSync } from "fs";
|
|
|
5
5
|
import { dirname, join as join4 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { styleText } from "util";
|
|
8
|
-
import { Command as
|
|
8
|
+
import { Command as Command8 } from "commander";
|
|
9
9
|
|
|
10
10
|
// src/commands/board/issues.ts
|
|
11
11
|
import { Argument } from "commander";
|
|
@@ -226,6 +226,135 @@ Examples:
|
|
|
226
226
|
issues(board);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
// src/commands/component/create.ts
|
|
230
|
+
import { Option as Option2 } from "commander";
|
|
231
|
+
var ASSIGNEE_TYPES = [
|
|
232
|
+
"PROJECT_DEFAULT",
|
|
233
|
+
"COMPONENT_LEAD",
|
|
234
|
+
"PROJECT_LEAD",
|
|
235
|
+
"UNASSIGNED"
|
|
236
|
+
];
|
|
237
|
+
function create(parent) {
|
|
238
|
+
parent.command("create").description("Create a new component in a project").requiredOption("--project <key>", "Project key (e.g., AI)").requiredOption("--name <name>", "Component name").option("--description <text>", "Component description").option("--lead <username>", "Username of the component lead").addOption(new Option2("--assignee-type <type>", "Assignee strategy").choices(ASSIGNEE_TYPES)).addHelpText(
|
|
239
|
+
"after",
|
|
240
|
+
`
|
|
241
|
+
Examples:
|
|
242
|
+
jiradc component create --project AI --name Backend
|
|
243
|
+
jiradc component create --project AI --name Frontend --description "UI work" --lead jsmith
|
|
244
|
+
jiradc component create --project AI --name Infra --assignee-type COMPONENT_LEAD --lead jsmith`
|
|
245
|
+
).action(
|
|
246
|
+
async (opts) => {
|
|
247
|
+
const client = getClient();
|
|
248
|
+
const result = await client.components.create({
|
|
249
|
+
project: opts.project,
|
|
250
|
+
name: opts.name,
|
|
251
|
+
description: opts.description,
|
|
252
|
+
leadUserName: opts.lead,
|
|
253
|
+
assigneeType: opts.assigneeType
|
|
254
|
+
});
|
|
255
|
+
output(result);
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/commands/component/delete.ts
|
|
261
|
+
function deleteComponent(parent) {
|
|
262
|
+
parent.command("delete <id>").description("Delete a component, optionally reassigning its issues to another component").option("--move-issues-to <id>", "Reassign existing issues to this component ID before deletion").addHelpText(
|
|
263
|
+
"after",
|
|
264
|
+
`
|
|
265
|
+
Examples:
|
|
266
|
+
jiradc component delete 11289
|
|
267
|
+
jiradc component delete 11289 --move-issues-to 11290`
|
|
268
|
+
).action(async (id, opts) => {
|
|
269
|
+
const client = getClient();
|
|
270
|
+
await client.components.delete({ id, moveIssuesTo: opts.moveIssuesTo });
|
|
271
|
+
output({ deleted: true, componentId: id, ...opts.moveIssuesTo && { movedIssuesTo: opts.moveIssuesTo } });
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/commands/component/get.ts
|
|
276
|
+
function get(parent) {
|
|
277
|
+
parent.command("get <id>").description("Get a component by ID").addHelpText("after", "\nExamples:\n jiradc component get 11289").action(async (id) => {
|
|
278
|
+
const client = getClient();
|
|
279
|
+
const result = await client.components.get({ id });
|
|
280
|
+
output(result);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/commands/component/issue-count.ts
|
|
285
|
+
function issueCount(parent) {
|
|
286
|
+
parent.command("issue-count <id>").description("Get the number of issues currently using this component").addHelpText("after", "\nExamples:\n jiradc component issue-count 11289").action(async (id) => {
|
|
287
|
+
const client = getClient();
|
|
288
|
+
const result = await client.components.getRelatedIssueCounts({ id });
|
|
289
|
+
output(result);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// src/commands/component/list.ts
|
|
294
|
+
function list2(parent) {
|
|
295
|
+
parent.command("list <projectKey>").description("List all components for a project").addHelpText("after", "\nExamples:\n jiradc component list AI").action(async (projectKey) => {
|
|
296
|
+
const client = getClient();
|
|
297
|
+
const result = await client.components.list({ projectKeyOrId: projectKey });
|
|
298
|
+
output(result);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/commands/component/update.ts
|
|
303
|
+
import { Option as Option3 } from "commander";
|
|
304
|
+
var ASSIGNEE_TYPES2 = [
|
|
305
|
+
"PROJECT_DEFAULT",
|
|
306
|
+
"COMPONENT_LEAD",
|
|
307
|
+
"PROJECT_LEAD",
|
|
308
|
+
"UNASSIGNED"
|
|
309
|
+
];
|
|
310
|
+
function update(parent) {
|
|
311
|
+
parent.command("update <id>").description("Update an existing component (only provided fields are changed)").option("--name <name>", "New component name").option("--description <text>", "New component description").option("--lead <username>", "Username of the component lead (empty string clears it)").addOption(new Option3("--assignee-type <type>", "New assignee strategy").choices(ASSIGNEE_TYPES2)).addHelpText(
|
|
312
|
+
"after",
|
|
313
|
+
`
|
|
314
|
+
Examples:
|
|
315
|
+
jiradc component update 11289 --name Backend
|
|
316
|
+
jiradc component update 11289 --description "Server-side code"
|
|
317
|
+
jiradc component update 11289 --lead jsmith --assignee-type COMPONENT_LEAD`
|
|
318
|
+
).action(
|
|
319
|
+
async (id, opts) => {
|
|
320
|
+
if (opts.name === void 0 && opts.description === void 0 && opts.lead === void 0 && opts.assigneeType === void 0) {
|
|
321
|
+
throw new Error("Provide at least one of --name, --description, --lead, --assignee-type");
|
|
322
|
+
}
|
|
323
|
+
const client = getClient();
|
|
324
|
+
const result = await client.components.update({
|
|
325
|
+
id,
|
|
326
|
+
name: opts.name,
|
|
327
|
+
description: opts.description,
|
|
328
|
+
leadUserName: opts.lead,
|
|
329
|
+
assigneeType: opts.assigneeType
|
|
330
|
+
});
|
|
331
|
+
output(result);
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/commands/component/index.ts
|
|
337
|
+
function registerComponentCommands(program2) {
|
|
338
|
+
const component = program2.command("component").description("Project component operations").addHelpText(
|
|
339
|
+
"after",
|
|
340
|
+
`
|
|
341
|
+
Examples:
|
|
342
|
+
$ jiradc component list AI
|
|
343
|
+
$ jiradc component get 11289
|
|
344
|
+
$ jiradc component create --project AI --name Backend
|
|
345
|
+
$ jiradc component update 11289 --name Backend
|
|
346
|
+
$ jiradc component delete 11289 --move-issues-to 11290
|
|
347
|
+
$ jiradc component issue-count 11289
|
|
348
|
+
`
|
|
349
|
+
);
|
|
350
|
+
list2(component);
|
|
351
|
+
get(component);
|
|
352
|
+
create(component);
|
|
353
|
+
update(component);
|
|
354
|
+
deleteComponent(component);
|
|
355
|
+
issueCount(component);
|
|
356
|
+
}
|
|
357
|
+
|
|
229
358
|
// src/commands/field/options.ts
|
|
230
359
|
function options(parent) {
|
|
231
360
|
parent.command("options <id>").description("Get available options for a custom field").option("--query <text>", "Filter options by text").option("--max <number>", "Max results to return (1-1000)", intInRange(1, 1e3), 25).option("--page <number>", "Page number (1-indexed)", positiveInt).addHelpText(
|
|
@@ -343,7 +472,7 @@ function download(parent) {
|
|
|
343
472
|
}
|
|
344
473
|
|
|
345
474
|
// src/commands/issue/attachment/list.ts
|
|
346
|
-
function
|
|
475
|
+
function list3(parent) {
|
|
347
476
|
parent.command("list <key>").description("List attachments on an issue").addHelpText("after", "\nExamples:\n jiradc issue attachment list PROJ-123").action(async (key) => {
|
|
348
477
|
const client = getClient();
|
|
349
478
|
const issue = await client.issues.get({
|
|
@@ -406,7 +535,7 @@ Examples:
|
|
|
406
535
|
`
|
|
407
536
|
);
|
|
408
537
|
upload(attachment);
|
|
409
|
-
|
|
538
|
+
list3(attachment);
|
|
410
539
|
download(attachment);
|
|
411
540
|
downloadAll(attachment);
|
|
412
541
|
deleteAttachment(attachment);
|
|
@@ -475,6 +604,162 @@ function batchChangelog(parent) {
|
|
|
475
604
|
});
|
|
476
605
|
}
|
|
477
606
|
|
|
607
|
+
// src/utils/transformers.ts
|
|
608
|
+
function transformPaged(response, fn) {
|
|
609
|
+
const { startAt, maxResults, total } = response;
|
|
610
|
+
if ("issues" in response) {
|
|
611
|
+
const mapped2 = response.issues.map(fn);
|
|
612
|
+
return { startAt, maxResults, total, isLast: startAt + mapped2.length >= total, issues: mapped2 };
|
|
613
|
+
}
|
|
614
|
+
if ("values" in response) {
|
|
615
|
+
const mapped2 = response.values.map(fn);
|
|
616
|
+
return { startAt, maxResults, total, isLast: startAt + mapped2.length >= total, values: mapped2 };
|
|
617
|
+
}
|
|
618
|
+
const mapped = response.worklogs.map(fn);
|
|
619
|
+
return { startAt, maxResults, total, isLast: startAt + mapped.length >= total, worklogs: mapped };
|
|
620
|
+
}
|
|
621
|
+
function issueBrowseUrl(key, ctx) {
|
|
622
|
+
return `${ctx.baseUrl}/browse/${key}`;
|
|
623
|
+
}
|
|
624
|
+
function transformCreatedIssue(r, ctx) {
|
|
625
|
+
return { id: r.id, key: r.key, url: issueBrowseUrl(r.key, ctx) };
|
|
626
|
+
}
|
|
627
|
+
function transformUser(user) {
|
|
628
|
+
const { self: _self, avatarUrls: _avatarUrls, expand: _expand, ...rest } = user;
|
|
629
|
+
return rest;
|
|
630
|
+
}
|
|
631
|
+
function transformIssueType(t) {
|
|
632
|
+
const { self: _self, iconUrl: _iconUrl, avatarId: _avatarId, ...rest } = t;
|
|
633
|
+
return rest;
|
|
634
|
+
}
|
|
635
|
+
function transformStatus(s) {
|
|
636
|
+
const { self: _self, iconUrl: _iconUrl, ...rest } = s;
|
|
637
|
+
return rest;
|
|
638
|
+
}
|
|
639
|
+
function transformPriority(p) {
|
|
640
|
+
const { self: _self, iconUrl: _iconUrl, ...rest } = p;
|
|
641
|
+
return rest;
|
|
642
|
+
}
|
|
643
|
+
function transformResolution(r) {
|
|
644
|
+
const { self: _self, ...rest } = r;
|
|
645
|
+
return rest;
|
|
646
|
+
}
|
|
647
|
+
function transformVersion(v) {
|
|
648
|
+
const { self: _self, ...rest } = v;
|
|
649
|
+
return rest;
|
|
650
|
+
}
|
|
651
|
+
function transformIssueLinkType(t) {
|
|
652
|
+
const { self: _self, ...rest } = t;
|
|
653
|
+
return rest;
|
|
654
|
+
}
|
|
655
|
+
function transformComment(c) {
|
|
656
|
+
const { self: _self, author, updateAuthor, ...rest } = c;
|
|
657
|
+
return {
|
|
658
|
+
...rest,
|
|
659
|
+
...author ? { author: transformUser(author) } : {},
|
|
660
|
+
...updateAuthor ? { updateAuthor: transformUser(updateAuthor) } : {}
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
function transformWorklog(w) {
|
|
664
|
+
const { self: _self, author, updateAuthor, ...rest } = w;
|
|
665
|
+
return {
|
|
666
|
+
...rest,
|
|
667
|
+
...author ? { author: transformUser(author) } : {},
|
|
668
|
+
...updateAuthor ? { updateAuthor: transformUser(updateAuthor) } : {}
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
function transformAttachment(a) {
|
|
672
|
+
const { self: _self, author, ...rest } = a;
|
|
673
|
+
return {
|
|
674
|
+
...rest,
|
|
675
|
+
...author ? { author: transformUser(author) } : {}
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function transformIssueBasic(b, ctx) {
|
|
679
|
+
const { self: _self, fields, ...rest } = b;
|
|
680
|
+
return {
|
|
681
|
+
...rest,
|
|
682
|
+
url: issueBrowseUrl(b.key, ctx),
|
|
683
|
+
...fields ? {
|
|
684
|
+
fields: {
|
|
685
|
+
...fields.summary !== void 0 ? { summary: fields.summary } : {},
|
|
686
|
+
...fields.status ? { status: transformStatus(fields.status) } : {},
|
|
687
|
+
...fields.priority ? { priority: transformPriority(fields.priority) } : {},
|
|
688
|
+
...fields.issuetype ? { issuetype: transformIssueType(fields.issuetype) } : {}
|
|
689
|
+
}
|
|
690
|
+
} : {}
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
function transformIssueLink(l, ctx) {
|
|
694
|
+
const { self: _self, type, inwardIssue, outwardIssue, ...rest } = l;
|
|
695
|
+
return {
|
|
696
|
+
...rest,
|
|
697
|
+
type: transformIssueLinkType(type),
|
|
698
|
+
...inwardIssue ? { inwardIssue: transformIssueBasic(inwardIssue, ctx) } : {},
|
|
699
|
+
...outwardIssue ? { outwardIssue: transformIssueBasic(outwardIssue, ctx) } : {}
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
function transformIssue(issue, ctx) {
|
|
703
|
+
const { self: _self, expand: _expand, fields, ...rest } = issue;
|
|
704
|
+
return {
|
|
705
|
+
...rest,
|
|
706
|
+
url: issueBrowseUrl(issue.key, ctx),
|
|
707
|
+
fields: transformIssueFields(fields, ctx)
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function transformIssueFields(fields, ctx) {
|
|
711
|
+
const {
|
|
712
|
+
issuetype,
|
|
713
|
+
status,
|
|
714
|
+
priority,
|
|
715
|
+
resolution,
|
|
716
|
+
assignee,
|
|
717
|
+
reporter,
|
|
718
|
+
creator,
|
|
719
|
+
fixVersions,
|
|
720
|
+
versions: versions2,
|
|
721
|
+
issuelinks,
|
|
722
|
+
subtasks,
|
|
723
|
+
parent,
|
|
724
|
+
comment: comment2,
|
|
725
|
+
worklog: worklog2,
|
|
726
|
+
attachment,
|
|
727
|
+
...rest
|
|
728
|
+
} = fields;
|
|
729
|
+
return {
|
|
730
|
+
...rest,
|
|
731
|
+
issuetype: transformIssueType(issuetype),
|
|
732
|
+
status: transformStatus(status),
|
|
733
|
+
...priority ? { priority: transformPriority(priority) } : {},
|
|
734
|
+
...resolution ? { resolution: transformResolution(resolution) } : {},
|
|
735
|
+
...assignee ? { assignee: transformUser(assignee) } : {},
|
|
736
|
+
...reporter ? { reporter: transformUser(reporter) } : {},
|
|
737
|
+
...creator ? { creator: transformUser(creator) } : {},
|
|
738
|
+
...fixVersions ? { fixVersions: fixVersions.map(transformVersion) } : {},
|
|
739
|
+
...versions2 ? { versions: versions2.map(transformVersion) } : {},
|
|
740
|
+
...issuelinks ? { issuelinks: issuelinks.map((l) => transformIssueLink(l, ctx)) } : {},
|
|
741
|
+
...subtasks ? { subtasks: subtasks.map((s) => transformIssueBasic(s, ctx)) } : {},
|
|
742
|
+
...parent ? { parent: transformIssueBasic(parent, ctx) } : {},
|
|
743
|
+
...comment2 ? {
|
|
744
|
+
comment: {
|
|
745
|
+
comments: comment2.comments.map(transformComment),
|
|
746
|
+
maxResults: comment2.maxResults,
|
|
747
|
+
total: comment2.total,
|
|
748
|
+
startAt: comment2.startAt
|
|
749
|
+
}
|
|
750
|
+
} : {},
|
|
751
|
+
...worklog2 ? {
|
|
752
|
+
worklog: {
|
|
753
|
+
worklogs: worklog2.worklogs.map(transformWorklog),
|
|
754
|
+
maxResults: worklog2.maxResults,
|
|
755
|
+
total: worklog2.total,
|
|
756
|
+
startAt: worklog2.startAt
|
|
757
|
+
}
|
|
758
|
+
} : {},
|
|
759
|
+
...attachment ? { attachment: attachment.map(transformAttachment) } : {}
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
|
|
478
763
|
// src/commands/issue/batch-create.ts
|
|
479
764
|
function batchCreate(parent) {
|
|
480
765
|
parent.command("batch-create").description("Create multiple issues from a JSON array").requiredOption("--issues <json>", "JSON array of issue objects").addHelpText(
|
|
@@ -484,12 +769,13 @@ Examples:
|
|
|
484
769
|
jiradc issue batch-create --issues '[{"projectKeyOrId":"PROJ","issueTypeName":"Task","summary":"Task 1"},{"projectKeyOrId":"PROJ","issueTypeName":"Task","summary":"Task 2"}]'`
|
|
485
770
|
).action(async (opts) => {
|
|
486
771
|
const client = getClient();
|
|
772
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
487
773
|
const parsed = JSON.parse(opts.issues);
|
|
488
774
|
const results = [];
|
|
489
775
|
for (const issue of parsed) {
|
|
490
776
|
try {
|
|
491
777
|
const result = await client.issues.create(issue);
|
|
492
|
-
results.push({ key: result.key });
|
|
778
|
+
results.push({ key: result.key, url: issueBrowseUrl(result.key, ctx) });
|
|
493
779
|
} catch (error) {
|
|
494
780
|
results.push({ error: error instanceof Error ? error.message : "Unknown error" });
|
|
495
781
|
}
|
|
@@ -536,6 +822,7 @@ Examples:
|
|
|
536
822
|
).action(
|
|
537
823
|
async (key, opts) => {
|
|
538
824
|
const client = getClient();
|
|
825
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
539
826
|
const source = await client.issues.get({ issueKeyOrId: key, fields: CLONE_FIELDS });
|
|
540
827
|
const f = source.fields;
|
|
541
828
|
const createParams = {
|
|
@@ -555,7 +842,8 @@ Examples:
|
|
|
555
842
|
const cloneResult = {
|
|
556
843
|
cloned: true,
|
|
557
844
|
source: key,
|
|
558
|
-
newIssue: result
|
|
845
|
+
newIssue: result,
|
|
846
|
+
url: issueBrowseUrl(newKey, ctx)
|
|
559
847
|
};
|
|
560
848
|
if (opts.includeAttachments && f.attachment?.length) {
|
|
561
849
|
const tmpFiles = [];
|
|
@@ -607,7 +895,7 @@ function commentEdit(parent) {
|
|
|
607
895
|
parent.command("comment-edit <key>").description("Edit an existing comment").requiredOption("--id <commentId>", "Comment ID to edit").requiredOption("--body <text>", "Updated comment body in wiki markup").addHelpText("after", '\nExamples:\n jiradc issue comment-edit PROJ-123 --id 12345 --body "Updated comment text"').action(async (key, opts) => {
|
|
608
896
|
const client = getClient();
|
|
609
897
|
const result = await client.issues.editComment({ issueKeyOrId: key, commentId: opts.id, body: opts.body });
|
|
610
|
-
output(result);
|
|
898
|
+
output(transformComment(result));
|
|
611
899
|
});
|
|
612
900
|
}
|
|
613
901
|
|
|
@@ -616,12 +904,12 @@ function comment(parent) {
|
|
|
616
904
|
parent.command("comment <key>").description("Add a comment to an issue").requiredOption("--body <text>", "Comment body in wiki markup").addHelpText("after", '\nExamples:\n jiradc issue comment PROJ-123 --body "Fixed in latest build"').action(async (key, opts) => {
|
|
617
905
|
const client = getClient();
|
|
618
906
|
const result = await client.issues.addComment({ issueKeyOrId: key, body: opts.body });
|
|
619
|
-
output(result);
|
|
907
|
+
output(transformComment(result));
|
|
620
908
|
});
|
|
621
909
|
}
|
|
622
910
|
|
|
623
911
|
// src/commands/issue/create.ts
|
|
624
|
-
function
|
|
912
|
+
function create2(parent) {
|
|
625
913
|
parent.command("create").description("Create a new issue").requiredOption("--project <key>", "Project key or ID").requiredOption("--type <name>", "Issue type name (e.g., Task, Bug, Story)").requiredOption("--summary <text>", "Issue summary/title").option("--description <text>", "Issue description in wiki markup").option("--assignee <username>", "Assignee username").option("--reporter <username>", "Reporter username").option("--priority <name>", "Priority name (e.g., High, Medium, Low)").option("--labels <labels>", "Comma-separated labels").option("--components <names>", "Comma-separated component names").option("--fix-versions <versions>", "Comma-separated fix version names").option("--due-date <date>", "Due date in YYYY-MM-DD format").option("--parent <key>", "Parent issue key (for subtasks)").option("--custom-fields <json>", `Additional custom fields as JSON (e.g., '{"customfield_10100": "EPIC-1"}')`).addHelpText(
|
|
626
914
|
"after",
|
|
627
915
|
`
|
|
@@ -633,6 +921,7 @@ Examples:
|
|
|
633
921
|
).action(
|
|
634
922
|
async (opts) => {
|
|
635
923
|
const client = getClient();
|
|
924
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
636
925
|
const result = await client.issues.create({
|
|
637
926
|
projectKeyOrId: opts.project,
|
|
638
927
|
issueTypeName: opts.type,
|
|
@@ -648,7 +937,7 @@ Examples:
|
|
|
648
937
|
parent: opts.parent,
|
|
649
938
|
customFields: opts.customFields ? JSON.parse(opts.customFields) : void 0
|
|
650
939
|
});
|
|
651
|
-
output(result);
|
|
940
|
+
output(transformCreatedIssue(result, ctx));
|
|
652
941
|
}
|
|
653
942
|
);
|
|
654
943
|
}
|
|
@@ -756,7 +1045,7 @@ function getWorklog(parent) {
|
|
|
756
1045
|
startAt: opts.startAt,
|
|
757
1046
|
maxResults: opts.max
|
|
758
1047
|
});
|
|
759
|
-
output(result);
|
|
1048
|
+
output(transformPaged(result, transformWorklog));
|
|
760
1049
|
});
|
|
761
1050
|
}
|
|
762
1051
|
|
|
@@ -777,19 +1066,20 @@ var DEFAULT_FIELDS = [
|
|
|
777
1066
|
];
|
|
778
1067
|
|
|
779
1068
|
// src/commands/issue/get.ts
|
|
780
|
-
function
|
|
1069
|
+
function get2(parent) {
|
|
781
1070
|
parent.command("get <key>").description("Get issue details").option("--fields <fields>", "Comma-separated fields to return (defaults to essential fields)").option("--all-fields", "Return all fields instead of defaults").option("--expand <expand>", 'Expand options (e.g., "transitions", "changelog")').addHelpText(
|
|
782
1071
|
"after",
|
|
783
1072
|
"\nExamples:\n jiradc issue get PROJ-123\n jiradc issue get PROJ-123 --fields summary,status,assignee\n jiradc issue get PROJ-123 --all-fields\n jiradc issue get PROJ-123 --expand changelog,transitions"
|
|
784
1073
|
).action(async (key, opts) => {
|
|
785
1074
|
const client = getClient();
|
|
1075
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
786
1076
|
const fields = opts.allFields ? void 0 : opts.fields?.split(",").map((f) => f.trim()) ?? DEFAULT_FIELDS;
|
|
787
1077
|
const result = await client.issues.get({
|
|
788
1078
|
issueKeyOrId: key,
|
|
789
1079
|
fields,
|
|
790
1080
|
expand: opts.expand
|
|
791
1081
|
});
|
|
792
|
-
output(result);
|
|
1082
|
+
output(transformIssue(result, ctx));
|
|
793
1083
|
});
|
|
794
1084
|
}
|
|
795
1085
|
|
|
@@ -797,11 +1087,18 @@ function get(parent) {
|
|
|
797
1087
|
function linkEpic(parent) {
|
|
798
1088
|
parent.command("link-epic <key>").description("Link an issue to an epic").requiredOption("--epic <epicKey>", "Epic issue key").addHelpText("after", "\nExamples:\n jiradc issue link-epic PROJ-456 --epic PROJ-123").action(async (key, opts) => {
|
|
799
1089
|
const client = getClient();
|
|
1090
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
800
1091
|
await client.issues.update({
|
|
801
1092
|
issueKeyOrId: key,
|
|
802
1093
|
fields: { customfield_10100: opts.epic }
|
|
803
1094
|
});
|
|
804
|
-
output({
|
|
1095
|
+
output({
|
|
1096
|
+
linked: true,
|
|
1097
|
+
issue: key,
|
|
1098
|
+
url: issueBrowseUrl(key, ctx),
|
|
1099
|
+
epic: opts.epic,
|
|
1100
|
+
epicUrl: issueBrowseUrl(opts.epic, ctx)
|
|
1101
|
+
});
|
|
805
1102
|
});
|
|
806
1103
|
}
|
|
807
1104
|
|
|
@@ -810,7 +1107,7 @@ function linkTypes(parent) {
|
|
|
810
1107
|
parent.command("link-types").description("List all issue link types").addHelpText("after", "\nExamples:\n jiradc issue link-types").action(async () => {
|
|
811
1108
|
const client = getClient();
|
|
812
1109
|
const result = await client.links.getTypes();
|
|
813
|
-
output(result);
|
|
1110
|
+
output(result.map(transformIssueLinkType));
|
|
814
1111
|
});
|
|
815
1112
|
}
|
|
816
1113
|
|
|
@@ -838,6 +1135,7 @@ function search2(parent) {
|
|
|
838
1135
|
'\nExamples:\n jiradc issue search "project = PROJ AND status = Open"\n jiradc issue search "assignee = currentUser()" --max 10 --fields summary,status\n jiradc issue search "project = PROJ" --start-at 50 --max 50'
|
|
839
1136
|
).action(async (jql, opts) => {
|
|
840
1137
|
const client = getClient();
|
|
1138
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
841
1139
|
const fields = opts.allFields ? void 0 : opts.fields?.split(",").map((f) => f.trim()) ?? DEFAULT_FIELDS;
|
|
842
1140
|
const result = await client.issues.search({
|
|
843
1141
|
jql,
|
|
@@ -845,7 +1143,7 @@ function search2(parent) {
|
|
|
845
1143
|
maxResults: opts.max,
|
|
846
1144
|
fields
|
|
847
1145
|
});
|
|
848
|
-
output(result);
|
|
1146
|
+
output(transformPaged(result, (i) => transformIssue(i, ctx)));
|
|
849
1147
|
});
|
|
850
1148
|
}
|
|
851
1149
|
|
|
@@ -856,8 +1154,9 @@ function transition(parent) {
|
|
|
856
1154
|
'\nExamples:\n jiradc issue transition PROJ-123 --to 31\n jiradc issue transition PROJ-123 --to 31 --comment "Moving to review"'
|
|
857
1155
|
).action(async (key, opts) => {
|
|
858
1156
|
const client = getClient();
|
|
1157
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
859
1158
|
await client.issues.transition({ issueKeyOrId: key, transitionId: opts.to, comment: opts.comment });
|
|
860
|
-
output({ transitioned: true, issueKey: key });
|
|
1159
|
+
output({ transitioned: true, issueKey: key, url: issueBrowseUrl(key, ctx) });
|
|
861
1160
|
});
|
|
862
1161
|
}
|
|
863
1162
|
|
|
@@ -880,7 +1179,7 @@ function unlink2(parent) {
|
|
|
880
1179
|
}
|
|
881
1180
|
|
|
882
1181
|
// src/commands/issue/update.ts
|
|
883
|
-
function
|
|
1182
|
+
function update2(parent) {
|
|
884
1183
|
parent.command("update <key>").description("Update issue fields").option("--fields <json>", "JSON string of fields to update").option("--notify-users", "Notify users about the update (default: true)").option("--attachments <paths>", "Comma-separated local file paths to attach").addHelpText(
|
|
885
1184
|
"after",
|
|
886
1185
|
`
|
|
@@ -891,10 +1190,10 @@ Examples:
|
|
|
891
1190
|
jiradc issue update PROJ-123 --fields '{"summary": "With attachment"}' --attachments ./report.pdf`
|
|
892
1191
|
).action(async (key, opts) => {
|
|
893
1192
|
if (!opts.fields && !opts.attachments) {
|
|
894
|
-
|
|
895
|
-
process.exit(1);
|
|
1193
|
+
throw new Error("Provide --fields and/or --attachments");
|
|
896
1194
|
}
|
|
897
1195
|
const client = getClient();
|
|
1196
|
+
const ctx = { baseUrl: client.baseUrl };
|
|
898
1197
|
if (opts.fields) {
|
|
899
1198
|
const parsed = JSON.parse(opts.fields);
|
|
900
1199
|
await client.issues.update({ issueKeyOrId: key, fields: parsed, notifyUsers: opts.notifyUsers });
|
|
@@ -909,7 +1208,12 @@ Examples:
|
|
|
909
1208
|
}
|
|
910
1209
|
}
|
|
911
1210
|
}
|
|
912
|
-
output({
|
|
1211
|
+
output({
|
|
1212
|
+
updated: true,
|
|
1213
|
+
issueKey: key,
|
|
1214
|
+
url: issueBrowseUrl(key, ctx),
|
|
1215
|
+
...uploaded.length > 0 && { attachments: uploaded }
|
|
1216
|
+
});
|
|
913
1217
|
});
|
|
914
1218
|
}
|
|
915
1219
|
|
|
@@ -926,7 +1230,7 @@ function worklog(parent) {
|
|
|
926
1230
|
comment: opts.comment,
|
|
927
1231
|
started: opts.started
|
|
928
1232
|
});
|
|
929
|
-
output(result);
|
|
1233
|
+
output(transformWorklog(result));
|
|
930
1234
|
});
|
|
931
1235
|
}
|
|
932
1236
|
|
|
@@ -944,10 +1248,10 @@ Examples:
|
|
|
944
1248
|
$ jiradc issue attachment list PROJ-123
|
|
945
1249
|
`
|
|
946
1250
|
);
|
|
947
|
-
|
|
1251
|
+
get2(issue);
|
|
948
1252
|
search2(issue);
|
|
949
|
-
|
|
950
|
-
|
|
1253
|
+
create2(issue);
|
|
1254
|
+
update2(issue);
|
|
951
1255
|
deleteIssue(issue);
|
|
952
1256
|
transition(issue);
|
|
953
1257
|
transitions(issue);
|
|
@@ -968,17 +1272,8 @@ Examples:
|
|
|
968
1272
|
devStatus(issue);
|
|
969
1273
|
}
|
|
970
1274
|
|
|
971
|
-
// src/commands/project/components.ts
|
|
972
|
-
function components(parent) {
|
|
973
|
-
parent.command("components <key>").description("Get all components for a project").addHelpText("after", "\nExamples:\n jiradc project components PROJ").action(async (key) => {
|
|
974
|
-
const client = getClient();
|
|
975
|
-
const result = await client.projects.getComponents({ projectKeyOrId: key });
|
|
976
|
-
output(result);
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
|
|
980
1275
|
// src/commands/project/list.ts
|
|
981
|
-
function
|
|
1276
|
+
function list4(parent) {
|
|
982
1277
|
parent.command("list").description("List all projects").option("--expand <expand>", 'Expand options (e.g., "description,lead")').option("--include-archived", "Include archived projects (default: false)").addHelpText(
|
|
983
1278
|
"after",
|
|
984
1279
|
"\nExamples:\n jiradc project list\n jiradc project list --expand description,lead\n jiradc project list --include-archived"
|
|
@@ -1009,16 +1304,14 @@ function registerProjectCommands(program2) {
|
|
|
1009
1304
|
Examples:
|
|
1010
1305
|
$ jiradc project list
|
|
1011
1306
|
$ jiradc project versions PROJ
|
|
1012
|
-
$ jiradc project components PROJ
|
|
1013
1307
|
`
|
|
1014
1308
|
);
|
|
1015
|
-
|
|
1309
|
+
list4(project);
|
|
1016
1310
|
versions(project);
|
|
1017
|
-
components(project);
|
|
1018
1311
|
}
|
|
1019
1312
|
|
|
1020
1313
|
// src/commands/sprint/create.ts
|
|
1021
|
-
function
|
|
1314
|
+
function create3(parent) {
|
|
1022
1315
|
parent.command("create").description("Create a new sprint").requiredOption("--board <id>", "Board ID to create sprint in", positiveInt).requiredOption("--name <name>", "Sprint name").option("--start-date <date>", "Start date in ISO 8601 format").option("--end-date <date>", "End date in ISO 8601 format").option("--goal <goal>", "Sprint goal").addHelpText(
|
|
1023
1316
|
"after",
|
|
1024
1317
|
'\nExamples:\n jiradc sprint create --board 42 --name "Sprint 10"\n jiradc sprint create --board 42 --name "Sprint 10" --start-date 2026-03-20 --end-date 2026-04-03 --goal "Complete auth module"'
|
|
@@ -1055,10 +1348,10 @@ function issues2(parent) {
|
|
|
1055
1348
|
}
|
|
1056
1349
|
|
|
1057
1350
|
// src/commands/sprint/list.ts
|
|
1058
|
-
import { Option as
|
|
1351
|
+
import { Option as Option4 } from "commander";
|
|
1059
1352
|
var SPRINT_STATES = ["future", "active", "closed"];
|
|
1060
|
-
function
|
|
1061
|
-
parent.command("list").description("List sprints for a board").requiredOption("--board <id>", "Board ID", positiveInt).addOption(new
|
|
1353
|
+
function list5(parent) {
|
|
1354
|
+
parent.command("list").description("List sprints for a board").requiredOption("--board <id>", "Board ID", positiveInt).addOption(new Option4("--state <state>", "Filter by sprint state").choices(SPRINT_STATES)).addHelpText(
|
|
1062
1355
|
"after",
|
|
1063
1356
|
"\nExamples:\n jiradc sprint list --board 42\n jiradc sprint list --board 42 --state active"
|
|
1064
1357
|
).action(async (opts) => {
|
|
@@ -1072,10 +1365,10 @@ function list4(parent) {
|
|
|
1072
1365
|
}
|
|
1073
1366
|
|
|
1074
1367
|
// src/commands/sprint/update.ts
|
|
1075
|
-
import { Argument as Argument3, Option as
|
|
1368
|
+
import { Argument as Argument3, Option as Option5 } from "commander";
|
|
1076
1369
|
var SPRINT_STATES2 = ["future", "active", "closed"];
|
|
1077
|
-
function
|
|
1078
|
-
parent.command("update").description("Update an existing sprint").addArgument(new Argument3("<id>", "Sprint ID").argParser(positiveInt)).option("--name <name>", "New sprint name").addOption(new
|
|
1370
|
+
function update3(parent) {
|
|
1371
|
+
parent.command("update").description("Update an existing sprint").addArgument(new Argument3("<id>", "Sprint ID").argParser(positiveInt)).option("--name <name>", "New sprint name").addOption(new Option5("--state <state>", "New sprint state").choices(SPRINT_STATES2)).option("--start-date <date>", "New start date in ISO 8601 format").option("--end-date <date>", "New end date in ISO 8601 format").option("--goal <goal>", "New sprint goal").addHelpText(
|
|
1079
1372
|
"after",
|
|
1080
1373
|
'\nExamples:\n jiradc sprint update 100 --name "Sprint 10 - Extended"\n jiradc sprint update 100 --state active\n jiradc sprint update 100 --end-date 2026-04-10 --goal "Updated goal"'
|
|
1081
1374
|
).action(
|
|
@@ -1106,10 +1399,10 @@ Examples:
|
|
|
1106
1399
|
$ jiradc sprint create --board 42 --name "Sprint 10" --start-date 2026-04-01 --end-date 2026-04-14
|
|
1107
1400
|
`
|
|
1108
1401
|
);
|
|
1109
|
-
|
|
1402
|
+
list5(sprint);
|
|
1110
1403
|
issues2(sprint);
|
|
1111
|
-
|
|
1112
|
-
|
|
1404
|
+
create3(sprint);
|
|
1405
|
+
update3(sprint);
|
|
1113
1406
|
}
|
|
1114
1407
|
|
|
1115
1408
|
// src/commands/user/me.ts
|
|
@@ -1147,7 +1440,7 @@ function readPackageVersion() {
|
|
|
1147
1440
|
}
|
|
1148
1441
|
var DIM = "\x1B[2m";
|
|
1149
1442
|
var RESET = "\x1B[0m";
|
|
1150
|
-
var program = new
|
|
1443
|
+
var program = new Command8();
|
|
1151
1444
|
program.name("jiradc").description("Jira Data Center CLI").version(readPackageVersion()).configureHelp({
|
|
1152
1445
|
styleTitle: (str) => styleText("bold", str),
|
|
1153
1446
|
styleUsage: (str) => styleText("dim", str),
|
|
@@ -1179,6 +1472,7 @@ program.hook("preAction", (thisCommand) => {
|
|
|
1179
1472
|
});
|
|
1180
1473
|
registerIssueCommands(program);
|
|
1181
1474
|
registerProjectCommands(program);
|
|
1475
|
+
registerComponentCommands(program);
|
|
1182
1476
|
registerBoardCommands(program);
|
|
1183
1477
|
registerSprintCommands(program);
|
|
1184
1478
|
registerFieldCommands(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jiradc-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12-g39f1036.1",
|
|
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.31-g39f1036.1"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/node": "24.10.4",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"tsx": "^4.19.2",
|
|
23
23
|
"typescript": "^5.7.2",
|
|
24
24
|
"vitest": "^4.0.16",
|
|
25
|
-
"config-
|
|
26
|
-
"config-
|
|
25
|
+
"config-eslint": "0.0.0",
|
|
26
|
+
"config-typescript": "0.0.0"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=22.0.0"
|