Skip to content

Commit b835c42

Browse files
authored
Merge pull request #229 from asgarovf/locus/sprint-jira-package-62j24r
Sprint: jira-package
2 parents 43cdfa6 + c1a5b52 commit b835c42

26 files changed

+3745
-17
lines changed

bun.lock

Lines changed: 72 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
"format": "biome check --write --formatter-enabled=true --assist-enabled=true ",
2424
"version": "changeset version",
2525
"release": "bun run build:packages && changeset publish",
26-
"build:packages": "bun run build:sdk && bun run build:gateway && bun run build:pm2 && bun run build:cron && bun run build:linear && bun run build:telegram && bun run build:cli",
26+
"build:packages": "bun run build:sdk && bun run build:gateway && bun run build:pm2 && bun run build:cron && bun run build:linear && bun run build:jira && bun run build:telegram && bun run build:cli",
2727
"build:linear": "cd packages/linear && bun run build",
28+
"build:jira": "cd packages/jira && bun run build",
2829
"build:cron": "cd packages/cron && bun run build",
2930
"build:sdk": "cd packages/sdk && bun run build",
3031
"build:gateway": "cd packages/gateway && bun run build",

packages/jira/package.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "@locusai/locus-jira",
3+
"version": "0.1.0",
4+
"description": "Fetch and execute Jira issues with Locus",
5+
"type": "module",
6+
"bin": {
7+
"locus-jira": "./bin/locus-jira.js"
8+
},
9+
"files": [
10+
"bin",
11+
"package.json",
12+
"README.md"
13+
],
14+
"locus": {
15+
"displayName": "Jira",
16+
"description": "Fetch and execute Jira issues with Locus",
17+
"commands": [
18+
"jira"
19+
],
20+
"version": "0.1.0"
21+
},
22+
"scripts": {
23+
"build": "bun build src/cli.ts --outfile bin/locus-jira.js --target node",
24+
"typecheck": "tsc --noEmit",
25+
"lint": "biome lint .",
26+
"format": "biome format --write .",
27+
"clean": "rm -rf dist bin node_modules"
28+
},
29+
"dependencies": {
30+
"@locusai/sdk": "^0.26.1",
31+
"axios": "^1.7.0",
32+
"open": "^10.0.0"
33+
},
34+
"devDependencies": {
35+
"@types/node": "^22.0.0",
36+
"typescript": "^5.7.0"
37+
},
38+
"keywords": [
39+
"locusai-package",
40+
"locus",
41+
"jira"
42+
],
43+
"engines": {
44+
"node": ">=18"
45+
},
46+
"license": "MIT"
47+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* API Token authentication for Jira Cloud.
3+
*
4+
* Prompts the user for instance URL, email, and API token,
5+
* then validates by calling GET /rest/api/3/myself with Basic auth.
6+
*/
7+
8+
import axios from "axios";
9+
import { handleJiraError } from "../errors.js";
10+
import type { JiraApiTokenCredentials } from "../types.js";
11+
import { normalizeUrl, prompt } from "./prompt.js";
12+
13+
/**
14+
* Interactively prompt the user for Jira Cloud API token credentials
15+
* and validate them by calling the /rest/api/3/myself endpoint.
16+
*/
17+
export async function promptForApiToken(): Promise<JiraApiTokenCredentials> {
18+
process.stderr.write("\n Jira Cloud — API Token Authentication\n\n");
19+
20+
const rawUrl = await prompt(
21+
" Jira instance URL (e.g. https://myteam.atlassian.net): "
22+
);
23+
if (!rawUrl) {
24+
throw new Error("Instance URL is required.");
25+
}
26+
const baseUrl = normalizeUrl(rawUrl);
27+
28+
const email = await prompt(" Email: ");
29+
if (!email) {
30+
throw new Error("Email is required.");
31+
}
32+
33+
const apiToken = await prompt(" API token: ", true);
34+
if (!apiToken) {
35+
throw new Error("API token is required.");
36+
}
37+
38+
process.stderr.write(" Validating credentials...\n");
39+
40+
const encoded = Buffer.from(`${email}:${apiToken}`).toString("base64");
41+
42+
try {
43+
const response = await axios.get(`${baseUrl}/rest/api/3/myself`, {
44+
headers: {
45+
Authorization: `Basic ${encoded}`,
46+
Accept: "application/json",
47+
},
48+
timeout: 15_000,
49+
});
50+
51+
const displayName =
52+
(response.data as Record<string, unknown>)?.displayName ?? email;
53+
process.stderr.write(` Authenticated as: ${displayName}\n\n`);
54+
} catch (error) {
55+
if (axios.isAxiosError(error)) {
56+
handleJiraError(error);
57+
}
58+
throw error;
59+
}
60+
61+
return {
62+
method: "api-token",
63+
email,
64+
apiToken,
65+
baseUrl,
66+
};
67+
}

0 commit comments

Comments
 (0)