@knpkv/jira-cli 0.1.1 → 1.0.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/CHANGELOG.md +67 -0
- package/README.md +66 -4
- package/dist/IssueService.d.ts +2 -2
- package/dist/IssueService.d.ts.map +1 -1
- package/dist/IssueService.js +3 -3
- package/dist/IssueService.js.map +1 -1
- package/dist/JiraAuth.d.ts +14 -14
- package/dist/JiraAuth.d.ts.map +1 -1
- package/dist/JiraAuth.js +18 -10
- package/dist/JiraAuth.js.map +1 -1
- package/dist/JiraCliError.d.ts +30 -0
- package/dist/JiraCliError.d.ts.map +1 -1
- package/dist/JiraCliError.js +14 -0
- package/dist/JiraCliError.js.map +1 -1
- package/dist/MarkdownWriter.d.ts +4 -4
- package/dist/MarkdownWriter.d.ts.map +1 -1
- package/dist/MarkdownWriter.js +6 -6
- package/dist/MarkdownWriter.js.map +1 -1
- package/dist/SyncWorkspace.d.ts +34 -0
- package/dist/SyncWorkspace.d.ts.map +1 -0
- package/dist/SyncWorkspace.js +105 -0
- package/dist/SyncWorkspace.js.map +1 -0
- package/dist/VersionService.d.ts +206 -0
- package/dist/VersionService.d.ts.map +1 -0
- package/dist/VersionService.js +426 -0
- package/dist/VersionService.js.map +1 -0
- package/dist/bin.js +29 -22
- package/dist/bin.js.map +1 -1
- package/dist/commands/auth.d.ts +2 -21
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +6 -6
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/get.d.ts +3 -8
- package/dist/commands/get.d.ts.map +1 -1
- package/dist/commands/get.js +4 -4
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/index.d.ts +2 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -2
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/issue.d.ts +8 -0
- package/dist/commands/issue.d.ts.map +1 -0
- package/dist/commands/issue.js +10 -0
- package/dist/commands/issue.js.map +1 -0
- package/dist/commands/layers.d.ts +6 -18
- package/dist/commands/layers.d.ts.map +1 -1
- package/dist/commands/layers.js +35 -24
- package/dist/commands/layers.js.map +1 -1
- package/dist/commands/search.d.ts +3 -8
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +8 -8
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/version.d.ts +12 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +179 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +14 -1
- package/dist/internal/frontmatter.js.map +1 -1
- package/dist/internal/oauthServer.d.ts +17 -5
- package/dist/internal/oauthServer.d.ts.map +1 -1
- package/dist/internal/oauthServer.js +23 -40
- package/dist/internal/oauthServer.js.map +1 -1
- package/dist/internal/openBrowser.d.ts +10 -0
- package/dist/internal/openBrowser.d.ts.map +1 -0
- package/dist/internal/openBrowser.js +17 -0
- package/dist/internal/openBrowser.js.map +1 -0
- package/dist/internal/sync/baseline.d.ts +11 -0
- package/dist/internal/sync/baseline.d.ts.map +1 -0
- package/dist/internal/sync/baseline.js +18 -0
- package/dist/internal/sync/baseline.js.map +1 -0
- package/dist/internal/sync/changes.d.ts +15 -0
- package/dist/internal/sync/changes.d.ts.map +1 -0
- package/dist/internal/sync/changes.js +72 -0
- package/dist/internal/sync/changes.js.map +1 -0
- package/dist/internal/sync/config.d.ts +12 -0
- package/dist/internal/sync/config.d.ts.map +1 -0
- package/dist/internal/sync/config.js +53 -0
- package/dist/internal/sync/config.js.map +1 -0
- package/dist/internal/sync/document.d.ts +9 -0
- package/dist/internal/sync/document.d.ts.map +1 -0
- package/dist/internal/sync/document.js +173 -0
- package/dist/internal/sync/document.js.map +1 -0
- package/dist/internal/sync/fieldValues.d.ts +30 -0
- package/dist/internal/sync/fieldValues.d.ts.map +1 -0
- package/dist/internal/sync/fieldValues.js +91 -0
- package/dist/internal/sync/fieldValues.js.map +1 -0
- package/dist/internal/sync/manifest.d.ts +12 -0
- package/dist/internal/sync/manifest.d.ts.map +1 -0
- package/dist/internal/sync/manifest.js +23 -0
- package/dist/internal/sync/manifest.js.map +1 -0
- package/dist/internal/sync/paths.d.ts +26 -0
- package/dist/internal/sync/paths.d.ts.map +1 -0
- package/dist/internal/sync/paths.js +22 -0
- package/dist/internal/sync/paths.js.map +1 -0
- package/dist/internal/sync/schemas.d.ts +128 -0
- package/dist/internal/sync/schemas.d.ts.map +1 -0
- package/dist/internal/sync/schemas.js +82 -0
- package/dist/internal/sync/schemas.js.map +1 -0
- package/dist/internal/sync/types.d.ts +144 -0
- package/dist/internal/sync/types.d.ts.map +1 -0
- package/dist/internal/sync/types.js +17 -0
- package/dist/internal/sync/types.js.map +1 -0
- package/package.json +13 -12
- package/skills/jira/SKILL.md +90 -0
- package/skills/jira/agents/openai.yaml +4 -0
- package/src/IssueService.ts +34 -28
- package/src/JiraAuth.ts +53 -39
- package/src/JiraCliError.ts +24 -0
- package/src/MarkdownWriter.ts +7 -11
- package/src/SyncWorkspace.ts +185 -0
- package/src/VersionService.ts +647 -0
- package/src/bin.ts +39 -29
- package/src/commands/auth.ts +6 -12
- package/src/commands/get.ts +4 -4
- package/src/commands/index.ts +2 -2
- package/src/commands/issue.ts +13 -0
- package/src/commands/layers.ts +44 -26
- package/src/commands/search.ts +8 -8
- package/src/commands/version.ts +267 -0
- package/src/internal/frontmatter.ts +15 -1
- package/src/internal/oauthServer.ts +43 -70
- package/src/internal/openBrowser.ts +31 -0
- package/src/internal/sync/baseline.ts +27 -0
- package/src/internal/sync/changes.ts +118 -0
- package/src/internal/sync/config.ts +76 -0
- package/src/internal/sync/document.ts +201 -0
- package/src/internal/sync/fieldValues.ts +145 -0
- package/src/internal/sync/manifest.ts +32 -0
- package/src/internal/sync/paths.ts +48 -0
- package/src/internal/sync/schemas.ts +103 -0
- package/src/internal/sync/types.ts +192 -0
- package/test/SyncWorkspace.test.ts +76 -0
- package/test/VersionService.test.ts +266 -0
- package/test/commandTree.test.ts +266 -0
- package/test/frontmatter.test.ts +69 -0
- package/test/integration.test.ts +187 -0
- package/test/syncChanges.test.ts +106 -0
- package/test/syncConfig.test.ts +138 -0
- package/test/syncDocument.test.ts +69 -0
- package/test/syncFieldValues.test.ts +101 -0
- package/vitest.config.integration.ts +17 -0
- package/vitest.config.ts +6 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jira project version (release) fetching with people-field resolution.
|
|
3
|
+
*
|
|
4
|
+
* **Mental model**
|
|
5
|
+
*
|
|
6
|
+
* - **API → domain mapping**: {@link VersionService} wraps the generated V3 client,
|
|
7
|
+
* normalising a project version into a {@link Version} object with resolved Driver,
|
|
8
|
+
* Contributors, and Approvers (each rendered as a {@link Person}).
|
|
9
|
+
* - **Expand options**: `approvers,driver,operations,issuesstatus` plus a passthrough
|
|
10
|
+
* for any extra fields the API returns (`contributors` is sent by Jira Premium even
|
|
11
|
+
* though it is not in the public OpenAPI spec).
|
|
12
|
+
* - **Account-id resolution**: account IDs are looked up against
|
|
13
|
+
* `/rest/api/3/user?accountId={id}` and cached per service instance.
|
|
14
|
+
* - **Mutations**: {@link VersionServiceShape.updateVersion} edits version fields
|
|
15
|
+
* (e.g. description) and {@link VersionServiceShape.addRelatedWork} /
|
|
16
|
+
* {@link VersionServiceShape.listRelatedWork} manage the "Related work" links that
|
|
17
|
+
* surface as Confluence pages on a release report. Mutations require the
|
|
18
|
+
* `manage:jira-project` OAuth scope (see `JiraAuth`).
|
|
19
|
+
*
|
|
20
|
+
* **Common tasks**
|
|
21
|
+
*
|
|
22
|
+
* - List versions for a project: `service.listProjectVersions("RPS", { released: true })`
|
|
23
|
+
* - Get a single version: `service.getVersion("12345")`
|
|
24
|
+
* - Set the description: `service.updateVersion("12345", { description: "..." })`
|
|
25
|
+
* - Attach a Confluence page: `service.addRelatedWork("12345", { title, category, url })`
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
29
|
+
import { JiraApiClient, toEffect } from "@knpkv/jira-api-client";
|
|
30
|
+
import * as Context from "effect/Context";
|
|
31
|
+
import * as Effect from "effect/Effect";
|
|
32
|
+
import * as Layer from "effect/Layer";
|
|
33
|
+
import { buildByVersionJql } from "./internal/jqlBuilder.js";
|
|
34
|
+
import { JiraApiError } from "./JiraCliError.js";
|
|
35
|
+
/**
|
|
36
|
+
* VersionService tag.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { Effect } from "effect"
|
|
41
|
+
* import { VersionService } from "@knpkv/jira-cli/VersionService"
|
|
42
|
+
*
|
|
43
|
+
* Effect.gen(function* () {
|
|
44
|
+
* const versions = yield* VersionService
|
|
45
|
+
* const list = yield* versions.listProjectVersions("RPS", { released: true })
|
|
46
|
+
* console.log(`Found ${list.length} released versions`)
|
|
47
|
+
* })
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @category Services
|
|
51
|
+
*/
|
|
52
|
+
export class VersionService extends Context.Service()("@knpkv/jira-cli/VersionService") {
|
|
53
|
+
}
|
|
54
|
+
const EXPAND = "approvers,driver,operations,issuesstatus,contributors";
|
|
55
|
+
const asRaw = (v) => (v && typeof v === "object" ? v : {});
|
|
56
|
+
/**
|
|
57
|
+
* Render a Jira custom-field value as a flat string.
|
|
58
|
+
*
|
|
59
|
+
* Handles the common shapes returned by `/rest/api/3/search/jql`:
|
|
60
|
+
* - cascading select: `{ value, child: { value } }` → `"Parent > Child"`
|
|
61
|
+
* - single select / option: `{ value }` → `"Parent"`
|
|
62
|
+
* - user object: `{ displayName }` → display name
|
|
63
|
+
* - plain string/number → coerced to string
|
|
64
|
+
* - array of any of the above → values joined with `, `
|
|
65
|
+
* - null / unset / unknown shape → `null`
|
|
66
|
+
*/
|
|
67
|
+
export const renderCustomFieldValue = (raw) => {
|
|
68
|
+
if (raw === null || raw === undefined)
|
|
69
|
+
return null;
|
|
70
|
+
if (typeof raw === "string")
|
|
71
|
+
return raw.length > 0 ? raw : null;
|
|
72
|
+
if (typeof raw === "number" || typeof raw === "boolean")
|
|
73
|
+
return String(raw);
|
|
74
|
+
if (Array.isArray(raw)) {
|
|
75
|
+
const parts = raw.map(renderCustomFieldValue).filter((v) => !!v);
|
|
76
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
77
|
+
}
|
|
78
|
+
if (typeof raw === "object") {
|
|
79
|
+
const obj = raw;
|
|
80
|
+
const parent = stringOrNull(obj["value"]);
|
|
81
|
+
if (parent) {
|
|
82
|
+
const child = obj["child"];
|
|
83
|
+
if (child && typeof child === "object") {
|
|
84
|
+
const childValue = stringOrNull(child["value"]);
|
|
85
|
+
if (childValue)
|
|
86
|
+
return `${parent} > ${childValue}`;
|
|
87
|
+
}
|
|
88
|
+
return parent;
|
|
89
|
+
}
|
|
90
|
+
const displayName = stringOrNull(obj["displayName"]);
|
|
91
|
+
if (displayName)
|
|
92
|
+
return displayName;
|
|
93
|
+
const name = stringOrNull(obj["name"]);
|
|
94
|
+
if (name)
|
|
95
|
+
return name;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
};
|
|
99
|
+
const stringOrNull = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
100
|
+
export const personFromObject = (raw, fallbackId) => {
|
|
101
|
+
if (raw && typeof raw === "object") {
|
|
102
|
+
const obj = raw;
|
|
103
|
+
const accountId = stringOrNull(obj["accountId"]) ?? fallbackId ?? null;
|
|
104
|
+
if (!accountId)
|
|
105
|
+
return null;
|
|
106
|
+
return {
|
|
107
|
+
accountId,
|
|
108
|
+
displayName: stringOrNull(obj["displayName"]) ?? accountId,
|
|
109
|
+
emailAddress: stringOrNull(obj["emailAddress"])
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (typeof raw === "string" && raw.length > 0) {
|
|
113
|
+
return { accountId: raw, displayName: raw, emailAddress: null };
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
};
|
|
117
|
+
export const extractContributorIds = (raw) => {
|
|
118
|
+
// Jira Premium *may* return `contributors` on the version (undocumented in the
|
|
119
|
+
// public OpenAPI spec) — read defensively. In practice we've observed it
|
|
120
|
+
// empty, hence the assignee-based fallback below.
|
|
121
|
+
const field = raw["contributors"];
|
|
122
|
+
if (!Array.isArray(field))
|
|
123
|
+
return [];
|
|
124
|
+
const ids = [];
|
|
125
|
+
for (const c of field) {
|
|
126
|
+
if (typeof c === "string" && c.length > 0)
|
|
127
|
+
ids.push(c);
|
|
128
|
+
else if (c && typeof c === "object") {
|
|
129
|
+
const id = c["accountId"];
|
|
130
|
+
if (typeof id === "string" && id.length > 0)
|
|
131
|
+
ids.push(id);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return ids;
|
|
135
|
+
};
|
|
136
|
+
/** Normalise a Jira "Related work" entry into a {@link RelatedWork}. */
|
|
137
|
+
export const toRelatedWork = (raw) => {
|
|
138
|
+
const o = asRaw(raw);
|
|
139
|
+
return {
|
|
140
|
+
relatedWorkId: stringOrNull(o["relatedWorkId"]),
|
|
141
|
+
title: stringOrNull(o["title"]),
|
|
142
|
+
category: stringOrNull(o["category"]) ?? "",
|
|
143
|
+
url: stringOrNull(o["url"])
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
const make = Effect.gen(function* () {
|
|
147
|
+
const client = yield* JiraApiClient;
|
|
148
|
+
const userCache = new Map();
|
|
149
|
+
// In-flight lookups keyed by accountId so concurrent callers (bounded by the
|
|
150
|
+
// `concurrency: 4` fan-outs) share a single request instead of duplicating it.
|
|
151
|
+
const userInFlight = new Map();
|
|
152
|
+
// Cached lookup of all custom field IDs sharing a given display name.
|
|
153
|
+
const fieldIdsByName = new Map();
|
|
154
|
+
const resolveFieldIds = (name) => Effect.gen(function* () {
|
|
155
|
+
const cached = fieldIdsByName.get(name);
|
|
156
|
+
if (cached !== undefined)
|
|
157
|
+
return cached;
|
|
158
|
+
const result = yield* toEffect(client.v3.client.GET("/rest/api/3/field")).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to list Jira fields`, cause })));
|
|
159
|
+
const matches = [];
|
|
160
|
+
if (Array.isArray(result)) {
|
|
161
|
+
for (const f of result) {
|
|
162
|
+
if (f && typeof f === "object") {
|
|
163
|
+
const obj = f;
|
|
164
|
+
if (obj["name"] === name && typeof obj["id"] === "string") {
|
|
165
|
+
matches.push(obj["id"]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
fieldIdsByName.set(name, matches);
|
|
171
|
+
return matches;
|
|
172
|
+
});
|
|
173
|
+
const fetchUser = (accountId) => toEffect(client.v3.client.GET("/rest/api/3/user", { params: { query: { accountId } } })).pipe(Effect.map((u) => {
|
|
174
|
+
const obj = asRaw(u);
|
|
175
|
+
const person = {
|
|
176
|
+
accountId,
|
|
177
|
+
displayName: stringOrNull(obj["displayName"]) ?? accountId,
|
|
178
|
+
emailAddress: stringOrNull(obj["emailAddress"])
|
|
179
|
+
};
|
|
180
|
+
userCache.set(accountId, person);
|
|
181
|
+
return person;
|
|
182
|
+
}), Effect.catch(() => {
|
|
183
|
+
// User may be deleted / inaccessible — fall back to bare account id.
|
|
184
|
+
const fallback = { accountId, displayName: accountId, emailAddress: null };
|
|
185
|
+
userCache.set(accountId, fallback);
|
|
186
|
+
return Effect.succeed(fallback);
|
|
187
|
+
}),
|
|
188
|
+
// Drop the in-flight memo once resolved so a later miss can refetch.
|
|
189
|
+
Effect.ensuring(Effect.sync(() => userInFlight.delete(accountId))));
|
|
190
|
+
const resolveUser = (accountId) => Effect.gen(function* () {
|
|
191
|
+
const cached = userCache.get(accountId);
|
|
192
|
+
if (cached)
|
|
193
|
+
return cached;
|
|
194
|
+
const existing = userInFlight.get(accountId);
|
|
195
|
+
if (existing)
|
|
196
|
+
return yield* existing;
|
|
197
|
+
// `Effect.cached` shares one execution across all awaiters of the returned
|
|
198
|
+
// effect. Building it and storing it in `userInFlight` happens in
|
|
199
|
+
// synchronous effect steps (no async boundary), so concurrent uncached
|
|
200
|
+
// callers — bounded by the `concurrency: 4` fan-outs — dedupe to one
|
|
201
|
+
// request rather than each issuing their own.
|
|
202
|
+
const shared = yield* Effect.cached(fetchUser(accountId));
|
|
203
|
+
userInFlight.set(accountId, shared);
|
|
204
|
+
return yield* shared;
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* Fetch every ticket whose `fixVersion` matches `versionName`, returning the
|
|
208
|
+
* minimum metadata downstream audits need (key, summary, assignee, labels).
|
|
209
|
+
*
|
|
210
|
+
* `projectKey` scopes the query to a single project so version names that
|
|
211
|
+
* collide across projects (e.g. `"1.0.0"`) don't pull in unrelated issues.
|
|
212
|
+
* When omitted (e.g. {@link getVersion}, which has no project context), the
|
|
213
|
+
* query is instance-wide and may match same-named versions in other projects.
|
|
214
|
+
*/
|
|
215
|
+
const ticketsForVersion = (versionName, customFieldNames, projectKey) => Effect.gen(function* () {
|
|
216
|
+
const nameToIds = new Map();
|
|
217
|
+
for (const name of customFieldNames) {
|
|
218
|
+
const ids = yield* resolveFieldIds(name);
|
|
219
|
+
nameToIds.set(name, ids);
|
|
220
|
+
}
|
|
221
|
+
const allFieldIds = new Set();
|
|
222
|
+
for (const ids of nameToIds.values())
|
|
223
|
+
for (const id of ids)
|
|
224
|
+
allFieldIds.add(id);
|
|
225
|
+
const requestedFields = ["assignee", "labels", "summary", ...allFieldIds];
|
|
226
|
+
const raws = [];
|
|
227
|
+
const PAGE = 100;
|
|
228
|
+
const MAX_PAGES = 100;
|
|
229
|
+
let nextPageToken = undefined;
|
|
230
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
231
|
+
const result = yield* toEffect(client.v3.client.GET("/rest/api/3/search/jql", {
|
|
232
|
+
params: {
|
|
233
|
+
query: {
|
|
234
|
+
jql: buildByVersionJql(versionName, projectKey),
|
|
235
|
+
fields: requestedFields,
|
|
236
|
+
maxResults: PAGE,
|
|
237
|
+
...(nextPageToken ? { nextPageToken } : {})
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
})).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to fetch tickets for fixVersion "${versionName}"`, cause })));
|
|
241
|
+
const resObj = asRaw(result);
|
|
242
|
+
const issues = (Array.isArray(resObj["issues"]) ? resObj["issues"] : []);
|
|
243
|
+
for (const issue of issues) {
|
|
244
|
+
const key = typeof issue["key"] === "string" ? issue["key"] : "";
|
|
245
|
+
const fields = asRaw(issue["fields"]);
|
|
246
|
+
const assignee = fields["assignee"];
|
|
247
|
+
let assigneeId = null;
|
|
248
|
+
if (assignee && typeof assignee === "object") {
|
|
249
|
+
const accountId = assignee["accountId"];
|
|
250
|
+
if (typeof accountId === "string" && accountId.length > 0)
|
|
251
|
+
assigneeId = accountId;
|
|
252
|
+
}
|
|
253
|
+
const labelsRaw = fields["labels"];
|
|
254
|
+
const labels = [];
|
|
255
|
+
if (Array.isArray(labelsRaw)) {
|
|
256
|
+
for (const l of labelsRaw)
|
|
257
|
+
if (typeof l === "string" && l.length > 0)
|
|
258
|
+
labels.push(l);
|
|
259
|
+
}
|
|
260
|
+
const customFields = {};
|
|
261
|
+
for (const name of customFieldNames) {
|
|
262
|
+
const ids = nameToIds.get(name) ?? [];
|
|
263
|
+
let resolved = null;
|
|
264
|
+
for (const id of ids) {
|
|
265
|
+
const v = renderCustomFieldValue(fields[id]);
|
|
266
|
+
if (v !== null) {
|
|
267
|
+
resolved = v;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
customFields[name] = resolved;
|
|
272
|
+
}
|
|
273
|
+
raws.push({
|
|
274
|
+
key,
|
|
275
|
+
summary: stringOrNull(fields["summary"]),
|
|
276
|
+
assigneeId,
|
|
277
|
+
labels,
|
|
278
|
+
customFields
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
const isLast = resObj["isLast"];
|
|
282
|
+
const next = resObj["nextPageToken"];
|
|
283
|
+
if (isLast === true || typeof next !== "string" || next.length === 0)
|
|
284
|
+
break;
|
|
285
|
+
nextPageToken = next;
|
|
286
|
+
}
|
|
287
|
+
const uniqueAssignees = Array.from(new Set(raws.map((t) => t.assigneeId).filter((id) => !!id)));
|
|
288
|
+
yield* Effect.forEach(uniqueAssignees, (id) => resolveUser(id), { concurrency: 4 });
|
|
289
|
+
return raws.map((t) => ({
|
|
290
|
+
key: t.key,
|
|
291
|
+
summary: t.summary,
|
|
292
|
+
assignee: t.assigneeId ? userCache.get(t.assigneeId) ?? null : null,
|
|
293
|
+
labels: t.labels,
|
|
294
|
+
customFields: t.customFields
|
|
295
|
+
}));
|
|
296
|
+
});
|
|
297
|
+
const mapVersion = (raw, customFieldNames, projectKey) => Effect.gen(function* () {
|
|
298
|
+
const id = String(raw["id"] ?? "");
|
|
299
|
+
const name = String(raw["name"] ?? "");
|
|
300
|
+
const driverId = stringOrNull(raw["driver"]);
|
|
301
|
+
const declared = extractContributorIds(raw);
|
|
302
|
+
const approversRaw = (Array.isArray(raw["approvers"]) ? raw["approvers"] : []);
|
|
303
|
+
const tickets = yield* ticketsForVersion(name, customFieldNames, projectKey);
|
|
304
|
+
const contributorIds = declared.length > 0
|
|
305
|
+
? declared
|
|
306
|
+
: Array.from(new Set(tickets.map((t) => t.assignee?.accountId).filter((v) => !!v)));
|
|
307
|
+
const driver = driverId ? yield* resolveUser(driverId) : null;
|
|
308
|
+
const contributors = yield* Effect.forEach(contributorIds, (id) => resolveUser(id), { concurrency: 4 });
|
|
309
|
+
const approvers = yield* Effect.forEach(approversRaw, (a) => Effect.gen(function* () {
|
|
310
|
+
const accountId = stringOrNull(a["accountId"]);
|
|
311
|
+
const person = accountId
|
|
312
|
+
? yield* resolveUser(accountId)
|
|
313
|
+
: (personFromObject(a) ?? { accountId: "<unknown>", displayName: "<unknown>", emailAddress: null });
|
|
314
|
+
return {
|
|
315
|
+
person,
|
|
316
|
+
status: String(a["status"] ?? "UNKNOWN").toUpperCase(),
|
|
317
|
+
declineReason: stringOrNull(a["declineReason"]),
|
|
318
|
+
description: stringOrNull(a["description"])
|
|
319
|
+
};
|
|
320
|
+
}), { concurrency: 4 });
|
|
321
|
+
return {
|
|
322
|
+
id,
|
|
323
|
+
name,
|
|
324
|
+
description: stringOrNull(raw["description"]),
|
|
325
|
+
released: raw["released"] === true,
|
|
326
|
+
archived: raw["archived"] === true,
|
|
327
|
+
startDate: stringOrNull(raw["startDate"]),
|
|
328
|
+
releaseDate: stringOrNull(raw["releaseDate"]),
|
|
329
|
+
driver,
|
|
330
|
+
contributors,
|
|
331
|
+
approvers,
|
|
332
|
+
tickets,
|
|
333
|
+
url: stringOrNull(raw["self"]) ?? ""
|
|
334
|
+
};
|
|
335
|
+
});
|
|
336
|
+
/**
|
|
337
|
+
* Map a version's scalar fields only — no ticket scan, no people resolution.
|
|
338
|
+
* Used for mutation responses ({@link updateVersion}) whose PUT payload carries
|
|
339
|
+
* no `expand`, so the heavy {@link ticketsForVersion} fan-out would only ever
|
|
340
|
+
* feed an empty `contributors` fallback. `driver`/`contributors`/`approvers`/
|
|
341
|
+
* `tickets` are returned empty.
|
|
342
|
+
*/
|
|
343
|
+
const mapVersionScalar = (raw) => ({
|
|
344
|
+
id: String(raw["id"] ?? ""),
|
|
345
|
+
name: String(raw["name"] ?? ""),
|
|
346
|
+
description: stringOrNull(raw["description"]),
|
|
347
|
+
released: raw["released"] === true,
|
|
348
|
+
archived: raw["archived"] === true,
|
|
349
|
+
startDate: stringOrNull(raw["startDate"]),
|
|
350
|
+
releaseDate: stringOrNull(raw["releaseDate"]),
|
|
351
|
+
driver: null,
|
|
352
|
+
contributors: [],
|
|
353
|
+
approvers: [],
|
|
354
|
+
tickets: [],
|
|
355
|
+
url: stringOrNull(raw["self"]) ?? ""
|
|
356
|
+
});
|
|
357
|
+
const PAGE_SIZE = 50;
|
|
358
|
+
const MAX_PAGES = 200;
|
|
359
|
+
const listProjectVersions = (projectKey, options) => Effect.gen(function* () {
|
|
360
|
+
const all = [];
|
|
361
|
+
let startAt = 0;
|
|
362
|
+
const cap = options?.maxResults;
|
|
363
|
+
const customFieldNames = options?.customFieldNames ?? [];
|
|
364
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
365
|
+
const result = yield* toEffect(client.v3.client.GET("/rest/api/3/project/{projectIdOrKey}/version", {
|
|
366
|
+
params: {
|
|
367
|
+
path: { projectIdOrKey: projectKey },
|
|
368
|
+
query: { startAt, maxResults: PAGE_SIZE, expand: EXPAND, orderBy: "-releaseDate" }
|
|
369
|
+
}
|
|
370
|
+
})).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to list versions for ${projectKey}`, cause })));
|
|
371
|
+
const resObj = asRaw(result);
|
|
372
|
+
const values = (Array.isArray(resObj["values"]) ? resObj["values"] : []);
|
|
373
|
+
for (const v of values) {
|
|
374
|
+
if (options?.released === true && v["released"] !== true)
|
|
375
|
+
continue;
|
|
376
|
+
if (options?.unreleased === true && v["released"] === true)
|
|
377
|
+
continue;
|
|
378
|
+
all.push(v);
|
|
379
|
+
if (cap !== undefined && all.length >= cap)
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
if (cap !== undefined && all.length >= cap)
|
|
383
|
+
break;
|
|
384
|
+
const isLast = resObj["isLast"];
|
|
385
|
+
if (isLast === true || values.length < PAGE_SIZE)
|
|
386
|
+
break;
|
|
387
|
+
startAt += values.length;
|
|
388
|
+
}
|
|
389
|
+
return yield* Effect.forEach(all, (r) => mapVersion(r, customFieldNames, projectKey), { concurrency: 4 });
|
|
390
|
+
});
|
|
391
|
+
const getVersion = (id) => toEffect(client.v3.client.GET("/rest/api/3/version/{id}", {
|
|
392
|
+
params: { path: { id }, query: { expand: EXPAND } }
|
|
393
|
+
})).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to get version ${id}`, cause })), Effect.flatMap((raw) => mapVersion(asRaw(raw), [])));
|
|
394
|
+
const updateVersion = (id, input) => toEffect(client.v3.client.PUT("/rest/api/3/version/{id}", {
|
|
395
|
+
params: { path: { id } },
|
|
396
|
+
body: { ...(input.description !== undefined ? { description: input.description } : {}) }
|
|
397
|
+
})).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to update version ${id}`, cause })), Effect.map((raw) => mapVersionScalar(asRaw(raw))));
|
|
398
|
+
const listRelatedWork = (id) => toEffect(client.v3.client.GET("/rest/api/3/version/{id}/relatedwork", { params: { path: { id } } })).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to list related work for version ${id}`, cause })), Effect.map((raw) => (Array.isArray(raw) ? raw : []).map(toRelatedWork)));
|
|
399
|
+
const addRelatedWork = (id, input) => toEffect(client.v3.client.POST("/rest/api/3/version/{id}/relatedwork", {
|
|
400
|
+
params: { path: { id } },
|
|
401
|
+
body: { title: input.title, category: input.category, url: input.url }
|
|
402
|
+
})).pipe(Effect.mapError((cause) => new JiraApiError({ message: `Failed to add related work to version ${id}`, cause })), Effect.map((raw) => {
|
|
403
|
+
const w = toRelatedWork(raw);
|
|
404
|
+
// POST echoes the created entity; fall back to the input we sent.
|
|
405
|
+
return {
|
|
406
|
+
relatedWorkId: w.relatedWorkId,
|
|
407
|
+
title: w.title ?? input.title,
|
|
408
|
+
category: w.category || input.category,
|
|
409
|
+
url: w.url ?? input.url
|
|
410
|
+
};
|
|
411
|
+
}));
|
|
412
|
+
return VersionService.of({
|
|
413
|
+
listProjectVersions,
|
|
414
|
+
getVersion,
|
|
415
|
+
updateVersion,
|
|
416
|
+
listRelatedWork,
|
|
417
|
+
addRelatedWork
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
/**
|
|
421
|
+
* Layer for VersionService.
|
|
422
|
+
*
|
|
423
|
+
* @category Layers
|
|
424
|
+
*/
|
|
425
|
+
export const layer = Layer.effect(VersionService, make);
|
|
426
|
+
//# sourceMappingURL=VersionService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VersionService.js","sourceRoot":"","sources":["../src/VersionService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA6IhD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,cAAe,SAAQ,OAAO,CAAC,OAAO,EAGhD,CAAC,gCAAgC,CAAC;CAAG;AAExC,MAAM,MAAM,GAAG,uDAAuD,CAAA;AAItE,MAAM,KAAK,GAAG,CAAC,CAAU,EAAO,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAY,EAAiB,EAAE;IACpE,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAClD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;IAC/D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7E,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnD,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAU,CAAA;QACtB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,CAAA;YAC1B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvC,MAAM,UAAU,GAAG,YAAY,CAAE,KAAa,CAAC,OAAO,CAAC,CAAC,CAAA;gBACxD,IAAI,UAAU;oBAAE,OAAO,GAAG,MAAM,MAAM,UAAU,EAAE,CAAA;YACpD,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QACD,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAA;QACpD,IAAI,WAAW;YAAE,OAAO,WAAW,CAAA;QACnC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QACtC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;IACvB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,CAAU,EAAiB,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAEpG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAAE,UAAmB,EAAiB,EAAE;IACnF,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,GAAU,CAAA;QACtB,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,UAAU,IAAI,IAAI,CAAA;QACtE,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAA;QAC3B,OAAO;YACL,SAAS;YACT,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,SAAS;YAC1D,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;SAChD,CAAA;IACH,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;IACjE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAQ,EAAyB,EAAE;IACvE,+EAA+E;IAC/E,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,CAAA;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACpC,MAAM,GAAG,GAAkB,EAAE,CAAA;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;aACjD,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,EAAE,GAAI,CAAS,CAAC,WAAW,CAAC,CAAA;YAClC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAY,EAAe,EAAE;IACzD,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACpB,OAAO;QACL,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC/C,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC/B,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;QAC3C,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;KAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAA;IACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC3C,6EAA6E;IAC7E,+EAA+E;IAC/E,MAAM,YAAY,GAAG,IAAI,GAAG,EAAwC,CAAA;IAEpE,sEAAsE;IACtE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAiC,CAAA;IAE/D,MAAM,eAAe,GAAG,CACtB,IAAY,EACwC,EAAE,CAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC5E,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAC1C,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,4BAA4B,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;QACtG,MAAM,OAAO,GAAkB,EAAE,CAAA;QACjC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;oBAC/B,MAAM,GAAG,GAAG,CAAQ,CAAA;oBACpB,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;wBAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAW,CAAC,CAAA;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACjC,OAAO,OAAO,CAAA;IAChB,CAAC,CAAwD,CAAA;IAEzD,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAgC,EAAE,CACpE,QAAQ,CACN,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAC/E,CAAC,IAAI,CACJ,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpB,MAAM,MAAM,GAAW;YACrB,SAAS;YACT,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,SAAS;YAC1D,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;SAChD,CAAA;QACD,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAChC,OAAO,MAAM,CAAA;IACf,CAAC,CAAC,EACF,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;QAChB,qEAAqE;QACrE,MAAM,QAAQ,GAAW,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;QAClF,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QAClC,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjC,CAAC,CAAC;IACF,qEAAqE;IACrE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CACnE,CAAA;IAEH,MAAM,WAAW,GAAG,CAAC,SAAiB,EAAgC,EAAE,CACtE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACvC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,QAAQ;YAAE,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAA;QACpC,2EAA2E;QAC3E,kEAAkE;QAClE,uEAAuE;QACvE,qEAAqE;QACrE,8CAA8C;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;QACzD,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QACnC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAA;IACtB,CAAC,CAAC,CAAA;IAUJ;;;;;;;;OAQG;IACH,MAAM,iBAAiB,GAAG,CACxB,WAAmB,EACnB,gBAAuC,EACvC,UAAmB,EACwC,EAAE,CAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiC,CAAA;QAC1D,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YACxC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC1B,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;QACrC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE;YAAE,KAAK,MAAM,EAAE,IAAI,GAAG;gBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC/E,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,CAAA;QAEzE,MAAM,IAAI,GAAqB,EAAE,CAAA;QACjC,MAAM,IAAI,GAAG,GAAG,CAAA;QAChB,MAAM,SAAS,GAAG,GAAG,CAAA;QACrB,IAAI,aAAa,GAAuB,SAAS,CAAA;QACjD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE;gBAC7C,MAAM,EAAE;oBACN,KAAK,EAAE;wBACL,GAAG,EAAE,iBAAiB,CAAC,WAAW,EAAE,UAAU,CAAC;wBAC/C,MAAM,EAAE,eAAe;wBACvB,UAAU,EAAE,IAAI;wBAChB,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC5C;iBACF;aACF,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,2CAA2C,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC,CAChG,CACF,CAAA;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;YAC5B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAe,CAAA;YACtF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAW,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;gBACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;gBACnC,IAAI,UAAU,GAAkB,IAAI,CAAA;gBACpC,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC7C,MAAM,SAAS,GAAI,QAAgB,CAAC,WAAW,CAAC,CAAA;oBAChD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;wBAAE,UAAU,GAAG,SAAS,CAAA;gBACnF,CAAC;gBACD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAClC,MAAM,MAAM,GAAkB,EAAE,CAAA;gBAChC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC7B,KAAK,MAAM,CAAC,IAAI,SAAS;wBAAE,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;4BAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACtF,CAAC;gBACD,MAAM,YAAY,GAAkC,EAAE,CAAA;gBACtD,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;oBACpC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;oBACrC,IAAI,QAAQ,GAAkB,IAAI,CAAA;oBAClC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;wBACrB,MAAM,CAAC,GAAG,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;wBAC5C,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;4BACf,QAAQ,GAAG,CAAC,CAAA;4BACZ,MAAK;wBACP,CAAC;oBACH,CAAC;oBACD,YAAY,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAA;gBAC/B,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC;oBACR,GAAG;oBACH,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;oBACxC,UAAU;oBACV,MAAM;oBACN,YAAY;iBACb,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,CAAA;YACpC,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAK;YAC3E,aAAa,GAAG,IAAI,CAAA;QACtB,CAAC;QAED,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAChC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC1E,CAAA;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;QAEnF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YACnE,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC,CAAC,CAAA;IACL,CAAC,CAA+D,CAAA;IAEhE,MAAM,UAAU,GAAG,CACjB,GAAQ,EACR,gBAAuC,EACvC,UAAmB,EACmB,EAAE,CACxC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;QACtC,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC5C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAe,CAAA;QAE5F,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAA;QAE5E,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;YACxC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAElG,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7D,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;QAEvG,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAC1D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAA;YAC9C,MAAM,MAAM,GAAG,SAAS;gBACtB,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC;gBAC/B,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAA;YACrG,OAAO;gBACL,MAAM;gBACN,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,CAAC,WAAW,EAAE;gBACtD,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;gBAC/C,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;aAC5C,CAAA;QACH,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;QAEzB,OAAO;YACL,EAAE;YACF,IAAI;YACJ,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7C,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;YAClC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;YAClC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7C,MAAM;YACN,YAAY;YACZ,SAAS;YACT,OAAO;YACP,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;SACrC,CAAA;IACH,CAAC,CAAC,CAAA;IAEJ;;;;;;OAMG;IACH,MAAM,gBAAgB,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,CAAC;QAC/C,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7C,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;QAClC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;QAClC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzC,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,EAAE;QAChB,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;QACX,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;KACrC,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,EAAE,CAAA;IACpB,MAAM,SAAS,GAAG,GAAG,CAAA;IAErB,MAAM,mBAAmB,GAAG,CAC1B,UAAkB,EAClB,OAA6B,EACwB,EAAE,CAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7E,MAAM,GAAG,GAAe,EAAE,CAAA;QAC1B,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,MAAM,GAAG,GAAG,OAAO,EAAE,UAAU,CAAA;QAC/B,MAAM,gBAAgB,GAAG,OAAO,EAAE,gBAAgB,IAAI,EAAE,CAAA;QACxD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,8CAA8C,EAAE;gBACnE,MAAM,EAAE;oBACN,IAAI,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE;oBACpC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;iBACnF;aACF,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,+BAA+B,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAC9G,CAAA;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;YAC5B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAe,CAAA;YACtF,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,OAAO,EAAE,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI;oBAAE,SAAQ;gBAClE,IAAI,OAAO,EAAE,UAAU,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI;oBAAE,SAAQ;gBACpE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACX,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;oBAAE,MAAK;YACnD,CAAC;YACD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;gBAAE,MAAK;YACjD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC/B,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS;gBAAE,MAAK;YACvD,OAAO,IAAI,MAAM,CAAC,MAAM,CAAA;QAC1B,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3G,CAAC,CAAyD,CAAA;IAE1D,MAAM,UAAU,GAAG,CAAC,EAAU,EAAwC,EAAE,CACtE,QAAQ,CACN,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE;QAC/C,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;KACpD,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAC/F,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CACpD,CAAA;IAEH,MAAM,aAAa,GAAG,CAAC,EAAU,EAAE,KAAyB,EAAwC,EAAE,CACpG,QAAQ,CACN,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE;QAC/C,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;QACxB,IAAI,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;KACzF,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAClG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAClD,CAAA;IAEH,MAAM,eAAe,GAAG,CAAC,EAAU,EAA2D,EAAE,CAC9F,QAAQ,CACN,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,sCAAsC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAC3F,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,2CAA2C,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EACjH,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CACxE,CAAA;IAEH,MAAM,cAAc,GAAG,CAAC,EAAU,EAAE,KAA0B,EAA4C,EAAE,CAC1G,QAAQ,CACN,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE;QAC5D,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;QACxB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE;KACvE,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yCAAyC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAC/G,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QAC5B,kEAAkE;QAClE,OAAO;YACL,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;YAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ;YACtC,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG;SACxB,CAAA;IACH,CAAC,CAAC,CACH,CAAA;IAEH,OAAO,cAAc,CAAC,EAAE,CAAC;QACvB,mBAAmB;QACnB,UAAU;QACV,aAAa;QACb,eAAe;QACf,cAAc;KACf,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA"}
|
package/dist/bin.js
CHANGED
|
@@ -2,38 +2,45 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* CLI entry point — assembles commands, selects layer by subcommand, runs via `NodeRuntime`.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Arguments are read from Effect's `Stdio` service at the runtime edge.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { NodeRuntime, NodeStdio } from "@effect/platform-node";
|
|
10
|
+
import { makeInstallCommand } from "@knpkv/agent-skills";
|
|
11
|
+
import * as Console from "effect/Console";
|
|
11
12
|
import * as Effect from "effect/Effect";
|
|
12
|
-
import * as
|
|
13
|
-
import
|
|
13
|
+
import * as Stdio from "effect/Stdio";
|
|
14
|
+
import { Command } from "effect/unstable/cli";
|
|
14
15
|
import pkg from "../package.json" with { type: "json" };
|
|
15
|
-
import { AppLayer, authCommand, AuthOnlyLayer,
|
|
16
|
+
import { AppLayer, authCommand, AuthOnlyLayer, getLayerType, handleError, issueCommand, MinimalLayer, versionCommand } from "./commands/index.js";
|
|
17
|
+
const skillsInstall = makeInstallCommand({
|
|
18
|
+
description: "Install the Jira agent skill",
|
|
19
|
+
name: "install",
|
|
20
|
+
skills: ["jira"]
|
|
21
|
+
});
|
|
22
|
+
const skillsCommand = Command.make("skills", {}, () => Console.log("Usage: jira skills install")).pipe(Command.withDescription("Local write agent skill commands"), Command.withSubcommands([skillsInstall]));
|
|
16
23
|
// === Main command ===
|
|
17
|
-
const jira = Command.make("jira").pipe(Command.withDescription("
|
|
24
|
+
const jira = Command.make("jira").pipe(Command.withDescription("Jira CLI commands"), Command.withSubcommands([
|
|
18
25
|
authCommand,
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
issueCommand,
|
|
27
|
+
skillsCommand,
|
|
28
|
+
versionCommand
|
|
21
29
|
]));
|
|
22
30
|
// === Run CLI ===
|
|
23
|
-
const cli = Command.
|
|
24
|
-
name: pkg.name,
|
|
31
|
+
const cli = Command.runWith(jira, {
|
|
25
32
|
version: pkg.version
|
|
26
33
|
});
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const program = Effect.gen(function* () {
|
|
35
|
+
const stdio = yield* Stdio.Stdio;
|
|
36
|
+
const args = yield* stdio.args;
|
|
37
|
+
const layerType = getLayerType(args);
|
|
38
|
+
const layer = layerType === "full"
|
|
39
|
+
? AppLayer
|
|
40
|
+
: layerType === "auth"
|
|
41
|
+
? AuthOnlyLayer
|
|
42
|
+
: MinimalLayer;
|
|
43
|
+
return yield* cli(args).pipe(Effect.provide(layer));
|
|
44
|
+
}).pipe(Effect.provide(NodeStdio.layer), Effect.catchCause((cause) => handleError(cause)));
|
|
38
45
|
NodeRuntime.runMain(program);
|
|
39
46
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACvD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,qBAAqB,CAAA;AAE5B,MAAM,aAAa,GAAG,kBAAkB,CAAC;IACvC,WAAW,EAAE,8BAA8B;IAC3C,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,CAAC,MAAM,CAAC;CACjB,CAAC,CAAA;AAEF,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CACpG,OAAO,CAAC,eAAe,CAAC,kCAAkC,CAAC,EAC3D,OAAO,CAAC,eAAe,CAAC,CAAC,aAAa,CAAC,CAAC,CACzC,CAAA;AAED,uBAAuB;AACvB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CACpC,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAC5C,OAAO,CAAC,eAAe,CAAC;IACtB,WAAW;IACX,YAAY;IACZ,aAAa;IACb,cAAc;CACf,CAAC,CACH,CAAA;AAED,kBAAkB;AAClB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE;IAChC,OAAO,EAAE,GAAG,CAAC,OAAO;CACrB,CAAC,CAAA;AAEF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAA;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAA;IAC9B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,KAAK,GAAG,SAAS,KAAK,MAAM;QAChC,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS,KAAK,MAAM;YACtB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,YAAY,CAAA;IAEhB,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAC1B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CACtB,CAAA;AACH,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAC/B,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CACjD,CAAA;AAED,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA"}
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* **Mental model**
|
|
5
|
-
*
|
|
6
|
-
* - Each command is a standalone `Command.make` that yields into `JiraAuth` service methods.
|
|
7
|
-
* - `create` opens the Atlassian Developer Console; `configure` prompts for client ID/secret.
|
|
8
|
-
*
|
|
9
|
-
* @internal
|
|
10
|
-
*/
|
|
11
|
-
import { Command } from "@effect/cli";
|
|
12
|
-
import * as Option from "effect/Option";
|
|
13
|
-
import { JiraAuth } from "../JiraAuth.js";
|
|
14
|
-
export declare const authCommand: Command.Command<"auth", JiraAuth | import("@effect/platform/CommandExecutor").CommandExecutor | import("@effect/platform/Terminal").Terminal, import("@knpkv/atlassian-common/auth").OAuthError | import("@knpkv/atlassian-common/config").FileSystemError | import("@knpkv/atlassian-common/config").HomeDirectoryError | import("@effect/platform/Error").PlatformError | import("@effect/platform/Terminal").QuitException, {
|
|
15
|
-
readonly subcommand: Option.Option<{} | {
|
|
16
|
-
readonly clientId: Option.Option<string>;
|
|
17
|
-
readonly clientSecret: Option.Option<string>;
|
|
18
|
-
} | {
|
|
19
|
-
readonly site: Option.Option<string>;
|
|
20
|
-
} | {} | {}>;
|
|
21
|
-
}>;
|
|
1
|
+
import { Command } from "effect/unstable/cli";
|
|
2
|
+
export declare const authCommand: Command.Command<"auth", {}, {}, import("@knpkv/atlassian-common/auth").OAuthError | import("effect/PlatformError").PlatformError | import("@knpkv/atlassian-common/config").FileSystemError | import("@knpkv/atlassian-common/config").HomeDirectoryError | import("effect/Terminal").QuitError, never>;
|
|
22
3
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAA2B,MAAM,qBAAqB,CAAA;AA+FtE,eAAO,MAAM,WAAW,ySASvB,CAAA"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
|
-
import { Command, Options, Prompt } from "@effect/cli";
|
|
12
|
-
import * as PlatformCommand from "@effect/platform/Command";
|
|
13
11
|
import * as Console from "effect/Console";
|
|
14
12
|
import * as Effect from "effect/Effect";
|
|
15
13
|
import * as Option from "effect/Option";
|
|
14
|
+
import { Command, Flag as Options, Prompt } from "effect/unstable/cli";
|
|
15
|
+
import { openBrowser } from "../internal/openBrowser.js";
|
|
16
16
|
import { JiraAuth } from "../JiraAuth.js";
|
|
17
17
|
// === Auth create command ===
|
|
18
18
|
const createCommand = Command.make("create", {}, () => Effect.gen(function* () {
|
|
@@ -36,11 +36,11 @@ Creating OAuth app in Atlassian Developer Console...
|
|
|
36
36
|
6. Run: jira auth configure --client-id <ID> --client-secret <SECRET>
|
|
37
37
|
`);
|
|
38
38
|
const url = "https://developer.atlassian.com/console/myapps/create-3lo-app/";
|
|
39
|
-
yield*
|
|
39
|
+
yield* openBrowser(url).pipe(Effect.catch(() => Effect.void));
|
|
40
40
|
})).pipe(Command.withDescription("Create OAuth app in Atlassian Developer Console"));
|
|
41
41
|
// === Auth configure command ===
|
|
42
|
-
const clientIdOption = Options.
|
|
43
|
-
const clientSecretOption = Options.
|
|
42
|
+
const clientIdOption = Options.string("client-id").pipe(Options.withDescription("OAuth client ID from Atlassian Developer Console"), Options.optional);
|
|
43
|
+
const clientSecretOption = Options.string("client-secret").pipe(Options.withDescription("OAuth client secret"), Options.optional);
|
|
44
44
|
const configureCommand = Command.make("configure", { clientId: clientIdOption, clientSecret: clientSecretOption }, ({ clientId, clientSecret }) => Effect.gen(function* () {
|
|
45
45
|
const auth = yield* JiraAuth;
|
|
46
46
|
const rawClientId = Option.isSome(clientId)
|
|
@@ -53,7 +53,7 @@ const configureCommand = Command.make("configure", { clientId: clientIdOption, c
|
|
|
53
53
|
yield* Console.log("OAuth configured. Run 'jira auth login' to authenticate.");
|
|
54
54
|
})).pipe(Command.withDescription("Configure OAuth client credentials"));
|
|
55
55
|
// === Auth login command ===
|
|
56
|
-
const siteOption = Options.
|
|
56
|
+
const siteOption = Options.string("site").pipe(Options.withDescription("Jira site URL to use (for accounts with multiple sites)"), Options.optional);
|
|
57
57
|
const loginCommand = Command.make("login", { site: siteOption }, ({ site }) => Effect.gen(function* () {
|
|
58
58
|
const auth = yield* JiraAuth;
|
|
59
59
|
const result = yield* auth.login(Option.isSome(site) ? { siteUrl: site.value } : undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,8BAA8B;AAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;CAkBtB,CAAC,CAAA;IACE,MAAM,GAAG,GAAG,gEAAgE,CAAA;IAC5E,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;AAC/D,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,iDAAiD,CAAC,CAAC,CAAA;AAEtF,iCAAiC;AACjC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACrD,OAAO,CAAC,eAAe,CAAC,kDAAkD,CAAC,EAC3E,OAAO,CAAC,QAAQ,CACjB,CAAA;AACD,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAC7D,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,EAC9C,OAAO,CAAC,QAAQ,CACjB,CAAA;AAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CACnC,WAAW,EACX,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,EAC9D,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,CAC7B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAA;IAE5B,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACzC,CAAC,CAAC,QAAQ,CAAC,KAAK;QAChB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAA;IAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QACjD,CAAC,CAAC,YAAY,CAAC,KAAK;QACpB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC,CAAA;IAEjE,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC,CAAA;IAC/E,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;AAChF,CAAC,CAAC,CACL,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,oCAAoC,CAAC,CAAC,CAAA;AAErE,6BAA6B;AAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAC5C,OAAO,CAAC,eAAe,CAAC,yDAAyD,CAAC,EAClF,OAAO,CAAC,QAAQ,CACjB,CAAA;AAED,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAC5E,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAA;IAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;IACvE,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,uCAAuC,CAAC,CAAC,CAAA;AAE5E,8BAA8B;AAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAA;IAC5B,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA;IACpB,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;AAClC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,8BAA8B,CAAC,CAAC,CAAA;AAEnE,8BAA8B;AAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,CACpD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAA;IAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAA;IACzC,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;IAClE,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;IAC7E,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,4BAA4B,CAAC,CAAC,CAAA;AAEjE,6BAA6B;AAC7B,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAClD,OAAO,CAAC,eAAe,CAAC,6BAA6B,CAAC,EACtD,OAAO,CAAC,eAAe,CAAC;IACtB,aAAa;IACb,gBAAgB;IAChB,YAAY;IACZ,aAAa;IACb,aAAa;CACd,CAAC,CACH,CAAA"}
|