@eyeauras/youtrack-cli 0.1.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/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/src/agile-commands.d.ts +2 -0
- package/dist/src/agile-commands.d.ts.map +1 -0
- package/dist/src/agile-commands.js +18 -0
- package/dist/src/agile-commands.js.map +1 -0
- package/dist/src/agile.d.ts +8 -0
- package/dist/src/agile.d.ts.map +1 -0
- package/dist/src/agile.js +64 -0
- package/dist/src/agile.js.map +1 -0
- package/dist/src/article-extras-commands.d.ts +2 -0
- package/dist/src/article-extras-commands.d.ts.map +1 -0
- package/dist/src/article-extras-commands.js +27 -0
- package/dist/src/article-extras-commands.js.map +1 -0
- package/dist/src/article-extras.d.ts +8 -0
- package/dist/src/article-extras.d.ts.map +1 -0
- package/dist/src/article-extras.js +22 -0
- package/dist/src/article-extras.js.map +1 -0
- package/dist/src/articles-commands.d.ts +3 -0
- package/dist/src/articles-commands.d.ts.map +1 -0
- package/dist/src/articles-commands.js +25 -0
- package/dist/src/articles-commands.js.map +1 -0
- package/dist/src/articles.d.ts +11 -0
- package/dist/src/articles.d.ts.map +1 -0
- package/dist/src/articles.js +41 -0
- package/dist/src/articles.js.map +1 -0
- package/dist/src/attachment-download-commands.d.ts +2 -0
- package/dist/src/attachment-download-commands.d.ts.map +1 -0
- package/dist/src/attachment-download-commands.js +19 -0
- package/dist/src/attachment-download-commands.js.map +1 -0
- package/dist/src/attachment-download.d.ts +16 -0
- package/dist/src/attachment-download.d.ts.map +1 -0
- package/dist/src/attachment-download.js +127 -0
- package/dist/src/attachment-download.js.map +1 -0
- package/dist/src/attachment-form.d.ts +2 -0
- package/dist/src/attachment-form.d.ts.map +1 -0
- package/dist/src/attachment-form.js +20 -0
- package/dist/src/attachment-form.js.map +1 -0
- package/dist/src/bin.d.ts +3 -0
- package/dist/src/bin.d.ts.map +1 -0
- package/dist/src/bin.js +10 -0
- package/dist/src/bin.js.map +1 -0
- package/dist/src/bundle-values-commands.d.ts +3 -0
- package/dist/src/bundle-values-commands.d.ts.map +1 -0
- package/dist/src/bundle-values-commands.js +30 -0
- package/dist/src/bundle-values-commands.js.map +1 -0
- package/dist/src/bundle-values.d.ts +13 -0
- package/dist/src/bundle-values.d.ts.map +1 -0
- package/dist/src/bundle-values.js +24 -0
- package/dist/src/bundle-values.js.map +1 -0
- package/dist/src/cli-support.d.ts +19 -0
- package/dist/src/cli-support.d.ts.map +1 -0
- package/dist/src/cli-support.js +81 -0
- package/dist/src/cli-support.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +99 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/client.d.ts +62 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +348 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/field-catalog-commands.d.ts +4 -0
- package/dist/src/field-catalog-commands.d.ts.map +1 -0
- package/dist/src/field-catalog-commands.js +31 -0
- package/dist/src/field-catalog-commands.js.map +1 -0
- package/dist/src/field-catalog.d.ts +12 -0
- package/dist/src/field-catalog.d.ts.map +1 -0
- package/dist/src/field-catalog.js +22 -0
- package/dist/src/field-catalog.js.map +1 -0
- package/dist/src/group-directory-commands.d.ts +3 -0
- package/dist/src/group-directory-commands.d.ts.map +1 -0
- package/dist/src/group-directory-commands.js +37 -0
- package/dist/src/group-directory-commands.js.map +1 -0
- package/dist/src/group-directory.d.ts +12 -0
- package/dist/src/group-directory.d.ts.map +1 -0
- package/dist/src/group-directory.js +23 -0
- package/dist/src/group-directory.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/issue-attachments-commands.d.ts +2 -0
- package/dist/src/issue-attachments-commands.d.ts.map +1 -0
- package/dist/src/issue-attachments-commands.js +21 -0
- package/dist/src/issue-attachments-commands.js.map +1 -0
- package/dist/src/issue-attachments.d.ts +5 -0
- package/dist/src/issue-attachments.d.ts.map +1 -0
- package/dist/src/issue-attachments.js +11 -0
- package/dist/src/issue-attachments.js.map +1 -0
- package/dist/src/issue-context-commands.d.ts +4 -0
- package/dist/src/issue-context-commands.d.ts.map +1 -0
- package/dist/src/issue-context-commands.js +47 -0
- package/dist/src/issue-context-commands.js.map +1 -0
- package/dist/src/issue-context.d.ts +15 -0
- package/dist/src/issue-context.d.ts.map +1 -0
- package/dist/src/issue-context.js +60 -0
- package/dist/src/issue-context.js.map +1 -0
- package/dist/src/issue-fields-commands.d.ts +5 -0
- package/dist/src/issue-fields-commands.d.ts.map +1 -0
- package/dist/src/issue-fields-commands.js +21 -0
- package/dist/src/issue-fields-commands.js.map +1 -0
- package/dist/src/issue-fields.d.ts +9 -0
- package/dist/src/issue-fields.d.ts.map +1 -0
- package/dist/src/issue-fields.js +101 -0
- package/dist/src/issue-fields.js.map +1 -0
- package/dist/src/issue-query-commands.d.ts +3 -0
- package/dist/src/issue-query-commands.d.ts.map +1 -0
- package/dist/src/issue-query-commands.js +58 -0
- package/dist/src/issue-query-commands.js.map +1 -0
- package/dist/src/issue-query.d.ts +16 -0
- package/dist/src/issue-query.d.ts.map +1 -0
- package/dist/src/issue-query.js +75 -0
- package/dist/src/issue-query.js.map +1 -0
- package/dist/src/issue-relations-commands.d.ts +3 -0
- package/dist/src/issue-relations-commands.d.ts.map +1 -0
- package/dist/src/issue-relations-commands.js +28 -0
- package/dist/src/issue-relations-commands.js.map +1 -0
- package/dist/src/issue-relations.d.ts +14 -0
- package/dist/src/issue-relations.d.ts.map +1 -0
- package/dist/src/issue-relations.js +35 -0
- package/dist/src/issue-relations.js.map +1 -0
- package/dist/src/issue-time-commands.d.ts +3 -0
- package/dist/src/issue-time-commands.d.ts.map +1 -0
- package/dist/src/issue-time-commands.js +24 -0
- package/dist/src/issue-time-commands.js.map +1 -0
- package/dist/src/issue-time.d.ts +9 -0
- package/dist/src/issue-time.d.ts.map +1 -0
- package/dist/src/issue-time.js +88 -0
- package/dist/src/issue-time.js.map +1 -0
- package/dist/src/time-settings-commands.d.ts +3 -0
- package/dist/src/time-settings-commands.d.ts.map +1 -0
- package/dist/src/time-settings-commands.js +27 -0
- package/dist/src/time-settings-commands.js.map +1 -0
- package/dist/src/time-settings.d.ts +8 -0
- package/dist/src/time-settings.d.ts.map +1 -0
- package/dist/src/time-settings.js +14 -0
- package/dist/src/time-settings.js.map +1 -0
- package/dist/src/user-directory-commands.d.ts +3 -0
- package/dist/src/user-directory-commands.d.ts.map +1 -0
- package/dist/src/user-directory-commands.js +24 -0
- package/dist/src/user-directory-commands.js.map +1 -0
- package/dist/src/user-directory.d.ts +9 -0
- package/dist/src/user-directory.d.ts.map +1 -0
- package/dist/src/user-directory.js +15 -0
- package/dist/src/user-directory.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Connection, type ProjectionOptions, type YouTrackObject } from "./client.js";
|
|
2
|
+
export declare const listArticles: (connection: Connection, options?: import("./client.js").PageOptions | undefined) => Promise<YouTrackObject[]>;
|
|
3
|
+
export declare const getArticle: (connection: Connection, articleID: string, options?: ProjectionOptions | undefined) => Promise<YouTrackObject>;
|
|
4
|
+
export declare function createArticle(connection: Connection, input: unknown, options?: ProjectionOptions): Promise<YouTrackObject | null>;
|
|
5
|
+
export declare function updateArticle(connection: Connection, articleID: string, input: unknown, options?: ProjectionOptions): Promise<YouTrackObject | null>;
|
|
6
|
+
export declare const listArticleComments: (connection: Connection, articleID: string, options?: import("./client.js").PageOptions | undefined) => Promise<YouTrackObject[]>;
|
|
7
|
+
export declare const getArticleComment: (connection: Connection, articleID: string, commentID: string, options?: ProjectionOptions | undefined) => Promise<YouTrackObject>;
|
|
8
|
+
export declare function addArticleComment(connection: Connection, articleID: string, input: unknown, options?: ProjectionOptions): Promise<YouTrackObject | null>;
|
|
9
|
+
export declare function updateArticleComment(connection: Connection, articleID: string, commentID: string, input: unknown, options?: ProjectionOptions): Promise<YouTrackObject | null>;
|
|
10
|
+
export declare const listProjectArticles: (connection: Connection, projectID: string, options?: import("./client.js").PageOptions | undefined) => Promise<YouTrackObject[]>;
|
|
11
|
+
//# sourceMappingURL=articles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"articles.d.ts","sourceRoot":"","sources":["../../src/articles.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAWrB,eAAO,MAAM,YAAY,gHAAsD,CAAC;AAChF,eAAO,MAAM,UAAU,iHAAiD,CAAC;AAEzE,wBAAsB,aAAa,CACjC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAahC;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAchC;AAED,eAAO,MAAM,mBAAmB,mIAG/B,CAAC;AACF,eAAO,MAAM,iBAAiB,oIAI7B,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,eAAO,MAAM,mBAAmB,mIAG/B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { encodedID, fields, mutate, mutationBody, narrative, nullableText, readCollectionAt, readObjectAt, } from "./client.js";
|
|
2
|
+
const articleListFields = "id,idReadable,summary,project(id,shortName),updated";
|
|
3
|
+
const articleDetailFields = `${articleListFields},content,parentArticle(id,idReadable),created`;
|
|
4
|
+
const articleWriteFields = "id,idReadable,summary,updated";
|
|
5
|
+
const articleCommentFields = "id,text,author(id,login),created,updated";
|
|
6
|
+
function articlePath(articleID) {
|
|
7
|
+
return `api/articles/${encodedID(articleID, "article ID")}`;
|
|
8
|
+
}
|
|
9
|
+
export const listArticles = readCollectionAt("api/articles", articleListFields);
|
|
10
|
+
export const getArticle = readObjectAt(articlePath, articleDetailFields);
|
|
11
|
+
export async function createArticle(connection, input, options = {}) {
|
|
12
|
+
const body = mutationBody(input, ["project", "summary", "content"]);
|
|
13
|
+
const project = mutationBody(body.project, ["id"]);
|
|
14
|
+
return mutate(connection, "api/articles", {
|
|
15
|
+
project: { id: narrative(project.id, "project.id") },
|
|
16
|
+
summary: narrative(body.summary, "summary"),
|
|
17
|
+
...(Object.hasOwn(body, "content") ? { content: nullableText(body.content, "article content") } : {}),
|
|
18
|
+
}, fields(options, articleWriteFields));
|
|
19
|
+
}
|
|
20
|
+
export async function updateArticle(connection, articleID, input, options = {}) {
|
|
21
|
+
const body = mutationBody(input, ["summary", "content"]);
|
|
22
|
+
if (Object.keys(body).length === 0) {
|
|
23
|
+
throw new Error("YouTrack article update requires summary or content.");
|
|
24
|
+
}
|
|
25
|
+
return mutate(connection, articlePath(articleID), {
|
|
26
|
+
...(Object.hasOwn(body, "summary") ? { summary: narrative(body.summary, "summary") } : {}),
|
|
27
|
+
...(Object.hasOwn(body, "content") ? { content: nullableText(body.content, "article content") } : {}),
|
|
28
|
+
}, fields(options, articleWriteFields));
|
|
29
|
+
}
|
|
30
|
+
export const listArticleComments = readCollectionAt((articleID) => `${articlePath(articleID)}/comments`, articleCommentFields);
|
|
31
|
+
export const getArticleComment = readObjectAt((articleID, commentID) => `${articlePath(articleID)}/comments/${encodedID(commentID, "comment ID")}`, articleCommentFields);
|
|
32
|
+
export async function addArticleComment(connection, articleID, input, options = {}) {
|
|
33
|
+
const body = mutationBody(input, ["text"]);
|
|
34
|
+
return mutate(connection, `${articlePath(articleID)}/comments`, { text: narrative(body.text, "text") }, fields(options, articleCommentFields));
|
|
35
|
+
}
|
|
36
|
+
export async function updateArticleComment(connection, articleID, commentID, input, options = {}) {
|
|
37
|
+
const body = mutationBody(input, ["text"]);
|
|
38
|
+
return mutate(connection, `${articlePath(articleID)}/comments/${encodedID(commentID, "comment ID")}`, { text: narrative(body.text, "text") }, fields(options, articleCommentFields));
|
|
39
|
+
}
|
|
40
|
+
export const listProjectArticles = readCollectionAt((projectID) => `api/admin/projects/${encodedID(projectID, "project ID")}/articles`, articleListFields);
|
|
41
|
+
//# sourceMappingURL=articles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"articles.js","sourceRoot":"","sources":["../../src/articles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-download-commands.d.ts","sourceRoot":"","sources":["../../src/attachment-download-commands.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,yBAAyB,mDA0BrC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readCommand } from "./cli-support.js";
|
|
2
|
+
import { downloadIssueAttachment, downloadLimit, downloadName } from "./attachment-download.js";
|
|
3
|
+
export const attachmentDownloadCommand = readCommand("download <issueID> <attachmentID>", "Download one attachment into this profile's downloads directory without overwriting files", async (connection, { args, options }, context) => downloadIssueAttachment(connection, args.issueID, args.attachmentID, context.appArguments.AppDataDirectory, {
|
|
4
|
+
...(typeof options.name === "string" ? { name: options.name } : {}),
|
|
5
|
+
...(typeof options.maxBytes === "number" ? { maxBytes: options.maxBytes } : {}),
|
|
6
|
+
}), [
|
|
7
|
+
{
|
|
8
|
+
flags: "--name <basename>",
|
|
9
|
+
description: "Optional safe filename; an existing name is never overwritten",
|
|
10
|
+
parse: downloadName,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
flags: "--max-bytes <n>",
|
|
14
|
+
description: "Maximum transfer size in bytes (1-104857600)",
|
|
15
|
+
defaultValue: 25 * 1024 * 1024,
|
|
16
|
+
parse: downloadLimit,
|
|
17
|
+
},
|
|
18
|
+
]);
|
|
19
|
+
//# sourceMappingURL=attachment-download-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-download-commands.js","sourceRoot":"","sources":["../../src/attachment-download-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhG,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAClD,mCAAmC,EACnC,2FAA2F,EAC3F,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,uBAAuB,CACvE,UAAU,EACV,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,YAAY,EACjB,OAAO,CAAC,YAAY,CAAC,gBAAgB,EACrC;IACE,GAAG,CAAC,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,GAAG,CAAC,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAChF,CACF,EACD;IACI;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,+DAA+D;QAC5E,KAAK,EAAE,YAAY;KACpB;IACD;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,8CAA8C;QAC3D,YAAY,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;QAC9B,KAAK,EAAE,aAAa;KACrB;CACF,CACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Connection } from "./client.js";
|
|
2
|
+
export interface DownloadOptions {
|
|
3
|
+
name?: string;
|
|
4
|
+
maxBytes?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface AttachmentDownloadResult {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
path: string;
|
|
10
|
+
bytes: number;
|
|
11
|
+
contentType: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function downloadName(value: string): string;
|
|
14
|
+
export declare function downloadLimit(value: number | string): number;
|
|
15
|
+
export declare function downloadIssueAttachment(connection: Connection, issueID: string, attachmentID: string, appDataDirectory: string, options?: DownloadOptions): Promise<AttachmentDownloadResult>;
|
|
16
|
+
//# sourceMappingURL=attachment-download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-download.d.ts","sourceRoot":"","sources":["../../src/attachment-download.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAM5D;AAiED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,wBAAwB,CAAC,CAmDnC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ProfileFileError, publishProfileFile } from "@eyeauras/cli-factory";
|
|
2
|
+
import { getIssueAttachmentDownloadMetadata, youTrackUrl, } from "./client.js";
|
|
3
|
+
class DownloadError extends ProfileFileError {
|
|
4
|
+
}
|
|
5
|
+
export function downloadName(value) {
|
|
6
|
+
if (!value || Buffer.byteLength(value, "utf8") > 180 || value === "." || value === ".." ||
|
|
7
|
+
/[<>:"/\\|?*\u0000-\u001f\u007f-\u009f\p{Cf}]/u.test(value) || /[. ]$/.test(value) ||
|
|
8
|
+
/^(?:con|prn|aux|nul|conin\$|conout\$|clock\$|com[1-9¹²³]|lpt[1-9¹²³])(?:[ .]|$)/i.test(value)) {
|
|
9
|
+
throw new Error("YouTrack download name must be one safe basename, without reserved paths or characters.");
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
export function downloadLimit(value) {
|
|
14
|
+
const number = typeof value === "string" && /^\d+$/.test(value) ? Number(value) : value;
|
|
15
|
+
if (typeof number !== "number" || !Number.isSafeInteger(number) || number < 1 || number > 104857600) {
|
|
16
|
+
throw new Error("YouTrack max-bytes must be an integer between 1 and 104857600.");
|
|
17
|
+
}
|
|
18
|
+
return number;
|
|
19
|
+
}
|
|
20
|
+
function attachmentUrl(connection, value) {
|
|
21
|
+
const invalid = new DownloadError("YouTrack attachment URL must use the profile origin and documented attachment path; " +
|
|
22
|
+
"external/CDN downloads are unsupported.");
|
|
23
|
+
try {
|
|
24
|
+
if (/[\\\u0000-\u0020\u007f]/.test(value) || value.includes("#")) {
|
|
25
|
+
throw invalid;
|
|
26
|
+
}
|
|
27
|
+
const base = new URL(youTrackUrl(connection.baseUrl));
|
|
28
|
+
const rawPath = value.split("?", 1)[0];
|
|
29
|
+
const originPath = rawPath.replace(/^(?:https?:)?\/\/[^/]*/, "");
|
|
30
|
+
const prefix = originPath.startsWith("/") ? `${base.pathname}api/files/` : "api/files/";
|
|
31
|
+
if (!originPath.startsWith(prefix)) {
|
|
32
|
+
throw invalid;
|
|
33
|
+
}
|
|
34
|
+
const segments = originPath.slice(prefix.length).split("/");
|
|
35
|
+
const fileID = decodeURIComponent(segments[0] ?? "");
|
|
36
|
+
if (!fileID || fileID === "." || fileID === ".." || /[/\\%?#\u0000-\u0020\u007f]/.test(fileID) ||
|
|
37
|
+
segments.length > 2 || (segments.length === 2 && !/^sign=.+$/.test(segments[1]))) {
|
|
38
|
+
throw invalid;
|
|
39
|
+
}
|
|
40
|
+
const url = new URL(value, base);
|
|
41
|
+
if (url.origin !== base.origin || url.protocol !== base.protocol || url.username || url.password || url.hash ||
|
|
42
|
+
!url.pathname.startsWith(`${base.pathname}api/files/`)) {
|
|
43
|
+
throw invalid;
|
|
44
|
+
}
|
|
45
|
+
const pathSignature = segments[1]?.slice(5);
|
|
46
|
+
const querySignatures = url.search.slice(1).split("&")
|
|
47
|
+
.filter((part) => part && part.split("=", 1)[0] !== "updated")
|
|
48
|
+
.map((part) => part.slice(part.indexOf("=") + 1));
|
|
49
|
+
const signatures = [
|
|
50
|
+
...(pathSignature === undefined ? [] : [pathSignature, decodeURIComponent(pathSignature)]),
|
|
51
|
+
...querySignatures.flatMap((part) => [part, decodeURIComponent(part.replace(/\+/g, " "))]),
|
|
52
|
+
];
|
|
53
|
+
const token = connection.token.trim();
|
|
54
|
+
if (decodeURIComponent(url.href).includes(token) ||
|
|
55
|
+
[...url.searchParams].some(([key, part]) => key.includes(token) || part.includes(token))) {
|
|
56
|
+
throw invalid;
|
|
57
|
+
}
|
|
58
|
+
return { url, secrets: [token, ...signatures].filter(Boolean) };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw invalid;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function redact(value, secrets) {
|
|
65
|
+
for (const secret of secrets) {
|
|
66
|
+
value = value.replaceAll(secret, "redacted");
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
function filenamePart(value, fallback, length) {
|
|
71
|
+
return value.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, length).replace(/^\.+|[. ]+$/g, "") || fallback;
|
|
72
|
+
}
|
|
73
|
+
function contentType(value, secrets) {
|
|
74
|
+
const type = value?.split(";", 1)[0]?.trim() ?? "";
|
|
75
|
+
return type && redact(type, secrets) === type && /^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/.test(type)
|
|
76
|
+
? type : "application/octet-stream";
|
|
77
|
+
}
|
|
78
|
+
export async function downloadIssueAttachment(connection, issueID, attachmentID, appDataDirectory, options = {}) {
|
|
79
|
+
const requestedName = options.name === undefined ? undefined : downloadName(options.name);
|
|
80
|
+
const maxBytes = downloadLimit(options.maxBytes ?? 25 * 1024 * 1024);
|
|
81
|
+
try {
|
|
82
|
+
const metadata = await getIssueAttachmentDownloadMetadata(connection, issueID, attachmentID);
|
|
83
|
+
if (metadata.id !== attachmentID) {
|
|
84
|
+
throw new DownloadError("YouTrack returned a different attachment identity for the download.");
|
|
85
|
+
}
|
|
86
|
+
const { url, secrets } = attachmentUrl(connection, metadata.url);
|
|
87
|
+
const id = filenamePart(redact(metadata.id, secrets), "attachment", 64);
|
|
88
|
+
const name = requestedName ??
|
|
89
|
+
downloadName(`${id}-${filenamePart(redact(metadata.name, secrets), "attachment", 96)}`);
|
|
90
|
+
if (redact(name, secrets) !== name || redact(appDataDirectory, secrets) !== appDataDirectory) {
|
|
91
|
+
throw new DownloadError("YouTrack download destination must not contain reflected credentials or signatures.");
|
|
92
|
+
}
|
|
93
|
+
let type = "application/octet-stream";
|
|
94
|
+
const saved = await publishProfileFile({
|
|
95
|
+
appDataDirectory,
|
|
96
|
+
name,
|
|
97
|
+
maxBytes,
|
|
98
|
+
signal: connection.signal,
|
|
99
|
+
openResponse: () => (connection.fetch ?? globalThis.fetch)(url, {
|
|
100
|
+
method: "GET",
|
|
101
|
+
headers: { Accept: "application/octet-stream", "Accept-Encoding": "identity" },
|
|
102
|
+
credentials: "omit",
|
|
103
|
+
redirect: "error",
|
|
104
|
+
...(connection.signal === undefined ? {} : { signal: connection.signal }),
|
|
105
|
+
}),
|
|
106
|
+
inspectResponse(response) {
|
|
107
|
+
if (!response.ok || response.status === 206) {
|
|
108
|
+
throw new DownloadError(`YouTrack attachment download failed (HTTP ${response.status}).`);
|
|
109
|
+
}
|
|
110
|
+
const length = response.headers.get("content-length");
|
|
111
|
+
const declared = length === null ? undefined : Number(length);
|
|
112
|
+
if (length !== null && (!/^\d+$/.test(length) || !Number.isSafeInteger(declared))) {
|
|
113
|
+
throw new DownloadError("YouTrack attachment has an invalid Content-Length.");
|
|
114
|
+
}
|
|
115
|
+
if (declared !== undefined && declared > maxBytes) {
|
|
116
|
+
throw new DownloadError("YouTrack attachment exceeds the configured byte limit.");
|
|
117
|
+
}
|
|
118
|
+
type = contentType(response.headers.get("content-type") ?? metadata.mimeType, secrets);
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
return { id, name, path: saved.path, bytes: saved.bytes, contentType: type };
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
throw error instanceof ProfileFileError ? error : new DownloadError("YouTrack attachment download failed; check cancellation, connectivity and profile filesystem access.");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=attachment-download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-download.js","sourceRoot":"","sources":["../../src/attachment-download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-form.d.ts","sourceRoot":"","sources":["../../src/attachment-form.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAcxE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { requiredText } from "./client.js";
|
|
4
|
+
export async function attachmentForm(filePath) {
|
|
5
|
+
requiredText(filePath, "file path");
|
|
6
|
+
let file;
|
|
7
|
+
try {
|
|
8
|
+
if (!(await fs.promises.stat(filePath)).isFile()) {
|
|
9
|
+
throw new Error();
|
|
10
|
+
}
|
|
11
|
+
file = await fs.openAsBlob(filePath);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
throw new Error("YouTrack upload requires a readable regular file.");
|
|
15
|
+
}
|
|
16
|
+
const form = new FormData();
|
|
17
|
+
form.append("upload1", file, basename(filePath));
|
|
18
|
+
return form;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=attachment-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-form.js","sourceRoot":"","sources":["../../src/attachment-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,YAAY,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACpC,IAAI,IAAU,CAAC;IACf,IAAI,CAAC;QACH,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/src/bin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;AAChC,IAAI,CAAC;IACH,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;AACrC,CAAC;QAAS,CAAC;IACT,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-values-commands.d.ts","sourceRoot":"","sources":["../../src/bundle-values-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAiBxE,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAqE5D,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { command } from "@eyeauras/cli-factory";
|
|
2
|
+
import { pagedRead, projectedRead } from "./cli-support.js";
|
|
3
|
+
import { getBuildBundle, getBuildValue, getOwnedBundle, getOwnedValue, getVersionBundle, getVersionValue, listBuildBundles, listBuildValues, listOwnedBundles, listOwnedValues, listVersionBundles, listVersionValues, } from "./bundle-values.js";
|
|
4
|
+
export const bundleValuesChildren = [
|
|
5
|
+
command("build", "Inspect build bundles and their values", [
|
|
6
|
+
pagedRead("list", "List one page of build bundles without expanding values", listBuildBundles),
|
|
7
|
+
projectedRead("get <bundle>", "Show a build bundle by database ID without expanding values", getBuildBundle),
|
|
8
|
+
command("value", "Inspect values in a build bundle", [
|
|
9
|
+
pagedRead("list <bundle>", "List one page of build values, preserving archived entries", listBuildValues),
|
|
10
|
+
projectedRead("get <bundle> <value>", "Show a build value and its assembly timestamp", getBuildValue),
|
|
11
|
+
]),
|
|
12
|
+
]),
|
|
13
|
+
command("owned", "Inspect owned-field bundles and their values", [
|
|
14
|
+
pagedRead("list", "List one page of owned-field bundles without expanding values", listOwnedBundles),
|
|
15
|
+
projectedRead("get <bundle>", "Show an owned-field bundle by database ID without expanding values", getOwnedBundle),
|
|
16
|
+
command("value", "Inspect values in an owned-field bundle", [
|
|
17
|
+
pagedRead("list <bundle>", "List one page of owned values, preserving archived entries", listOwnedValues),
|
|
18
|
+
projectedRead("get <bundle> <value>", "Show an owned value and its associated user", getOwnedValue),
|
|
19
|
+
]),
|
|
20
|
+
]),
|
|
21
|
+
command("version", "Inspect version bundles and their values", [
|
|
22
|
+
pagedRead("list", "List one page of version bundles without expanding values", listVersionBundles),
|
|
23
|
+
projectedRead("get <bundle>", "Show a version bundle by database ID without expanding values", getVersionBundle),
|
|
24
|
+
command("value", "Inspect version values; default startDate requires YouTrack 2023.1+", [
|
|
25
|
+
pagedRead("list <bundle>", "List one page of version values, preserving archived entries", listVersionValues),
|
|
26
|
+
projectedRead("get <bundle> <value>", "Show a version value with raw release/start dates", getVersionValue),
|
|
27
|
+
]),
|
|
28
|
+
]),
|
|
29
|
+
];
|
|
30
|
+
//# sourceMappingURL=bundle-values-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-values-commands.js","sourceRoot":"","sources":["../../src/bundle-values-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA0B,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,CAAC,MAAM,oBAAoB,GAAiC;IAChE,OAAO,CAAC,OAAO,EAAE,wCAAwC,EAAE;QACzD,SAAS,CAAC,MAAM,EAAE,yDAAyD,EAAE,gBAAgB,CAAC;QAC9F,aAAa,CACX,cAAc,EACd,6DAA6D,EAC7D,cAAc,CACf;QACD,OAAO,CAAC,OAAO,EAAE,kCAAkC,EAAE;YACnD,SAAS,CACP,eAAe,EACf,4DAA4D,EAC5D,eAAe,CAChB;YACD,aAAa,CACX,sBAAsB,EACtB,+CAA+C,EAC/C,aAAa,CACd;SACF,CAAC;KACH,CAAC;IACF,OAAO,CAAC,OAAO,EAAE,8CAA8C,EAAE;QAC/D,SAAS,CACP,MAAM,EACN,+DAA+D,EAC/D,gBAAgB,CACjB;QACD,aAAa,CACX,cAAc,EACd,oEAAoE,EACpE,cAAc,CACf;QACD,OAAO,CAAC,OAAO,EAAE,yCAAyC,EAAE;YAC1D,SAAS,CACP,eAAe,EACf,4DAA4D,EAC5D,eAAe,CAChB;YACD,aAAa,CACX,sBAAsB,EACtB,6CAA6C,EAC7C,aAAa,CACd;SACF,CAAC;KACH,CAAC;IACF,OAAO,CAAC,SAAS,EAAE,0CAA0C,EAAE;QAC7D,SAAS,CACP,MAAM,EACN,2DAA2D,EAC3D,kBAAkB,CACnB;QACD,aAAa,CACX,cAAc,EACd,+DAA+D,EAC/D,gBAAgB,CACjB;QACD,OAAO,CAAC,OAAO,EAAE,qEAAqE,EAAE;YACtF,SAAS,CACP,eAAe,EACf,8DAA8D,EAC9D,iBAAiB,CAClB;YACD,aAAa,CACX,sBAAsB,EACtB,mDAAmD,EACnD,eAAe,CAChB;SACF,CAAC;KACH,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const listBuildBundles: (connection: import("./client.js").Connection, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
2
|
+
export declare const getBuildBundle: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
3
|
+
export declare const listBuildValues: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
4
|
+
export declare const getBuildValue: (connection: import("./client.js").Connection, bundleID: string, valueID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
5
|
+
export declare const listOwnedBundles: (connection: import("./client.js").Connection, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
6
|
+
export declare const getOwnedBundle: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
7
|
+
export declare const listOwnedValues: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
8
|
+
export declare const getOwnedValue: (connection: import("./client.js").Connection, bundleID: string, valueID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
9
|
+
export declare const listVersionBundles: (connection: import("./client.js").Connection, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
10
|
+
export declare const getVersionBundle: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
11
|
+
export declare const listVersionValues: (connection: import("./client.js").Connection, bundleID: string, options?: import("./client.js").PageOptions | undefined) => Promise<import("./client.js").YouTrackObject[]>;
|
|
12
|
+
export declare const getVersionValue: (connection: import("./client.js").Connection, bundleID: string, valueID: string, options?: import("./client.js").ProjectionOptions | undefined) => Promise<import("./client.js").YouTrackObject>;
|
|
13
|
+
//# sourceMappingURL=bundle-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-values.d.ts","sourceRoot":"","sources":["../../src/bundle-values.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,gBAAgB,4JAAsD,CAAC;AACpF,eAAO,MAAM,cAAc,kLAG1B,CAAC;AACF,eAAO,MAAM,eAAe,8KAG3B,CAAC;AACF,eAAO,MAAM,aAAa,mMAGzB,CAAC;AACF,eAAO,MAAM,gBAAgB,4JAA2D,CAAC;AACzF,eAAO,MAAM,cAAc,kLAG1B,CAAC;AACF,eAAO,MAAM,eAAe,8KAG3B,CAAC;AACF,eAAO,MAAM,aAAa,mMAGzB,CAAC;AACF,eAAO,MAAM,kBAAkB,4JAAwD,CAAC;AACxF,eAAO,MAAM,gBAAgB,kLAG5B,CAAC;AACF,eAAO,MAAM,iBAAiB,8KAG7B,CAAC;AACF,eAAO,MAAM,eAAe,mMAG3B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { encodedID, readCollectionAt, readObjectAt } from "./client.js";
|
|
2
|
+
const root = "api/admin/customFieldSettings/bundles";
|
|
3
|
+
const bundleFields = "id,name,isUpdateable";
|
|
4
|
+
const valueFields = "id,name,description,archived,ordinal";
|
|
5
|
+
const buildValueFields = `${valueFields},assembleDate`;
|
|
6
|
+
const ownedValueFields = `${valueFields},owner(id,login)`;
|
|
7
|
+
const versionValueFields = `${valueFields},released,releaseDate,startDate`;
|
|
8
|
+
const bundlePath = (kind, bundleID) => `${root}/${kind}` +
|
|
9
|
+
(bundleID === undefined ? "" : `/${encodedID(bundleID, "bundle ID")}`);
|
|
10
|
+
const valuePath = (kind, bundleID, valueID) => `${bundlePath(kind, bundleID)}/values` +
|
|
11
|
+
(valueID === undefined ? "" : `/${encodedID(valueID, "value ID")}`);
|
|
12
|
+
export const listBuildBundles = readCollectionAt(bundlePath("build"), bundleFields);
|
|
13
|
+
export const getBuildBundle = readObjectAt((bundleID) => bundlePath("build", bundleID), bundleFields);
|
|
14
|
+
export const listBuildValues = readCollectionAt((bundleID) => valuePath("build", bundleID), buildValueFields);
|
|
15
|
+
export const getBuildValue = readObjectAt((bundleID, valueID) => valuePath("build", bundleID, valueID), buildValueFields);
|
|
16
|
+
export const listOwnedBundles = readCollectionAt(bundlePath("ownedField"), bundleFields);
|
|
17
|
+
export const getOwnedBundle = readObjectAt((bundleID) => bundlePath("ownedField", bundleID), bundleFields);
|
|
18
|
+
export const listOwnedValues = readCollectionAt((bundleID) => valuePath("ownedField", bundleID), ownedValueFields);
|
|
19
|
+
export const getOwnedValue = readObjectAt((bundleID, valueID) => valuePath("ownedField", bundleID, valueID), ownedValueFields);
|
|
20
|
+
export const listVersionBundles = readCollectionAt(bundlePath("version"), bundleFields);
|
|
21
|
+
export const getVersionBundle = readObjectAt((bundleID) => bundlePath("version", bundleID), bundleFields);
|
|
22
|
+
export const listVersionValues = readCollectionAt((bundleID) => valuePath("version", bundleID), versionValueFields);
|
|
23
|
+
export const getVersionValue = readObjectAt((bundleID, valueID) => valuePath("version", bundleID, valueID), versionValueFields);
|
|
24
|
+
//# sourceMappingURL=bundle-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-values.js","sourceRoot":"","sources":["../../src/bundle-values.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CommandContext, type CommandDefinition, type GatedTargetCommand, type OptionDefinition } from "@eyeauras/cli-factory";
|
|
2
|
+
import { type Connection, type IssueSearchOptions } from "./client.js";
|
|
3
|
+
export declare const bodyOptions: readonly OptionDefinition[];
|
|
4
|
+
export declare const projectionOptions: readonly OptionDefinition[];
|
|
5
|
+
export declare const pageOptions: readonly OptionDefinition[];
|
|
6
|
+
export declare function connection(context: CommandContext): Promise<Connection>;
|
|
7
|
+
export declare const readCommand: GatedTargetCommand<Connection>, updateCommand: GatedTargetCommand<Connection>;
|
|
8
|
+
type PositionalValues<Text extends string> = Text extends `<${string}> ${infer Rest}` ? [string, ...PositionalValues<Rest>] : Text extends `<${string}>` ? [string] : [];
|
|
9
|
+
type CommandValues<Syntax extends string> = Syntax extends `${string} ${infer Arguments}` ? PositionalValues<Arguments> : [];
|
|
10
|
+
type ReadOperation<Syntax extends string> = (connection: Connection, ...arguments_: [...CommandValues<Syntax>, IssueSearchOptions]) => unknown;
|
|
11
|
+
type BodyOperation<Syntax extends string> = (connection: Connection, ...arguments_: [...CommandValues<Syntax>, unknown]) => unknown;
|
|
12
|
+
type ProjectedBodyOperation<Syntax extends string> = (connection: Connection, ...arguments_: [...CommandValues<Syntax>, unknown, IssueSearchOptions]) => unknown;
|
|
13
|
+
export declare function pagedRead<const Syntax extends string>(syntax: Syntax, description: string, operation: ReadOperation<Syntax>): CommandDefinition;
|
|
14
|
+
export declare function projectedRead<const Syntax extends string>(syntax: Syntax, description: string, operation: ReadOperation<Syntax>): CommandDefinition;
|
|
15
|
+
export declare function bodyUpdate<const Syntax extends string>(syntax: Syntax, description: string, operation: BodyOperation<Syntax>): CommandDefinition;
|
|
16
|
+
export declare function projectedBodyUpdate<const Syntax extends string>(syntax: Syntax, description: string, operation: ProjectedBodyOperation<Syntax>): CommandDefinition;
|
|
17
|
+
export declare function readOptions(options: Record<string, unknown>): IssueSearchOptions;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=cli-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/cli-support.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAe,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEpF,eAAO,MAAM,WAAW,EAAE,SAAS,gBAAgB,EAOlD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,SAAS,gBAAgB,EAExD,CAAC;AACF,eAAO,MAAM,WAAW,EAAE,SAAS,gBAAgB,EAgBlD,CAAC;AAEF,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7E;AAED,eAAO,MACC,WAAW,kCACT,aAAa,gCACO,CAAC;AAE/B,KAAK,gBAAgB,CAAC,IAAI,SAAS,MAAM,IACvC,IAAI,SAAS,IAAI,MAAM,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAC1E,IAAI,SAAS,IAAI,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GACnC,EAAE,CAAC;AACX,KAAK,aAAa,CAAC,MAAM,SAAS,MAAM,IACtC,MAAM,SAAS,GAAG,MAAM,IAAI,MAAM,SAAS,EAAE,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;AAEnF,KAAK,aAAa,CAAC,MAAM,SAAS,MAAM,IAAI,CAC1C,UAAU,EAAE,UAAU,EACtB,GAAG,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,KAC1D,OAAO,CAAC;AAEb,KAAK,aAAa,CAAC,MAAM,SAAS,MAAM,IAAI,CAC1C,UAAU,EAAE,UAAU,EACtB,GAAG,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,KAC/C,OAAO,CAAC;AAEb,KAAK,sBAAsB,CAAC,MAAM,SAAS,MAAM,IAAI,CACnD,UAAU,EAAE,UAAU,EACtB,GAAG,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,KACnE,OAAO,CAAC;AAwCb,wBAAgB,SAAS,CAAC,KAAK,CAAC,MAAM,SAAS,MAAM,EACnD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,GAC/B,iBAAiB,CAKnB;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,MAAM,SAAS,MAAM,EACvD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,GAC/B,iBAAiB,CAKnB;AAED,wBAAgB,UAAU,CAAC,KAAK,CAAC,MAAM,SAAS,MAAM,EACpD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,GAC/B,iBAAiB,CAKnB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,MAAM,SAAS,MAAM,EAC7D,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,sBAAsB,CAAC,MAAM,CAAC,GACxC,iBAAiB,CAMnB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAOhF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { integerParser, jsonParser, targetCommands, } from "@eyeauras/cli-factory";
|
|
2
|
+
import { youTrackUrl } from "./client.js";
|
|
3
|
+
export const bodyOptions = [
|
|
4
|
+
{
|
|
5
|
+
flags: "--body <json>",
|
|
6
|
+
description: "Required JSON object containing this command's supported fields",
|
|
7
|
+
required: true,
|
|
8
|
+
parse: jsonParser("YouTrack body must be valid JSON."),
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
export const projectionOptions = [
|
|
12
|
+
{ flags: "--fields <projection>", description: "Explicit YouTrack fields projection" },
|
|
13
|
+
];
|
|
14
|
+
export const pageOptions = [
|
|
15
|
+
...projectionOptions,
|
|
16
|
+
{
|
|
17
|
+
flags: "--top <count>", description: "Maximum results (1-100)", defaultValue: 50,
|
|
18
|
+
parse: integerParser({
|
|
19
|
+
min: 1, max: 100, signed: false,
|
|
20
|
+
errorMessage: "YouTrack top must be a decimal integer between 1 and 100.",
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
flags: "--skip <offset>", description: "Nonnegative result offset", defaultValue: 0,
|
|
25
|
+
parse: integerParser({
|
|
26
|
+
min: 0, max: Number.MAX_SAFE_INTEGER, signed: false,
|
|
27
|
+
errorMessage: "YouTrack skip must be a nonnegative safe decimal integer.",
|
|
28
|
+
}),
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
export async function connection(context) {
|
|
32
|
+
const baseUrl = youTrackUrl(context.profile.values.url);
|
|
33
|
+
return {
|
|
34
|
+
baseUrl,
|
|
35
|
+
token: await context.secrets.require("token"),
|
|
36
|
+
fetch: context.fetch,
|
|
37
|
+
signal: context.signal,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export const { read: readCommand, update: updateCommand, } = targetCommands(connection);
|
|
41
|
+
function positionalNames(syntax) {
|
|
42
|
+
const tokens = syntax.split(" ").slice(1);
|
|
43
|
+
const names = tokens.map((token) => /^<([A-Za-z][A-Za-z0-9_-]*)>$/.exec(token)?.[1]);
|
|
44
|
+
if (names.some((name) => name === undefined)) {
|
|
45
|
+
throw new Error("YouTrack operation helpers require only named positional arguments.");
|
|
46
|
+
}
|
|
47
|
+
return names;
|
|
48
|
+
}
|
|
49
|
+
function positionalArguments(names, args) {
|
|
50
|
+
const values = args;
|
|
51
|
+
return names.map((name) => String(values[name]));
|
|
52
|
+
}
|
|
53
|
+
function operationCommand(leaf, syntax, description, operation, options, operationOptions) {
|
|
54
|
+
const names = positionalNames(syntax);
|
|
55
|
+
return leaf(syntax, description, (connection, input) => Reflect.apply(operation, undefined, [
|
|
56
|
+
connection,
|
|
57
|
+
...positionalArguments(names, input.args),
|
|
58
|
+
...operationOptions(input.options),
|
|
59
|
+
]), options);
|
|
60
|
+
}
|
|
61
|
+
export function pagedRead(syntax, description, operation) {
|
|
62
|
+
return operationCommand(readCommand, syntax, description, operation, pageOptions, (options) => [readOptions(options)]);
|
|
63
|
+
}
|
|
64
|
+
export function projectedRead(syntax, description, operation) {
|
|
65
|
+
return operationCommand(readCommand, syntax, description, operation, projectionOptions, (options) => [readOptions(options)]);
|
|
66
|
+
}
|
|
67
|
+
export function bodyUpdate(syntax, description, operation) {
|
|
68
|
+
return operationCommand(updateCommand, syntax, description, operation, bodyOptions, (options) => [options.body]);
|
|
69
|
+
}
|
|
70
|
+
export function projectedBodyUpdate(syntax, description, operation) {
|
|
71
|
+
return operationCommand(updateCommand, syntax, description, operation, [...bodyOptions, ...projectionOptions], (options) => [options.body, readOptions(options)]);
|
|
72
|
+
}
|
|
73
|
+
export function readOptions(options) {
|
|
74
|
+
return {
|
|
75
|
+
...(typeof options.fields === "string" ? { fields: options.fields } : {}),
|
|
76
|
+
...(typeof options.top === "number" ? { top: options.top } : {}),
|
|
77
|
+
...(typeof options.skip === "number" ? { skip: options.skip } : {}),
|
|
78
|
+
...(typeof options.query === "string" ? { query: options.query } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=cli-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-support.js","sourceRoot":"","sources":["../../src/cli-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAmC/B,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,CA0GtE"}
|