@eyeauras/youtrack-cli 0.5.6 → 0.6.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 +78 -72
- package/dist/src/agile-commands.d.ts.map +1 -1
- package/dist/src/agile-commands.js +8 -9
- package/dist/src/agile-commands.js.map +1 -1
- package/dist/src/agile.d.ts.map +1 -1
- package/dist/src/agile.js +9 -15
- package/dist/src/agile.js.map +1 -1
- package/dist/src/article-extras-commands.d.ts.map +1 -1
- package/dist/src/article-extras-commands.js +13 -12
- package/dist/src/article-extras-commands.js.map +1 -1
- package/dist/src/articles-commands.d.ts.map +1 -1
- package/dist/src/articles-commands.js +15 -13
- package/dist/src/articles-commands.js.map +1 -1
- package/dist/src/articles.d.ts +3 -3
- package/dist/src/articles.d.ts.map +1 -1
- package/dist/src/articles.js +19 -19
- package/dist/src/articles.js.map +1 -1
- package/dist/src/attachment-download-commands.d.ts.map +1 -1
- package/dist/src/attachment-download-commands.js +10 -9
- package/dist/src/attachment-download-commands.js.map +1 -1
- package/dist/src/attachment-download.d.ts +7 -3
- package/dist/src/attachment-download.d.ts.map +1 -1
- package/dist/src/attachment-download.js +33 -40
- package/dist/src/attachment-download.js.map +1 -1
- package/dist/src/attachment-form.js +3 -3
- package/dist/src/attachment-form.js.map +1 -1
- package/dist/src/bundle-values-commands.d.ts.map +1 -1
- package/dist/src/bundle-values-commands.js +21 -18
- package/dist/src/bundle-values-commands.js.map +1 -1
- package/dist/src/cli-support.d.ts +5 -5
- package/dist/src/cli-support.d.ts.map +1 -1
- package/dist/src/cli-support.js +28 -26
- package/dist/src/cli-support.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +55 -39
- package/dist/src/cli.js.map +1 -1
- package/dist/src/client.d.ts +5 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +66 -49
- package/dist/src/client.js.map +1 -1
- package/dist/src/field-catalog-commands.d.ts.map +1 -1
- package/dist/src/field-catalog-commands.js +19 -16
- package/dist/src/field-catalog-commands.js.map +1 -1
- package/dist/src/group-directory-commands.d.ts.map +1 -1
- package/dist/src/group-directory-commands.js +17 -16
- package/dist/src/group-directory-commands.js.map +1 -1
- package/dist/src/issue-attachments-commands.d.ts.map +1 -1
- package/dist/src/issue-attachments-commands.js +9 -8
- package/dist/src/issue-attachments-commands.js.map +1 -1
- package/dist/src/issue-batch.d.ts +3 -1
- package/dist/src/issue-batch.d.ts.map +1 -1
- package/dist/src/issue-batch.js +19 -14
- package/dist/src/issue-batch.js.map +1 -1
- package/dist/src/issue-context-commands.d.ts.map +1 -1
- package/dist/src/issue-context-commands.js +13 -12
- package/dist/src/issue-context-commands.js.map +1 -1
- package/dist/src/issue-context.d.ts.map +1 -1
- package/dist/src/issue-context.js +9 -13
- package/dist/src/issue-context.js.map +1 -1
- package/dist/src/issue-fields-commands.d.ts.map +1 -1
- package/dist/src/issue-fields-commands.js +10 -9
- package/dist/src/issue-fields-commands.js.map +1 -1
- package/dist/src/issue-fields.d.ts +2 -4
- package/dist/src/issue-fields.d.ts.map +1 -1
- package/dist/src/issue-fields.js +39 -100
- package/dist/src/issue-fields.js.map +1 -1
- package/dist/src/issue-query-commands.d.ts.map +1 -1
- package/dist/src/issue-query-commands.js +15 -14
- package/dist/src/issue-query-commands.js.map +1 -1
- package/dist/src/issue-query.d.ts.map +1 -1
- package/dist/src/issue-query.js +7 -10
- package/dist/src/issue-query.js.map +1 -1
- package/dist/src/issue-relations-commands.d.ts.map +1 -1
- package/dist/src/issue-relations-commands.js +17 -16
- package/dist/src/issue-relations-commands.js.map +1 -1
- package/dist/src/issue-relations.js +2 -2
- package/dist/src/issue-relations.js.map +1 -1
- package/dist/src/issue-time-commands.d.ts.map +1 -1
- package/dist/src/issue-time-commands.js +12 -11
- package/dist/src/issue-time-commands.js.map +1 -1
- package/dist/src/issue-time.d.ts.map +1 -1
- package/dist/src/issue-time.js +16 -19
- package/dist/src/issue-time.js.map +1 -1
- package/dist/src/presentation.d.ts +59 -0
- package/dist/src/presentation.d.ts.map +1 -0
- package/dist/src/presentation.js +467 -0
- package/dist/src/presentation.js.map +1 -0
- package/dist/src/time-settings-commands.d.ts.map +1 -1
- package/dist/src/time-settings-commands.js +13 -11
- package/dist/src/time-settings-commands.js.map +1 -1
- package/dist/src/user-directory-commands.d.ts.map +1 -1
- package/dist/src/user-directory-commands.js +14 -12
- package/dist/src/user-directory-commands.js.map +1 -1
- package/package.json +2 -2
package/dist/src/issue-batch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { saveFile } from "@eyeauras/cli-factory";
|
|
2
2
|
import { parse } from "csv-parse/sync";
|
|
3
3
|
import { encodedID, mutate, mutationBody } from "./client.js";
|
|
4
4
|
import { issueRequest, issueWrite, issueWriteFields } from "./issue-fields.js";
|
|
@@ -18,7 +18,7 @@ function csvRows(text) {
|
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
catch {
|
|
21
|
-
throw new Error("
|
|
21
|
+
throw new Error("The manifest must be valid CSV with one header of distinct supported columns.");
|
|
22
22
|
}
|
|
23
23
|
return records.map((record) => {
|
|
24
24
|
const row = {};
|
|
@@ -47,7 +47,7 @@ function csvRows(text) {
|
|
|
47
47
|
export function manifestRows(text, path) {
|
|
48
48
|
const csv = /\.csv$/i.test(path);
|
|
49
49
|
if (!csv && !/\.json$/i.test(path))
|
|
50
|
-
throw new Error("
|
|
50
|
+
throw new Error("The manifest must be a .json or .csv file.");
|
|
51
51
|
let rows;
|
|
52
52
|
if (csv) {
|
|
53
53
|
rows = csvRows(text);
|
|
@@ -57,14 +57,14 @@ export function manifestRows(text, path) {
|
|
|
57
57
|
rows = JSON.parse(text);
|
|
58
58
|
}
|
|
59
59
|
catch {
|
|
60
|
-
throw new Error("
|
|
60
|
+
throw new Error("The manifest must be valid JSON.");
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
if (!Array.isArray(rows) || !rows.length)
|
|
64
|
-
throw new Error("
|
|
64
|
+
throw new Error("The manifest must be a nonempty array of rows.");
|
|
65
65
|
return rows.map((value, index) => {
|
|
66
66
|
try {
|
|
67
|
-
const source = mutationBody(value
|
|
67
|
+
const source = mutationBody(value);
|
|
68
68
|
const { action, issue, ...body } = source;
|
|
69
69
|
if (action === "create" && issue === undefined)
|
|
70
70
|
return { row: index + 1, source, write: issueWrite(body, true) };
|
|
@@ -72,10 +72,10 @@ export function manifestRows(text, path) {
|
|
|
72
72
|
encodedID(issue, "issue ID");
|
|
73
73
|
return { row: index + 1, source, issue, write: issueWrite(body, false) };
|
|
74
74
|
}
|
|
75
|
-
throw new Error("
|
|
75
|
+
throw new Error("The action must be create, or update with an issue ID.");
|
|
76
76
|
}
|
|
77
77
|
catch (error) {
|
|
78
|
-
throw new Error(`
|
|
78
|
+
throw new Error(`Manifest row ${index + 1}: ${error.message}`);
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
}
|
|
@@ -85,11 +85,11 @@ export function manifestRows(text, path) {
|
|
|
85
85
|
*/
|
|
86
86
|
export async function applyIssueBatch(connection, rows, options) {
|
|
87
87
|
if (options.failedRows !== undefined && !/\.json$/i.test(options.failedRows)) {
|
|
88
|
-
throw new Error("
|
|
88
|
+
throw new Error("--failed-rows must end with .json.");
|
|
89
89
|
}
|
|
90
90
|
const results = [];
|
|
91
91
|
let stop = false;
|
|
92
|
-
for (const row of rows) {
|
|
92
|
+
for (const [index, row] of rows.entries()) {
|
|
93
93
|
if (stop || connection.signal?.aborted) {
|
|
94
94
|
results.push({ row: row.row, status: "unattempted" });
|
|
95
95
|
continue;
|
|
@@ -103,9 +103,13 @@ export async function applyIssueBatch(connection, rows, options) {
|
|
|
103
103
|
catch (error) {
|
|
104
104
|
const status = error.status;
|
|
105
105
|
const rejected = !sent || (typeof status === "number" && status >= 400 && status < 500);
|
|
106
|
-
|
|
106
|
+
const message = error.message;
|
|
107
|
+
results.push({ row: row.row, status: rejected ? "failed" : "uncertain", error: message });
|
|
108
|
+
options.progress?.(`Row ${row.row}: ${rejected ? "failed" : "uncertain"} (${message})`);
|
|
107
109
|
stop = !options.continueOnError;
|
|
108
110
|
}
|
|
111
|
+
if ((index + 1) % 10 === 0 && index + 1 < rows.length)
|
|
112
|
+
options.progress?.(`Processed ${index + 1} of ${rows.length} rows.`);
|
|
109
113
|
}
|
|
110
114
|
const count = (status) => results.filter((result) => result.status === status).length;
|
|
111
115
|
const resubmit = rows.filter((_row, index) => ["failed", "unattempted"].includes(String(results[index]?.status)));
|
|
@@ -113,9 +117,10 @@ export async function applyIssueBatch(connection, rows, options) {
|
|
|
113
117
|
if (options.failedRows !== undefined && resubmit.length) {
|
|
114
118
|
try {
|
|
115
119
|
failedRows = {
|
|
116
|
-
...await
|
|
117
|
-
|
|
118
|
-
name:
|
|
120
|
+
...await saveFile({
|
|
121
|
+
cwd: options.cwd,
|
|
122
|
+
name: "failed-rows.json",
|
|
123
|
+
output: options.failedRows,
|
|
119
124
|
content: `${JSON.stringify(resubmit.map((row) => row.source), null, 2)}\n`,
|
|
120
125
|
signal: connection.signal,
|
|
121
126
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-batch.js","sourceRoot":"","sources":["../../src/issue-batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"issue-batch.js","sourceRoot":"","sources":["../../src/issue-batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-context-commands.d.ts","sourceRoot":"","sources":["../../src/issue-context-commands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"issue-context-commands.d.ts","sourceRoot":"","sources":["../../src/issue-context-commands.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,mBAAmB,qDAU/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,qDAyBhC,CAAC;AAEF,eAAO,MAAM,sBAAsB,qDASlC,CAAC"}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { command } from "@eyeauras/cli-factory";
|
|
2
2
|
import { bodyUpdate, pagedRead, projectedRead, readCommand, projectionOptions, readOptions } from "./cli-support.js";
|
|
3
3
|
import { activityCategories, getActivitiesPage, getComment, getIssueActivitiesPage, getVcsChange, listIssueSprints, listVcsChanges, updateComment, } from "./issue-context.js";
|
|
4
|
+
import { commentShown, commentUpdated, sprintTable } from "./presentation.js";
|
|
4
5
|
const activityOptions = [
|
|
5
6
|
...projectionOptions,
|
|
6
7
|
{
|
|
7
8
|
flags: "--categories <categories>",
|
|
8
|
-
description: "
|
|
9
|
+
description: "Comma-separated activity category IDs",
|
|
9
10
|
required: true,
|
|
10
11
|
parse: activityCategories,
|
|
11
12
|
},
|
|
12
13
|
{
|
|
13
14
|
flags: "--cursor <cursor>",
|
|
14
|
-
description: "
|
|
15
|
+
description: "beforeCursor or afterCursor from a previous page",
|
|
15
16
|
},
|
|
16
|
-
{ flags: "--reverse", description: "
|
|
17
|
+
{ flags: "--reverse", description: "Newest activities first" },
|
|
17
18
|
];
|
|
18
19
|
function activityReadOptions(options) {
|
|
19
20
|
return {
|
|
@@ -24,24 +25,24 @@ function activityReadOptions(options) {
|
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
export const contextRootCommands = [
|
|
27
|
-
command("activities", "Inspect activities across
|
|
28
|
-
readCommand("page", "Read one
|
|
28
|
+
command("activities", "Inspect activities across issues", [
|
|
29
|
+
readCommand("page", "Read one cursor page of activities", async (connection, { options }, context) => getActivitiesPage(connection, activityReadOptions(options)), activityOptions),
|
|
29
30
|
]),
|
|
30
31
|
];
|
|
31
32
|
export const contextIssueChildren = [
|
|
32
33
|
command("activity", "Inspect the issue activity stream", [
|
|
33
|
-
readCommand("page <issueID>", "Read one
|
|
34
|
+
readCommand("page <issueID>", "Read one cursor page of activities", async (connection, { args, options }, context) => getIssueActivitiesPage(connection, args.issueID, activityReadOptions(options)), activityOptions),
|
|
34
35
|
]),
|
|
35
|
-
command("sprints", "Inspect sprints that contain an issue", [
|
|
36
|
-
pagedRead("list <issueID>", "List
|
|
36
|
+
command("sprints", "Inspect the sprints that contain an issue", [
|
|
37
|
+
pagedRead("list <issueID>", "List the issue's sprints", listIssueSprints, sprintTable),
|
|
37
38
|
]),
|
|
38
39
|
command("vcs-changes", "Inspect linked VCS changes and pull requests", [
|
|
39
|
-
pagedRead("list <issueID>", "List
|
|
40
|
-
projectedRead("get <issueID> <changeID>", "
|
|
40
|
+
pagedRead("list <issueID>", "List VCS changes and pull requests", listVcsChanges),
|
|
41
|
+
projectedRead("get <issueID> <changeID>", "Show a VCS change or pull request", getVcsChange),
|
|
41
42
|
]),
|
|
42
43
|
];
|
|
43
44
|
export const contextCommentChildren = [
|
|
44
|
-
projectedRead("get <issueID> <commentID>", "
|
|
45
|
-
bodyUpdate("update <issueID> <commentID>", "Replace
|
|
45
|
+
projectedRead("get <issueID> <commentID>", "Show a comment", getComment, commentShown),
|
|
46
|
+
bodyUpdate("update <issueID> <commentID>", "Replace a comment's text", updateComment, "text", commentUpdated("issueID", "commentID")),
|
|
46
47
|
];
|
|
47
48
|
//# sourceMappingURL=issue-context-commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-context-commands.js","sourceRoot":"","sources":["../../src/issue-context-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAyB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACrH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,aAAa,GAEd,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"issue-context-commands.js","sourceRoot":"","sources":["../../src/issue-context-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAyB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACrH,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,aAAa,GAEd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,eAAe,GAAgC;IACnD,GAAG,iBAAiB;IACpB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE,uCAAuC;QACpD,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,kBAAkB;KAC1B;IACD;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,kDAAkD;KAChE;IACD,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,yBAAyB,EAAE;CAC/D,CAAC;AAEF,SAAS,mBAAmB,CAAC,OAAgC;IAC3D,OAAO;QACL,GAAG,WAAW,CAAC,OAAO,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QACtC,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC/E,GAAG,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,OAAO,CAAC,YAAY,EAAE,kCAAkC,EAAE;QACxD,WAAW,CACT,MAAM,EACN,oCAAoC,EACpC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,CACzC,iBAAiB,CAAC,UAAU,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,EAC7D,eAAe,CAChB;KACF,CAAC;CACH,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,OAAO,CAAC,UAAU,EAAE,mCAAmC,EAAE;QACvD,WAAW,CACT,gBAAgB,EAChB,oCAAoC,EACpC,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,CAC/C,sBAAsB,CACpB,UAAU,EACV,IAAI,CAAC,OAAO,EACZ,mBAAmB,CAAC,OAAO,CAAC,CAC7B,EACH,eAAe,CAChB;KACF,CAAC;IACF,OAAO,CAAC,SAAS,EAAE,2CAA2C,EAAE;QAC9D,SAAS,CAAC,gBAAgB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,WAAW,CAAC;KACvF,CAAC;IACF,OAAO,CAAC,aAAa,EAAE,8CAA8C,EAAE;QACrE,SAAS,CAAC,gBAAgB,EAAE,oCAAoC,EAAE,cAAc,CAAC;QACjF,aAAa,CACX,0BAA0B,EAC1B,mCAAmC,EACnC,YAAY,CACb;KACF,CAAC;CACH,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,aAAa,CAAC,2BAA2B,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,CAAC;IACtF,UAAU,CACR,8BAA8B,EAC9B,0BAA0B,EAC1B,aAAa,EACb,MAAM,EACN,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CACvC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-context.d.ts","sourceRoot":"","sources":["../../src/issue-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAaL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAOD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"issue-context.d.ts","sourceRoot":"","sources":["../../src/issue-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAaL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAOD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAgDD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAEzB;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAEzB;AAED,eAAO,MAAM,UAAU,kIAItB,CAAC;AAEF,wBAAsB,aAAa,CACjC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,eAAO,MAAM,gBAAgB,2GAG5B,CAAC;AACF,eAAO,MAAM,cAAc,2GAG1B,CAAC;AACF,eAAO,MAAM,YAAY,iIAIxB,CAAC"}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import { encodedID, fields, issuePath, mutate, mutationBody,
|
|
1
|
+
import { encodedID, fields, issuePath, mutate, mutationBody, nullableText, page, readCollection, readCollectionAt, readObject, readObjectAt, requiredText, } from "./client.js";
|
|
2
2
|
const activityFields = "id,beforeCursor,afterCursor,hasBefore,hasAfter,reverse,activities(id,$type,timestamp,author(id,login),category(id))";
|
|
3
3
|
const commentFields = "id,text,author(id,login),created,updated";
|
|
4
4
|
const vcsFields = "id,$type,date,fetched,text,author(login)";
|
|
5
5
|
export function activityCategories(value) {
|
|
6
|
-
requiredText(value, "categories");
|
|
7
|
-
if (value.split(",").some((category) => !category.trim())) {
|
|
8
|
-
throw new Error("YouTrack categories must contain nonempty comma-separated category IDs.");
|
|
9
|
-
}
|
|
10
|
-
return value;
|
|
6
|
+
return requiredText(value, "categories");
|
|
11
7
|
}
|
|
12
8
|
function activityQuery(options) {
|
|
13
9
|
if (options.reverse !== undefined && typeof options.reverse !== "boolean") {
|
|
14
|
-
throw new Error("
|
|
10
|
+
throw new Error("--reverse must be boolean.");
|
|
15
11
|
}
|
|
16
12
|
return {
|
|
17
13
|
fields: fields(options, activityFields),
|
|
@@ -25,20 +21,20 @@ async function activityPage(connection, path, options) {
|
|
|
25
21
|
if (options.fields === undefined &&
|
|
26
22
|
["activities", "beforeCursor", "afterCursor", "hasBefore", "hasAfter", "reverse"]
|
|
27
23
|
.some((key) => !Object.hasOwn(result, key))) {
|
|
28
|
-
throw new Error("
|
|
24
|
+
throw new Error("Invalid activity page from YouTrack.");
|
|
29
25
|
}
|
|
30
26
|
if (result.activities !== undefined &&
|
|
31
27
|
(!Array.isArray(result.activities) || result.activities.some((item) => item === null || typeof item !== "object" || Array.isArray(item)))) {
|
|
32
|
-
throw new Error("
|
|
28
|
+
throw new Error("Invalid activity page from YouTrack.");
|
|
33
29
|
}
|
|
34
30
|
for (const key of ["beforeCursor", "afterCursor"]) {
|
|
35
31
|
if (result[key] !== undefined && typeof result[key] !== "string") {
|
|
36
|
-
throw new Error("
|
|
32
|
+
throw new Error("Invalid activity page from YouTrack.");
|
|
37
33
|
}
|
|
38
34
|
}
|
|
39
35
|
for (const key of ["hasBefore", "hasAfter", "reverse"]) {
|
|
40
36
|
if (result[key] !== undefined && typeof result[key] !== "boolean") {
|
|
41
|
-
throw new Error("
|
|
37
|
+
throw new Error("Invalid activity page from YouTrack.");
|
|
42
38
|
}
|
|
43
39
|
}
|
|
44
40
|
return result;
|
|
@@ -51,8 +47,8 @@ export async function getIssueActivitiesPage(connection, issueID, options) {
|
|
|
51
47
|
}
|
|
52
48
|
export const getComment = readObjectAt((issueID, commentID) => `${issuePath(issueID)}/comments/${encodedID(commentID, "comment ID")}`, commentFields);
|
|
53
49
|
export async function updateComment(connection, issueID, commentID, input) {
|
|
54
|
-
const body = mutationBody(input
|
|
55
|
-
return mutate(connection, `${issuePath(issueID)}/comments/${encodedID(commentID, "comment ID")}`, { text:
|
|
50
|
+
const body = mutationBody(input);
|
|
51
|
+
return mutate(connection, `${issuePath(issueID)}/comments/${encodedID(commentID, "comment ID")}`, { ...body, ...(Object.hasOwn(body, "text") ? { text: nullableText(body.text, "text") } : {}) }, commentFields);
|
|
56
52
|
}
|
|
57
53
|
export const listIssueSprints = readCollectionAt((issueID) => `${issuePath(issueID)}/sprints`, "id,name,goal,start,finish,archived,agile(id,name)");
|
|
58
54
|
export const listVcsChanges = readCollectionAt((issueID) => `${issuePath(issueID)}/vcsChanges`, vcsFields);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-context.js","sourceRoot":"","sources":["../../src/issue-context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"issue-context.js","sourceRoot":"","sources":["../../src/issue-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-fields-commands.d.ts","sourceRoot":"","sources":["../../src/issue-fields-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"issue-fields-commands.d.ts","sourceRoot":"","sources":["../../src/issue-fields-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAaxE,eAAO,MAAM,qBAAqB,EAAE,SAAS,iBAAiB,EAM7D,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAE1D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,SAAS,iBAAiB,EAY3D,CAAC"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { command } from "@eyeauras/cli-factory";
|
|
2
2
|
import { bodyUpdate, pagedRead, projectedRead } from "./cli-support.js";
|
|
3
3
|
import { getProject, getProjectField, listProjectFields, listUsers, getIssueField, listIssueFields, setIssueField, } from "./issue-fields.js";
|
|
4
|
+
import { issueFieldRecord, issueFieldTable, projectFieldTable, projectRecord, userTable } from "./presentation.js";
|
|
4
5
|
export const fieldsProjectChildren = [
|
|
5
|
-
projectedRead("get <project>", "Show a project
|
|
6
|
-
command("field", "Inspect project custom-field settings
|
|
7
|
-
pagedRead("list <project>", "List
|
|
8
|
-
projectedRead("get <project> <field>", "Show project custom
|
|
6
|
+
projectedRead("get <project>", "Show a project", getProject, projectRecord),
|
|
7
|
+
command("field", "Inspect project custom-field settings", [
|
|
8
|
+
pagedRead("list <project>", "List the project's custom fields", listProjectFields, projectFieldTable),
|
|
9
|
+
projectedRead("get <project> <field>", "Show a project custom field", getProjectField),
|
|
9
10
|
]),
|
|
10
11
|
];
|
|
11
12
|
export const fieldsUserChildren = [
|
|
12
|
-
pagedRead("list", "List
|
|
13
|
+
pagedRead("list", "List users", listUsers, userTable),
|
|
13
14
|
];
|
|
14
15
|
export const fieldsIssueChildren = [
|
|
15
|
-
command("fields", "Read and set
|
|
16
|
-
pagedRead("list <issueID>", "List
|
|
17
|
-
projectedRead("get <issueID> <fieldID>", "Show a field
|
|
18
|
-
bodyUpdate("set <issueID> <fieldID>", "Set
|
|
16
|
+
command("fields", "Read and set custom fields", [
|
|
17
|
+
pagedRead("list <issueID>", "List the issue's custom fields", listIssueFields, issueFieldTable),
|
|
18
|
+
projectedRead("get <issueID> <fieldID>", "Show a custom field", getIssueField, issueFieldRecord),
|
|
19
|
+
bodyUpdate("set <issueID> <fieldID>", "Set a field value or state event", setIssueField, undefined, issueFieldRecord),
|
|
19
20
|
]),
|
|
20
21
|
];
|
|
21
22
|
//# sourceMappingURL=issue-fields-commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-fields-commands.js","sourceRoot":"","sources":["../../src/issue-fields-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA0B,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"issue-fields-commands.js","sourceRoot":"","sources":["../../src/issue-fields-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA0B,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnH,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,aAAa,CAAC,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,aAAa,CAAC;IAC3E,OAAO,CAAC,OAAO,EAAE,uCAAuC,EAAE;QACxD,SAAS,CAAC,gBAAgB,EAAE,kCAAkC,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;QACrG,aAAa,CAAC,uBAAuB,EAAE,6BAA6B,EAAE,eAAe,CAAC;KACvF,CAAC;CACH,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAiC;IAC9D,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC;CACtD,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAiC;IAC/D,OAAO,CAAC,QAAQ,EAAE,4BAA4B,EAAE;QAC9C,SAAS,CAAC,gBAAgB,EAAE,gCAAgC,EAAE,eAAe,EAAE,eAAe,CAAC;QAC/F,aAAa,CAAC,yBAAyB,EAAE,qBAAqB,EAAE,aAAa,EAAE,gBAAgB,CAAC;QAChG,UAAU,CACR,yBAAyB,EACzB,kCAAkC,EAClC,aAAa,EACb,SAAS,EACT,gBAAgB,CACjB;KACF,CAAC;CACH,CAAC"}
|
|
@@ -7,15 +7,13 @@ export declare const listIssueFields: (connection: Connection, issueID: string,
|
|
|
7
7
|
export declare const getIssueField: (connection: Connection, issueID: string, fieldID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<YouTrackObject>;
|
|
8
8
|
export declare function setIssueField(connection: Connection, issueID: string, fieldID: string, input: unknown): Promise<YouTrackObject | null>;
|
|
9
9
|
export declare const issueWriteFields = "id,idReadable,summary,updated";
|
|
10
|
-
/** A
|
|
10
|
+
/** A JSON issue body; the API resolves supplied identity selectors. */
|
|
11
11
|
export interface IssueWrite {
|
|
12
|
-
project?: YouTrackObject;
|
|
13
12
|
body: YouTrackObject;
|
|
14
|
-
customFields?: YouTrackObject[];
|
|
15
13
|
}
|
|
16
14
|
/** Validate an issue create/update body without network access. */
|
|
17
15
|
export declare function issueWrite(input: unknown, create: boolean): IssueWrite;
|
|
18
|
-
/**
|
|
16
|
+
/** Send native selectors without extra catalog reads or body rewriting. */
|
|
19
17
|
export declare function issueRequest(connection: Connection, write: IssueWrite, issueID?: string): Promise<{
|
|
20
18
|
path: string;
|
|
21
19
|
body: YouTrackObject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-fields.d.ts","sourceRoot":"","sources":["../../src/issue-fields.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"issue-fields.d.ts","sourceRoot":"","sources":["../../src/issue-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,UAAU,EACf,KAAK,cAAc,EAEpB,MAAM,aAAa,CAAC;AAerB,eAAO,MAAM,UAAU,uIAAsE,CAAC;AAC9F,eAAO,MAAM,iBAAiB,mIAG7B,CAAC;AACF,eAAO,MAAM,eAAe,wJAI3B,CAAC;AACF,eAAO,MAAM,SAAS,gHAAqD,CAAC;AAC5E,eAAO,MAAM,eAAe,iIAG3B,CAAC;AACF,eAAO,MAAM,aAAa,sJAA4C,CAAC;AAmEvE,wBAAsB,aAAa,CACjC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAYhC;AAED,eAAO,MAAM,gBAAgB,kCAAkC,CAAC;AAEhE,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;CACtB;AAOD,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU,CAsBtE;AAED,2EAA2E;AAC3E,wBAAsB,YAAY,CAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,CAEjD;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAGxG;AAED,wBAAsB,WAAW,CAC/B,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAGhC"}
|
package/dist/src/issue-fields.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { encodedID, issuePath, mutationBody, mutate, narrative, nullableText, readCollectionAt,
|
|
1
|
+
import { encodedID, issuePath, mutationBody, mutate, narrative, nullableText, readCollectionAt, readObjectAt, } from "./client.js";
|
|
2
2
|
const projectFieldFields = "id,field(id,name,fieldType(id,valueType,isMultiValue)),canBeEmpty,emptyFieldText,isPublic";
|
|
3
3
|
const issueFieldFields = "id,name,$type,value(id,name,login,minutes,presentation,text),projectCustomField(id)";
|
|
4
4
|
function projectPath(projectID) {
|
|
@@ -14,19 +14,18 @@ export const listUsers = readCollectionAt("api/users", "id,login,fullName");
|
|
|
14
14
|
export const listIssueFields = readCollectionAt((issueID) => `${issuePath(issueID)}/customFields`, issueFieldFields);
|
|
15
15
|
export const getIssueField = readObjectAt(fieldPath, issueFieldFields);
|
|
16
16
|
function reference(value, user) {
|
|
17
|
-
const body = mutationBody(value
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const body = mutationBody(value);
|
|
18
|
+
for (const key of user ? ["id", "name", "login"] : ["id", "name"]) {
|
|
19
|
+
if (Object.hasOwn(body, key))
|
|
20
|
+
narrative(body[key], `value.${key}`);
|
|
20
21
|
}
|
|
21
|
-
return
|
|
22
|
-
key, narrative(item, `value.${key}`),
|
|
23
|
-
]));
|
|
22
|
+
return body;
|
|
24
23
|
}
|
|
25
24
|
function fieldValue(type, value) {
|
|
26
25
|
const entity = /^(Single|Multi)(Enum|Build|Version|Owned|Group|User)IssueCustomField$/.exec(type);
|
|
27
26
|
if (entity?.[1] === "Multi") {
|
|
28
27
|
if (!Array.isArray(value)) {
|
|
29
|
-
throw new Error("
|
|
28
|
+
throw new Error("A multi-value field requires an array; use [] to clear it.");
|
|
30
29
|
}
|
|
31
30
|
return value.map((item) => reference(item, entity[2] === "User"));
|
|
32
31
|
}
|
|
@@ -36,7 +35,7 @@ function fieldValue(type, value) {
|
|
|
36
35
|
if (![
|
|
37
36
|
"SimpleIssueCustomField", "DateIssueCustomField", "PeriodIssueCustomField", "TextIssueCustomField",
|
|
38
37
|
].includes(type)) {
|
|
39
|
-
|
|
38
|
+
return value;
|
|
40
39
|
}
|
|
41
40
|
if (value === null) {
|
|
42
41
|
return null;
|
|
@@ -46,22 +45,19 @@ function fieldValue(type, value) {
|
|
|
46
45
|
if (typeof value === "string" || (typeof value === "number" && Number.isFinite(value))) {
|
|
47
46
|
return value;
|
|
48
47
|
}
|
|
49
|
-
throw new Error("
|
|
48
|
+
throw new Error("A simple field requires text, a finite number or null.");
|
|
50
49
|
case "DateIssueCustomField":
|
|
51
50
|
if (typeof value === "number" && Number.isSafeInteger(value)) {
|
|
52
51
|
return value;
|
|
53
52
|
}
|
|
54
|
-
throw new Error("
|
|
53
|
+
throw new Error("A date field requires a timestamp in milliseconds or null.");
|
|
55
54
|
case "PeriodIssueCustomField": {
|
|
56
|
-
const body = mutationBody(value
|
|
57
|
-
|
|
58
|
-
throw new Error("YouTrack period value requires minutes or presentation.");
|
|
59
|
-
}
|
|
60
|
-
const result = {};
|
|
55
|
+
const body = mutationBody(value);
|
|
56
|
+
const result = { ...body };
|
|
61
57
|
if (Object.hasOwn(body, "minutes")) {
|
|
62
58
|
if (typeof body.minutes !== "number" || !Number.isSafeInteger(body.minutes) ||
|
|
63
|
-
body.minutes <
|
|
64
|
-
throw new Error("
|
|
59
|
+
body.minutes < -2_147_483_648 || body.minutes > 2_147_483_647) {
|
|
60
|
+
throw new Error("The period minutes must be a signed 32-bit integer.");
|
|
65
61
|
}
|
|
66
62
|
result.minutes = body.minutes;
|
|
67
63
|
}
|
|
@@ -71,119 +67,62 @@ function fieldValue(type, value) {
|
|
|
71
67
|
return result;
|
|
72
68
|
}
|
|
73
69
|
default: {
|
|
74
|
-
const body = mutationBody(value
|
|
75
|
-
if (body.text !== null && typeof body.text !== "string") {
|
|
76
|
-
throw new Error("
|
|
70
|
+
const body = mutationBody(value);
|
|
71
|
+
if (Object.hasOwn(body, "text") && body.text !== null && typeof body.text !== "string") {
|
|
72
|
+
throw new Error("A text field requires text or null.");
|
|
77
73
|
}
|
|
78
|
-
return
|
|
74
|
+
return body;
|
|
79
75
|
}
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
78
|
export async function setIssueField(connection, issueID, fieldID, input) {
|
|
83
|
-
const body = mutationBody(input
|
|
79
|
+
const body = mutationBody(input);
|
|
84
80
|
const type = narrative(body.$type, "field $type");
|
|
85
81
|
let update;
|
|
86
|
-
if (type === "StateMachineIssueCustomField") {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
const event = mutationBody(body.event, ["id"]);
|
|
91
|
-
update = { $type: type, event: { id: narrative(event.id, "event.id") } };
|
|
82
|
+
if (type === "StateMachineIssueCustomField" && Object.hasOwn(body, "event")) {
|
|
83
|
+
const event = mutationBody(body.event);
|
|
84
|
+
update = { ...body, $type: type, event: { ...event, id: narrative(event.id, "event.id") } };
|
|
92
85
|
}
|
|
93
86
|
else {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
update = { $type: type, value: fieldValue(type, body.value) };
|
|
87
|
+
update = { ...body, $type: type,
|
|
88
|
+
...(Object.hasOwn(body, "value") ? { value: fieldValue(type, body.value) } : {}) };
|
|
98
89
|
}
|
|
99
90
|
return mutate(connection, fieldPath(issueID, fieldID), update, issueFieldFields);
|
|
100
91
|
}
|
|
101
92
|
export const issueWriteFields = "id,idReadable,summary,updated";
|
|
102
|
-
function
|
|
93
|
+
function textSelectors(body, keys, label) {
|
|
103
94
|
const present = keys.filter((key) => Object.hasOwn(body, key));
|
|
104
|
-
|
|
105
|
-
throw new Error(`YouTrack ${label} must use exactly one of ${keys.join(" or ")}.`);
|
|
106
|
-
}
|
|
107
|
-
const key = present[0];
|
|
108
|
-
return { [key]: narrative(body[key], `${label} ${key}`) };
|
|
95
|
+
return Object.fromEntries(present.map(key => [key, narrative(body[key], `${label} ${key}`)]));
|
|
109
96
|
}
|
|
110
97
|
/** Validate an issue create/update body without network access. */
|
|
111
98
|
export function issueWrite(input, create) {
|
|
112
|
-
const body = mutationBody(input
|
|
113
|
-
|
|
114
|
-
throw new Error("YouTrack issue update requires summary, description or customFields.");
|
|
115
|
-
}
|
|
116
|
-
const write = { body: {} };
|
|
99
|
+
const body = mutationBody(input);
|
|
100
|
+
const write = { body: { ...body } };
|
|
117
101
|
if (create) {
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
const project = mutationBody(body.project);
|
|
103
|
+
write.body.project = { ...project, ...textSelectors(project, ["id", "shortName"], "project") };
|
|
120
104
|
}
|
|
121
105
|
if (create || Object.hasOwn(body, "summary"))
|
|
122
|
-
write.body.summary =
|
|
106
|
+
write.body.summary = nullableText(body.summary, "summary");
|
|
123
107
|
if (Object.hasOwn(body, "description"))
|
|
124
108
|
write.body.description = nullableText(body.description, "description");
|
|
125
109
|
if (Object.hasOwn(body, "customFields")) {
|
|
126
|
-
if (!Array.isArray(body.customFields)
|
|
127
|
-
throw new Error("
|
|
110
|
+
if (!Array.isArray(body.customFields)) {
|
|
111
|
+
throw new Error("The customFields must be an array.");
|
|
128
112
|
}
|
|
129
113
|
const customFields = body.customFields.map((item) => {
|
|
130
|
-
const entry = mutationBody(item
|
|
114
|
+
const entry = mutationBody(item);
|
|
131
115
|
const type = narrative(entry.$type, "field $type");
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
if (!Object.hasOwn(entry, "value"))
|
|
136
|
-
throw new Error("YouTrack custom field requires value.");
|
|
137
|
-
return { $type: type, ...oneOf(entry, ["id", "name"], "custom field"), value: fieldValue(type, entry.value) };
|
|
116
|
+
return { ...entry, $type: type, ...textSelectors(entry, ["id", "name"], "custom field"),
|
|
117
|
+
...(Object.hasOwn(entry, "value") ? { value: fieldValue(type, entry.value) } : {}) };
|
|
138
118
|
});
|
|
139
|
-
|
|
140
|
-
if (new Set(customFields.map(({ id, name }) => JSON.stringify([id, name]))).size !== customFields.length) {
|
|
141
|
-
throw new Error("YouTrack customFields must not repeat a field.");
|
|
142
|
-
}
|
|
143
|
-
write.customFields = customFields;
|
|
119
|
+
write.body.customFields = customFields;
|
|
144
120
|
}
|
|
145
121
|
return write;
|
|
146
122
|
}
|
|
147
|
-
/**
|
|
123
|
+
/** Send native selectors without extra catalog reads or body rewriting. */
|
|
148
124
|
export async function issueRequest(connection, write, issueID) {
|
|
149
|
-
|
|
150
|
-
let fieldsPath = issueID === undefined ? "" : `${issuePath(issueID)}/customFields`;
|
|
151
|
-
if (write.project) {
|
|
152
|
-
let id = write.project.id;
|
|
153
|
-
const shortName = write.project.shortName;
|
|
154
|
-
if (typeof shortName === "string") {
|
|
155
|
-
const project = await readObject(connection, projectPath(shortName), { fields: "id,shortName" });
|
|
156
|
-
if (typeof project.shortName !== "string" || project.shortName.toLowerCase() !== shortName.toLowerCase()) {
|
|
157
|
-
throw new Error("YouTrack project shortName did not resolve to that project.");
|
|
158
|
-
}
|
|
159
|
-
id = project.id;
|
|
160
|
-
}
|
|
161
|
-
if (typeof id !== "string" || !id)
|
|
162
|
-
throw new Error("YouTrack returned an invalid project identity.");
|
|
163
|
-
body.project = { id };
|
|
164
|
-
fieldsPath = `${projectPath(id)}/customFields`;
|
|
165
|
-
}
|
|
166
|
-
if (write.customFields) {
|
|
167
|
-
const catalog = write.customFields.some((field) => typeof field.name === "string")
|
|
168
|
-
? await readPages(connection, fieldsPath, { fields: issueID === undefined ? "id,field(name)" : "id,name" }, {
|
|
169
|
-
top: 50, skip: 0,
|
|
170
|
-
})
|
|
171
|
-
: [];
|
|
172
|
-
const customFields = write.customFields.map(({ name, ...field }) => {
|
|
173
|
-
if (typeof name !== "string")
|
|
174
|
-
return field;
|
|
175
|
-
const matches = catalog.filter((item) => (typeof item.name === "string" ? item.name : item.field?.name) === name);
|
|
176
|
-
const id = matches.length === 1 ? matches[0].id : undefined;
|
|
177
|
-
if (typeof id !== "string")
|
|
178
|
-
throw new Error("YouTrack custom field name must match exactly one field.");
|
|
179
|
-
return { ...field, id };
|
|
180
|
-
});
|
|
181
|
-
if (new Set(customFields.map((field) => field.id)).size !== customFields.length) {
|
|
182
|
-
throw new Error("YouTrack customFields must not repeat a field.");
|
|
183
|
-
}
|
|
184
|
-
body.customFields = customFields;
|
|
185
|
-
}
|
|
186
|
-
return { path: issueID === undefined ? "api/issues" : issuePath(issueID), body };
|
|
125
|
+
return { path: issueID === undefined ? "api/issues" : issuePath(issueID), body: write.body };
|
|
187
126
|
}
|
|
188
127
|
export async function createIssue(connection, input) {
|
|
189
128
|
const { path, body } = await issueRequest(connection, issueWrite(input, true));
|