@decaf-ts/integrations 0.12.0 → 0.14.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/dist/integrations.cjs +1 -1
- package/lib/cjs/calendar/environment.cjs +48 -0
- package/lib/cjs/calendar/environment.cjs.map +1 -0
- package/lib/cjs/calendar/google-calendar/GoogleCalendarService.cjs +338 -0
- package/lib/cjs/calendar/google-calendar/GoogleCalendarService.cjs.map +1 -0
- package/lib/cjs/calendar/google-calendar/index.cjs +20 -0
- package/lib/cjs/calendar/google-calendar/index.cjs.map +1 -0
- package/lib/cjs/comms/discord/DiscordService.cjs +318 -0
- package/lib/cjs/comms/discord/DiscordService.cjs.map +1 -0
- package/lib/cjs/comms/discord/index.cjs +19 -0
- package/lib/cjs/comms/discord/index.cjs.map +1 -0
- package/lib/cjs/comms/environment.cjs +16 -0
- package/lib/cjs/comms/environment.cjs.map +1 -1
- package/lib/cjs/comms/index.cjs +3 -0
- package/lib/cjs/comms/index.cjs.map +1 -1
- package/lib/cjs/comms/outlook/MicrosoftOutlookService.cjs +325 -0
- package/lib/cjs/comms/outlook/MicrosoftOutlookService.cjs.map +1 -0
- package/lib/cjs/comms/outlook/index.cjs +19 -0
- package/lib/cjs/comms/outlook/index.cjs.map +1 -0
- package/lib/cjs/comms/whatsapp/WhatsAppService.cjs +274 -0
- package/lib/cjs/comms/whatsapp/WhatsAppService.cjs.map +1 -0
- package/lib/cjs/comms/whatsapp/index.cjs +19 -0
- package/lib/cjs/comms/whatsapp/index.cjs.map +1 -0
- package/lib/cjs/index.cjs +3 -3
- package/lib/cjs/io/confluence/ConfluenceService.cjs +317 -0
- package/lib/cjs/io/confluence/ConfluenceService.cjs.map +1 -0
- package/lib/cjs/io/confluence/index.cjs +19 -0
- package/lib/cjs/io/confluence/index.cjs.map +1 -0
- package/lib/cjs/io/environment.cjs +28 -0
- package/lib/cjs/io/environment.cjs.map +1 -1
- package/lib/cjs/io/google-docs/GoogleDocsService.cjs +275 -0
- package/lib/cjs/io/google-docs/GoogleDocsService.cjs.map +1 -0
- package/lib/cjs/io/google-docs/index.cjs +19 -0
- package/lib/cjs/io/google-docs/index.cjs.map +1 -0
- package/lib/cjs/io/index.cjs +5 -0
- package/lib/cjs/io/index.cjs.map +1 -1
- package/lib/cjs/io/jira/JiraService.cjs +354 -0
- package/lib/cjs/io/jira/JiraService.cjs.map +1 -0
- package/lib/cjs/io/jira/index.cjs +19 -0
- package/lib/cjs/io/jira/index.cjs.map +1 -0
- package/lib/cjs/io/microsoft-excel/MicrosoftExcelService.cjs +253 -0
- package/lib/cjs/io/microsoft-excel/MicrosoftExcelService.cjs.map +1 -0
- package/lib/cjs/io/microsoft-excel/index.cjs +19 -0
- package/lib/cjs/io/microsoft-excel/index.cjs.map +1 -0
- package/lib/cjs/io/microsoft-sharepoint/MicrosoftSharePointService.cjs +261 -0
- package/lib/cjs/io/microsoft-sharepoint/MicrosoftSharePointService.cjs.map +1 -0
- package/lib/cjs/io/microsoft-sharepoint/index.cjs +19 -0
- package/lib/cjs/io/microsoft-sharepoint/index.cjs.map +1 -0
- package/lib/esm/calendar/environment.js +44 -0
- package/lib/esm/calendar/environment.js.map +1 -0
- package/lib/esm/calendar/google-calendar/GoogleCalendarService.js +333 -0
- package/lib/esm/calendar/google-calendar/GoogleCalendarService.js.map +1 -0
- package/lib/esm/calendar/google-calendar/index.js +3 -0
- package/lib/esm/calendar/google-calendar/index.js.map +1 -0
- package/lib/esm/comms/discord/DiscordService.js +313 -0
- package/lib/esm/comms/discord/DiscordService.js.map +1 -0
- package/lib/esm/comms/discord/index.js +2 -0
- package/lib/esm/comms/discord/index.js.map +1 -0
- package/lib/esm/comms/environment.js +16 -0
- package/lib/esm/comms/environment.js.map +1 -1
- package/lib/esm/comms/index.js +3 -0
- package/lib/esm/comms/index.js.map +1 -1
- package/lib/esm/comms/outlook/MicrosoftOutlookService.js +320 -0
- package/lib/esm/comms/outlook/MicrosoftOutlookService.js.map +1 -0
- package/lib/esm/comms/outlook/index.js +2 -0
- package/lib/esm/comms/outlook/index.js.map +1 -0
- package/lib/esm/comms/whatsapp/WhatsAppService.js +269 -0
- package/lib/esm/comms/whatsapp/WhatsAppService.js.map +1 -0
- package/lib/esm/comms/whatsapp/index.js +2 -0
- package/lib/esm/comms/whatsapp/index.js.map +1 -0
- package/lib/esm/index.js +3 -3
- package/lib/esm/io/confluence/ConfluenceService.js +312 -0
- package/lib/esm/io/confluence/ConfluenceService.js.map +1 -0
- package/lib/esm/io/confluence/index.js +2 -0
- package/lib/esm/io/confluence/index.js.map +1 -0
- package/lib/esm/io/environment.js +28 -0
- package/lib/esm/io/environment.js.map +1 -1
- package/lib/esm/io/google-docs/GoogleDocsService.js +270 -0
- package/lib/esm/io/google-docs/GoogleDocsService.js.map +1 -0
- package/lib/esm/io/google-docs/index.js +2 -0
- package/lib/esm/io/google-docs/index.js.map +1 -0
- package/lib/esm/io/index.js +5 -0
- package/lib/esm/io/index.js.map +1 -1
- package/lib/esm/io/jira/JiraService.js +349 -0
- package/lib/esm/io/jira/JiraService.js.map +1 -0
- package/lib/esm/io/jira/index.js +2 -0
- package/lib/esm/io/jira/index.js.map +1 -0
- package/lib/esm/io/microsoft-excel/MicrosoftExcelService.js +248 -0
- package/lib/esm/io/microsoft-excel/MicrosoftExcelService.js.map +1 -0
- package/lib/esm/io/microsoft-excel/index.js +2 -0
- package/lib/esm/io/microsoft-excel/index.js.map +1 -0
- package/lib/esm/io/microsoft-sharepoint/MicrosoftSharePointService.js +256 -0
- package/lib/esm/io/microsoft-sharepoint/MicrosoftSharePointService.js.map +1 -0
- package/lib/esm/io/microsoft-sharepoint/index.js +2 -0
- package/lib/esm/io/microsoft-sharepoint/index.js.map +1 -0
- package/lib/types/calendar/environment.d.cts +48 -0
- package/lib/types/calendar/environment.d.mts +48 -0
- package/lib/types/calendar/google-calendar/GoogleCalendarService.d.cts +316 -0
- package/lib/types/calendar/google-calendar/GoogleCalendarService.d.mts +316 -0
- package/lib/types/calendar/google-calendar/index.d.cts +2 -0
- package/lib/types/calendar/google-calendar/index.d.mts +2 -0
- package/lib/types/comms/discord/DiscordService.d.cts +285 -0
- package/lib/types/comms/discord/DiscordService.d.mts +285 -0
- package/lib/types/comms/discord/index.d.cts +1 -0
- package/lib/types/comms/discord/index.d.mts +1 -0
- package/lib/types/comms/environment.d.cts +34 -8
- package/lib/types/comms/environment.d.mts +34 -8
- package/lib/types/comms/index.d.cts +3 -0
- package/lib/types/comms/index.d.mts +3 -0
- package/lib/types/comms/outlook/MicrosoftOutlookService.d.cts +282 -0
- package/lib/types/comms/outlook/MicrosoftOutlookService.d.mts +282 -0
- package/lib/types/comms/outlook/index.d.cts +1 -0
- package/lib/types/comms/outlook/index.d.mts +1 -0
- package/lib/types/comms/whatsapp/WhatsAppService.d.cts +258 -0
- package/lib/types/comms/whatsapp/WhatsAppService.d.mts +258 -0
- package/lib/types/comms/whatsapp/index.d.cts +1 -0
- package/lib/types/comms/whatsapp/index.d.mts +1 -0
- package/lib/types/index.d.cts +2 -2
- package/lib/types/index.d.mts +2 -2
- package/lib/types/io/confluence/ConfluenceService.d.cts +250 -0
- package/lib/types/io/confluence/ConfluenceService.d.mts +250 -0
- package/lib/types/io/confluence/index.d.cts +1 -0
- package/lib/types/io/confluence/index.d.mts +1 -0
- package/lib/types/io/environment.d.cts +52 -12
- package/lib/types/io/environment.d.mts +52 -12
- package/lib/types/io/google-docs/GoogleDocsService.d.cts +188 -0
- package/lib/types/io/google-docs/GoogleDocsService.d.mts +188 -0
- package/lib/types/io/google-docs/index.d.cts +1 -0
- package/lib/types/io/google-docs/index.d.mts +1 -0
- package/lib/types/io/index.d.cts +5 -0
- package/lib/types/io/index.d.mts +5 -0
- package/lib/types/io/jira/JiraService.d.cts +300 -0
- package/lib/types/io/jira/JiraService.d.mts +300 -0
- package/lib/types/io/jira/index.d.cts +1 -0
- package/lib/types/io/jira/index.d.mts +1 -0
- package/lib/types/io/microsoft-excel/MicrosoftExcelService.d.cts +230 -0
- package/lib/types/io/microsoft-excel/MicrosoftExcelService.d.mts +230 -0
- package/lib/types/io/microsoft-excel/index.d.cts +1 -0
- package/lib/types/io/microsoft-excel/index.d.mts +1 -0
- package/lib/types/io/microsoft-sharepoint/MicrosoftSharePointService.d.cts +226 -0
- package/lib/types/io/microsoft-sharepoint/MicrosoftSharePointService.d.mts +226 -0
- package/lib/types/io/microsoft-sharepoint/index.d.cts +1 -0
- package/lib/types/io/microsoft-sharepoint/index.d.mts +1 -0
- package/package.json +101 -5
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoogleDocsService = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @module integrations/io/google-docs/service
|
|
6
|
+
* @summary Google Docs API integration service for document content operations.
|
|
7
|
+
* @description Exposes Google Docs document operations (get, create, batch
|
|
8
|
+
* update, append text, and replace-all) as an undecorated client-based service
|
|
9
|
+
* built on {@link HttpApiService}. Configuration comes from an explicit
|
|
10
|
+
* `GoogleDocsServiceConfig` or the `io.googleDocs` environment slice. An OAuth
|
|
11
|
+
* access token is sent as a bearer token when present; otherwise an API key is
|
|
12
|
+
* sent as `X-Goog-Api-Key` (writes generally require OAuth). Credentials are
|
|
13
|
+
* referenced from configuration (and, from as-graph nodes, from the resolved
|
|
14
|
+
* `google-docs` credential secret) and are never embedded in source. Failures
|
|
15
|
+
* are mapped to decaf errors via {@link httpError}.
|
|
16
|
+
*/
|
|
17
|
+
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
|
18
|
+
const environment_js_1 = require("./../environment.cjs");
|
|
19
|
+
const environmentValue_js_1 = require("./../../shared/environmentValue.cjs");
|
|
20
|
+
const index_js_1 = require("./../../shared/http/index.cjs");
|
|
21
|
+
/**
|
|
22
|
+
* @description Google Docs API integration service
|
|
23
|
+
* @summary An undecorated HTTP service for reading and creating documents,
|
|
24
|
+
* running raw batch updates, appending text, and replacing all matching text.
|
|
25
|
+
* Every operation needs either an OAuth token or an API key; missing
|
|
26
|
+
* credentials or identifiers raise `InternalError`, and transport failures are
|
|
27
|
+
* mapped to decaf errors via {@link httpError}.
|
|
28
|
+
* @class GoogleDocsService
|
|
29
|
+
* @extends HttpApiService
|
|
30
|
+
* @category IO
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { GoogleDocsService } from "@decaf-ts/integrations/io/google-docs";
|
|
34
|
+
*
|
|
35
|
+
* const docs = new GoogleDocsService();
|
|
36
|
+
* await docs.initialize({
|
|
37
|
+
* token: process.env.GRAPH_CREDENTIAL_GOOGLE_DOCS_TOKEN,
|
|
38
|
+
* });
|
|
39
|
+
* await docs.appendText(process.env.GOOGLE_DOC_ID ?? "", "New paragraph");
|
|
40
|
+
* ```
|
|
41
|
+
* @mermaid
|
|
42
|
+
* sequenceDiagram
|
|
43
|
+
* autonumber
|
|
44
|
+
* participant Caller
|
|
45
|
+
* participant Service as GoogleDocsService
|
|
46
|
+
* participant API as Google Docs API
|
|
47
|
+
* Caller->>Service: appendText(documentId, text)
|
|
48
|
+
* activate Service
|
|
49
|
+
* Service->>Service: requireAuth()
|
|
50
|
+
* Service->>API: GET /documents/{id}
|
|
51
|
+
* activate API
|
|
52
|
+
* API-->>Service: body content endIndex
|
|
53
|
+
* deactivate API
|
|
54
|
+
* Service->>API: POST /documents/{id}:batchUpdate
|
|
55
|
+
* activate API
|
|
56
|
+
* API-->>Service: batch update result
|
|
57
|
+
* deactivate API
|
|
58
|
+
* Service-->>Caller: batch update result
|
|
59
|
+
* deactivate Service
|
|
60
|
+
* @memberOf module:integrations/io/google-docs/service
|
|
61
|
+
*/
|
|
62
|
+
class GoogleDocsService extends index_js_1.HttpApiService {
|
|
63
|
+
constructor() {
|
|
64
|
+
super(...arguments);
|
|
65
|
+
/**
|
|
66
|
+
* @description The provider name used in error messages
|
|
67
|
+
*/
|
|
68
|
+
this.serviceName = "Google Docs";
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @description The Google Docs API base URL
|
|
72
|
+
* @summary Used when the resolved config carries no `baseUrl`.
|
|
73
|
+
* @returns {string} `"https://docs.googleapis.com/v1"`.
|
|
74
|
+
*/
|
|
75
|
+
defaultBaseUrl() {
|
|
76
|
+
return "https://docs.googleapis.com/v1";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @description Builds the Google Docs authentication headers
|
|
80
|
+
* @summary Prefers `Authorization: Bearer <token>`, falls back to
|
|
81
|
+
* `X-Goog-Api-Key: <apiKey>`, and returns no headers when neither is set.
|
|
82
|
+
* @param {GoogleDocsServiceConfig} config - The resolved service configuration.
|
|
83
|
+
* @returns {Record<string, string>} The authentication headers.
|
|
84
|
+
*/
|
|
85
|
+
authHeaders(config) {
|
|
86
|
+
if (config.token)
|
|
87
|
+
return { Authorization: `Bearer ${config.token}` };
|
|
88
|
+
if (config.apiKey)
|
|
89
|
+
return { "X-Goog-Api-Key": config.apiKey };
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @description Reads the Google Docs credentials and defaults from the environment
|
|
94
|
+
* @summary Reads the `io.googleDocs` slice and returns a partial config when
|
|
95
|
+
* a token or API key is configured, `undefined` otherwise. Values pass
|
|
96
|
+
* through `envString`/`envNumber` to reject unset-leaf proxies.
|
|
97
|
+
* @returns {Partial<GoogleDocsServiceConfig> | undefined} A partial config, or `undefined` when no credential is configured.
|
|
98
|
+
*/
|
|
99
|
+
configFromEnvironment() {
|
|
100
|
+
const env = environment_js_1.IoEnvironment.io.googleDocs;
|
|
101
|
+
const token = (0, environmentValue_js_1.envString)(env?.token);
|
|
102
|
+
const apiKey = (0, environmentValue_js_1.envString)(env?.apiKey);
|
|
103
|
+
if (!token && !apiKey)
|
|
104
|
+
return undefined;
|
|
105
|
+
return {
|
|
106
|
+
token,
|
|
107
|
+
apiKey,
|
|
108
|
+
baseUrl: (0, environmentValue_js_1.envString)(env.baseUrl),
|
|
109
|
+
timeout: (0, environmentValue_js_1.envNumber)(env.timeout),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* @description Asserts that an OAuth token or API key is configured
|
|
114
|
+
* @summary Called by every operation before it touches the network.
|
|
115
|
+
* @returns {void}
|
|
116
|
+
* @throws {InternalError} When neither a token nor an API key is configured.
|
|
117
|
+
*/
|
|
118
|
+
requireAuth() {
|
|
119
|
+
if (!this.config.token && !this.config.apiKey) {
|
|
120
|
+
throw new db_decorators_1.InternalError("Google Docs requires an OAuth token or an API key");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @description Fetches a Google Docs document
|
|
125
|
+
* @summary `GET`s `/documents/<id>` and returns the full document payload.
|
|
126
|
+
* @param {string} documentId - The document ID.
|
|
127
|
+
* @returns {Promise<unknown>} The document payload.
|
|
128
|
+
* @throws {InternalError} When no credential is configured or the document ID is empty.
|
|
129
|
+
* @throws {NotFoundError} When the document does not exist (HTTP 404).
|
|
130
|
+
* @throws {BadRequestError} When Google rejects the request.
|
|
131
|
+
*/
|
|
132
|
+
async getDocument(documentId) {
|
|
133
|
+
this.requireAuth();
|
|
134
|
+
if (!documentId) {
|
|
135
|
+
throw new db_decorators_1.InternalError("Google Docs requires a document id");
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const response = await this.client.get(`/documents/${encodeURIComponent(documentId)}`);
|
|
139
|
+
return response.data;
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
throw (0, index_js_1.httpError)("Google Docs", "get document", error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @description Creates a Google Docs document
|
|
147
|
+
* @summary `POST`s a new document with the given title and returns its
|
|
148
|
+
* payload (including `documentId`).
|
|
149
|
+
* @param {string} title - The new document title.
|
|
150
|
+
* @returns {Promise<unknown>} The created document payload.
|
|
151
|
+
* @throws {InternalError} When no credential is configured or the title is empty.
|
|
152
|
+
* @throws {BadRequestError} When Google rejects the request.
|
|
153
|
+
*/
|
|
154
|
+
async createDocument(title) {
|
|
155
|
+
this.requireAuth();
|
|
156
|
+
if (!title) {
|
|
157
|
+
throw new db_decorators_1.InternalError("Google Docs requires a document title");
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const response = await this.client.post("/documents", { title });
|
|
161
|
+
return response.data;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
throw (0, index_js_1.httpError)("Google Docs", "create document", error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* @description Applies a raw Google Docs batch update
|
|
169
|
+
* @summary `POST`s the `requests` array to `/documents/<id>:batchUpdate`
|
|
170
|
+
* unchanged, allowing any Docs API request type.
|
|
171
|
+
* @param {string} documentId - The document ID.
|
|
172
|
+
* @param {unknown[]} requests - The Docs API request objects.
|
|
173
|
+
* @returns {Promise<unknown>} The batch update response payload.
|
|
174
|
+
* @throws {InternalError} When no credential is configured, or the document ID or requests are missing.
|
|
175
|
+
* @throws {NotFoundError} When the document does not exist (HTTP 404).
|
|
176
|
+
* @throws {BadRequestError} When Google rejects a request.
|
|
177
|
+
*/
|
|
178
|
+
async batchUpdate(documentId, requests) {
|
|
179
|
+
this.requireAuth();
|
|
180
|
+
if (!documentId || !Array.isArray(requests) || !requests.length) {
|
|
181
|
+
throw new db_decorators_1.InternalError("Google Docs batchUpdate requires a document id and requests");
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const response = await this.client.post(`/documents/${encodeURIComponent(documentId)}:batchUpdate`, { requests });
|
|
185
|
+
return response.data;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
throw (0, index_js_1.httpError)("Google Docs", "batch update", error);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* @description Appends text to the end of a Google Docs document
|
|
193
|
+
* @summary Reads the document to find the final `endIndex`, then inserts the
|
|
194
|
+
* text just before it through a `batchUpdate`.
|
|
195
|
+
* @param {string} documentId - The document ID.
|
|
196
|
+
* @param {string} text - The text to append.
|
|
197
|
+
* @returns {Promise<unknown>} The batch update response payload.
|
|
198
|
+
* @throws {InternalError} When no credential is configured, or the document ID or text is empty.
|
|
199
|
+
* @throws {NotFoundError} When the document does not exist (HTTP 404).
|
|
200
|
+
* @throws {BadRequestError} When Google rejects the update.
|
|
201
|
+
*/
|
|
202
|
+
async appendText(documentId, text) {
|
|
203
|
+
this.requireAuth();
|
|
204
|
+
if (!documentId || !text) {
|
|
205
|
+
throw new db_decorators_1.InternalError("Google Docs appendText requires a document id and text");
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const document = await this.client.get(`/documents/${encodeURIComponent(documentId)}`);
|
|
209
|
+
const content = document.data.body?.content ?? [];
|
|
210
|
+
const last = content[content.length - 1];
|
|
211
|
+
const endIndex = last?.endIndex ?? 1;
|
|
212
|
+
const response = await this.client.post(`/documents/${encodeURIComponent(documentId)}:batchUpdate`, {
|
|
213
|
+
requests: [
|
|
214
|
+
{
|
|
215
|
+
insertText: {
|
|
216
|
+
location: { index: Math.max(endIndex - 1, 1) },
|
|
217
|
+
text,
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
});
|
|
222
|
+
return response.data;
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
throw (0, index_js_1.httpError)("Google Docs", "append text", error);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* @description Replaces all matching text in a Google Docs document
|
|
230
|
+
* @summary Sends a `replaceAllText` request honoring the `matchCase` option
|
|
231
|
+
* and returns the batch update response payload.
|
|
232
|
+
* @param {GoogleDocsReplaceInput} input - The document, find/replace text, and case option.
|
|
233
|
+
* @returns {Promise<unknown>} The batch update response payload.
|
|
234
|
+
* @throws {InternalError} When no credential is configured, or the document ID or find text is empty.
|
|
235
|
+
* @throws {NotFoundError} When the document does not exist (HTTP 404).
|
|
236
|
+
* @throws {BadRequestError} When Google rejects the update.
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* await docs.replaceAllText({
|
|
240
|
+
* documentId: "abc123",
|
|
241
|
+
* find: "TODO",
|
|
242
|
+
* replace: "DONE",
|
|
243
|
+
* matchCase: true,
|
|
244
|
+
* });
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
async replaceAllText(input) {
|
|
248
|
+
this.requireAuth();
|
|
249
|
+
if (!input.documentId || !input.find) {
|
|
250
|
+
throw new db_decorators_1.InternalError("Google Docs replaceAllText requires a document id and find text");
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const response = await this.client.post(`/documents/${encodeURIComponent(input.documentId)}:batchUpdate`, {
|
|
254
|
+
requests: [
|
|
255
|
+
{
|
|
256
|
+
replaceAllText: {
|
|
257
|
+
containsText: {
|
|
258
|
+
text: input.find,
|
|
259
|
+
matchCase: input.matchCase ?? false,
|
|
260
|
+
},
|
|
261
|
+
replaceText: input.replace ?? "",
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
});
|
|
266
|
+
return response.data;
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
throw (0, index_js_1.httpError)("Google Docs", "replace all text", error);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
exports.GoogleDocsService = GoogleDocsService;
|
|
274
|
+
//# sourceMappingURL=GoogleDocsService.js.map
|
|
275
|
+
//# sourceMappingURL=GoogleDocsService.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io/google-docs/GoogleDocsService.cjs","sourceRoot":"","sources":["io/google-docs/GoogleDocsService.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./GoogleDocsService.cjs"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
19
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io/google-docs/index.cjs","sourceRoot":"","sources":["io/google-docs/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,iCAAiC"}
|
package/lib/cjs/io/index.cjs
CHANGED
|
@@ -25,6 +25,11 @@ __exportStar(require("./airtable/index.cjs"), exports);
|
|
|
25
25
|
__exportStar(require("./google-sheets/index.cjs"), exports);
|
|
26
26
|
__exportStar(require("./graphql/index.cjs"), exports);
|
|
27
27
|
__exportStar(require("./spreadsheet/index.cjs"), exports);
|
|
28
|
+
__exportStar(require("./microsoft-excel/index.cjs"), exports);
|
|
29
|
+
__exportStar(require("./confluence/index.cjs"), exports);
|
|
30
|
+
__exportStar(require("./jira/index.cjs"), exports);
|
|
31
|
+
__exportStar(require("./google-docs/index.cjs"), exports);
|
|
32
|
+
__exportStar(require("./microsoft-sharepoint/index.cjs"), exports);
|
|
28
33
|
__exportStar(require("./environment.cjs"), exports);
|
|
29
34
|
//# sourceMappingURL=index.js.map
|
|
30
35
|
//# sourceMappingURL=index.cjs.map
|
package/lib/cjs/io/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io/index.cjs","sourceRoot":"","sources":["io/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;GAMG;AACH,sDAAoC;AACpC,2DAAyC;AACzC,qDAAmC;AACnC,yDAAuC;AACvC,mDAAiC;AACjC,iCAAiC"}
|
|
1
|
+
{"version":3,"file":"io/index.cjs","sourceRoot":"","sources":["io/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;GAMG;AACH,sDAAoC;AACpC,2DAAyC;AACzC,qDAAmC;AACnC,yDAAuC;AACvC,6DAA2C;AAC3C,wDAAsC;AACtC,kDAAgC;AAChC,yDAAuC;AACvC,kEAAgD;AAChD,mDAAiC;AACjC,iCAAiC"}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JiraService = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @module integrations/io/jira/service
|
|
6
|
+
* @summary Jira REST API integration service for issues, comments, and workflows.
|
|
7
|
+
* @description Exposes Jira issue operations (create, read, update, delete,
|
|
8
|
+
* comment, transition, and JQL search) through the Jira REST `api/2` surface as
|
|
9
|
+
* an undecorated client-based service built on {@link HttpApiService}.
|
|
10
|
+
* Configuration comes from an explicit `JiraServiceConfig` or the `io.jira`
|
|
11
|
+
* environment slice. When both `username` and `token` are configured the
|
|
12
|
+
* service sends HTTP Basic authentication (API token as the password);
|
|
13
|
+
* otherwise the token is sent as a bearer token. The site `baseUrl` is
|
|
14
|
+
* required. Credentials are referenced from configuration (and, from as-graph
|
|
15
|
+
* nodes, from the resolved `jira` credential secret) and are never embedded in
|
|
16
|
+
* source. Failures are mapped to decaf errors via {@link httpError}.
|
|
17
|
+
*/
|
|
18
|
+
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
|
19
|
+
const environment_js_1 = require("./../environment.cjs");
|
|
20
|
+
const environmentValue_js_1 = require("./../../shared/environmentValue.cjs");
|
|
21
|
+
const index_js_1 = require("./../../shared/http/index.cjs");
|
|
22
|
+
/** Default issue type written when a create does not specify one (`"Task"`). */
|
|
23
|
+
const DEFAULT_ISSUE_TYPE = "Task";
|
|
24
|
+
/**
|
|
25
|
+
* @description Jira REST API integration service
|
|
26
|
+
* @summary An undecorated HTTP service for issue CRUD, comments, workflow
|
|
27
|
+
* transitions, and JQL search. The site base URL and API token are required;
|
|
28
|
+
* supplying a `username` switches authentication to Basic, and transport
|
|
29
|
+
* failures are mapped to decaf errors via {@link httpError}.
|
|
30
|
+
* @class JiraService
|
|
31
|
+
* @extends HttpApiService
|
|
32
|
+
* @category IO
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { JiraService } from "@decaf-ts/integrations/io/jira";
|
|
36
|
+
*
|
|
37
|
+
* const jira = new JiraService();
|
|
38
|
+
* await jira.initialize({
|
|
39
|
+
* baseUrl: "https://example.atlassian.net",
|
|
40
|
+
* username: process.env.JIRA_USERNAME,
|
|
41
|
+
* token: process.env.GRAPH_CREDENTIAL_JIRA_TOKEN,
|
|
42
|
+
* });
|
|
43
|
+
* const issue = await jira.createIssue({
|
|
44
|
+
* projectKey: "OPS",
|
|
45
|
+
* summary: "Deployment failed",
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
* @mermaid
|
|
49
|
+
* sequenceDiagram
|
|
50
|
+
* autonumber
|
|
51
|
+
* participant Caller
|
|
52
|
+
* participant Service as JiraService
|
|
53
|
+
* participant API as Jira REST API
|
|
54
|
+
* Caller->>Service: createIssue(input)
|
|
55
|
+
* activate Service
|
|
56
|
+
* Service->>Service: requireCredentials()
|
|
57
|
+
* Service->>API: POST /rest/api/2/issue
|
|
58
|
+
* activate API
|
|
59
|
+
* API-->>Service: { id, key }
|
|
60
|
+
* deactivate API
|
|
61
|
+
* Service-->>Caller: created issue
|
|
62
|
+
* deactivate Service
|
|
63
|
+
* @memberOf module:integrations/io/jira/service
|
|
64
|
+
*/
|
|
65
|
+
class JiraService extends index_js_1.HttpApiService {
|
|
66
|
+
constructor() {
|
|
67
|
+
super(...arguments);
|
|
68
|
+
/**
|
|
69
|
+
* @description The provider name used in error messages
|
|
70
|
+
*/
|
|
71
|
+
this.serviceName = "Jira";
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @description The default base URL for Jira
|
|
75
|
+
* @summary Returns an empty string; Jira is site-hosted, so the resolved
|
|
76
|
+
* `baseUrl` (from config or `io.jira.baseUrl`) is required.
|
|
77
|
+
* @returns {string} An empty string.
|
|
78
|
+
*/
|
|
79
|
+
defaultBaseUrl() {
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @description Builds the Jira authentication headers
|
|
84
|
+
* @summary Uses HTTP Basic (`username:token`) when both values are present,
|
|
85
|
+
* otherwise a bearer token when only `token` is present. Always requests
|
|
86
|
+
* JSON responses.
|
|
87
|
+
* @param {JiraServiceConfig} config - The resolved service configuration.
|
|
88
|
+
* @returns {Record<string, string>} The authorization and accept headers.
|
|
89
|
+
*/
|
|
90
|
+
authHeaders(config) {
|
|
91
|
+
if (config.username && config.token) {
|
|
92
|
+
const encoded = Buffer.from(`${config.username}:${config.token}`, "utf8").toString("base64");
|
|
93
|
+
return {
|
|
94
|
+
Authorization: `Basic ${encoded}`,
|
|
95
|
+
Accept: "application/json",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return config.token
|
|
99
|
+
? { Authorization: `Bearer ${config.token}`, Accept: "application/json" }
|
|
100
|
+
: { Accept: "application/json" };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @description Reads the Jira credentials and defaults from the environment
|
|
104
|
+
* @summary Reads the `io.jira` slice and returns a partial config when an
|
|
105
|
+
* API token is configured, `undefined` otherwise. Values pass through
|
|
106
|
+
* `envString`/`envNumber` to reject unset-leaf proxies.
|
|
107
|
+
* @returns {Partial<JiraServiceConfig> | undefined} A partial config, or `undefined` when no Jira token is configured.
|
|
108
|
+
*/
|
|
109
|
+
configFromEnvironment() {
|
|
110
|
+
const env = environment_js_1.IoEnvironment.io.jira;
|
|
111
|
+
const token = (0, environmentValue_js_1.envString)(env?.token);
|
|
112
|
+
if (!token)
|
|
113
|
+
return undefined;
|
|
114
|
+
return {
|
|
115
|
+
token,
|
|
116
|
+
username: (0, environmentValue_js_1.envString)(env.username),
|
|
117
|
+
baseUrl: (0, environmentValue_js_1.envString)(env.baseUrl),
|
|
118
|
+
timeout: (0, environmentValue_js_1.envNumber)(env.timeout),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* @description Asserts that the Jira token and site base URL are configured
|
|
123
|
+
* @summary Called by every operation before it touches the network.
|
|
124
|
+
* @returns {void}
|
|
125
|
+
* @throws {InternalError} When no API token or base URL is configured.
|
|
126
|
+
*/
|
|
127
|
+
requireCredentials() {
|
|
128
|
+
if (!this.config.token) {
|
|
129
|
+
throw new db_decorators_1.InternalError("Jira requires an API token");
|
|
130
|
+
}
|
|
131
|
+
if (!this.config.baseUrl) {
|
|
132
|
+
throw new db_decorators_1.InternalError("Jira requires a base URL");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* @description Builds the encoded issue path
|
|
137
|
+
* @summary Validates the issue key and URL-encodes it into
|
|
138
|
+
* `/rest/api/2/issue/<key>`.
|
|
139
|
+
* @param {string} issueKey - The Jira issue key.
|
|
140
|
+
* @returns {string} The issue API path.
|
|
141
|
+
* @throws {InternalError} When `issueKey` is empty.
|
|
142
|
+
*/
|
|
143
|
+
issuePath(issueKey) {
|
|
144
|
+
if (!issueKey) {
|
|
145
|
+
throw new db_decorators_1.InternalError("Jira requires an issue key");
|
|
146
|
+
}
|
|
147
|
+
return `/rest/api/2/issue/${encodeURIComponent(issueKey)}`;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @description Creates a Jira issue
|
|
151
|
+
* @summary `POST`s the project, summary, issue type (default `Task`),
|
|
152
|
+
* optional description, and extra fields to `/rest/api/2/issue`.
|
|
153
|
+
* @param {JiraIssueInput} input - The issue definition.
|
|
154
|
+
* @returns {Promise<unknown>} The created issue payload (including `id` and `key`).
|
|
155
|
+
* @throws {InternalError} When credentials are missing, or the project key or summary is empty.
|
|
156
|
+
* @throws {BadRequestError} When Jira rejects the issue.
|
|
157
|
+
*/
|
|
158
|
+
async createIssue(input) {
|
|
159
|
+
this.requireCredentials();
|
|
160
|
+
if (!input.projectKey || !input.summary) {
|
|
161
|
+
throw new db_decorators_1.InternalError("Jira createIssue requires a project key and summary");
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const response = await this.client.post("/rest/api/2/issue", {
|
|
165
|
+
fields: {
|
|
166
|
+
project: { key: input.projectKey },
|
|
167
|
+
summary: input.summary,
|
|
168
|
+
issuetype: { name: input.issueType ?? DEFAULT_ISSUE_TYPE },
|
|
169
|
+
...(input.description ? { description: input.description } : {}),
|
|
170
|
+
...(input.fields ?? {}),
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return response.data;
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
throw (0, index_js_1.httpError)("Jira", "create issue", error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @description Fetches a Jira issue
|
|
181
|
+
* @summary `GET`s the issue by key, optionally projecting the given field
|
|
182
|
+
* names.
|
|
183
|
+
* @param {string} issueKey - The issue key to fetch.
|
|
184
|
+
* @param {string[]} [fields] - Field names to include in the response.
|
|
185
|
+
* @returns {Promise<unknown>} The issue payload.
|
|
186
|
+
* @throws {InternalError} When credentials are missing or the issue key is empty.
|
|
187
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
188
|
+
* @throws {BadRequestError} When Jira rejects the request.
|
|
189
|
+
*/
|
|
190
|
+
async getIssue(issueKey, fields) {
|
|
191
|
+
this.requireCredentials();
|
|
192
|
+
try {
|
|
193
|
+
const response = await this.client.get(this.issuePath(issueKey), {
|
|
194
|
+
params: fields?.length ? { fields: fields.join(",") } : {},
|
|
195
|
+
});
|
|
196
|
+
return response.data;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw (0, index_js_1.httpError)("Jira", "get issue", error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* @description Updates fields on a Jira issue
|
|
204
|
+
* @summary `PUT`s the `fields` map to the issue and returns
|
|
205
|
+
* `{ updated: true, issueKey }`.
|
|
206
|
+
* @param {JiraIssueUpdate} input - The issue key and fields to update.
|
|
207
|
+
* @returns {Promise<unknown>} `{ updated: true, issueKey }` on success.
|
|
208
|
+
* @throws {InternalError} When credentials are missing, or the issue key or fields are empty.
|
|
209
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
210
|
+
* @throws {BadRequestError} When Jira rejects the update.
|
|
211
|
+
*/
|
|
212
|
+
async updateIssue(input) {
|
|
213
|
+
this.requireCredentials();
|
|
214
|
+
if (!input.fields) {
|
|
215
|
+
throw new db_decorators_1.InternalError("Jira updateIssue requires fields");
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
await this.client.put(this.issuePath(input.issueKey), {
|
|
219
|
+
fields: input.fields,
|
|
220
|
+
});
|
|
221
|
+
return { updated: true, issueKey: input.issueKey };
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
throw (0, index_js_1.httpError)("Jira", "update issue", error);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @description Deletes a Jira issue
|
|
229
|
+
* @summary `DELETE`s the issue and returns `{ deleted: true, issueKey }`.
|
|
230
|
+
* @param {string} issueKey - The issue key to delete.
|
|
231
|
+
* @returns {Promise<unknown>} `{ deleted: true, issueKey }` on success.
|
|
232
|
+
* @throws {InternalError} When credentials are missing or the issue key is empty.
|
|
233
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
234
|
+
* @throws {BadRequestError} When Jira rejects the deletion.
|
|
235
|
+
*/
|
|
236
|
+
async deleteIssue(issueKey) {
|
|
237
|
+
this.requireCredentials();
|
|
238
|
+
try {
|
|
239
|
+
await this.client.delete(this.issuePath(issueKey));
|
|
240
|
+
return { deleted: true, issueKey };
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
throw (0, index_js_1.httpError)("Jira", "delete issue", error);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* @description Adds a comment to a Jira issue
|
|
248
|
+
* @summary `POST`s the comment body to the issue's `/comment` endpoint.
|
|
249
|
+
* @param {JiraCommentInput} input - The issue key and comment body.
|
|
250
|
+
* @returns {Promise<unknown>} The created comment payload.
|
|
251
|
+
* @throws {InternalError} When credentials are missing, or the issue key or body is empty.
|
|
252
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
253
|
+
* @throws {BadRequestError} When Jira rejects the comment.
|
|
254
|
+
*/
|
|
255
|
+
async addComment(input) {
|
|
256
|
+
this.requireCredentials();
|
|
257
|
+
if (!input.body) {
|
|
258
|
+
throw new db_decorators_1.InternalError("Jira addComment requires a body");
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
const response = await this.client.post(`${this.issuePath(input.issueKey)}/comment`, { body: input.body });
|
|
262
|
+
return response.data;
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
throw (0, index_js_1.httpError)("Jira", "add comment", error);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* @description Lists the available workflow transitions for a Jira issue
|
|
270
|
+
* @summary `GET`s the issue's `/transitions` collection, whose IDs feed
|
|
271
|
+
* {@link JiraService.transitionIssue}.
|
|
272
|
+
* @param {string} issueKey - The issue key.
|
|
273
|
+
* @returns {Promise<unknown>} The available transitions payload.
|
|
274
|
+
* @throws {InternalError} When credentials are missing or the issue key is empty.
|
|
275
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
276
|
+
* @throws {BadRequestError} When Jira rejects the request.
|
|
277
|
+
*/
|
|
278
|
+
async getTransitions(issueKey) {
|
|
279
|
+
this.requireCredentials();
|
|
280
|
+
try {
|
|
281
|
+
const response = await this.client.get(`${this.issuePath(issueKey)}/transitions`);
|
|
282
|
+
return response.data;
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
throw (0, index_js_1.httpError)("Jira", "get transitions", error);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* @description Transitions a Jira issue through its workflow
|
|
290
|
+
* @summary `POST`s the transition ID to the issue's `/transitions` endpoint
|
|
291
|
+
* and returns the applied transition identifiers.
|
|
292
|
+
* @param {JiraTransitionInput} input - The issue key and transition ID.
|
|
293
|
+
* @returns {Promise<unknown>} `{ transitioned: true, issueKey, transitionId }` on success.
|
|
294
|
+
* @throws {InternalError} When credentials are missing, or the issue key or transition ID is empty.
|
|
295
|
+
* @throws {NotFoundError} When the issue does not exist (HTTP 404).
|
|
296
|
+
* @throws {BadRequestError} When Jira rejects the transition.
|
|
297
|
+
*/
|
|
298
|
+
async transitionIssue(input) {
|
|
299
|
+
this.requireCredentials();
|
|
300
|
+
if (!input.transitionId) {
|
|
301
|
+
throw new db_decorators_1.InternalError("Jira transitionIssue requires a transition id");
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
await this.client.post(`${this.issuePath(input.issueKey)}/transitions`, {
|
|
305
|
+
transition: { id: input.transitionId },
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
transitioned: true,
|
|
309
|
+
issueKey: input.issueKey,
|
|
310
|
+
transitionId: input.transitionId,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
throw (0, index_js_1.httpError)("Jira", "transition issue", error);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* @description Searches Jira issues with JQL
|
|
319
|
+
* @summary `POST`s the JQL query to `/rest/api/2/search` with a result cap
|
|
320
|
+
* (default `50`) and optional field projection.
|
|
321
|
+
* @param {JiraSearchInput} input - The JQL query and search options.
|
|
322
|
+
* @returns {Promise<unknown>} The search result payload.
|
|
323
|
+
* @throws {InternalError} When credentials are missing or the JQL query is empty.
|
|
324
|
+
* @throws {BadRequestError} When the JQL query is invalid.
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* const results = await jira.search({
|
|
328
|
+
* jql: 'project = "OPS" AND status = "Open"',
|
|
329
|
+
* maxResults: 100,
|
|
330
|
+
* fields: ["summary", "status"],
|
|
331
|
+
* });
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
async search(input) {
|
|
335
|
+
this.requireCredentials();
|
|
336
|
+
if (!input.jql) {
|
|
337
|
+
throw new db_decorators_1.InternalError("Jira search requires a JQL query");
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const response = await this.client.post("/rest/api/2/search", {
|
|
341
|
+
jql: input.jql,
|
|
342
|
+
maxResults: input.maxResults ?? 50,
|
|
343
|
+
...(input.fields ? { fields: input.fields } : {}),
|
|
344
|
+
});
|
|
345
|
+
return response.data;
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
throw (0, index_js_1.httpError)("Jira", "search issues", error);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
exports.JiraService = JiraService;
|
|
353
|
+
//# sourceMappingURL=JiraService.js.map
|
|
354
|
+
//# sourceMappingURL=JiraService.cjs.map
|