@theholocron/jira-client 0.11.5 → 1.0.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/dist/index.d.mts CHANGED
@@ -1,7 +1,10 @@
1
+ import { RestClient } from "@theholocron/http-client";
1
2
  //#region src/types.d.ts
2
3
  interface JiraClientOptions {
3
4
  host: string;
4
5
  token: string;
6
+ /** Override fetch for testing. Defaults to globalThis.fetch. */
7
+ fetch?: typeof fetch;
5
8
  }
6
9
  interface JiraIssueFields {
7
10
  [key: string]: unknown;
@@ -67,7 +70,7 @@ interface IssueLinkResult {
67
70
  ticket: string;
68
71
  status: number;
69
72
  }
70
- declare function links(options: JiraClientOptions): {
73
+ declare function links(client: RestClient): {
71
74
  create(ticket: string, link: string, type: string): Promise<number>;
72
75
  createMany(tickets: string[], link: string, type: string): Promise<IssueLinkResult[]>;
73
76
  getLinkTypes(params?: Record<string, string>): Promise<{
@@ -76,22 +79,22 @@ declare function links(options: JiraClientOptions): {
76
79
  };
77
80
  //#endregion
78
81
  //#region src/issues.d.ts
79
- declare function issues(options: JiraClientOptions): {
82
+ declare function issues(client: RestClient): {
80
83
  create(title: string, type: string, project: string, fields?: JiraIssueFields): Promise<JiraIssue>;
81
84
  get(ticket: string, params?: Record<string, string>): Promise<JiraIssue>;
82
85
  getMany(tickets: string[], params?: Record<string, string>): Promise<JiraIssue[]>;
83
86
  update(ticket: string, fields: JiraIssueFields): Promise<void>;
84
87
  getProperty(ticket: string, property: string): Promise<unknown>;
85
- search(query: JiraSearchQuery): Promise<JiraSearchResponse>;
88
+ search(query?: JiraSearchQuery): Promise<JiraSearchResponse>;
86
89
  };
87
90
  //#endregion
88
91
  //#region src/projects.d.ts
89
- declare function projects(options: JiraClientOptions): {
92
+ declare function projects(client: RestClient): {
90
93
  get(id: string): Promise<JiraProject>;
91
94
  };
92
95
  //#endregion
93
96
  //#region src/transitions.d.ts
94
- declare function transitions(options: JiraClientOptions): {
97
+ declare function transitions(client: RestClient): {
95
98
  create(ticket: string, statusId: string, fields?: JiraIssueFields): Promise<void>;
96
99
  get(ticket: string): Promise<{
97
100
  transitions: JiraTransition[];
@@ -100,7 +103,7 @@ declare function transitions(options: JiraClientOptions): {
100
103
  };
101
104
  //#endregion
102
105
  //#region src/versions.d.ts
103
- declare function versions(options: JiraClientOptions): {
106
+ declare function versions(client: RestClient): {
104
107
  create(name: string, project: string, fields?: Partial<JiraVersion>): Promise<JiraVersion>;
105
108
  get(version: string, params?: Record<string, string>): Promise<JiraVersion>;
106
109
  getMany(versionIds: string[], params?: Record<string, string>): Promise<JiraVersion[]>;
@@ -112,6 +115,7 @@ declare function versions(options: JiraClientOptions): {
112
115
  declare function createJiraClient(options: {
113
116
  host: string;
114
117
  token: string;
118
+ fetch?: typeof fetch;
115
119
  }): {
116
120
  issues: {
117
121
  create(title: string, type: string, project: string, fields?: JiraIssueFields): Promise<JiraIssue>;
@@ -119,7 +123,7 @@ declare function createJiraClient(options: {
119
123
  getMany(tickets: string[], params?: Record<string, string>): Promise<JiraIssue[]>;
120
124
  update(ticket: string, fields: JiraIssueFields): Promise<void>;
121
125
  getProperty(ticket: string, property: string): Promise<unknown>;
122
- search(query: JiraSearchQuery): Promise<JiraSearchResponse>;
126
+ search(query?: JiraSearchQuery): Promise<JiraSearchResponse>;
123
127
  };
124
128
  links: {
125
129
  create(ticket: string, link: string, type: string): Promise<number>;
package/dist/index.mjs CHANGED
@@ -1,86 +1,62 @@
1
- //#region src/client.ts
2
- function buildHeaders(token) {
3
- return {
4
- Accept: "application/json",
5
- Authorization: `Basic ${token}`,
6
- "Content-Type": "application/json; charset=UTF-8"
7
- };
8
- }
9
- function buildUrl(options, path, params) {
10
- const url = new URL(`${options.host}${path}`);
11
- if (params) {
12
- for (const [key, value] of Object.entries(params)) if (value !== void 0) url.searchParams.set(key, String(value));
13
- }
14
- return url.toString();
15
- }
16
- async function request(url, init) {
17
- const response = await fetch(url, init);
18
- if (!response.ok) throw new Error(`Jira API error ${response.status}: ${response.statusText}`);
19
- if (response.status === 204 || response.headers.get("content-length") === "0") return;
20
- return response.json();
21
- }
22
- //#endregion
1
+ import { ProviderApiError, createRestClient } from "@theholocron/http-client";
23
2
  //#region src/issues.ts
24
- function issues(options) {
25
- const headers = buildHeaders(options.token);
3
+ function issues(client) {
26
4
  return {
27
5
  create(title, type, project, fields = {}) {
28
- return request(buildUrl(options, "/issue/"), {
6
+ return client.request("/issue/", {
29
7
  method: "POST",
30
- headers,
31
- body: JSON.stringify({ fields: {
8
+ body: { fields: {
32
9
  project: { key: project },
33
10
  summary: title,
34
11
  issuetype: { name: type },
35
12
  ...fields
36
- } })
13
+ } }
37
14
  });
38
15
  },
39
16
  get(ticket, params) {
40
- return request(buildUrl(options, `/issue/${ticket}`, params), {
41
- method: "GET",
42
- headers
43
- });
17
+ return client.request(`/issue/${ticket}`, { query: params });
44
18
  },
45
19
  getMany(tickets, params) {
46
20
  return Promise.all(tickets.map((t) => this.get(t, params)));
47
21
  },
48
22
  update(ticket, fields) {
49
- return request(buildUrl(options, `/issue/${ticket}`), {
23
+ return client.request(`/issue/${ticket}`, {
50
24
  method: "PUT",
51
- headers,
52
- body: JSON.stringify({ fields })
25
+ body: { fields }
53
26
  });
54
27
  },
55
28
  getProperty(ticket, property) {
56
- return request(buildUrl(options, `/issue/${ticket}/properties/${property}`), {
57
- method: "GET",
58
- headers
59
- });
29
+ return client.request(`/issue/${ticket}/properties/${property}`);
60
30
  },
61
- search(query) {
62
- return request(buildUrl(options, "/search", query), {
63
- method: "GET",
64
- headers
65
- });
31
+ search(query = {}) {
32
+ const q = {};
33
+ if (query.jql !== void 0) q["jql"] = query.jql;
34
+ if (query.startAt !== void 0) q["startAt"] = String(query.startAt);
35
+ if (query.maxResults !== void 0) q["maxResults"] = String(query.maxResults);
36
+ if (query.fields !== void 0) q["fields"] = query.fields.join(",");
37
+ return client.request("/search", { query: q });
66
38
  }
67
39
  };
68
40
  }
69
41
  //#endregion
70
42
  //#region src/links.ts
71
- function links(options) {
72
- const headers = buildHeaders(options.token);
43
+ function links(client) {
73
44
  return {
74
- create(ticket, link, type) {
75
- return fetch(buildUrl(options, "/issueLink"), {
76
- method: "POST",
77
- headers,
78
- body: JSON.stringify({
79
- type: { name: type },
80
- inwardIssue: { key: ticket },
81
- outwardIssue: { key: link }
82
- })
83
- }).then((r) => r.status);
45
+ async create(ticket, link, type) {
46
+ try {
47
+ await client.request("/issueLink", {
48
+ method: "POST",
49
+ body: {
50
+ type: { name: type },
51
+ inwardIssue: { key: ticket },
52
+ outwardIssue: { key: link }
53
+ }
54
+ });
55
+ return 201;
56
+ } catch (err) {
57
+ if (err instanceof ProviderApiError && err.status !== void 0 && err.status > 0) return err.status;
58
+ throw err;
59
+ }
84
60
  },
85
61
  createMany(tickets, link, type) {
86
62
  return Promise.all(tickets.map(async (ticket) => ({
@@ -89,103 +65,87 @@ function links(options) {
89
65
  })));
90
66
  },
91
67
  getLinkTypes(params) {
92
- return request(buildUrl(options, "/issueLinkType", params), {
93
- method: "GET",
94
- headers
95
- });
68
+ return client.request("/issueLinkType", { query: params });
96
69
  }
97
70
  };
98
71
  }
99
72
  //#endregion
100
73
  //#region src/projects.ts
101
- function projects(options) {
102
- const headers = buildHeaders(options.token);
74
+ function projects(client) {
103
75
  return { get(id) {
104
- return request(buildUrl(options, `/project/${id}`, { expand: "issueTypes" }), {
105
- method: "GET",
106
- headers
107
- });
76
+ return client.request(`/project/${id}`, { query: { expand: "issueTypes" } });
108
77
  } };
109
78
  }
110
79
  //#endregion
111
80
  //#region src/transitions.ts
112
- function transitions(options) {
113
- const headers = buildHeaders(options.token);
81
+ function transitions(client) {
114
82
  return {
115
83
  create(ticket, statusId, fields = {}) {
116
- return request(buildUrl(options, `/issue/${ticket}/transitions`), {
84
+ return client.request(`/issue/${ticket}/transitions`, {
117
85
  method: "POST",
118
- headers,
119
- body: JSON.stringify({
86
+ body: {
120
87
  transition: { id: statusId },
121
88
  fields
122
- })
89
+ }
123
90
  });
124
91
  },
125
92
  get(ticket) {
126
- return request(buildUrl(options, `/issue/${ticket}/transitions`), {
127
- method: "GET",
128
- headers
129
- });
93
+ return client.request(`/issue/${ticket}/transitions`);
130
94
  },
131
95
  getResolutions() {
132
- return request(buildUrl(options, "/resolution"), {
133
- method: "GET",
134
- headers
135
- });
96
+ return client.request("/resolution");
136
97
  }
137
98
  };
138
99
  }
139
100
  //#endregion
140
101
  //#region src/versions.ts
141
- function versions(options) {
142
- const headers = buildHeaders(options.token);
102
+ function versions(client) {
143
103
  return {
144
104
  create(name, project, fields = {}) {
145
- return request(buildUrl(options, "/version"), {
105
+ return client.request("/version", {
146
106
  method: "POST",
147
- headers,
148
- body: JSON.stringify({
107
+ body: {
149
108
  name,
150
109
  project,
151
110
  startDate: (/* @__PURE__ */ new Date()).toISOString(),
152
111
  ...fields
153
- })
112
+ }
154
113
  });
155
114
  },
156
115
  get(version, params) {
157
- return request(buildUrl(options, `/version/${version}`, params), {
158
- method: "GET",
159
- headers
160
- });
116
+ return client.request(`/version/${version}`, { query: params });
161
117
  },
162
118
  getMany(versionIds, params) {
163
119
  return Promise.all(versionIds.map((v) => this.get(v, params)));
164
120
  },
165
121
  update(version, fields) {
166
- return request(buildUrl(options, `/version/${version}`), {
122
+ return client.request(`/version/${version}`, {
167
123
  method: "PUT",
168
- headers,
169
- body: JSON.stringify(fields)
124
+ body: fields
170
125
  });
171
126
  },
172
127
  delete(version) {
173
- return request(buildUrl(options, `/version/${version}`), {
174
- method: "DELETE",
175
- headers
176
- });
128
+ return client.request(`/version/${version}`, { method: "DELETE" });
177
129
  }
178
130
  };
179
131
  }
180
132
  //#endregion
181
133
  //#region src/index.ts
182
134
  function createJiraClient(options) {
135
+ const client = createRestClient({
136
+ baseUrl: options.host,
137
+ token: `Basic ${options.token}`,
138
+ tokenScheme: "apikey",
139
+ apiKeyHeader: "authorization",
140
+ vendor: "Jira",
141
+ fetch: options.fetch
142
+ });
183
143
  return {
184
- issues: issues(options),
185
- links: links(options),
186
- projects: projects(options),
187
- transitions: transitions(options),
188
- versions: versions(options)
144
+ issues: issues(client),
145
+ links: links(client),
146
+ projects: projects(client),
147
+ transitions: transitions(client),
148
+ versions: versions(client)
189
149
  };
190
150
  }
191
151
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/jira-client",
3
- "version": "0.11.5",
3
+ "version": "1.0.1",
4
4
  "description": "A TypeScript client for the Jira REST API",
5
5
  "homepage": "https://github.com/theholocron/clients/tree/main/packages/jira-client#readme",
6
6
  "bugs": "https://github.com/theholocron/clients/issues",
@@ -11,7 +11,16 @@
11
11
  },
12
12
  "license": "GPL-3.0",
13
13
  "author": "Newton Koumantzelis",
14
+ "keywords": [
15
+ "jira",
16
+ "atlassian",
17
+ "tickets",
18
+ "project-management",
19
+ "typescript",
20
+ "api"
21
+ ],
14
22
  "type": "module",
23
+ "sideEffects": false,
15
24
  "main": "./dist/index.mjs",
16
25
  "exports": {
17
26
  ".": {
@@ -20,6 +29,9 @@
20
29
  "default": "./dist/index.mjs"
21
30
  }
22
31
  },
32
+ "dependencies": {
33
+ "@theholocron/http-client": "^0.11.5"
34
+ },
23
35
  "devDependencies": {
24
36
  "@types/node": "^26.1.1",
25
37
  "@theholocron/eslint-config": "^7.0.0",