dsh-plugin-github-issues 0.0.0-stage → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +147 -2
- package/cordis.patch.yml +20 -0
- package/docs/README.zh.md +134 -0
- package/icon.svg +9 -0
- package/lib/client.js +3243 -0
- package/lib/controller.js +289 -0
- package/lib/controller.js.map +1 -0
- package/lib/github/auth.js +249 -0
- package/lib/github/auth.js.map +1 -0
- package/lib/github/client.js +767 -0
- package/lib/github/client.js.map +1 -0
- package/lib/github/queries.js +479 -0
- package/lib/github/queries.js.map +1 -0
- package/lib/github/state.js +186 -0
- package/lib/github/state.js.map +1 -0
- package/lib/github/types.js +29 -0
- package/lib/github/types.js.map +1 -0
- package/lib/github/vm.js +362 -0
- package/lib/github/vm.js.map +1 -0
- package/lib/index.js +65 -0
- package/lib/index.js.map +1 -0
- package/lib/prompt.js +87 -0
- package/lib/prompt.js.map +1 -0
- package/lib/remote-methods.js +32 -0
- package/lib/remote-methods.js.map +1 -0
- package/lib/types/controller.d.ts +105 -0
- package/lib/types/controller.d.ts.map +1 -0
- package/lib/types/github/auth.d.ts +52 -0
- package/lib/types/github/auth.d.ts.map +1 -0
- package/lib/types/github/client.d.ts +40 -0
- package/lib/types/github/client.d.ts.map +1 -0
- package/lib/types/github/queries.d.ts +172 -0
- package/lib/types/github/queries.d.ts.map +1 -0
- package/lib/types/github/state.d.ts +51 -0
- package/lib/types/github/state.d.ts.map +1 -0
- package/lib/types/github/types.d.ts +79 -0
- package/lib/types/github/types.d.ts.map +1 -0
- package/lib/types/github/vm.d.ts +260 -0
- package/lib/types/github/vm.d.ts.map +1 -0
- package/lib/types/index.d.ts +46 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/prompt.d.ts +30 -0
- package/lib/types/prompt.d.ts.map +1 -0
- package/lib/types/remote-methods.d.ts +32 -0
- package/lib/types/remote-methods.d.ts.map +1 -0
- package/lib/types/vm.d.ts +264 -0
- package/lib/types/vm.d.ts.map +1 -0
- package/lib/types/workspace.d.ts +43 -0
- package/lib/types/workspace.d.ts.map +1 -0
- package/lib/vm.js +42 -0
- package/lib/vm.js.map +1 -0
- package/lib/workspace.js +57 -0
- package/lib/workspace.js.map +1 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +97 -4
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plugin's non-secret state file.
|
|
3
|
+
*
|
|
4
|
+
* Preferences (which repo or project the panel shows, the pinned issue, the
|
|
5
|
+
* handoff template) are not credentials, so they live in the plugin's own
|
|
6
|
+
* directory instead of the DSH settings profile: the profile patch is rewritten
|
|
7
|
+
* by upgrades and its `.bak` copies would duplicate whatever is written there.
|
|
8
|
+
*
|
|
9
|
+
* @module dsh-plugin-github-issues/github/state
|
|
10
|
+
*/
|
|
11
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { mergePrefs } from "../vm.js";
|
|
14
|
+
/** How many links one installation keeps; older handoffs fall off the tail. */
|
|
15
|
+
const MAX_LINKS = 500;
|
|
16
|
+
/** Clamp one untrusted patch value to a known preference list. */
|
|
17
|
+
function pick(value, allowed, fallback) {
|
|
18
|
+
return typeof value === 'string' && allowed.includes(value)
|
|
19
|
+
? value
|
|
20
|
+
: fallback;
|
|
21
|
+
}
|
|
22
|
+
/** Read one optional string, treating an empty string as absent. */
|
|
23
|
+
function optionalString(value) {
|
|
24
|
+
return typeof value === 'string' && value !== '' ? value : undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Apply a browser-supplied preference patch onto the current preferences.
|
|
28
|
+
* @param current - the preferences currently stored.
|
|
29
|
+
* @param patch - the untrusted patch.
|
|
30
|
+
* @returns the next preferences, with every field validated.
|
|
31
|
+
*/
|
|
32
|
+
export function applyPrefsPatch(current, patch) {
|
|
33
|
+
if (typeof patch !== 'object' || patch === null)
|
|
34
|
+
return current;
|
|
35
|
+
const input = patch;
|
|
36
|
+
const next = { ...current };
|
|
37
|
+
if ('state' in input)
|
|
38
|
+
next.state = pick(input.state, ['open', 'closed', 'all'], current.state);
|
|
39
|
+
if ('assignee' in input) {
|
|
40
|
+
const assignee = typeof input.assignee === 'string' ? input.assignee.trim() : '';
|
|
41
|
+
if (assignee === '@me' || assignee === 'all' || /^[A-Za-z0-9][A-Za-z0-9-]*$/.test(assignee))
|
|
42
|
+
next.assignee = assignee;
|
|
43
|
+
}
|
|
44
|
+
if ('org' in input)
|
|
45
|
+
next.org = optionalString(input.org);
|
|
46
|
+
if ('repo' in input)
|
|
47
|
+
next.repo = optionalString(input.repo);
|
|
48
|
+
if ('handoffMode' in input)
|
|
49
|
+
next.handoffMode = pick(input.handoffMode, ['draft', 'send'], current.handoffMode);
|
|
50
|
+
if ('repo' in input)
|
|
51
|
+
next.repo = optionalString(input.repo);
|
|
52
|
+
if ('projectId' in input)
|
|
53
|
+
next.projectId = optionalString(input.projectId);
|
|
54
|
+
if ('org' in input)
|
|
55
|
+
next.org = optionalString(input.org);
|
|
56
|
+
if ('promptTemplate' in input) {
|
|
57
|
+
const template = typeof input.promptTemplate === 'string' ? input.promptTemplate : '';
|
|
58
|
+
next.promptTemplate = template === '' ? current.promptTemplate : template.slice(0, 4_000);
|
|
59
|
+
}
|
|
60
|
+
if ('pinned' in input) {
|
|
61
|
+
const pinned = input.pinned;
|
|
62
|
+
if (pinned === null || pinned === undefined) {
|
|
63
|
+
next.pinned = undefined;
|
|
64
|
+
}
|
|
65
|
+
else if (typeof pinned === 'object') {
|
|
66
|
+
const { repo, number } = pinned;
|
|
67
|
+
if (typeof repo === 'string' && repo.includes('/') && typeof number === 'number' && Number.isInteger(number) && number > 0) {
|
|
68
|
+
next.pinned = { repo, number };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return next;
|
|
73
|
+
}
|
|
74
|
+
/** File-backed preference storage for one installation. */
|
|
75
|
+
export class PrefsStore {
|
|
76
|
+
stateDir;
|
|
77
|
+
configureHandoff;
|
|
78
|
+
configureTemplate;
|
|
79
|
+
file;
|
|
80
|
+
directory;
|
|
81
|
+
cached;
|
|
82
|
+
cachedLinks;
|
|
83
|
+
/**
|
|
84
|
+
* @param stateDir - owner-only directory this installation's state lives in.
|
|
85
|
+
* @param configureHandoff - the deployment's default handoff mode.
|
|
86
|
+
* @param configureTemplate - the deployment's default prompt template.
|
|
87
|
+
*/
|
|
88
|
+
constructor(stateDir, configureHandoff, configureTemplate) {
|
|
89
|
+
this.stateDir = stateDir;
|
|
90
|
+
this.configureHandoff = configureHandoff;
|
|
91
|
+
this.configureTemplate = configureTemplate;
|
|
92
|
+
this.directory = stateDir;
|
|
93
|
+
this.file = join(stateDir, 'state.json');
|
|
94
|
+
}
|
|
95
|
+
/** Read the current preferences, creating defaults on first use. */
|
|
96
|
+
load() {
|
|
97
|
+
if (this.cached !== undefined)
|
|
98
|
+
return this.cached;
|
|
99
|
+
const saved = this.readFile()?.prefs;
|
|
100
|
+
this.cached = mergePrefs(saved, this.configureHandoff, this.configureTemplate);
|
|
101
|
+
return this.cached;
|
|
102
|
+
}
|
|
103
|
+
/** Every recorded issue → session link, oldest first. */
|
|
104
|
+
links() {
|
|
105
|
+
if (this.cachedLinks !== undefined)
|
|
106
|
+
return this.cachedLinks;
|
|
107
|
+
const links = this.readFile()?.links;
|
|
108
|
+
this.cachedLinks = Array.isArray(links)
|
|
109
|
+
? links.filter((link) => {
|
|
110
|
+
if (typeof link !== 'object' || link === null)
|
|
111
|
+
return false;
|
|
112
|
+
const record = link;
|
|
113
|
+
return typeof record.repo === 'string' && typeof record.number === 'number'
|
|
114
|
+
&& typeof record.sessionId === 'string' && typeof record.at === 'number';
|
|
115
|
+
})
|
|
116
|
+
: [];
|
|
117
|
+
return this.cachedLinks;
|
|
118
|
+
}
|
|
119
|
+
/** The links recorded for one issue, newest last. */
|
|
120
|
+
linksFor(repo, number) {
|
|
121
|
+
return this.links()
|
|
122
|
+
.filter(link => link.repo === repo && link.number === number)
|
|
123
|
+
.map(link => ({ sessionId: link.sessionId, at: link.at }));
|
|
124
|
+
}
|
|
125
|
+
/** Record one issue → session handoff, idempotently. */
|
|
126
|
+
link(repo, number, sessionId) {
|
|
127
|
+
const existing = this.links();
|
|
128
|
+
const already = existing.some(link => link.repo === repo && link.number === number && link.sessionId === sessionId);
|
|
129
|
+
if (already)
|
|
130
|
+
return existing;
|
|
131
|
+
const next = [...existing, { repo, number, sessionId, at: Date.now() }].slice(-MAX_LINKS);
|
|
132
|
+
this.cachedLinks = next;
|
|
133
|
+
this.writeFile(next);
|
|
134
|
+
return next;
|
|
135
|
+
}
|
|
136
|
+
/** Remove one link (or every link for the issue when `sessionId` is omitted). */
|
|
137
|
+
unlink(repo, number, sessionId) {
|
|
138
|
+
const next = this.links().filter(link => {
|
|
139
|
+
if (link.repo !== repo || link.number !== number)
|
|
140
|
+
return true;
|
|
141
|
+
return sessionId === undefined ? false : link.sessionId !== sessionId;
|
|
142
|
+
});
|
|
143
|
+
this.cachedLinks = next;
|
|
144
|
+
this.writeFile(next);
|
|
145
|
+
return next;
|
|
146
|
+
}
|
|
147
|
+
/** Read the state file once, tolerating absence, v1 files, and corruption. */
|
|
148
|
+
readFile() {
|
|
149
|
+
try {
|
|
150
|
+
const parsed = JSON.parse(readFileSync(this.file, 'utf8'));
|
|
151
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
152
|
+
return undefined;
|
|
153
|
+
if (parsed.version !== 1 && parsed.version !== 2)
|
|
154
|
+
return undefined;
|
|
155
|
+
const prefs = typeof parsed.prefs === 'object' && parsed.prefs !== null
|
|
156
|
+
? parsed.prefs
|
|
157
|
+
: undefined;
|
|
158
|
+
return { ...prefs === undefined ? {} : { prefs }, links: parsed.links };
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Merge one patch into the stored preferences and persist them. */
|
|
165
|
+
save(patch) {
|
|
166
|
+
const next = applyPrefsPatch(this.load(), patch);
|
|
167
|
+
this.cached = next;
|
|
168
|
+
this.writeFile(this.links());
|
|
169
|
+
return next;
|
|
170
|
+
}
|
|
171
|
+
/** Write the whole state document atomically with owner-only permissions. */
|
|
172
|
+
writeFile(links) {
|
|
173
|
+
mkdirSync(this.directory, { recursive: true, mode: 0o700 });
|
|
174
|
+
try {
|
|
175
|
+
chmodSync(this.directory, 0o700);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// A pre-existing directory may not be ours to chmod; the write still works.
|
|
179
|
+
}
|
|
180
|
+
const text = `${JSON.stringify({ version: 2, prefs: this.cached ?? this.load(), links }, null, 2)}\n`;
|
|
181
|
+
const temporary = `${this.file}.tmp-${String(process.pid)}`;
|
|
182
|
+
writeFileSync(temporary, text, { mode: 0o600 });
|
|
183
|
+
renameSync(temporary, this.file);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/github/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Host-side GitHub contract.
|
|
3
|
+
*
|
|
4
|
+
* Pure data in and pure data out: no Cordis types, no transport, no Node imports
|
|
5
|
+
* beyond the standard library, so the implementation is testable with a fake
|
|
6
|
+
* fetch and the Remote controller stays a thin forwarding layer.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-plugin-github-issues/github/types
|
|
9
|
+
*/
|
|
10
|
+
/** A classified failure, so the UI can tell "missing scope" from "network down". */
|
|
11
|
+
export class GitHubApiError extends Error {
|
|
12
|
+
code;
|
|
13
|
+
status;
|
|
14
|
+
constructor(message, code, status) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'GitHubApiError';
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.status = status;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Split `owner/name` and reject malformed values before they reach GraphQL. */
|
|
22
|
+
export function splitRepo(repo) {
|
|
23
|
+
const slash = repo.indexOf('/');
|
|
24
|
+
if (slash <= 0 || slash === repo.length - 1 || repo.indexOf('/', slash + 1) !== -1) {
|
|
25
|
+
throw new GitHubApiError(`invalid repository "${repo}"; expected "owner/name"`, 'invalid_repo');
|
|
26
|
+
}
|
|
27
|
+
return { owner: repo.slice(0, slash), name: repo.slice(slash + 1) };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/github/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0CH,oFAAoF;AACpF,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAAQ;IACZ,MAAM,CAAoB;IAEnC,YAAY,OAAe,EAAE,IAAY,EAAE,MAAe;QACxD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAqBD,gFAAgF;AAChF,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,cAAc,CAAC,uBAAuB,IAAI,0BAA0B,EAAE,cAAc,CAAC,CAAA;IACjG,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAA;AACrE,CAAC"}
|
package/lib/github/vm.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure mapping from GitHub's GraphQL wire shapes to the shared view models.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here performs I/O or touches a transport: a raw node goes in, a
|
|
5
|
+
* renderable value comes out. Keeping the mapping pure is what lets the layout
|
|
6
|
+
* rules (priority precedence, check glyphs, excerpt length) be tested against
|
|
7
|
+
* the trimmed JSON captured in the research notes instead of a live API.
|
|
8
|
+
*
|
|
9
|
+
* Raw shapes are deliberately loose — every field is optional and nullable — so
|
|
10
|
+
* a partial or aliased response maps to something sensible rather than crashing
|
|
11
|
+
* the panel.
|
|
12
|
+
*
|
|
13
|
+
* @module dsh-plugin-github-issues/github/vm
|
|
14
|
+
*/
|
|
15
|
+
/** Conclusions that mean "this check needs a human before merging". */
|
|
16
|
+
const FAILING_CONCLUSIONS = new Set([
|
|
17
|
+
'FAILURE', 'TIMED_OUT', 'CANCELLED', 'ACTION_REQUIRED',
|
|
18
|
+
]);
|
|
19
|
+
/** Commit-status states that mean failure. */
|
|
20
|
+
const FAILING_STATUSES = new Set(['FAILURE', 'ERROR']);
|
|
21
|
+
/** The reason a closed issue carries, restricted to the states the UI renders. */
|
|
22
|
+
function stateReasonOf(value) {
|
|
23
|
+
switch (value) {
|
|
24
|
+
case 'COMPLETED': return 'COMPLETED';
|
|
25
|
+
case 'NOT_PLANNED': return 'NOT_PLANNED';
|
|
26
|
+
case 'DUPLICATE': return 'DUPLICATE';
|
|
27
|
+
case 'REOPENED': return 'REOPENED';
|
|
28
|
+
default: return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Map GitHub's issue/PR state to the two-state view.
|
|
33
|
+
* A merged pull request renders as closed, because the card has no separate
|
|
34
|
+
* merged state (the PR's own `merged` flag is only on {@link LinkedPRVM}).
|
|
35
|
+
*/
|
|
36
|
+
function issueStateOf(value) {
|
|
37
|
+
return value === 'CLOSED' || value === 'MERGED' ? 'CLOSED' : 'OPEN';
|
|
38
|
+
}
|
|
39
|
+
/** Map a raw milestone to its view model, or `undefined` when the issue has none. */
|
|
40
|
+
export function toMilestoneVM(node) {
|
|
41
|
+
if (node === null || node === undefined || typeof node.title !== 'string' || node.title === '')
|
|
42
|
+
return undefined;
|
|
43
|
+
return {
|
|
44
|
+
title: node.title,
|
|
45
|
+
dueOn: typeof node.dueOn === 'string' ? node.dueOn : null,
|
|
46
|
+
state: node.state === 'CLOSED' ? 'CLOSED' : 'OPEN',
|
|
47
|
+
progress: typeof node.progressPercentage === 'number' ? node.progressPercentage : null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Map a label connection to view models, dropping malformed entries. */
|
|
51
|
+
export function toLabelVMs(nodes) {
|
|
52
|
+
const labels = [];
|
|
53
|
+
for (const node of nodes ?? []) {
|
|
54
|
+
if (node === null || typeof node.name !== 'string' || node.name === '')
|
|
55
|
+
continue;
|
|
56
|
+
labels.push({ name: node.name, color: typeof node.color === 'string' ? node.color : '' });
|
|
57
|
+
}
|
|
58
|
+
return labels;
|
|
59
|
+
}
|
|
60
|
+
/** Map an assignee connection to view models, dropping entries without a login. */
|
|
61
|
+
export function toAssigneeVMs(nodes) {
|
|
62
|
+
const assignees = [];
|
|
63
|
+
for (const node of nodes ?? []) {
|
|
64
|
+
if (node === null || typeof node.login !== 'string' || node.login === '')
|
|
65
|
+
continue;
|
|
66
|
+
assignees.push({
|
|
67
|
+
login: node.login,
|
|
68
|
+
...typeof node.avatarUrl === 'string' && node.avatarUrl !== '' ? { avatarUrl: node.avatarUrl } : {},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return assignees;
|
|
72
|
+
}
|
|
73
|
+
/** Map the issue-type node, or `undefined` where the org has not enabled types. */
|
|
74
|
+
function toIssueTypeVM(node) {
|
|
75
|
+
if (node === null || node === undefined || typeof node.name !== 'string' || node.name === '')
|
|
76
|
+
return undefined;
|
|
77
|
+
return {
|
|
78
|
+
name: node.name,
|
|
79
|
+
...typeof node.color === 'string' && node.color !== '' ? { color: node.color } : {},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Map the rolled-up check state, or `null` when GitHub reports none. */
|
|
83
|
+
export function checkStateOf(rollup) {
|
|
84
|
+
switch (rollup?.state) {
|
|
85
|
+
case 'SUCCESS': return 'SUCCESS';
|
|
86
|
+
case 'FAILURE': return 'FAILURE';
|
|
87
|
+
case 'ERROR': return 'ERROR';
|
|
88
|
+
case 'PENDING': return 'PENDING';
|
|
89
|
+
case 'EXPECTED': return 'EXPECTED';
|
|
90
|
+
case 'NEUTRAL': return 'NEUTRAL';
|
|
91
|
+
case 'SKIPPED': return 'SKIPPED';
|
|
92
|
+
default: return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The names of checks that failed, at most five.
|
|
97
|
+
* Check runs fail on a terminal bad conclusion; legacy statuses fail on
|
|
98
|
+
* `FAILURE` or `ERROR`. Pending checks are not counted as failing.
|
|
99
|
+
*/
|
|
100
|
+
export function failingChecksOf(rollup) {
|
|
101
|
+
const failing = [];
|
|
102
|
+
for (const node of rollup?.contexts?.nodes ?? []) {
|
|
103
|
+
if (node === null)
|
|
104
|
+
continue;
|
|
105
|
+
if ('context' in node) {
|
|
106
|
+
if (typeof node.context === 'string' && FAILING_STATUSES.has(node.state ?? ''))
|
|
107
|
+
failing.push(node.context);
|
|
108
|
+
}
|
|
109
|
+
else if ('name' in node) {
|
|
110
|
+
if (typeof node.name === 'string' && FAILING_CONCLUSIONS.has(node.conclusion ?? ''))
|
|
111
|
+
failing.push(node.name);
|
|
112
|
+
}
|
|
113
|
+
if (failing.length >= 5)
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
return failing.slice(0, 5);
|
|
117
|
+
}
|
|
118
|
+
/** Map one linked pull request, including its check glyph inputs. */
|
|
119
|
+
export function toLinkedPRVM(node) {
|
|
120
|
+
const state = node.state === 'MERGED'
|
|
121
|
+
? 'MERGED'
|
|
122
|
+
: node.state === 'CLOSED' ? 'CLOSED' : 'OPEN';
|
|
123
|
+
const reviewDecision = node.reviewDecision === 'APPROVED'
|
|
124
|
+
|| node.reviewDecision === 'CHANGES_REQUESTED'
|
|
125
|
+
|| node.reviewDecision === 'REVIEW_REQUIRED'
|
|
126
|
+
? node.reviewDecision
|
|
127
|
+
: null;
|
|
128
|
+
const failingChecks = failingChecksOf(node.statusCheckRollup);
|
|
129
|
+
return {
|
|
130
|
+
number: typeof node.number === 'number' ? node.number : 0,
|
|
131
|
+
title: typeof node.title === 'string' ? node.title : '',
|
|
132
|
+
url: typeof node.url === 'string' ? node.url : '',
|
|
133
|
+
state,
|
|
134
|
+
isDraft: node.isDraft === true,
|
|
135
|
+
merged: node.merged === true,
|
|
136
|
+
reviewDecision,
|
|
137
|
+
checks: checkStateOf(node.statusCheckRollup),
|
|
138
|
+
...failingChecks.length === 0 ? {} : { failingChecks },
|
|
139
|
+
...typeof node.author?.login === 'string' && node.author.login !== '' ? { author: node.author.login } : {},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Map a linked-PR connection, dropping malformed entries. */
|
|
143
|
+
function toLinkedPRVMs(nodes) {
|
|
144
|
+
const pullRequests = [];
|
|
145
|
+
for (const node of nodes ?? []) {
|
|
146
|
+
if (node === null)
|
|
147
|
+
continue;
|
|
148
|
+
pullRequests.push(toLinkedPRVM(node));
|
|
149
|
+
}
|
|
150
|
+
return pullRequests;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Read the `Priority` value out of a project item's `fieldValueByName` answer.
|
|
154
|
+
* Single-select values carry a name and a color enum; text and number fields
|
|
155
|
+
* are accepted as names too, because a project may model priority either way.
|
|
156
|
+
*/
|
|
157
|
+
export function priorityFromProjectValue(value) {
|
|
158
|
+
if (value === null || value === undefined)
|
|
159
|
+
return undefined;
|
|
160
|
+
const name = typeof value.name === 'string' && value.name !== ''
|
|
161
|
+
? value.name
|
|
162
|
+
: typeof value.text === 'string' && value.text !== ''
|
|
163
|
+
? value.text
|
|
164
|
+
: typeof value.number === 'number' ? String(value.number) : undefined;
|
|
165
|
+
if (name === undefined)
|
|
166
|
+
return undefined;
|
|
167
|
+
return {
|
|
168
|
+
source: 'project',
|
|
169
|
+
name,
|
|
170
|
+
...typeof value.color === 'string' && value.color !== '' ? { color: value.color } : {},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/** Read the org-level Issue Field named `Priority`, when the issue has a value. */
|
|
174
|
+
export function priorityFromIssueFields(values) {
|
|
175
|
+
for (const value of values?.nodes ?? []) {
|
|
176
|
+
if (value === null)
|
|
177
|
+
continue;
|
|
178
|
+
const fieldName = value.field?.name;
|
|
179
|
+
if (typeof fieldName !== 'string' || fieldName.toLowerCase() !== 'priority')
|
|
180
|
+
continue;
|
|
181
|
+
if (typeof value.name !== 'string' || value.name === '')
|
|
182
|
+
continue;
|
|
183
|
+
return {
|
|
184
|
+
source: 'issue-field',
|
|
185
|
+
name: value.name,
|
|
186
|
+
...typeof value.color === 'string' && value.color !== '' ? { color: value.color } : {},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Fall back to a `P0`..`P4` label.
|
|
193
|
+
* When a repository somehow carries several such labels, the lowest number wins
|
|
194
|
+
* (P0 is the highest priority); the label's own bare hex color is carried along.
|
|
195
|
+
*/
|
|
196
|
+
export function priorityFromLabels(labels) {
|
|
197
|
+
let best;
|
|
198
|
+
let bestRank = Number.POSITIVE_INFINITY;
|
|
199
|
+
for (const label of labels ?? []) {
|
|
200
|
+
if (label === null || typeof label.name !== 'string')
|
|
201
|
+
continue;
|
|
202
|
+
if (!/^P[0-4]$/i.test(label.name))
|
|
203
|
+
continue;
|
|
204
|
+
const rank = Number.parseInt(label.name.slice(1), 10);
|
|
205
|
+
if (rank >= bestRank)
|
|
206
|
+
continue;
|
|
207
|
+
best = label;
|
|
208
|
+
bestRank = rank;
|
|
209
|
+
}
|
|
210
|
+
if (best === undefined)
|
|
211
|
+
return undefined;
|
|
212
|
+
return {
|
|
213
|
+
source: 'label',
|
|
214
|
+
name: best.name,
|
|
215
|
+
...typeof best.color === 'string' && best.color !== '' ? { color: best.color } : {},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Pick the rendered priority by source precedence:
|
|
220
|
+
* project field, then org Issue Field, then label.
|
|
221
|
+
* @param project - priority read from the containing project item.
|
|
222
|
+
* @param issueField - priority read from the issue's org fields.
|
|
223
|
+
* @param label - priority read from `P0`..`P4` labels.
|
|
224
|
+
* @returns the first defined value, or `undefined` when no source has one.
|
|
225
|
+
*/
|
|
226
|
+
export function pickPriority(project, issueField, label) {
|
|
227
|
+
return project ?? issueField ?? label;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Turn an issue body into a one-line preview.
|
|
231
|
+
* Headings, images, links, and fences are reduced to their text, whitespace is
|
|
232
|
+
* collapsed, and the result is cut at `max` characters with an ellipsis.
|
|
233
|
+
* @param body - the issue body as returned by the API.
|
|
234
|
+
* @param max - the excerpt budget in characters.
|
|
235
|
+
* @returns the excerpt, or `undefined` when the body has no text.
|
|
236
|
+
*/
|
|
237
|
+
export function bodyExcerpt(body, max = 200) {
|
|
238
|
+
if (typeof body !== 'string' || body.trim() === '')
|
|
239
|
+
return undefined;
|
|
240
|
+
let text = body
|
|
241
|
+
.replace(/<!--[\s\S]*?-->/g, ' ')
|
|
242
|
+
.replace(/^#{1,6}\s+/gm, '')
|
|
243
|
+
.replace(/!\[[^\]]*\]\([^)]*\)/g, ' ')
|
|
244
|
+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
245
|
+
.replace(/```[a-zA-Z0-9_-]*/g, ' ')
|
|
246
|
+
.replace(/`([^`]*)`/g, '$1')
|
|
247
|
+
.replace(/<[^>]+>/g, ' ')
|
|
248
|
+
.replace(/^\s*>\s?/gm, '')
|
|
249
|
+
.replace(/\s+/g, ' ')
|
|
250
|
+
.trim();
|
|
251
|
+
if (text === '')
|
|
252
|
+
return undefined;
|
|
253
|
+
if (text.length <= max)
|
|
254
|
+
return text;
|
|
255
|
+
return `${text.slice(0, Math.max(1, max - 1)).trimEnd()}…`;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Map one issue node to the list-row view model.
|
|
259
|
+
* @param node - an issue node from a search, repository, or project query.
|
|
260
|
+
* @param options - project context, when the node came from a project item.
|
|
261
|
+
* @returns the card the panel renders.
|
|
262
|
+
*/
|
|
263
|
+
export function toIssueCardVM(node, options = {}) {
|
|
264
|
+
const issueType = toIssueTypeVM(node.issueType);
|
|
265
|
+
const milestone = toMilestoneVM(node.milestone);
|
|
266
|
+
const body = typeof node.body === 'string' ? node.body : '';
|
|
267
|
+
const excerpt = bodyExcerpt(body);
|
|
268
|
+
const priority = pickPriority(options.projectPriority, priorityFromIssueFields(node.issueFieldValues), priorityFromLabels(node.labels?.nodes));
|
|
269
|
+
return {
|
|
270
|
+
id: typeof node.id === 'string' ? node.id : '',
|
|
271
|
+
repo: typeof node.repository?.nameWithOwner === 'string' ? node.repository.nameWithOwner : '',
|
|
272
|
+
number: typeof node.number === 'number' ? node.number : 0,
|
|
273
|
+
title: typeof node.title === 'string' ? node.title : '',
|
|
274
|
+
url: typeof node.url === 'string' ? node.url : '',
|
|
275
|
+
state: issueStateOf(node.state),
|
|
276
|
+
stateReason: stateReasonOf(node.stateReason),
|
|
277
|
+
isPrivate: node.repository?.isPrivate === true,
|
|
278
|
+
labels: toLabelVMs(node.labels?.nodes),
|
|
279
|
+
assignees: toAssigneeVMs(node.assignees?.nodes),
|
|
280
|
+
updatedAt: typeof node.updatedAt === 'string' ? node.updatedAt : '',
|
|
281
|
+
commentCount: typeof node.comments?.totalCount === 'number' ? node.comments.totalCount : 0,
|
|
282
|
+
linkedPRs: toLinkedPRVMs(node.closedByPullRequestsReferences?.nodes),
|
|
283
|
+
...issueType === undefined ? {} : { issueType },
|
|
284
|
+
...milestone === undefined ? {} : { milestone },
|
|
285
|
+
...excerpt === undefined ? {} : { bodyExcerpt: excerpt },
|
|
286
|
+
...priority === undefined ? {} : { priority },
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Map a `timelineItems` connection to mentioned PRs.
|
|
291
|
+
* Closing references are not filtered here (the caller owns the card); duplicates
|
|
292
|
+
* are dropped. The panel filters out PRs already listed as closing references.
|
|
293
|
+
* @param crossRefs - `timelineItems.nodes` from the cross-reference request.
|
|
294
|
+
* @param closingNumbers - PR numbers already rendered as closing references.
|
|
295
|
+
* @returns mentioned pull requests in timeline order.
|
|
296
|
+
*/
|
|
297
|
+
export function toMentionedPRsVM(crossRefs, closingNumbers = new Set()) {
|
|
298
|
+
const mentioned = [];
|
|
299
|
+
const seen = new Set();
|
|
300
|
+
for (const item of crossRefs ?? []) {
|
|
301
|
+
if (item === null || item.__typename !== 'CrossReferencedEvent')
|
|
302
|
+
continue;
|
|
303
|
+
const source = item.source;
|
|
304
|
+
if (source === null || source === undefined || source.__typename !== 'PullRequest')
|
|
305
|
+
continue;
|
|
306
|
+
const pullRequest = toLinkedPRVM(source);
|
|
307
|
+
if (pullRequest.number <= 0)
|
|
308
|
+
continue;
|
|
309
|
+
if (closingNumbers.has(pullRequest.number) || seen.has(pullRequest.number))
|
|
310
|
+
continue;
|
|
311
|
+
seen.add(pullRequest.number);
|
|
312
|
+
mentioned.push(pullRequest);
|
|
313
|
+
}
|
|
314
|
+
return mentioned;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Map one issue node plus its cross-references to the detail view.
|
|
318
|
+
* `mentionedPRs` excludes PRs that already appear as closing references, since
|
|
319
|
+
* the panel renders those separately.
|
|
320
|
+
* @param node - the issue node from the detail query.
|
|
321
|
+
* @param crossRefs - the issue's `timelineItems.nodes` (cross-referenced events).
|
|
322
|
+
* @returns the detail the composer dock renders.
|
|
323
|
+
*/
|
|
324
|
+
export function toIssueDetailVM(node, crossRefs) {
|
|
325
|
+
const card = toIssueCardVM(node);
|
|
326
|
+
const closingNumbers = new Set(card.linkedPRs.map(pullRequest => pullRequest.number));
|
|
327
|
+
return {
|
|
328
|
+
...card,
|
|
329
|
+
body: typeof node.body === 'string' ? node.body : '',
|
|
330
|
+
mentionedPRs: toMentionedPRsVM(crossRefs, closingNumbers),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Map one Projects v2 item to a card.
|
|
335
|
+
* Draft issues and redacted items have no repository or number and are
|
|
336
|
+
* skipped; pull requests are rendered as issue-like cards, closed when merged.
|
|
337
|
+
* @param item - one node of a project's `items` connection.
|
|
338
|
+
* @returns the card, or `undefined` when the item is not renderable.
|
|
339
|
+
*/
|
|
340
|
+
export function toProjectItemCardVM(item) {
|
|
341
|
+
if (item === null || item === undefined)
|
|
342
|
+
return undefined;
|
|
343
|
+
const content = item.content;
|
|
344
|
+
if (content === null || content === undefined)
|
|
345
|
+
return undefined;
|
|
346
|
+
if (content.__typename !== 'Issue' && content.__typename !== 'PullRequest')
|
|
347
|
+
return undefined;
|
|
348
|
+
const projectPriority = priorityFromProjectValue(item.priority);
|
|
349
|
+
const card = toIssueCardVM(content, projectPriority === undefined ? {} : { projectPriority });
|
|
350
|
+
const status = item.status;
|
|
351
|
+
if (status !== null && status !== undefined && typeof status.name === 'string' && status.name !== '') {
|
|
352
|
+
return {
|
|
353
|
+
...card,
|
|
354
|
+
projectStatus: {
|
|
355
|
+
name: status.name,
|
|
356
|
+
...typeof status.color === 'string' && status.color !== '' ? { color: status.color } : {},
|
|
357
|
+
},
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return card;
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=vm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm.js","sourceRoot":"","sources":["../../src/github/vm.ts"],"names":[],"mappings":"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"}
|