@a9n-shoji/rvw 0.4.0 → 0.4.2
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 +26 -0
- package/README.md +4 -0
- package/dist/cli.mjs +660 -155
- package/dist/cli.mjs.map +3 -3
- package/dist/web/assets/DocumentViewer-CWTnSlpG.js +1420 -0
- package/dist/web/assets/{FileIcon-AhP8Ezk9.js → FileIcon-wDKKQgGv.js} +94 -94
- package/dist/web/assets/{MarkdownTable-Clfr8wUw.js → MarkdownTable-IiPLNTUX.js} +1 -1
- package/dist/web/assets/{MermaidExpandedView-BjmXfluL.js → MermaidExpandedView-BT6F4F2R.js} +2 -2
- package/dist/web/assets/{MermaidSurface-B2Z3pJme.js → MermaidSurface-CKiZv7R8.js} +1 -1
- package/dist/web/assets/StructureViewer-u7de1S8C.js +5 -0
- package/dist/web/assets/{CommentThread-dsad9VaW.js → WalkthroughPanel-D2KqSIf9.js} +20 -20
- package/dist/web/assets/WalkthroughViewer-BDb-99Qk.js +43 -0
- package/dist/web/assets/index-B0xRoLW2.css +1 -0
- package/dist/web/assets/index-DUZmOKYW.js +11 -0
- package/dist/web/index.html +5 -5
- package/migrations/017_domain_revisions.sql +14 -0
- package/package.json +1 -1
- package/dist/web/assets/DocumentViewer-CPq2FCqU.js +0 -1414
- package/dist/web/assets/StructureViewer-CyDDQwHl.js +0 -1
- package/dist/web/assets/WalkthroughViewer-c3XUP0RH.js +0 -43
- package/dist/web/assets/index-CWOtOTHG.js +0 -11
- package/dist/web/assets/index-D_e3Zku8.css +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -18947,6 +18947,13 @@ function secureNewPath(targetPath, expectedMode, label, chmod = chmodSync) {
|
|
|
18947
18947
|
}
|
|
18948
18948
|
assertSecureExistingPath(targetPath, expectedMode, label);
|
|
18949
18949
|
}
|
|
18950
|
+
var domainRevisionMetaKeys = {
|
|
18951
|
+
pullRequests: "revision_pull_requests",
|
|
18952
|
+
pullRequestContent: "revision_pull_request_content",
|
|
18953
|
+
comments: "revision_comments",
|
|
18954
|
+
walkthroughs: "revision_walkthroughs",
|
|
18955
|
+
structures: "revision_structures"
|
|
18956
|
+
};
|
|
18950
18957
|
var RvwDatabase = class {
|
|
18951
18958
|
filePath;
|
|
18952
18959
|
configuredPath;
|
|
@@ -19090,10 +19097,69 @@ var RvwDatabase = class {
|
|
|
19090
19097
|
).run();
|
|
19091
19098
|
return this.getChangeSequence();
|
|
19092
19099
|
}
|
|
19100
|
+
incrementDomainRevisions(domains) {
|
|
19101
|
+
const uniqueDomains = [...new Set(domains)];
|
|
19102
|
+
this.incrementChangeSequence();
|
|
19103
|
+
const increment2 = this.database.prepare(
|
|
19104
|
+
"UPDATE app_meta SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT) WHERE key = ?"
|
|
19105
|
+
);
|
|
19106
|
+
for (const domain2 of uniqueDomains) increment2.run(domainRevisionMetaKeys[domain2]);
|
|
19107
|
+
return this.getChangeSequence();
|
|
19108
|
+
}
|
|
19093
19109
|
getChangeSequence() {
|
|
19094
19110
|
const row = this.database.prepare("SELECT value FROM app_meta WHERE key = 'change_sequence'").get();
|
|
19095
19111
|
return Number(stringValue(row, "value"));
|
|
19096
19112
|
}
|
|
19113
|
+
getRevisionSnapshot() {
|
|
19114
|
+
const rows = this.database.prepare(
|
|
19115
|
+
`SELECT key, value
|
|
19116
|
+
FROM app_meta
|
|
19117
|
+
WHERE key IN (
|
|
19118
|
+
'change_sequence',
|
|
19119
|
+
'revision_pull_requests',
|
|
19120
|
+
'revision_pull_request_content',
|
|
19121
|
+
'revision_comments',
|
|
19122
|
+
'revision_walkthroughs',
|
|
19123
|
+
'revision_structures'
|
|
19124
|
+
)`
|
|
19125
|
+
).all();
|
|
19126
|
+
const values = new Map(rows.map((row) => [stringValue(row, "key"), stringValue(row, "value")]));
|
|
19127
|
+
const value = (key2) => {
|
|
19128
|
+
const raw3 = values.get(key2);
|
|
19129
|
+
if (raw3 === void 0) throw new RvwError("DATABASE_ERROR", `revision\u304C\u3042\u308A\u307E\u305B\u3093: ${key2}`);
|
|
19130
|
+
return Number(raw3);
|
|
19131
|
+
};
|
|
19132
|
+
return {
|
|
19133
|
+
changeSequence: value("change_sequence"),
|
|
19134
|
+
revisions: {
|
|
19135
|
+
pullRequests: value(domainRevisionMetaKeys.pullRequests),
|
|
19136
|
+
pullRequestContent: value(domainRevisionMetaKeys.pullRequestContent),
|
|
19137
|
+
comments: value(domainRevisionMetaKeys.comments),
|
|
19138
|
+
walkthroughs: value(domainRevisionMetaKeys.walkthroughs),
|
|
19139
|
+
structures: value(domainRevisionMetaKeys.structures)
|
|
19140
|
+
}
|
|
19141
|
+
};
|
|
19142
|
+
}
|
|
19143
|
+
getDomainRevisions() {
|
|
19144
|
+
return this.getRevisionSnapshot().revisions;
|
|
19145
|
+
}
|
|
19146
|
+
getPullRequestRevisionSnapshot(id) {
|
|
19147
|
+
this.database.exec("BEGIN");
|
|
19148
|
+
try {
|
|
19149
|
+
const result = {
|
|
19150
|
+
pullRequest: this.getPullRequest(id),
|
|
19151
|
+
revisionSnapshot: this.getRevisionSnapshot()
|
|
19152
|
+
};
|
|
19153
|
+
this.database.exec("COMMIT");
|
|
19154
|
+
return result;
|
|
19155
|
+
} catch (error51) {
|
|
19156
|
+
try {
|
|
19157
|
+
this.database.exec("ROLLBACK");
|
|
19158
|
+
} catch {
|
|
19159
|
+
}
|
|
19160
|
+
throw error51;
|
|
19161
|
+
}
|
|
19162
|
+
}
|
|
19097
19163
|
getCommentWatchDatabaseId() {
|
|
19098
19164
|
const row = this.database.prepare("SELECT value FROM app_meta WHERE key = 'comment_watch_database_id'").get();
|
|
19099
19165
|
if (!row) throw new RvwError("DATABASE_ERROR", "comment watch\u306Edatabase ID\u304C\u3042\u308A\u307E\u305B\u3093\u3002");
|
|
@@ -19246,7 +19312,19 @@ var RvwDatabase = class {
|
|
|
19246
19312
|
const statement = this.database.prepare(
|
|
19247
19313
|
"UPDATE pull_requests SET github_state = ?, github_is_draft = ? WHERE id = ?"
|
|
19248
19314
|
);
|
|
19315
|
+
let changed = false;
|
|
19249
19316
|
for (const update of updates) {
|
|
19317
|
+
const current = this.getPullRequest(update.pullRequestId);
|
|
19318
|
+
if (!current) {
|
|
19319
|
+
throw new RvwError(
|
|
19320
|
+
"PR_NOT_FOUND",
|
|
19321
|
+
`Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: ${update.pullRequestId}`,
|
|
19322
|
+
{ status: 404 }
|
|
19323
|
+
);
|
|
19324
|
+
}
|
|
19325
|
+
if (current.githubState === update.state && current.githubIsDraft === update.isDraft) {
|
|
19326
|
+
continue;
|
|
19327
|
+
}
|
|
19250
19328
|
const result = statement.run(update.state, update.isDraft ? 1 : 0, update.pullRequestId);
|
|
19251
19329
|
if (Number(result.changes) !== 1) {
|
|
19252
19330
|
throw new RvwError(
|
|
@@ -19255,18 +19333,24 @@ var RvwDatabase = class {
|
|
|
19255
19333
|
{ status: 404 }
|
|
19256
19334
|
);
|
|
19257
19335
|
}
|
|
19336
|
+
changed = true;
|
|
19258
19337
|
}
|
|
19259
|
-
this.
|
|
19338
|
+
if (changed) this.incrementDomainRevisions(["pullRequests"]);
|
|
19260
19339
|
});
|
|
19261
19340
|
}
|
|
19262
19341
|
updateRepositoryLocation(id, repository) {
|
|
19342
|
+
const existing = this.getPullRequest(id);
|
|
19343
|
+
if (!existing) throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002");
|
|
19344
|
+
if (existing.localRepositoryPath === repository.localRepositoryPath && existing.gitCommonDir === repository.gitCommonDir) {
|
|
19345
|
+
return existing;
|
|
19346
|
+
}
|
|
19263
19347
|
this.immediateTransaction(() => {
|
|
19264
19348
|
const result = this.database.prepare(
|
|
19265
19349
|
"UPDATE pull_requests SET local_repository_path = ?, git_common_dir = ?, updated_at = ? WHERE id = ?"
|
|
19266
19350
|
).run(repository.localRepositoryPath, repository.gitCommonDir, (/* @__PURE__ */ new Date()).toISOString(), id);
|
|
19267
19351
|
if (Number(result.changes) === 0)
|
|
19268
19352
|
throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002");
|
|
19269
|
-
this.
|
|
19353
|
+
this.incrementDomainRevisions(["pullRequests"]);
|
|
19270
19354
|
});
|
|
19271
19355
|
const pullRequest = this.getPullRequest(id);
|
|
19272
19356
|
if (!pullRequest) throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002");
|
|
@@ -19276,6 +19360,8 @@ var RvwDatabase = class {
|
|
|
19276
19360
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19277
19361
|
const existing = this.findPullRequestByIdentity(github.owner, github.repository, github.number);
|
|
19278
19362
|
const id = existing?.id ?? randomUUID();
|
|
19363
|
+
const contentChanged = !existing || existing.latestTitle !== github.title || existing.latestBody !== github.body;
|
|
19364
|
+
const semanticChanged = !existing || existing.url !== github.url || existing.latestAuthorLogin !== github.authorLogin || existing.latestHeadRepositoryOwner !== github.headRepositoryOwner || existing.latestHeadRepositoryName !== github.headRepositoryName || existing.localRepositoryPath !== repository.localRepositoryPath || existing.gitCommonDir !== repository.gitCommonDir || contentChanged || existing.latestBaseRefName !== github.baseRefName || existing.latestHeadRefName !== github.headRefName || existing.latestBaseOid !== github.baseOid || existing.latestComparisonBaseOid !== comparisonBaseOid || existing.latestHeadOid !== github.headOid || existing.githubCreatedAt !== github.createdAt || existing.githubUpdatedAt !== github.updatedAt || existing.githubState !== github.state || existing.githubIsDraft !== github.isDraft;
|
|
19279
19365
|
this.database.prepare(
|
|
19280
19366
|
`INSERT INTO pull_requests(
|
|
19281
19367
|
id, host, owner, repository, number, github_url,
|
|
@@ -19329,16 +19415,19 @@ var RvwDatabase = class {
|
|
|
19329
19415
|
github.isDraft ? 1 : 0,
|
|
19330
19416
|
now,
|
|
19331
19417
|
existing?.createdAt ?? now,
|
|
19332
|
-
now,
|
|
19418
|
+
semanticChanged ? now : existing.updatedAt,
|
|
19333
19419
|
comparisonBaseOid
|
|
19334
19420
|
);
|
|
19335
|
-
return id;
|
|
19421
|
+
return { id, semanticChanged, contentChanged };
|
|
19336
19422
|
}
|
|
19337
19423
|
upsertPullRequest(github, repository, comparisonBaseOid) {
|
|
19338
19424
|
const id = this.immediateTransaction(() => {
|
|
19339
|
-
const
|
|
19340
|
-
|
|
19341
|
-
|
|
19425
|
+
const write = this.writePullRequest(github, repository, comparisonBaseOid);
|
|
19426
|
+
const domains = [];
|
|
19427
|
+
if (write.semanticChanged) domains.push("pullRequests");
|
|
19428
|
+
if (write.contentChanged) domains.push("pullRequestContent");
|
|
19429
|
+
if (domains.length > 0) this.incrementDomainRevisions(domains);
|
|
19430
|
+
return write.id;
|
|
19342
19431
|
});
|
|
19343
19432
|
const pullRequest = this.getPullRequest(id);
|
|
19344
19433
|
if (!pullRequest)
|
|
@@ -19347,10 +19436,14 @@ var RvwDatabase = class {
|
|
|
19347
19436
|
}
|
|
19348
19437
|
syncPullRequestAndComments(github, repository, comparisonBaseOid, updates) {
|
|
19349
19438
|
const id = this.immediateTransaction(() => {
|
|
19350
|
-
const
|
|
19351
|
-
this.applyCommentUpdates(updates, github.headOid);
|
|
19352
|
-
|
|
19353
|
-
|
|
19439
|
+
const write = this.writePullRequest(github, repository, comparisonBaseOid);
|
|
19440
|
+
const commentsChanged = this.applyCommentUpdates(updates, github.headOid);
|
|
19441
|
+
const domains = [];
|
|
19442
|
+
if (write.semanticChanged) domains.push("pullRequests");
|
|
19443
|
+
if (write.contentChanged) domains.push("pullRequestContent");
|
|
19444
|
+
if (commentsChanged) domains.push("comments");
|
|
19445
|
+
if (domains.length > 0) this.incrementDomainRevisions(domains);
|
|
19446
|
+
return write.id;
|
|
19354
19447
|
});
|
|
19355
19448
|
const pullRequest = this.getPullRequest(id);
|
|
19356
19449
|
if (!pullRequest)
|
|
@@ -19359,10 +19452,16 @@ var RvwDatabase = class {
|
|
|
19359
19452
|
}
|
|
19360
19453
|
resetPullRequest(github, repository, comparisonBaseOid) {
|
|
19361
19454
|
const id = this.immediateTransaction(() => {
|
|
19362
|
-
const
|
|
19363
|
-
this.deletePullRequestHistory(
|
|
19364
|
-
this.
|
|
19365
|
-
|
|
19455
|
+
const write = this.writePullRequest(github, repository, comparisonBaseOid);
|
|
19456
|
+
this.deletePullRequestHistory(write.id);
|
|
19457
|
+
this.incrementDomainRevisions([
|
|
19458
|
+
"pullRequests",
|
|
19459
|
+
"pullRequestContent",
|
|
19460
|
+
"comments",
|
|
19461
|
+
"walkthroughs",
|
|
19462
|
+
"structures"
|
|
19463
|
+
]);
|
|
19464
|
+
return write.id;
|
|
19366
19465
|
});
|
|
19367
19466
|
const pullRequest = this.getPullRequest(id);
|
|
19368
19467
|
if (!pullRequest)
|
|
@@ -19496,7 +19595,7 @@ var RvwDatabase = class {
|
|
|
19496
19595
|
key_hash, request_hash, structure_id, created_at
|
|
19497
19596
|
) VALUES (?, ?, ?, ?)`
|
|
19498
19597
|
).run(keyHash, input.idempotencyRequestHash, id, now);
|
|
19499
|
-
this.
|
|
19598
|
+
this.incrementDomainRevisions(["structures"]);
|
|
19500
19599
|
structureId = id;
|
|
19501
19600
|
});
|
|
19502
19601
|
if (!structureId) {
|
|
@@ -19579,7 +19678,7 @@ var RvwDatabase = class {
|
|
|
19579
19678
|
"INSERT OR IGNORE INTO structure_retired_edge_ids(structure_id, edge_id, retired_at) VALUES (?, ?, ?)"
|
|
19580
19679
|
);
|
|
19581
19680
|
for (const edgeId of retiredEdgesAtThisUpdate) retireEdge.run(id, edgeId, now);
|
|
19582
|
-
this.
|
|
19681
|
+
this.incrementDomainRevisions(["structures"]);
|
|
19583
19682
|
});
|
|
19584
19683
|
const structure = this.getStructure(id);
|
|
19585
19684
|
if (!structure) throw new RvwError("DATABASE_ERROR", "\u66F4\u65B0\u3057\u305FStructure\u3092\u8AAD\u307F\u51FA\u305B\u307E\u305B\u3093\u3002");
|
|
@@ -19619,7 +19718,7 @@ var RvwDatabase = class {
|
|
|
19619
19718
|
{ status: 409, details: { expectedUpdatedAt: expectedUpdatedAt2 } }
|
|
19620
19719
|
);
|
|
19621
19720
|
}
|
|
19622
|
-
this.
|
|
19721
|
+
this.incrementDomainRevisions(["structures"]);
|
|
19623
19722
|
return {
|
|
19624
19723
|
id: structure.id,
|
|
19625
19724
|
ref: structure.ref,
|
|
@@ -19715,7 +19814,7 @@ var RvwDatabase = class {
|
|
|
19715
19814
|
now
|
|
19716
19815
|
);
|
|
19717
19816
|
this.insertCodeReferences("walkthrough", id, input.references);
|
|
19718
|
-
this.
|
|
19817
|
+
this.incrementDomainRevisions(["walkthroughs"]);
|
|
19719
19818
|
});
|
|
19720
19819
|
const walkthrough = this.getWalkthrough(id);
|
|
19721
19820
|
if (!walkthrough) {
|
|
@@ -19742,7 +19841,7 @@ var RvwDatabase = class {
|
|
|
19742
19841
|
}
|
|
19743
19842
|
this.database.prepare("DELETE FROM walkthrough_references WHERE walkthrough_id = ?").run(id);
|
|
19744
19843
|
this.insertCodeReferences("walkthrough", id, input.references);
|
|
19745
|
-
this.
|
|
19844
|
+
this.incrementDomainRevisions(["walkthroughs"]);
|
|
19746
19845
|
});
|
|
19747
19846
|
const walkthrough = this.getWalkthrough(id);
|
|
19748
19847
|
if (!walkthrough) {
|
|
@@ -19778,7 +19877,9 @@ var RvwDatabase = class {
|
|
|
19778
19877
|
WHERE id IN (SELECT comment_id FROM comment_targets WHERE walkthrough_id = ?)`
|
|
19779
19878
|
).run(id);
|
|
19780
19879
|
this.database.prepare("DELETE FROM walkthroughs WHERE id = ?").run(id);
|
|
19781
|
-
this.
|
|
19880
|
+
this.incrementDomainRevisions(
|
|
19881
|
+
counts.comments === 0 ? ["walkthroughs"] : ["walkthroughs", "comments"]
|
|
19882
|
+
);
|
|
19782
19883
|
return {
|
|
19783
19884
|
id: walkthrough.id,
|
|
19784
19885
|
ref: walkthrough.ref,
|
|
@@ -19816,7 +19917,7 @@ var RvwDatabase = class {
|
|
|
19816
19917
|
post_id, comment_ref, pull_request_url, created_at
|
|
19817
19918
|
) VALUES (?, ?, ?, ?)`
|
|
19818
19919
|
).run(postId, formatCommentUri(id), pullRequest.url, now);
|
|
19819
|
-
this.
|
|
19920
|
+
this.incrementDomainRevisions(["comments"]);
|
|
19820
19921
|
});
|
|
19821
19922
|
const comment3 = this.getComment(id);
|
|
19822
19923
|
if (!comment3) throw new RvwError("DATABASE_ERROR", "\u4FDD\u5B58\u3057\u305F\u30B3\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u51FA\u305B\u307E\u305B\u3093\u3002");
|
|
@@ -19935,7 +20036,7 @@ var RvwDatabase = class {
|
|
|
19935
20036
|
FROM comments c
|
|
19936
20037
|
JOIN comment_targets t ON t.comment_id = c.id
|
|
19937
20038
|
LEFT JOIN walkthroughs w ON w.id = t.walkthrough_id
|
|
19938
|
-
WHERE c.pull_request_id = ?${where} ORDER BY c.updated_at DESC`
|
|
20039
|
+
WHERE c.pull_request_id = ?${where} ORDER BY c.updated_at DESC, c.id DESC`
|
|
19939
20040
|
).all(pullRequestId).map((row) => this.mapComment(row));
|
|
19940
20041
|
}
|
|
19941
20042
|
listCommentPage(pullRequestId, resolved, limit, offset) {
|
|
@@ -20061,7 +20162,7 @@ var RvwDatabase = class {
|
|
|
20061
20162
|
).run(idempotencyKeyHash, idempotencyRequestHash2, id, now);
|
|
20062
20163
|
}
|
|
20063
20164
|
this.database.prepare("UPDATE comments SET updated_at = ? WHERE id = ?").run(now, commentId);
|
|
20064
|
-
if (incrementSequence) this.
|
|
20165
|
+
if (incrementSequence) this.incrementDomainRevisions(["comments"]);
|
|
20065
20166
|
result = {
|
|
20066
20167
|
id,
|
|
20067
20168
|
commentId,
|
|
@@ -20096,7 +20197,7 @@ var RvwDatabase = class {
|
|
|
20096
20197
|
this.database.prepare("DELETE FROM comment_post_references WHERE post_id = ?").run(postId);
|
|
20097
20198
|
this.insertCodeReferences("comment-post", postId, references);
|
|
20098
20199
|
this.database.prepare("UPDATE comments SET updated_at = ? WHERE id = ?").run(now, commentId);
|
|
20099
|
-
this.
|
|
20200
|
+
this.incrementDomainRevisions(["comments"]);
|
|
20100
20201
|
});
|
|
20101
20202
|
const post = this.getCommentPost(postId);
|
|
20102
20203
|
if (!post) {
|
|
@@ -20128,7 +20229,7 @@ var RvwDatabase = class {
|
|
|
20128
20229
|
this.immediateTransaction(() => {
|
|
20129
20230
|
this.database.prepare("DELETE FROM comment_posts WHERE id = ? AND comment_id = ?").run(postId, commentId);
|
|
20130
20231
|
this.database.prepare("UPDATE comments SET updated_at = ? WHERE id = ?").run(now, commentId);
|
|
20131
|
-
this.
|
|
20232
|
+
this.incrementDomainRevisions(["comments"]);
|
|
20132
20233
|
});
|
|
20133
20234
|
return { commentId, postId };
|
|
20134
20235
|
}
|
|
@@ -20138,7 +20239,7 @@ var RvwDatabase = class {
|
|
|
20138
20239
|
const result = this.database.prepare("UPDATE comments SET resolved_at = ?, updated_at = ? WHERE id = ?").run(resolved ? now : null, now, commentId);
|
|
20139
20240
|
if (Number(result.changes) === 0)
|
|
20140
20241
|
throw new RvwError("COMMENT_NOT_FOUND", "\u30B3\u30E1\u30F3\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002");
|
|
20141
|
-
if (incrementSequence) this.
|
|
20242
|
+
if (incrementSequence) this.incrementDomainRevisions(["comments"]);
|
|
20142
20243
|
};
|
|
20143
20244
|
if (incrementSequence) this.immediateTransaction(write);
|
|
20144
20245
|
else write();
|
|
@@ -20153,14 +20254,18 @@ var RvwDatabase = class {
|
|
|
20153
20254
|
}
|
|
20154
20255
|
this.immediateTransaction(() => {
|
|
20155
20256
|
this.database.prepare("DELETE FROM comments WHERE id = ?").run(commentId);
|
|
20156
|
-
this.
|
|
20257
|
+
this.incrementDomainRevisions(["comments"]);
|
|
20157
20258
|
});
|
|
20158
20259
|
return { id: comment3.id, ref: comment3.ref };
|
|
20159
20260
|
}
|
|
20160
20261
|
applyCommentUpdates(updates, relatedCommitOid) {
|
|
20262
|
+
let changed = false;
|
|
20161
20263
|
for (const update of updates) {
|
|
20264
|
+
const current = this.getComment(update.commentId);
|
|
20265
|
+
if (!current) throw new RvwError("COMMENT_NOT_FOUND", "\u30B3\u30E1\u30F3\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002");
|
|
20162
20266
|
if (update.reply.trim().length > 0) {
|
|
20163
|
-
|
|
20267
|
+
const existingPostIds = new Set(current.posts.map(({ id }) => id));
|
|
20268
|
+
const reply = this.insertReply(
|
|
20164
20269
|
update.commentId,
|
|
20165
20270
|
{
|
|
20166
20271
|
body: update.reply,
|
|
@@ -20173,11 +20278,14 @@ var RvwDatabase = class {
|
|
|
20173
20278
|
},
|
|
20174
20279
|
false
|
|
20175
20280
|
);
|
|
20176
|
-
|
|
20177
|
-
|
|
20281
|
+
if (!existingPostIds.has(reply.id)) changed = true;
|
|
20282
|
+
}
|
|
20283
|
+
if (update.resolve && current.resolvedAt === null) {
|
|
20284
|
+
this.setCommentResolved(update.commentId, true, false);
|
|
20285
|
+
changed = true;
|
|
20178
20286
|
}
|
|
20179
|
-
if (update.resolve) this.setCommentResolved(update.commentId, true, false);
|
|
20180
20287
|
}
|
|
20288
|
+
return changed;
|
|
20181
20289
|
}
|
|
20182
20290
|
};
|
|
20183
20291
|
|
|
@@ -20187,12 +20295,13 @@ import path5 from "node:path";
|
|
|
20187
20295
|
import { TextDecoder as TextDecoder2 } from "node:util";
|
|
20188
20296
|
|
|
20189
20297
|
// src/shared/constants.ts
|
|
20190
|
-
var APP_VERSION = "0.4.
|
|
20298
|
+
var APP_VERSION = "0.4.2";
|
|
20191
20299
|
var PROTOCOL_VERSION = 4;
|
|
20192
20300
|
var VIEWER_ID_HEADER = "x-rvw-viewer-id";
|
|
20193
20301
|
var VIEWER_OPEN_LEASE_HEADER = "x-rvw-viewer-open-lease";
|
|
20194
20302
|
var VIEWER_OPEN_LEASE_QUERY = "viewerLease";
|
|
20195
20303
|
var GIT_OBJECT_ID_PATTERN = /^[0-9a-f]{40,64}$/i;
|
|
20304
|
+
var CONTENT_FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;
|
|
20196
20305
|
var MAX_TEXT_DOCUMENT_BYTES = 1024 * 1024;
|
|
20197
20306
|
var MAX_MARKDOWN_ASSET_BYTES = 5 * 1024 * 1024;
|
|
20198
20307
|
var MAX_GITHUB_ATTACHMENT_BYTES = 10 * 1024 * 1024;
|
|
@@ -28386,6 +28495,9 @@ ${normalizeLf(body3)}`;
|
|
|
28386
28495
|
function hashDocument(value) {
|
|
28387
28496
|
return createHash2("sha256").update(normalizeLf(value), "utf8").digest("hex");
|
|
28388
28497
|
}
|
|
28498
|
+
function pullRequestContentFingerprint(title, body3) {
|
|
28499
|
+
return hashDocument(buildPullRequestMarkdown(title, body3));
|
|
28500
|
+
}
|
|
28389
28501
|
function selectedLineText(value, startLine, endLine) {
|
|
28390
28502
|
const lines2 = normalizeLf(value).split("\n");
|
|
28391
28503
|
if (startLine < 1 || endLine < startLine || endLine > lines2.length) return null;
|
|
@@ -28477,6 +28589,34 @@ function structureSourceAnchor(structure, locator) {
|
|
|
28477
28589
|
const edge = structure.edges.find((candidate) => candidate.id === locator.edgeId);
|
|
28478
28590
|
return edge?.anchors[locator.anchorIndex] ?? null;
|
|
28479
28591
|
}
|
|
28592
|
+
function compareStableIds(left, right) {
|
|
28593
|
+
if (left === right) return 0;
|
|
28594
|
+
return left < right ? -1 : 1;
|
|
28595
|
+
}
|
|
28596
|
+
function closestMatchingStructureNode(structure, matchingNodeIds) {
|
|
28597
|
+
if (matchingNodeIds.size === 0) return null;
|
|
28598
|
+
const distances = /* @__PURE__ */ new Map([[structure.originNodeId, 0]]);
|
|
28599
|
+
const neighbors = new Map(structure.nodes.map((node2) => [node2.id, /* @__PURE__ */ new Set()]));
|
|
28600
|
+
for (const edge of structure.edges) {
|
|
28601
|
+
neighbors.get(edge.from)?.add(edge.to);
|
|
28602
|
+
neighbors.get(edge.to)?.add(edge.from);
|
|
28603
|
+
}
|
|
28604
|
+
const queue = [structure.originNodeId];
|
|
28605
|
+
for (let index2 = 0; index2 < queue.length; index2 += 1) {
|
|
28606
|
+
const nodeId = queue[index2];
|
|
28607
|
+
const distance = distances.get(nodeId);
|
|
28608
|
+
for (const neighbor of neighbors.get(nodeId) ?? []) {
|
|
28609
|
+
if (distances.has(neighbor)) continue;
|
|
28610
|
+
distances.set(neighbor, distance + 1);
|
|
28611
|
+
queue.push(neighbor);
|
|
28612
|
+
}
|
|
28613
|
+
}
|
|
28614
|
+
return structure.nodes.filter((node2) => matchingNodeIds.has(node2.id)).sort((left, right) => {
|
|
28615
|
+
const leftDistance = distances.get(left.id) ?? Number.POSITIVE_INFINITY;
|
|
28616
|
+
const rightDistance = distances.get(right.id) ?? Number.POSITIVE_INFINITY;
|
|
28617
|
+
return leftDistance - rightDistance || compareStableIds(left.id, right.id);
|
|
28618
|
+
})[0] ?? null;
|
|
28619
|
+
}
|
|
28480
28620
|
|
|
28481
28621
|
// src/domain/source-excerpt.ts
|
|
28482
28622
|
var SOURCE_EXCERPT_CONTEXT_LINES = 20;
|
|
@@ -41445,6 +41585,18 @@ function assertLinePair(startLine, endLine) {
|
|
|
41445
41585
|
}
|
|
41446
41586
|
var codeReferenceIdPattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
41447
41587
|
var walkthroughDiagramNodePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
41588
|
+
function structureSummary(structure) {
|
|
41589
|
+
return {
|
|
41590
|
+
id: structure.id,
|
|
41591
|
+
ref: structure.ref,
|
|
41592
|
+
pullRequestId: structure.pullRequestId,
|
|
41593
|
+
sourceOid: structure.sourceOid,
|
|
41594
|
+
title: structure.title,
|
|
41595
|
+
scope: structure.scope,
|
|
41596
|
+
createdAt: structure.createdAt,
|
|
41597
|
+
updatedAt: structure.updatedAt
|
|
41598
|
+
};
|
|
41599
|
+
}
|
|
41448
41600
|
var mermaidIdentifierPattern = /[A-Za-z][A-Za-z0-9_-]{0,63}/g;
|
|
41449
41601
|
var mermaidEdgePattern = /[<|o*x]*[-.=~]{2,}[|o*x>]*/g;
|
|
41450
41602
|
var mermaidClassShorthandPattern = /:::[A-Za-z][A-Za-z0-9_-]*(?:,[A-Za-z][A-Za-z0-9_-]*)*/g;
|
|
@@ -41666,6 +41818,20 @@ function assertCodeReferencePath(filePath) {
|
|
|
41666
41818
|
throw new RvwError("INVALID_INPUT", `code reference\u306Epath\u304C\u4E0D\u6B63\u3067\u3059: ${filePath}`);
|
|
41667
41819
|
}
|
|
41668
41820
|
}
|
|
41821
|
+
async function mapWithConcurrency(values, concurrency, mapper) {
|
|
41822
|
+
const results = new Array(values.length);
|
|
41823
|
+
let nextIndex = 0;
|
|
41824
|
+
const worker = async () => {
|
|
41825
|
+
while (nextIndex < values.length) {
|
|
41826
|
+
const index2 = nextIndex++;
|
|
41827
|
+
results[index2] = await mapper(values[index2], index2);
|
|
41828
|
+
}
|
|
41829
|
+
};
|
|
41830
|
+
await Promise.all(
|
|
41831
|
+
Array.from({ length: Math.min(concurrency, values.length) }, async () => await worker())
|
|
41832
|
+
);
|
|
41833
|
+
return results;
|
|
41834
|
+
}
|
|
41669
41835
|
var RvwService = class {
|
|
41670
41836
|
constructor(database, git, github) {
|
|
41671
41837
|
this.database = database;
|
|
@@ -42053,7 +42219,10 @@ var RvwService = class {
|
|
|
42053
42219
|
});
|
|
42054
42220
|
}
|
|
42055
42221
|
async getPullRequestView(id) {
|
|
42056
|
-
const pullRequest = this.
|
|
42222
|
+
const { pullRequest, revisionSnapshot } = this.database.getPullRequestRevisionSnapshot(id);
|
|
42223
|
+
if (!pullRequest) {
|
|
42224
|
+
throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002", { status: 404 });
|
|
42225
|
+
}
|
|
42057
42226
|
const commits = await this.git.commits(
|
|
42058
42227
|
pullRequest.localRepositoryPath,
|
|
42059
42228
|
pullRequest.latestComparisonBaseOid,
|
|
@@ -42061,11 +42230,30 @@ var RvwService = class {
|
|
|
42061
42230
|
);
|
|
42062
42231
|
return {
|
|
42063
42232
|
pullRequest,
|
|
42233
|
+
pullRequestContentFingerprint: pullRequestContentFingerprint(
|
|
42234
|
+
pullRequest.latestTitle,
|
|
42235
|
+
pullRequest.latestBody
|
|
42236
|
+
),
|
|
42064
42237
|
comparisonBaseOid: pullRequest.latestComparisonBaseOid,
|
|
42065
42238
|
headOid: pullRequest.latestHeadOid,
|
|
42066
|
-
commits
|
|
42239
|
+
commits,
|
|
42240
|
+
...revisionSnapshot
|
|
42067
42241
|
};
|
|
42068
42242
|
}
|
|
42243
|
+
assertPullRequestContentFingerprint(pullRequest, expectedFingerprint) {
|
|
42244
|
+
const actualFingerprint = pullRequestContentFingerprint(
|
|
42245
|
+
pullRequest.latestTitle,
|
|
42246
|
+
pullRequest.latestBody
|
|
42247
|
+
);
|
|
42248
|
+
if (expectedFingerprint !== void 0 && expectedFingerprint !== actualFingerprint) {
|
|
42249
|
+
throw new RvwError("STALE_CONTENT", "Pull Request\u672C\u6587\u304C\u66F4\u65B0\u3055\u308C\u3066\u3044\u307E\u3059\u3002", {
|
|
42250
|
+
status: 409,
|
|
42251
|
+
details: { expectedFingerprint, actualFingerprint },
|
|
42252
|
+
suggestions: ["\u6700\u65B0\u306EPull Request\u672C\u6587\u3092\u518D\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002"]
|
|
42253
|
+
});
|
|
42254
|
+
}
|
|
42255
|
+
return actualFingerprint;
|
|
42256
|
+
}
|
|
42069
42257
|
async assertCommitAvailable(pullRequest, oid) {
|
|
42070
42258
|
if (!GIT_OBJECT_ID_PATTERN.test(oid) || !await this.git.hasObject(pullRequest.localRepositoryPath, oid)) {
|
|
42071
42259
|
throw new RvwError("COMMIT_NOT_FOUND", `Git commit\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: ${oid}`, { status: 404 });
|
|
@@ -42122,6 +42310,26 @@ var RvwService = class {
|
|
|
42122
42310
|
);
|
|
42123
42311
|
return { ref, ...content3 };
|
|
42124
42312
|
}
|
|
42313
|
+
async getDocumentWithContentFingerprint(ref, expectedFingerprint) {
|
|
42314
|
+
if (ref.kind !== "pull-request-markdown") {
|
|
42315
|
+
return { document: await this.getDocument(ref), pullRequestContentFingerprint: null };
|
|
42316
|
+
}
|
|
42317
|
+
const pullRequest = this.getPullRequest(ref.pullRequestId);
|
|
42318
|
+
const fingerprint = this.assertPullRequestContentFingerprint(pullRequest, expectedFingerprint);
|
|
42319
|
+
const text5 = buildPullRequestMarkdown(pullRequest.latestTitle, pullRequest.latestBody);
|
|
42320
|
+
return {
|
|
42321
|
+
document: {
|
|
42322
|
+
ref,
|
|
42323
|
+
availability: "available",
|
|
42324
|
+
text: text5,
|
|
42325
|
+
byteLength: Buffer.byteLength(text5, "utf8"),
|
|
42326
|
+
entryKind: "virtual",
|
|
42327
|
+
normalizedLineEndings: false,
|
|
42328
|
+
oid: null
|
|
42329
|
+
},
|
|
42330
|
+
pullRequestContentFingerprint: fingerprint
|
|
42331
|
+
};
|
|
42332
|
+
}
|
|
42125
42333
|
async getRepositoryAsset(pullRequestId, sourceOid, filePath) {
|
|
42126
42334
|
const pullRequest = this.getPullRequest(pullRequestId);
|
|
42127
42335
|
await this.assertCommitAvailable(pullRequest, sourceOid);
|
|
@@ -42149,7 +42357,7 @@ var RvwService = class {
|
|
|
42149
42357
|
]);
|
|
42150
42358
|
return { ref, old, new: next2 };
|
|
42151
42359
|
}
|
|
42152
|
-
async search(pullRequestId, oid, query, options) {
|
|
42360
|
+
async search(pullRequestId, oid, query, options, expectedPullRequestContentFingerprint) {
|
|
42153
42361
|
const queryBytes = Buffer.byteLength(query, "utf8");
|
|
42154
42362
|
if (queryBytes === 0 || queryBytes > MAX_SEARCH_QUERY_BYTES || query.includes("\n") || query.includes("\r")) {
|
|
42155
42363
|
throw new RvwError(
|
|
@@ -42158,6 +42366,10 @@ var RvwService = class {
|
|
|
42158
42366
|
);
|
|
42159
42367
|
}
|
|
42160
42368
|
const pullRequest = this.getPullRequest(pullRequestId);
|
|
42369
|
+
const contentFingerprint = this.assertPullRequestContentFingerprint(
|
|
42370
|
+
pullRequest,
|
|
42371
|
+
expectedPullRequestContentFingerprint
|
|
42372
|
+
);
|
|
42161
42373
|
await this.assertCommitAvailable(pullRequest, oid);
|
|
42162
42374
|
const prMarkdown = buildPullRequestMarkdown(pullRequest.latestTitle, pullRequest.latestBody);
|
|
42163
42375
|
const results = [];
|
|
@@ -42183,6 +42395,7 @@ var RvwService = class {
|
|
|
42183
42395
|
});
|
|
42184
42396
|
}
|
|
42185
42397
|
return {
|
|
42398
|
+
pullRequestContentFingerprint: contentFingerprint,
|
|
42186
42399
|
results,
|
|
42187
42400
|
matchCount: results.reduce((count, result) => count + result.matches.length, 0),
|
|
42188
42401
|
truncated: gitResult.truncated || results.length >= MAX_SEARCH_RESULTS && (gitResult.results.length > 0 || prMarkdown.split("\n").some((line) => findFixedStringMatches(line, query, options).length > 0)),
|
|
@@ -42509,6 +42722,85 @@ var RvwService = class {
|
|
|
42509
42722
|
this.getPullRequest(pullRequestId);
|
|
42510
42723
|
return this.database.listStructures(pullRequestId);
|
|
42511
42724
|
}
|
|
42725
|
+
async listFileStructureReferences(pullRequestId, targetSourceOid, targetPath) {
|
|
42726
|
+
assertCodeReferencePath(targetPath);
|
|
42727
|
+
const index2 = await this.listFileStructureReferenceIndex(pullRequestId, targetSourceOid);
|
|
42728
|
+
return index2.entries.find(({ path: candidate }) => candidate === targetPath)?.references ?? [];
|
|
42729
|
+
}
|
|
42730
|
+
async listFileStructureReferenceIndex(pullRequestId, targetSourceOid) {
|
|
42731
|
+
const pullRequest = this.getPullRequest(pullRequestId);
|
|
42732
|
+
const structures = this.database.listStructures(pullRequestId).flatMap((summary) => {
|
|
42733
|
+
const structure = this.database.getStructure(summary.id);
|
|
42734
|
+
return structure?.pullRequestId === pullRequestId ? [structure] : [];
|
|
42735
|
+
});
|
|
42736
|
+
if (structures.length === 0) return { sourceOid: targetSourceOid, entries: [] };
|
|
42737
|
+
await this.assertCommitAvailable(pullRequest, targetSourceOid);
|
|
42738
|
+
const treePaths = (await this.git.tree(pullRequest.localRepositoryPath, targetSourceOid)).map(
|
|
42739
|
+
(entry) => entry.path
|
|
42740
|
+
);
|
|
42741
|
+
const targetPaths = new Set(treePaths);
|
|
42742
|
+
const successorIndexes = /* @__PURE__ */ new Map();
|
|
42743
|
+
const successorIndex = (sourceOid) => {
|
|
42744
|
+
const key2 = JSON.stringify([sourceOid, targetSourceOid]);
|
|
42745
|
+
const cached2 = successorIndexes.get(key2);
|
|
42746
|
+
if (cached2) return cached2;
|
|
42747
|
+
const index2 = this.git.changedFilesWithCopies(pullRequest.localRepositoryPath, sourceOid, targetSourceOid).then((changes) => {
|
|
42748
|
+
const successors = /* @__PURE__ */ new Map();
|
|
42749
|
+
for (const candidate of changes) {
|
|
42750
|
+
if (!candidate.status.startsWith("R") && !candidate.status.startsWith("C") || candidate.oldPath === null || candidate.newPath === null) {
|
|
42751
|
+
continue;
|
|
42752
|
+
}
|
|
42753
|
+
const paths = successors.get(candidate.oldPath) ?? /* @__PURE__ */ new Set();
|
|
42754
|
+
paths.add(candidate.newPath);
|
|
42755
|
+
successors.set(candidate.oldPath, paths);
|
|
42756
|
+
}
|
|
42757
|
+
return successors;
|
|
42758
|
+
});
|
|
42759
|
+
successorIndexes.set(key2, index2);
|
|
42760
|
+
return index2;
|
|
42761
|
+
};
|
|
42762
|
+
const resolvePath = (sourceOid, sourcePath) => {
|
|
42763
|
+
if (targetPaths.has(sourcePath)) return Promise.resolve(sourcePath);
|
|
42764
|
+
if (sourceOid === targetSourceOid) return Promise.resolve(null);
|
|
42765
|
+
return successorIndex(sourceOid).then((index2) => {
|
|
42766
|
+
const successors = index2.get(sourcePath);
|
|
42767
|
+
if (successors?.size !== 1) return null;
|
|
42768
|
+
const successor = [...successors][0];
|
|
42769
|
+
return targetPaths.has(successor) ? successor : null;
|
|
42770
|
+
});
|
|
42771
|
+
};
|
|
42772
|
+
const referencesByPath = /* @__PURE__ */ new Map();
|
|
42773
|
+
for (const structure of structures) {
|
|
42774
|
+
const matchingNodeIdsByPath = /* @__PURE__ */ new Map();
|
|
42775
|
+
for (const node2 of structure.nodes) {
|
|
42776
|
+
if (!node2.anchor) continue;
|
|
42777
|
+
const resolvedPath = await resolvePath(structure.sourceOid, node2.anchor.path);
|
|
42778
|
+
if (!resolvedPath) continue;
|
|
42779
|
+
const nodeIds = matchingNodeIdsByPath.get(resolvedPath) ?? /* @__PURE__ */ new Set();
|
|
42780
|
+
nodeIds.add(node2.id);
|
|
42781
|
+
matchingNodeIdsByPath.set(resolvedPath, nodeIds);
|
|
42782
|
+
}
|
|
42783
|
+
for (const [resolvedPath, matchingNodeIds] of matchingNodeIdsByPath) {
|
|
42784
|
+
const targetNode = closestMatchingStructureNode(structure, matchingNodeIds);
|
|
42785
|
+
if (!targetNode) continue;
|
|
42786
|
+
const references = referencesByPath.get(resolvedPath) ?? [];
|
|
42787
|
+
references.push({
|
|
42788
|
+
structure: structureSummary(structure),
|
|
42789
|
+
targetNodeId: targetNode.id,
|
|
42790
|
+
targetNodeLabel: targetNode.label,
|
|
42791
|
+
matchingNodeCount: matchingNodeIds.size
|
|
42792
|
+
});
|
|
42793
|
+
referencesByPath.set(resolvedPath, references);
|
|
42794
|
+
}
|
|
42795
|
+
}
|
|
42796
|
+
return {
|
|
42797
|
+
sourceOid: targetSourceOid,
|
|
42798
|
+
entries: treePaths.flatMap((path11) => {
|
|
42799
|
+
const references = referencesByPath.get(path11);
|
|
42800
|
+
return references ? [{ path: path11, references }] : [];
|
|
42801
|
+
})
|
|
42802
|
+
};
|
|
42803
|
+
}
|
|
42512
42804
|
listStructuresByReference(reference) {
|
|
42513
42805
|
const pullRequest = this.resolveStoredPullRequest(reference);
|
|
42514
42806
|
return { pullRequest, structures: this.database.listStructures(pullRequest.id) };
|
|
@@ -42867,38 +43159,15 @@ var RvwService = class {
|
|
|
42867
43159
|
path: reference.path
|
|
42868
43160
|
});
|
|
42869
43161
|
const latestHeadOid = pullRequest.latestHeadOid;
|
|
42870
|
-
|
|
42871
|
-
|
|
42872
|
-
|
|
42873
|
-
|
|
42874
|
-
|
|
42875
|
-
|
|
42876
|
-
|
|
42877
|
-
|
|
42878
|
-
|
|
42879
|
-
path: reference.path
|
|
42880
|
-
});
|
|
42881
|
-
if (latestDocument.availability === "missing") {
|
|
42882
|
-
const successorPaths = [
|
|
42883
|
-
...new Set(
|
|
42884
|
-
(await this.git.changedFilesWithCopies(
|
|
42885
|
-
pullRequest.localRepositoryPath,
|
|
42886
|
-
sourceOid,
|
|
42887
|
-
latestHeadOid
|
|
42888
|
-
)).filter(
|
|
42889
|
-
(candidate) => (candidate.status.startsWith("R") || candidate.status.startsWith("C")) && candidate.oldPath === reference.path && candidate.newPath !== null
|
|
42890
|
-
).map((candidate) => candidate.newPath)
|
|
42891
|
-
)
|
|
42892
|
-
];
|
|
42893
|
-
latestPath = successorPaths.length === 1 ? successorPaths[0] : null;
|
|
42894
|
-
latestDocument = latestPath === null ? null : await this.getDocument({
|
|
42895
|
-
kind: "repository-file",
|
|
42896
|
-
pullRequestId: pullRequest.id,
|
|
42897
|
-
sourceOid: latestHeadOid,
|
|
42898
|
-
path: latestPath
|
|
42899
|
-
});
|
|
42900
|
-
}
|
|
42901
|
-
}
|
|
43162
|
+
const resolvedLatestFile = await this.resolveSourceFileAtCommit(
|
|
43163
|
+
pullRequest,
|
|
43164
|
+
sourceOid,
|
|
43165
|
+
reference.path,
|
|
43166
|
+
latestHeadOid,
|
|
43167
|
+
sourceDocument
|
|
43168
|
+
);
|
|
43169
|
+
const latestPath = resolvedLatestFile?.path ?? null;
|
|
43170
|
+
const latestDocument = resolvedLatestFile?.document ?? null;
|
|
42902
43171
|
const latestFileExists = latestDocument !== null && latestDocument.availability !== "missing";
|
|
42903
43172
|
const latestFileDisplayable = latestDocument?.availability === "available";
|
|
42904
43173
|
const mappedRange = reference.startLine === null || reference.endLine === null ? latestFileDisplayable ? null : void 0 : sourceDocument.availability === "available" && latestDocument?.availability === "available" ? mapUnchangedLineRange(
|
|
@@ -42955,6 +43224,38 @@ var RvwService = class {
|
|
|
42955
43224
|
document: sourceDocument
|
|
42956
43225
|
};
|
|
42957
43226
|
}
|
|
43227
|
+
async resolveSourceFileAtCommit(pullRequest, sourceOid, sourcePath, targetSourceOid, sourceDocument) {
|
|
43228
|
+
const directDocument = sourceOid === targetSourceOid ? sourceDocument : await this.getDocument({
|
|
43229
|
+
kind: "repository-file",
|
|
43230
|
+
pullRequestId: pullRequest.id,
|
|
43231
|
+
sourceOid: targetSourceOid,
|
|
43232
|
+
path: sourcePath
|
|
43233
|
+
});
|
|
43234
|
+
if (directDocument.availability !== "missing") {
|
|
43235
|
+
return { path: sourcePath, document: directDocument };
|
|
43236
|
+
}
|
|
43237
|
+
if (sourceOid === targetSourceOid) return null;
|
|
43238
|
+
const successorPaths = [
|
|
43239
|
+
...new Set(
|
|
43240
|
+
(await this.git.changedFilesWithCopies(
|
|
43241
|
+
pullRequest.localRepositoryPath,
|
|
43242
|
+
sourceOid,
|
|
43243
|
+
targetSourceOid
|
|
43244
|
+
)).filter(
|
|
43245
|
+
(candidate) => (candidate.status.startsWith("R") || candidate.status.startsWith("C")) && candidate.oldPath === sourcePath && candidate.newPath !== null
|
|
43246
|
+
).map((candidate) => candidate.newPath)
|
|
43247
|
+
)
|
|
43248
|
+
];
|
|
43249
|
+
if (successorPaths.length !== 1) return null;
|
|
43250
|
+
const successorPath = successorPaths[0];
|
|
43251
|
+
const successorDocument = await this.getDocument({
|
|
43252
|
+
kind: "repository-file",
|
|
43253
|
+
pullRequestId: pullRequest.id,
|
|
43254
|
+
sourceOid: targetSourceOid,
|
|
43255
|
+
path: successorPath
|
|
43256
|
+
});
|
|
43257
|
+
return successorDocument.availability === "missing" ? null : { path: successorPath, document: successorDocument };
|
|
43258
|
+
}
|
|
42958
43259
|
getWalkthroughByUri(uri) {
|
|
42959
43260
|
const walkthrough = this.database.getWalkthrough(parseWalkthroughUri(uri));
|
|
42960
43261
|
if (!walkthrough) {
|
|
@@ -43204,40 +43505,54 @@ var RvwService = class {
|
|
|
43204
43505
|
}
|
|
43205
43506
|
return { ...placeMutableDocumentComment(comment3.target, walkthrough.body), path: null };
|
|
43206
43507
|
}
|
|
43207
|
-
async resolveRepositoryCommentPath(pullRequest, source, destinationOid) {
|
|
43508
|
+
async resolveRepositoryCommentPath(pullRequest, source, destinationOid, context) {
|
|
43208
43509
|
if (source.sourceOid === destinationOid) {
|
|
43209
43510
|
return { path: source.path, deleted: false };
|
|
43210
43511
|
}
|
|
43211
|
-
const
|
|
43212
|
-
|
|
43213
|
-
|
|
43214
|
-
|
|
43215
|
-
|
|
43512
|
+
const key2 = JSON.stringify([source.sourceOid, destinationOid]);
|
|
43513
|
+
let changesPromise = context.changedFiles.get(key2);
|
|
43514
|
+
if (!changesPromise) {
|
|
43515
|
+
changesPromise = this.git.changedFiles(
|
|
43516
|
+
pullRequest.localRepositoryPath,
|
|
43517
|
+
source.sourceOid,
|
|
43518
|
+
destinationOid
|
|
43519
|
+
);
|
|
43520
|
+
context.changedFiles.set(key2, changesPromise);
|
|
43521
|
+
}
|
|
43522
|
+
const changes = await changesPromise;
|
|
43216
43523
|
const change = changes.find((candidate) => candidate.oldPath === source.path);
|
|
43217
43524
|
if (change?.kind === "deleted" || change && change.newPath === null) {
|
|
43218
43525
|
return { path: source.path, deleted: true };
|
|
43219
43526
|
}
|
|
43220
43527
|
return { path: change?.newPath ?? source.path, deleted: false };
|
|
43221
43528
|
}
|
|
43222
|
-
async placeRepositoryCommentAtPath(pullRequest, source, destinationOid, destinationPath) {
|
|
43223
|
-
const destinationContent = await this.
|
|
43224
|
-
|
|
43225
|
-
|
|
43226
|
-
|
|
43227
|
-
|
|
43228
|
-
|
|
43529
|
+
async placeRepositoryCommentAtPath(pullRequest, source, destinationOid, destinationPath, context) {
|
|
43530
|
+
const destinationContent = await this.getPlacementDocument(
|
|
43531
|
+
pullRequest,
|
|
43532
|
+
{
|
|
43533
|
+
kind: "repository-file",
|
|
43534
|
+
pullRequestId: pullRequest.id,
|
|
43535
|
+
sourceOid: destinationOid,
|
|
43536
|
+
path: destinationPath
|
|
43537
|
+
},
|
|
43538
|
+
context
|
|
43539
|
+
);
|
|
43229
43540
|
if (source.startLine === null || source.endLine === null) {
|
|
43230
43541
|
return destinationContent.availability === "missing" ? { outdated: true, range: null, path: destinationPath } : { outdated: false, range: null, path: destinationPath };
|
|
43231
43542
|
}
|
|
43232
43543
|
if (destinationContent.availability !== "available") {
|
|
43233
43544
|
return { outdated: true, range: null, path: destinationPath };
|
|
43234
43545
|
}
|
|
43235
|
-
const sourceContent = await this.
|
|
43236
|
-
|
|
43237
|
-
|
|
43238
|
-
|
|
43239
|
-
|
|
43240
|
-
|
|
43546
|
+
const sourceContent = await this.getPlacementDocument(
|
|
43547
|
+
pullRequest,
|
|
43548
|
+
{
|
|
43549
|
+
kind: "repository-file",
|
|
43550
|
+
pullRequestId: pullRequest.id,
|
|
43551
|
+
sourceOid: source.sourceOid,
|
|
43552
|
+
path: source.path
|
|
43553
|
+
},
|
|
43554
|
+
context
|
|
43555
|
+
);
|
|
43241
43556
|
if (sourceContent.availability !== "available") {
|
|
43242
43557
|
return { outdated: true, range: null, path: destinationPath };
|
|
43243
43558
|
}
|
|
@@ -43250,55 +43565,171 @@ var RvwService = class {
|
|
|
43250
43565
|
return range ? { outdated: false, range, path: destinationPath } : { outdated: true, range: null, path: destinationPath };
|
|
43251
43566
|
}
|
|
43252
43567
|
async placeComment(comment3, destination) {
|
|
43253
|
-
|
|
43568
|
+
const pullRequest = this.getPullRequest(comment3.pullRequestId);
|
|
43569
|
+
return await this.placeCommentForDestination(
|
|
43570
|
+
comment3,
|
|
43571
|
+
pullRequest,
|
|
43572
|
+
{ kind: "document", ref: destination },
|
|
43573
|
+
this.createCommentPlacementRequestContext()
|
|
43574
|
+
);
|
|
43575
|
+
}
|
|
43576
|
+
createCommentPlacementRequestContext() {
|
|
43577
|
+
return {
|
|
43578
|
+
commitAvailability: /* @__PURE__ */ new Map(),
|
|
43579
|
+
changedFiles: /* @__PURE__ */ new Map(),
|
|
43580
|
+
documents: /* @__PURE__ */ new Map()
|
|
43581
|
+
};
|
|
43582
|
+
}
|
|
43583
|
+
async assertPlacementCommitAvailable(pullRequest, oid, context) {
|
|
43584
|
+
let available = context.commitAvailability.get(oid);
|
|
43585
|
+
if (!available) {
|
|
43586
|
+
available = this.assertCommitAvailable(pullRequest, oid);
|
|
43587
|
+
context.commitAvailability.set(oid, available);
|
|
43588
|
+
}
|
|
43589
|
+
await available;
|
|
43590
|
+
}
|
|
43591
|
+
async getPlacementDocument(pullRequest, ref, context) {
|
|
43592
|
+
const key2 = JSON.stringify(ref);
|
|
43593
|
+
let document3 = context.documents.get(key2);
|
|
43594
|
+
if (!document3) {
|
|
43595
|
+
document3 = (async () => {
|
|
43596
|
+
if (ref.kind === "pull-request-markdown") {
|
|
43597
|
+
const text5 = buildPullRequestMarkdown(pullRequest.latestTitle, pullRequest.latestBody);
|
|
43598
|
+
return {
|
|
43599
|
+
ref,
|
|
43600
|
+
availability: "available",
|
|
43601
|
+
text: text5,
|
|
43602
|
+
byteLength: Buffer.byteLength(text5, "utf8"),
|
|
43603
|
+
entryKind: "virtual",
|
|
43604
|
+
normalizedLineEndings: false,
|
|
43605
|
+
oid: null
|
|
43606
|
+
};
|
|
43607
|
+
}
|
|
43608
|
+
await this.assertPlacementCommitAvailable(pullRequest, ref.sourceOid, context);
|
|
43609
|
+
const content3 = await this.git.readDocument(
|
|
43610
|
+
pullRequest.localRepositoryPath,
|
|
43611
|
+
ref.sourceOid,
|
|
43612
|
+
ref.path
|
|
43613
|
+
);
|
|
43614
|
+
return { ref, ...content3 };
|
|
43615
|
+
})();
|
|
43616
|
+
context.documents.set(key2, document3);
|
|
43617
|
+
}
|
|
43618
|
+
return await document3;
|
|
43619
|
+
}
|
|
43620
|
+
async placeCommentForDestination(comment3, pullRequest, destination, context) {
|
|
43621
|
+
if (destination.kind === "walkthrough") {
|
|
43622
|
+
return this.placeWalkthroughComment(comment3, destination.walkthroughId);
|
|
43623
|
+
}
|
|
43624
|
+
if (destination.kind === "commit") {
|
|
43625
|
+
await this.assertPlacementCommitAvailable(pullRequest, destination.oid, context);
|
|
43626
|
+
}
|
|
43627
|
+
const documentDestination = destination.kind === "document" ? destination.ref : null;
|
|
43628
|
+
const destinationOid = destination.kind === "commit" ? destination.oid : documentDestination?.kind === "repository-file" ? documentDestination.sourceOid : null;
|
|
43629
|
+
if (documentDestination !== null && comment3.pullRequestId !== documentDestination.pullRequestId) {
|
|
43254
43630
|
return { outdated: true, range: null, path: null };
|
|
43255
43631
|
}
|
|
43256
43632
|
if (comment3.target.kind === "pull-request") return { outdated: false, range: null, path: null };
|
|
43257
43633
|
if (comment3.target.kind === "walkthrough") {
|
|
43258
43634
|
return this.placeWalkthroughComment(comment3);
|
|
43259
43635
|
}
|
|
43260
|
-
const pullRequest = this.getPullRequest(comment3.pullRequestId);
|
|
43261
43636
|
if (comment3.target.documentKind === "pull-request-markdown") {
|
|
43262
|
-
return destination.kind === "pull-request-markdown" ? this.placePullRequestMarkdownComment(comment3, pullRequest) : { outdated: true, range: null, path: null };
|
|
43637
|
+
return destination.kind === "commit" || documentDestination?.kind === "pull-request-markdown" ? this.placePullRequestMarkdownComment(comment3, pullRequest) : { outdated: true, range: null, path: null };
|
|
43263
43638
|
}
|
|
43264
|
-
if (
|
|
43639
|
+
if (destinationOid === null) return { outdated: true, range: null, path: null };
|
|
43265
43640
|
const source = comment3.target;
|
|
43641
|
+
await this.assertPlacementCommitAvailable(pullRequest, source.sourceOid, context);
|
|
43266
43642
|
const resolved = await this.resolveRepositoryCommentPath(
|
|
43267
43643
|
pullRequest,
|
|
43268
43644
|
source,
|
|
43269
|
-
|
|
43645
|
+
destinationOid,
|
|
43646
|
+
context
|
|
43270
43647
|
);
|
|
43271
43648
|
if (resolved.deleted) return { outdated: true, range: null, path: source.path };
|
|
43272
|
-
if (resolved.path !==
|
|
43649
|
+
if (documentDestination?.kind === "repository-file" && resolved.path !== documentDestination.path) {
|
|
43273
43650
|
return { outdated: true, range: null, path: resolved.path };
|
|
43274
43651
|
}
|
|
43275
43652
|
return await this.placeRepositoryCommentAtPath(
|
|
43276
43653
|
pullRequest,
|
|
43277
43654
|
source,
|
|
43278
|
-
|
|
43279
|
-
resolved.path
|
|
43655
|
+
destinationOid,
|
|
43656
|
+
resolved.path,
|
|
43657
|
+
context
|
|
43280
43658
|
);
|
|
43281
43659
|
}
|
|
43282
43660
|
async placeCommentAtCommit(comment3, destinationOid) {
|
|
43283
43661
|
const pullRequest = this.getPullRequest(comment3.pullRequestId);
|
|
43284
|
-
await this.
|
|
43285
|
-
|
|
43286
|
-
if (comment3.target.kind === "walkthrough") {
|
|
43287
|
-
return this.placeWalkthroughComment(comment3);
|
|
43288
|
-
}
|
|
43289
|
-
if (comment3.target.documentKind === "pull-request-markdown") {
|
|
43290
|
-
return this.placePullRequestMarkdownComment(comment3, pullRequest);
|
|
43291
|
-
}
|
|
43292
|
-
const source = comment3.target;
|
|
43293
|
-
const resolved = await this.resolveRepositoryCommentPath(pullRequest, source, destinationOid);
|
|
43294
|
-
if (resolved.deleted) return { outdated: true, range: null, path: source.path };
|
|
43295
|
-
return await this.placeRepositoryCommentAtPath(
|
|
43662
|
+
return await this.placeCommentForDestination(
|
|
43663
|
+
comment3,
|
|
43296
43664
|
pullRequest,
|
|
43297
|
-
|
|
43298
|
-
|
|
43299
|
-
resolved.path
|
|
43665
|
+
{ kind: "commit", oid: destinationOid },
|
|
43666
|
+
this.createCommentPlacementRequestContext()
|
|
43300
43667
|
);
|
|
43301
43668
|
}
|
|
43669
|
+
async resolveCommentPlacements(pullRequestId, commentIds, destinations, expectedPullRequestContentFingerprint) {
|
|
43670
|
+
const pullRequest = this.getPullRequest(pullRequestId);
|
|
43671
|
+
const contentFingerprint = this.assertPullRequestContentFingerprint(
|
|
43672
|
+
pullRequest,
|
|
43673
|
+
expectedPullRequestContentFingerprint
|
|
43674
|
+
);
|
|
43675
|
+
const uniqueCommentIds = [...new Set(commentIds)];
|
|
43676
|
+
const comments = [];
|
|
43677
|
+
const missingCommentIds = [];
|
|
43678
|
+
for (const commentId of uniqueCommentIds) {
|
|
43679
|
+
const comment3 = this.database.getComment(commentId);
|
|
43680
|
+
if (!comment3) {
|
|
43681
|
+
missingCommentIds.push(commentId);
|
|
43682
|
+
continue;
|
|
43683
|
+
}
|
|
43684
|
+
if (comment3.pullRequestId !== pullRequestId) {
|
|
43685
|
+
throw new RvwError(
|
|
43686
|
+
"INVALID_INPUT",
|
|
43687
|
+
`\u5225\u306EPull Request\u306E\u30B3\u30E1\u30F3\u30C8\u306F\u4E00\u62EC\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093: ${commentId}`
|
|
43688
|
+
);
|
|
43689
|
+
}
|
|
43690
|
+
comments.push(comment3);
|
|
43691
|
+
}
|
|
43692
|
+
const context = this.createCommentPlacementRequestContext();
|
|
43693
|
+
if (comments.length > 0) {
|
|
43694
|
+
for (const destination of destinations) {
|
|
43695
|
+
if (destination.kind === "commit") {
|
|
43696
|
+
await this.assertPlacementCommitAvailable(pullRequest, destination.oid, context);
|
|
43697
|
+
} else if (destination.kind === "document" && destination.ref.kind === "repository-file") {
|
|
43698
|
+
await this.assertPlacementCommitAvailable(
|
|
43699
|
+
pullRequest,
|
|
43700
|
+
destination.ref.sourceOid,
|
|
43701
|
+
context
|
|
43702
|
+
);
|
|
43703
|
+
}
|
|
43704
|
+
}
|
|
43705
|
+
}
|
|
43706
|
+
return {
|
|
43707
|
+
pullRequestContentFingerprint: contentFingerprint,
|
|
43708
|
+
comments: await mapWithConcurrency(comments, 4, async (comment3) => {
|
|
43709
|
+
const placements = [];
|
|
43710
|
+
const failures = [];
|
|
43711
|
+
for (const destination of destinations) {
|
|
43712
|
+
try {
|
|
43713
|
+
placements.push({
|
|
43714
|
+
destination,
|
|
43715
|
+
placement: await this.placeCommentForDestination(
|
|
43716
|
+
comment3,
|
|
43717
|
+
pullRequest,
|
|
43718
|
+
destination,
|
|
43719
|
+
context
|
|
43720
|
+
)
|
|
43721
|
+
});
|
|
43722
|
+
} catch (error51) {
|
|
43723
|
+
const placementError = asRvwError(error51);
|
|
43724
|
+
if (placementError.code !== "COMMIT_NOT_FOUND") throw error51;
|
|
43725
|
+
failures.push({ destination, error: placementError.toJSON() });
|
|
43726
|
+
}
|
|
43727
|
+
}
|
|
43728
|
+
return { commentId: comment3.id, placements, failures };
|
|
43729
|
+
}),
|
|
43730
|
+
missingCommentIds
|
|
43731
|
+
};
|
|
43732
|
+
}
|
|
43302
43733
|
async getResetPreview(pullRequestId) {
|
|
43303
43734
|
const pullRequest = this.getPullRequest(pullRequestId);
|
|
43304
43735
|
const refs = await this.git.listRefsByPrefix(
|
|
@@ -47596,9 +48027,30 @@ var editCommentPostSchema = external_exports.object({
|
|
|
47596
48027
|
body: external_exports.string().min(1).refine((value) => Buffer.byteLength(value, "utf8") <= MAX_COMMENT_BODY_BYTES),
|
|
47597
48028
|
references: external_exports.array(codeReferenceInputSchema).optional()
|
|
47598
48029
|
});
|
|
48030
|
+
var placementDocumentRefSchema = external_exports.discriminatedUnion("kind", [
|
|
48031
|
+
external_exports.object({ kind: external_exports.literal("pull-request-markdown"), pullRequestId: external_exports.uuid() }),
|
|
48032
|
+
external_exports.object({
|
|
48033
|
+
kind: external_exports.literal("repository-file"),
|
|
48034
|
+
pullRequestId: external_exports.uuid(),
|
|
48035
|
+
sourceOid: external_exports.string().regex(GIT_OBJECT_ID_PATTERN),
|
|
48036
|
+
path: external_exports.string().min(1)
|
|
48037
|
+
})
|
|
48038
|
+
]);
|
|
48039
|
+
var resolveCommentPlacementsSchema = external_exports.object({
|
|
48040
|
+
commentIds: external_exports.array(external_exports.uuid()),
|
|
48041
|
+
expectedPullRequestContentFingerprint: external_exports.string().regex(CONTENT_FINGERPRINT_PATTERN).optional(),
|
|
48042
|
+
destinations: external_exports.array(
|
|
48043
|
+
external_exports.union([
|
|
48044
|
+
external_exports.object({ kind: external_exports.literal("document"), ref: placementDocumentRefSchema }),
|
|
48045
|
+
external_exports.object({ kind: external_exports.literal("commit"), oid: external_exports.string().regex(GIT_OBJECT_ID_PATTERN) }),
|
|
48046
|
+
external_exports.object({ kind: external_exports.literal("walkthrough"), walkthroughId: external_exports.uuid() })
|
|
48047
|
+
])
|
|
48048
|
+
).min(1).max(4)
|
|
48049
|
+
});
|
|
47599
48050
|
|
|
47600
48051
|
// src/server/app.ts
|
|
47601
48052
|
var oidSchema = external_exports.string().regex(GIT_OBJECT_ID_PATTERN);
|
|
48053
|
+
var contentFingerprintSchema = external_exports.string().regex(CONTENT_FINGERPRINT_PATTERN);
|
|
47602
48054
|
var nonnegativeIndexSchema = external_exports.coerce.number().int().nonnegative();
|
|
47603
48055
|
var svgAssetContentSecurityPolicy = "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; sandbox";
|
|
47604
48056
|
function requiredQuery(value, name) {
|
|
@@ -47608,6 +48060,9 @@ function requiredQuery(value, name) {
|
|
|
47608
48060
|
function oidQuery(value, name) {
|
|
47609
48061
|
return oidSchema.parse(requiredQuery(value, name));
|
|
47610
48062
|
}
|
|
48063
|
+
function optionalContentFingerprint(value) {
|
|
48064
|
+
return value === void 0 ? void 0 : contentFingerprintSchema.parse(value);
|
|
48065
|
+
}
|
|
47611
48066
|
function structureSourceLocator(query) {
|
|
47612
48067
|
if (query.locatorKind === "node") {
|
|
47613
48068
|
return { kind: "node", nodeId: requiredQuery(query.nodeId, "nodeId") };
|
|
@@ -47717,7 +48172,7 @@ function createApp(service, options) {
|
|
|
47717
48172
|
rawViewerLease === void 0 ? void 0 : viewerIdSchema.parse(rawViewerLease)
|
|
47718
48173
|
);
|
|
47719
48174
|
}
|
|
47720
|
-
return context.json({ ok: true,
|
|
48175
|
+
return context.json({ ok: true, ...service.database.getRevisionSnapshot() });
|
|
47721
48176
|
});
|
|
47722
48177
|
app.post("/api/meta/viewers/release", async (context) => {
|
|
47723
48178
|
const input = viewerReleaseSchema.parse(await context.req.json());
|
|
@@ -47758,10 +48213,10 @@ function createApp(service, options) {
|
|
|
47758
48213
|
...await service.openPullRequest(input.reference, input.cwd)
|
|
47759
48214
|
});
|
|
47760
48215
|
});
|
|
47761
|
-
app.post(
|
|
47762
|
-
"
|
|
47763
|
-
|
|
47764
|
-
);
|
|
48216
|
+
app.post("/api/pull-requests/:id/refresh", async (context) => {
|
|
48217
|
+
const result = await service.refreshPullRequest(context.req.param("id"));
|
|
48218
|
+
return context.json({ ok: true, ...result });
|
|
48219
|
+
});
|
|
47765
48220
|
app.post("/api/pull-requests/:id/reset", async (context) => {
|
|
47766
48221
|
const input = resetSchema.parse(await context.req.json());
|
|
47767
48222
|
if (!input.yes) {
|
|
@@ -47799,7 +48254,13 @@ function createApp(service, options) {
|
|
|
47799
48254
|
});
|
|
47800
48255
|
app.get("/api/pull-requests/:id/document", async (context) => {
|
|
47801
48256
|
const ref = documentRefFromQuery(context.req.param("id"), context.req.query());
|
|
47802
|
-
return context.json({
|
|
48257
|
+
return context.json({
|
|
48258
|
+
ok: true,
|
|
48259
|
+
...await service.getDocumentWithContentFingerprint(
|
|
48260
|
+
ref,
|
|
48261
|
+
optionalContentFingerprint(context.req.query("expectedPullRequestContentFingerprint"))
|
|
48262
|
+
)
|
|
48263
|
+
});
|
|
47803
48264
|
});
|
|
47804
48265
|
app.on(["GET", "HEAD"], "/api/pull-requests/:id/markdown-asset", async (context) => {
|
|
47805
48266
|
const sourceOid = oidQuery(context.req.query("sourceOid"), "sourceOid");
|
|
@@ -47858,10 +48319,16 @@ function createApp(service, options) {
|
|
|
47858
48319
|
const wholeWord = parseBooleanQuery(context.req.query("wholeWord"), "wholeWord");
|
|
47859
48320
|
return context.json({
|
|
47860
48321
|
ok: true,
|
|
47861
|
-
...await service.search(
|
|
47862
|
-
|
|
47863
|
-
|
|
47864
|
-
|
|
48322
|
+
...await service.search(
|
|
48323
|
+
context.req.param("id"),
|
|
48324
|
+
oid,
|
|
48325
|
+
query,
|
|
48326
|
+
{
|
|
48327
|
+
matchCase,
|
|
48328
|
+
wholeWord
|
|
48329
|
+
},
|
|
48330
|
+
optionalContentFingerprint(context.req.query("expectedPullRequestContentFingerprint"))
|
|
48331
|
+
)
|
|
47865
48332
|
});
|
|
47866
48333
|
});
|
|
47867
48334
|
app.get("/api/pull-requests/:id/comments", (context) => {
|
|
@@ -47916,6 +48383,25 @@ function createApp(service, options) {
|
|
|
47916
48383
|
structures: service.listStructures(context.req.param("id"))
|
|
47917
48384
|
})
|
|
47918
48385
|
);
|
|
48386
|
+
app.get("/api/pull-requests/:id/structure-references", async (context) => {
|
|
48387
|
+
const sourceOid = oidQuery(context.req.query("sourceOid"), "sourceOid");
|
|
48388
|
+
const filePath = requiredQuery(context.req.query("path"), "path");
|
|
48389
|
+
return context.json({
|
|
48390
|
+
ok: true,
|
|
48391
|
+
references: await service.listFileStructureReferences(
|
|
48392
|
+
context.req.param("id"),
|
|
48393
|
+
sourceOid,
|
|
48394
|
+
filePath
|
|
48395
|
+
)
|
|
48396
|
+
});
|
|
48397
|
+
});
|
|
48398
|
+
app.get("/api/pull-requests/:id/structure-reference-index", async (context) => {
|
|
48399
|
+
const sourceOid = oidQuery(context.req.query("sourceOid"), "sourceOid");
|
|
48400
|
+
return context.json({
|
|
48401
|
+
ok: true,
|
|
48402
|
+
index: await service.listFileStructureReferenceIndex(context.req.param("id"), sourceOid)
|
|
48403
|
+
});
|
|
48404
|
+
});
|
|
47919
48405
|
app.get(
|
|
47920
48406
|
"/api/pull-requests/:id/structures/:structureId",
|
|
47921
48407
|
(context) => context.json({
|
|
@@ -47969,43 +48455,51 @@ function createApp(service, options) {
|
|
|
47969
48455
|
});
|
|
47970
48456
|
app.post("/api/comments/:id/posts", async (context) => {
|
|
47971
48457
|
const input = replySchema.parse(await context.req.json());
|
|
48458
|
+
const commentId = context.req.param("id");
|
|
48459
|
+
const post = await service.replyToComment(commentId, {
|
|
48460
|
+
body: input.body,
|
|
48461
|
+
...input.relatedCommitOid === void 0 ? {} : { relatedCommitOid: input.relatedCommitOid },
|
|
48462
|
+
...input.authorLabel === void 0 ? {} : { authorLabel: input.authorLabel },
|
|
48463
|
+
lastModifiedBy: "human",
|
|
48464
|
+
...input.references === void 0 ? {} : { references: input.references }
|
|
48465
|
+
});
|
|
47972
48466
|
return context.json(
|
|
47973
48467
|
{
|
|
47974
48468
|
ok: true,
|
|
47975
|
-
post
|
|
47976
|
-
|
|
47977
|
-
...input.relatedCommitOid === void 0 ? {} : { relatedCommitOid: input.relatedCommitOid },
|
|
47978
|
-
...input.authorLabel === void 0 ? {} : { authorLabel: input.authorLabel },
|
|
47979
|
-
lastModifiedBy: "human",
|
|
47980
|
-
...input.references === void 0 ? {} : { references: input.references }
|
|
47981
|
-
})
|
|
48469
|
+
post,
|
|
48470
|
+
comment: service.database.getComment(commentId)
|
|
47982
48471
|
},
|
|
47983
48472
|
201
|
|
47984
48473
|
);
|
|
47985
48474
|
});
|
|
47986
48475
|
app.patch("/api/comments/:id/posts/:postId", async (context) => {
|
|
47987
48476
|
const input = editCommentPostSchema.parse(await context.req.json());
|
|
48477
|
+
const commentId = context.req.param("id");
|
|
48478
|
+
const post = input.references === void 0 ? await service.updateCommentPost(
|
|
48479
|
+
commentId,
|
|
48480
|
+
context.req.param("postId"),
|
|
48481
|
+
input.body,
|
|
48482
|
+
"human"
|
|
48483
|
+
) : await service.editCommentPost(commentId, context.req.param("postId"), {
|
|
48484
|
+
body: input.body,
|
|
48485
|
+
references: input.references,
|
|
48486
|
+
lastModifiedBy: "human"
|
|
48487
|
+
});
|
|
47988
48488
|
return context.json({
|
|
47989
48489
|
ok: true,
|
|
47990
|
-
post
|
|
47991
|
-
|
|
47992
|
-
context.req.param("postId"),
|
|
47993
|
-
input.body,
|
|
47994
|
-
"human"
|
|
47995
|
-
) : await service.editCommentPost(context.req.param("id"), context.req.param("postId"), {
|
|
47996
|
-
body: input.body,
|
|
47997
|
-
references: input.references,
|
|
47998
|
-
lastModifiedBy: "human"
|
|
47999
|
-
})
|
|
48490
|
+
post,
|
|
48491
|
+
comment: service.database.getComment(commentId)
|
|
48000
48492
|
});
|
|
48001
48493
|
});
|
|
48002
|
-
app.delete(
|
|
48003
|
-
"
|
|
48004
|
-
(
|
|
48494
|
+
app.delete("/api/comments/:id/posts/:postId", (context) => {
|
|
48495
|
+
const commentId = context.req.param("id");
|
|
48496
|
+
const deleted = service.deleteReply(commentId, context.req.param("postId"));
|
|
48497
|
+
return context.json({
|
|
48005
48498
|
ok: true,
|
|
48006
|
-
deleted
|
|
48007
|
-
|
|
48008
|
-
|
|
48499
|
+
deleted,
|
|
48500
|
+
comment: service.database.getComment(commentId)
|
|
48501
|
+
});
|
|
48502
|
+
});
|
|
48009
48503
|
app.post(
|
|
48010
48504
|
"/api/comments/:id/resolve",
|
|
48011
48505
|
(context) => context.json({ ok: true, comment: service.setCommentResolved(context.req.param("id"), true) })
|
|
@@ -48018,6 +48512,18 @@ function createApp(service, options) {
|
|
|
48018
48512
|
"/api/comments/:id",
|
|
48019
48513
|
(context) => context.json({ ok: true, deleted: service.deleteComment(context.req.param("id")) })
|
|
48020
48514
|
);
|
|
48515
|
+
app.post("/api/pull-requests/:pullRequestId/comment-placements/resolve", async (context) => {
|
|
48516
|
+
const input = resolveCommentPlacementsSchema.parse(await context.req.json());
|
|
48517
|
+
return context.json({
|
|
48518
|
+
ok: true,
|
|
48519
|
+
...await service.resolveCommentPlacements(
|
|
48520
|
+
context.req.param("pullRequestId"),
|
|
48521
|
+
input.commentIds,
|
|
48522
|
+
input.destinations,
|
|
48523
|
+
input.expectedPullRequestContentFingerprint
|
|
48524
|
+
)
|
|
48525
|
+
});
|
|
48526
|
+
});
|
|
48021
48527
|
app.get("/api/comments/:id/placement", async (context) => {
|
|
48022
48528
|
const comment3 = service.database.getComment(context.req.param("id"));
|
|
48023
48529
|
if (!comment3)
|
|
@@ -48029,22 +48535,21 @@ function createApp(service, options) {
|
|
|
48029
48535
|
placement: { outdated: true, range: null, path: null }
|
|
48030
48536
|
});
|
|
48031
48537
|
}
|
|
48538
|
+
let destination;
|
|
48032
48539
|
if (context.req.query("kind") === "commit") {
|
|
48033
48540
|
const oid = oidQuery(context.req.query("oid"), "oid");
|
|
48034
|
-
|
|
48035
|
-
|
|
48036
|
-
placement: await service.placeCommentAtCommit(comment3, oid)
|
|
48037
|
-
});
|
|
48038
|
-
}
|
|
48039
|
-
if (context.req.query("kind") === "walkthrough") {
|
|
48541
|
+
destination = { kind: "commit", oid };
|
|
48542
|
+
} else if (context.req.query("kind") === "walkthrough") {
|
|
48040
48543
|
const walkthroughId = requiredQuery(context.req.query("walkthroughId"), "walkthroughId");
|
|
48041
|
-
|
|
48042
|
-
|
|
48043
|
-
|
|
48044
|
-
|
|
48544
|
+
destination = { kind: "walkthrough", walkthroughId };
|
|
48545
|
+
} else {
|
|
48546
|
+
destination = {
|
|
48547
|
+
kind: "document",
|
|
48548
|
+
ref: documentRefFromQuery(pullRequestId, context.req.query())
|
|
48549
|
+
};
|
|
48045
48550
|
}
|
|
48046
|
-
const
|
|
48047
|
-
return context.json({ ok: true, placement
|
|
48551
|
+
const placement = destination.kind === "commit" ? await service.placeCommentAtCommit(comment3, destination.oid) : destination.kind === "walkthrough" ? service.placeWalkthroughComment(comment3, destination.walkthroughId) : await service.placeComment(comment3, destination.ref);
|
|
48552
|
+
return context.json({ ok: true, placement });
|
|
48048
48553
|
});
|
|
48049
48554
|
if (options.staticDirectory && existsSync4(options.staticDirectory)) {
|
|
48050
48555
|
app.use("*", serveStatic({ root: options.staticDirectory }));
|