@a9n-shoji/rvw 0.4.0-beta.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +4 -0
- package/dist/cli.mjs +234 -43
- package/dist/cli.mjs.map +4 -4
- package/dist/web/assets/DocumentViewer-cnnF6CLV.js +1420 -0
- package/dist/web/assets/StructureViewer-B0fkdcLj.js +5 -0
- package/dist/web/assets/{CommentThread-dsad9VaW.js → WalkthroughPanel-BGgWu0bA.js} +1 -1
- package/dist/web/assets/{WalkthroughViewer-Ckb8Qlvj.js → WalkthroughViewer-DdPfdT2-.js} +4 -4
- package/dist/web/assets/index-B3zKWMdE.css +1 -0
- package/dist/web/assets/index-qmzlYGCz.js +11 -0
- package/dist/web/index.html +3 -3
- package/package.json +1 -1
- package/skills/rvw-structure/SKILL.md +0 -2
- package/skills/rvw-structure/references/structure-authoring.md +11 -3
- package/dist/web/assets/DocumentViewer-CN8CiQe9.js +0 -1417
- package/dist/web/assets/StructureViewer-Ywjlwt8f.js +0 -1
- package/dist/web/assets/index-AVz95gz4.js +0 -11
- package/dist/web/assets/index-Dq83UXVE.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.4.1] - 2026-09-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- repository fileから、そのfileをNode sourceとして参照するStructureをrename-awareに逆引きし、対応Nodeへ
|
|
13
|
+
閲覧状態を維持したまま移動できる機能
|
|
14
|
+
- Structure全体を現在のNode配置のままSVGまたは2倍基準のPNGへエクスポートする機能。focus、近傍、
|
|
15
|
+
viewportにかかわらず全Node、全Relation、全Edge labelを含み、画面の閲覧状態を変更しない
|
|
16
|
+
|
|
17
|
+
## [0.4.0] - 2026-09-01
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- 一つの具体的なbehavior / processing flowをsource-anchored origin、stable Node / Edge ID、exact source
|
|
22
|
+
anchorで提示し、1/2-hop / All、focus、pan / zoom / dragから探索できるproduction `Structure` document
|
|
23
|
+
- Structureのpublish / get / whole-value update / confirmation付きdeleteを行うCLI、Agent socket capability、
|
|
24
|
+
SQLite migration、HTTP API、Codex / Claude Code共通の`rvw-structure` Skill
|
|
25
|
+
- 変更表示の原文と行番号を保ちながら、追加・削除fileを除く空白だけの変更を`…`メニューから非表示にする
|
|
26
|
+
`Hide Whitespace`設定
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- 固定サイズのStructure Node内をscroll可能にし、表記ごとの余白、canvasのpan / zoom感度、source anchorの
|
|
31
|
+
fallback、stale判定、明示的な再解決を改善
|
|
32
|
+
- light / dark themeのdiff canvas、文字、追加・削除行、gutter、inline emphasisの配色をGitHubへ合わせる
|
|
33
|
+
- Hide Whitespace切替時に現在のsource lineをviewportへ保持し、空白差分がすべて隠れた場合は解除方法を表示
|
|
34
|
+
|
|
8
35
|
## [0.4.0-beta.0] - 2026-08-31
|
|
9
36
|
|
|
10
37
|
### Added
|
package/README.md
CHANGED
|
@@ -181,6 +181,10 @@ viewerではfocusがある時に1-hop / 2-hopへ絞り、Allでは全Node / Edge
|
|
|
181
181
|
保存しません。同じsubjectの更新は同じURIを完全置換し、存続するIDの位置を保ちます。別subjectは新しい
|
|
182
182
|
Structureとしてpublishします。
|
|
183
183
|
|
|
184
|
+
Structure headerの`Export`から、現在のNode配置を保った図全体をstandalone SVGまたは2倍基準のPNGとして
|
|
185
|
+
保存できます。focusや1-hop / 2-hopで画面上に絞り込んでいても、出力には全Node、全Relation、全Edge labelが
|
|
186
|
+
含まれ、pan / zoomや選択状態は持ち込みません。
|
|
187
|
+
|
|
184
188
|
## Codex / Claude Code Skills
|
|
185
189
|
|
|
186
190
|
アプリ本体からローカルSkillをインストールします。一度のinstallで、コメント処理用の`rvw`、
|
package/dist/cli.mjs
CHANGED
|
@@ -20187,7 +20187,7 @@ import path5 from "node:path";
|
|
|
20187
20187
|
import { TextDecoder as TextDecoder2 } from "node:util";
|
|
20188
20188
|
|
|
20189
20189
|
// src/shared/constants.ts
|
|
20190
|
-
var APP_VERSION = "0.4.
|
|
20190
|
+
var APP_VERSION = "0.4.1";
|
|
20191
20191
|
var PROTOCOL_VERSION = 4;
|
|
20192
20192
|
var VIEWER_ID_HEADER = "x-rvw-viewer-id";
|
|
20193
20193
|
var VIEWER_OPEN_LEASE_HEADER = "x-rvw-viewer-open-lease";
|
|
@@ -28466,10 +28466,45 @@ function placeMutableDocumentComment(anchor, currentText) {
|
|
|
28466
28466
|
return range ? { outdated: false, range } : { outdated: true, range: null };
|
|
28467
28467
|
}
|
|
28468
28468
|
|
|
28469
|
-
// src/domain/
|
|
28470
|
-
function
|
|
28469
|
+
// src/domain/source-reference.ts
|
|
28470
|
+
function sourceAnchorFingerprint(sourceOid, reference) {
|
|
28471
28471
|
return JSON.stringify([sourceOid, reference.path, reference.startLine, reference.endLine]);
|
|
28472
28472
|
}
|
|
28473
|
+
function structureSourceAnchor(structure, locator) {
|
|
28474
|
+
if (locator.kind === "node") {
|
|
28475
|
+
return structure.nodes.find((node2) => node2.id === locator.nodeId)?.anchor ?? null;
|
|
28476
|
+
}
|
|
28477
|
+
const edge = structure.edges.find((candidate) => candidate.id === locator.edgeId);
|
|
28478
|
+
return edge?.anchors[locator.anchorIndex] ?? null;
|
|
28479
|
+
}
|
|
28480
|
+
function compareStableIds(left, right) {
|
|
28481
|
+
if (left === right) return 0;
|
|
28482
|
+
return left < right ? -1 : 1;
|
|
28483
|
+
}
|
|
28484
|
+
function closestMatchingStructureNode(structure, matchingNodeIds) {
|
|
28485
|
+
if (matchingNodeIds.size === 0) return null;
|
|
28486
|
+
const distances = /* @__PURE__ */ new Map([[structure.originNodeId, 0]]);
|
|
28487
|
+
const neighbors = new Map(structure.nodes.map((node2) => [node2.id, /* @__PURE__ */ new Set()]));
|
|
28488
|
+
for (const edge of structure.edges) {
|
|
28489
|
+
neighbors.get(edge.from)?.add(edge.to);
|
|
28490
|
+
neighbors.get(edge.to)?.add(edge.from);
|
|
28491
|
+
}
|
|
28492
|
+
const queue = [structure.originNodeId];
|
|
28493
|
+
for (let index2 = 0; index2 < queue.length; index2 += 1) {
|
|
28494
|
+
const nodeId = queue[index2];
|
|
28495
|
+
const distance = distances.get(nodeId);
|
|
28496
|
+
for (const neighbor of neighbors.get(nodeId) ?? []) {
|
|
28497
|
+
if (distances.has(neighbor)) continue;
|
|
28498
|
+
distances.set(neighbor, distance + 1);
|
|
28499
|
+
queue.push(neighbor);
|
|
28500
|
+
}
|
|
28501
|
+
}
|
|
28502
|
+
return structure.nodes.filter((node2) => matchingNodeIds.has(node2.id)).sort((left, right) => {
|
|
28503
|
+
const leftDistance = distances.get(left.id) ?? Number.POSITIVE_INFINITY;
|
|
28504
|
+
const rightDistance = distances.get(right.id) ?? Number.POSITIVE_INFINITY;
|
|
28505
|
+
return leftDistance - rightDistance || compareStableIds(left.id, right.id);
|
|
28506
|
+
})[0] ?? null;
|
|
28507
|
+
}
|
|
28473
28508
|
|
|
28474
28509
|
// src/domain/source-excerpt.ts
|
|
28475
28510
|
var SOURCE_EXCERPT_CONTEXT_LINES = 20;
|
|
@@ -41438,6 +41473,18 @@ function assertLinePair(startLine, endLine) {
|
|
|
41438
41473
|
}
|
|
41439
41474
|
var codeReferenceIdPattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
41440
41475
|
var walkthroughDiagramNodePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
41476
|
+
function structureSummary(structure) {
|
|
41477
|
+
return {
|
|
41478
|
+
id: structure.id,
|
|
41479
|
+
ref: structure.ref,
|
|
41480
|
+
pullRequestId: structure.pullRequestId,
|
|
41481
|
+
sourceOid: structure.sourceOid,
|
|
41482
|
+
title: structure.title,
|
|
41483
|
+
scope: structure.scope,
|
|
41484
|
+
createdAt: structure.createdAt,
|
|
41485
|
+
updatedAt: structure.updatedAt
|
|
41486
|
+
};
|
|
41487
|
+
}
|
|
41441
41488
|
var mermaidIdentifierPattern = /[A-Za-z][A-Za-z0-9_-]{0,63}/g;
|
|
41442
41489
|
var mermaidEdgePattern = /[<|o*x]*[-.=~]{2,}[|o*x>]*/g;
|
|
41443
41490
|
var mermaidClassShorthandPattern = /:::[A-Za-z][A-Za-z0-9_-]*(?:,[A-Za-z][A-Za-z0-9_-]*)*/g;
|
|
@@ -42502,6 +42549,71 @@ var RvwService = class {
|
|
|
42502
42549
|
this.getPullRequest(pullRequestId);
|
|
42503
42550
|
return this.database.listStructures(pullRequestId);
|
|
42504
42551
|
}
|
|
42552
|
+
async listFileStructureReferences(pullRequestId, targetSourceOid, targetPath) {
|
|
42553
|
+
const pullRequest = this.getPullRequest(pullRequestId);
|
|
42554
|
+
assertCodeReferencePath(targetPath);
|
|
42555
|
+
const structures = this.database.listStructures(pullRequestId).flatMap((summary) => {
|
|
42556
|
+
const structure = this.database.getStructure(summary.id);
|
|
42557
|
+
return structure?.pullRequestId === pullRequestId ? [structure] : [];
|
|
42558
|
+
});
|
|
42559
|
+
await this.assertCommitAvailable(pullRequest, targetSourceOid);
|
|
42560
|
+
const targetPaths = new Set(
|
|
42561
|
+
(await this.git.tree(pullRequest.localRepositoryPath, targetSourceOid)).map(
|
|
42562
|
+
(entry) => entry.path
|
|
42563
|
+
)
|
|
42564
|
+
);
|
|
42565
|
+
if (!targetPaths.has(targetPath)) return [];
|
|
42566
|
+
const successorIndexes = /* @__PURE__ */ new Map();
|
|
42567
|
+
const successorIndex = (sourceOid) => {
|
|
42568
|
+
const key2 = JSON.stringify([sourceOid, targetSourceOid]);
|
|
42569
|
+
const cached2 = successorIndexes.get(key2);
|
|
42570
|
+
if (cached2) return cached2;
|
|
42571
|
+
const index2 = this.git.changedFilesWithCopies(pullRequest.localRepositoryPath, sourceOid, targetSourceOid).then((changes) => {
|
|
42572
|
+
const successors = /* @__PURE__ */ new Map();
|
|
42573
|
+
for (const candidate of changes) {
|
|
42574
|
+
if (!candidate.status.startsWith("R") && !candidate.status.startsWith("C") || candidate.oldPath === null || candidate.newPath === null) {
|
|
42575
|
+
continue;
|
|
42576
|
+
}
|
|
42577
|
+
const paths = successors.get(candidate.oldPath) ?? /* @__PURE__ */ new Set();
|
|
42578
|
+
paths.add(candidate.newPath);
|
|
42579
|
+
successors.set(candidate.oldPath, paths);
|
|
42580
|
+
}
|
|
42581
|
+
return successors;
|
|
42582
|
+
});
|
|
42583
|
+
successorIndexes.set(key2, index2);
|
|
42584
|
+
return index2;
|
|
42585
|
+
};
|
|
42586
|
+
const resolvePath = (sourceOid, sourcePath) => {
|
|
42587
|
+
if (targetPaths.has(sourcePath)) return Promise.resolve(sourcePath);
|
|
42588
|
+
if (sourceOid === targetSourceOid) return Promise.resolve(null);
|
|
42589
|
+
return successorIndex(sourceOid).then((index2) => {
|
|
42590
|
+
const successors = index2.get(sourcePath);
|
|
42591
|
+
if (successors?.size !== 1) return null;
|
|
42592
|
+
const successor = [...successors][0];
|
|
42593
|
+
return targetPaths.has(successor) ? successor : null;
|
|
42594
|
+
});
|
|
42595
|
+
};
|
|
42596
|
+
const references = [];
|
|
42597
|
+
for (const structure of structures) {
|
|
42598
|
+
const matchingNodeIds = /* @__PURE__ */ new Set();
|
|
42599
|
+
await Promise.all(
|
|
42600
|
+
structure.nodes.map(async (node2) => {
|
|
42601
|
+
if (!node2.anchor) return;
|
|
42602
|
+
const resolvedPath = await resolvePath(structure.sourceOid, node2.anchor.path);
|
|
42603
|
+
if (resolvedPath === targetPath) matchingNodeIds.add(node2.id);
|
|
42604
|
+
})
|
|
42605
|
+
);
|
|
42606
|
+
const targetNode = closestMatchingStructureNode(structure, matchingNodeIds);
|
|
42607
|
+
if (!targetNode) continue;
|
|
42608
|
+
references.push({
|
|
42609
|
+
structure: structureSummary(structure),
|
|
42610
|
+
targetNodeId: targetNode.id,
|
|
42611
|
+
targetNodeLabel: targetNode.label,
|
|
42612
|
+
matchingNodeCount: matchingNodeIds.size
|
|
42613
|
+
});
|
|
42614
|
+
}
|
|
42615
|
+
return references;
|
|
42616
|
+
}
|
|
42505
42617
|
listStructuresByReference(reference) {
|
|
42506
42618
|
const pullRequest = this.resolveStoredPullRequest(reference);
|
|
42507
42619
|
return { pullRequest, structures: this.database.listStructures(pullRequest.id) };
|
|
@@ -42796,7 +42908,7 @@ var RvwService = class {
|
|
|
42796
42908
|
}
|
|
42797
42909
|
return walkthrough;
|
|
42798
42910
|
}
|
|
42799
|
-
async
|
|
42911
|
+
async sourceReferenceFallbackTarget(pullRequest, sourceOid, filePath) {
|
|
42800
42912
|
const diffBaseOid = await this.git.firstParent(pullRequest.localRepositoryPath, sourceOid);
|
|
42801
42913
|
if (!diffBaseOid) {
|
|
42802
42914
|
return {
|
|
@@ -42827,46 +42939,48 @@ var RvwService = class {
|
|
|
42827
42939
|
status: 404
|
|
42828
42940
|
});
|
|
42829
42941
|
}
|
|
42830
|
-
const referenceFingerprint =
|
|
42942
|
+
const referenceFingerprint = sourceAnchorFingerprint(walkthrough.sourceOid, reference);
|
|
42943
|
+
return await this.resolveSourceAnchor(
|
|
42944
|
+
pullRequest,
|
|
42945
|
+
walkthrough.sourceOid,
|
|
42946
|
+
reference,
|
|
42947
|
+
referenceFingerprint
|
|
42948
|
+
);
|
|
42949
|
+
}
|
|
42950
|
+
async resolveStructureSource(pullRequestId, structureId, locator) {
|
|
42951
|
+
const pullRequest = this.getPullRequest(pullRequestId);
|
|
42952
|
+
const structure = this.getStructure(pullRequestId, structureId);
|
|
42953
|
+
const anchor = structureSourceAnchor(structure, locator);
|
|
42954
|
+
if (!anchor) {
|
|
42955
|
+
throw new RvwError("NOT_FOUND", "Structure\u306E\u53C2\u7167\u5143claim\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002", {
|
|
42956
|
+
status: 404
|
|
42957
|
+
});
|
|
42958
|
+
}
|
|
42959
|
+
const resolution = await this.resolveSourceAnchor(
|
|
42960
|
+
pullRequest,
|
|
42961
|
+
structure.sourceOid,
|
|
42962
|
+
anchor,
|
|
42963
|
+
sourceAnchorFingerprint(structure.sourceOid, anchor)
|
|
42964
|
+
);
|
|
42965
|
+
return { ...resolution, resolvedAnchor: anchor };
|
|
42966
|
+
}
|
|
42967
|
+
async resolveSourceAnchor(pullRequest, sourceOid, reference, referenceFingerprint) {
|
|
42831
42968
|
const sourceDocument = await this.getDocument({
|
|
42832
42969
|
kind: "repository-file",
|
|
42833
|
-
pullRequestId,
|
|
42834
|
-
sourceOid
|
|
42970
|
+
pullRequestId: pullRequest.id,
|
|
42971
|
+
sourceOid,
|
|
42835
42972
|
path: reference.path
|
|
42836
42973
|
});
|
|
42837
42974
|
const latestHeadOid = pullRequest.latestHeadOid;
|
|
42838
|
-
|
|
42839
|
-
|
|
42840
|
-
|
|
42841
|
-
|
|
42842
|
-
|
|
42843
|
-
|
|
42844
|
-
|
|
42845
|
-
|
|
42846
|
-
|
|
42847
|
-
path: reference.path
|
|
42848
|
-
});
|
|
42849
|
-
if (latestDocument.availability === "missing") {
|
|
42850
|
-
const successorPaths = [
|
|
42851
|
-
...new Set(
|
|
42852
|
-
(await this.git.changedFilesWithCopies(
|
|
42853
|
-
pullRequest.localRepositoryPath,
|
|
42854
|
-
walkthrough.sourceOid,
|
|
42855
|
-
latestHeadOid
|
|
42856
|
-
)).filter(
|
|
42857
|
-
(candidate) => (candidate.status.startsWith("R") || candidate.status.startsWith("C")) && candidate.oldPath === reference.path && candidate.newPath !== null
|
|
42858
|
-
).map((candidate) => candidate.newPath)
|
|
42859
|
-
)
|
|
42860
|
-
];
|
|
42861
|
-
latestPath = successorPaths.length === 1 ? successorPaths[0] : null;
|
|
42862
|
-
latestDocument = latestPath === null ? null : await this.getDocument({
|
|
42863
|
-
kind: "repository-file",
|
|
42864
|
-
pullRequestId,
|
|
42865
|
-
sourceOid: latestHeadOid,
|
|
42866
|
-
path: latestPath
|
|
42867
|
-
});
|
|
42868
|
-
}
|
|
42869
|
-
}
|
|
42975
|
+
const resolvedLatestFile = await this.resolveSourceFileAtCommit(
|
|
42976
|
+
pullRequest,
|
|
42977
|
+
sourceOid,
|
|
42978
|
+
reference.path,
|
|
42979
|
+
latestHeadOid,
|
|
42980
|
+
sourceDocument
|
|
42981
|
+
);
|
|
42982
|
+
const latestPath = resolvedLatestFile?.path ?? null;
|
|
42983
|
+
const latestDocument = resolvedLatestFile?.document ?? null;
|
|
42870
42984
|
const latestFileExists = latestDocument !== null && latestDocument.availability !== "missing";
|
|
42871
42985
|
const latestFileDisplayable = latestDocument?.availability === "available";
|
|
42872
42986
|
const mappedRange = reference.startLine === null || reference.endLine === null ? latestFileDisplayable ? null : void 0 : sourceDocument.availability === "available" && latestDocument?.availability === "available" ? mapUnchangedLineRange(
|
|
@@ -42879,7 +42993,7 @@ var RvwService = class {
|
|
|
42879
42993
|
if (resolvedToLatest && latestPath !== null && latestDocument !== null) {
|
|
42880
42994
|
return {
|
|
42881
42995
|
outcome: "latest",
|
|
42882
|
-
anchorSourceOid:
|
|
42996
|
+
anchorSourceOid: sourceOid,
|
|
42883
42997
|
latestHeadOid,
|
|
42884
42998
|
referenceFingerprint,
|
|
42885
42999
|
target: {
|
|
@@ -42896,9 +43010,9 @@ var RvwService = class {
|
|
|
42896
43010
|
document: latestDocument
|
|
42897
43011
|
};
|
|
42898
43012
|
}
|
|
42899
|
-
const targetFile = await this.
|
|
43013
|
+
const targetFile = await this.sourceReferenceFallbackTarget(
|
|
42900
43014
|
pullRequest,
|
|
42901
|
-
|
|
43015
|
+
sourceOid,
|
|
42902
43016
|
reference.path
|
|
42903
43017
|
);
|
|
42904
43018
|
const latestFile = latestFileExists && latestPath !== null ? {
|
|
@@ -42911,7 +43025,7 @@ var RvwService = class {
|
|
|
42911
43025
|
} : null;
|
|
42912
43026
|
return {
|
|
42913
43027
|
outcome: "source-fallback",
|
|
42914
|
-
anchorSourceOid:
|
|
43028
|
+
anchorSourceOid: sourceOid,
|
|
42915
43029
|
latestHeadOid,
|
|
42916
43030
|
referenceFingerprint,
|
|
42917
43031
|
target: {
|
|
@@ -42923,6 +43037,38 @@ var RvwService = class {
|
|
|
42923
43037
|
document: sourceDocument
|
|
42924
43038
|
};
|
|
42925
43039
|
}
|
|
43040
|
+
async resolveSourceFileAtCommit(pullRequest, sourceOid, sourcePath, targetSourceOid, sourceDocument) {
|
|
43041
|
+
const directDocument = sourceOid === targetSourceOid ? sourceDocument : await this.getDocument({
|
|
43042
|
+
kind: "repository-file",
|
|
43043
|
+
pullRequestId: pullRequest.id,
|
|
43044
|
+
sourceOid: targetSourceOid,
|
|
43045
|
+
path: sourcePath
|
|
43046
|
+
});
|
|
43047
|
+
if (directDocument.availability !== "missing") {
|
|
43048
|
+
return { path: sourcePath, document: directDocument };
|
|
43049
|
+
}
|
|
43050
|
+
if (sourceOid === targetSourceOid) return null;
|
|
43051
|
+
const successorPaths = [
|
|
43052
|
+
...new Set(
|
|
43053
|
+
(await this.git.changedFilesWithCopies(
|
|
43054
|
+
pullRequest.localRepositoryPath,
|
|
43055
|
+
sourceOid,
|
|
43056
|
+
targetSourceOid
|
|
43057
|
+
)).filter(
|
|
43058
|
+
(candidate) => (candidate.status.startsWith("R") || candidate.status.startsWith("C")) && candidate.oldPath === sourcePath && candidate.newPath !== null
|
|
43059
|
+
).map((candidate) => candidate.newPath)
|
|
43060
|
+
)
|
|
43061
|
+
];
|
|
43062
|
+
if (successorPaths.length !== 1) return null;
|
|
43063
|
+
const successorPath = successorPaths[0];
|
|
43064
|
+
const successorDocument = await this.getDocument({
|
|
43065
|
+
kind: "repository-file",
|
|
43066
|
+
pullRequestId: pullRequest.id,
|
|
43067
|
+
sourceOid: targetSourceOid,
|
|
43068
|
+
path: successorPath
|
|
43069
|
+
});
|
|
43070
|
+
return successorDocument.availability === "missing" ? null : { path: successorPath, document: successorDocument };
|
|
43071
|
+
}
|
|
42926
43072
|
getWalkthroughByUri(uri) {
|
|
42927
43073
|
const walkthrough = this.database.getWalkthrough(parseWalkthroughUri(uri));
|
|
42928
43074
|
if (!walkthrough) {
|
|
@@ -47567,6 +47713,7 @@ var editCommentPostSchema = external_exports.object({
|
|
|
47567
47713
|
|
|
47568
47714
|
// src/server/app.ts
|
|
47569
47715
|
var oidSchema = external_exports.string().regex(GIT_OBJECT_ID_PATTERN);
|
|
47716
|
+
var nonnegativeIndexSchema = external_exports.coerce.number().int().nonnegative();
|
|
47570
47717
|
var svgAssetContentSecurityPolicy = "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; sandbox";
|
|
47571
47718
|
function requiredQuery(value, name) {
|
|
47572
47719
|
if (!value) throw new RvwError("INVALID_INPUT", `${name} query\u304C\u5FC5\u8981\u3067\u3059\u3002`);
|
|
@@ -47575,6 +47722,23 @@ function requiredQuery(value, name) {
|
|
|
47575
47722
|
function oidQuery(value, name) {
|
|
47576
47723
|
return oidSchema.parse(requiredQuery(value, name));
|
|
47577
47724
|
}
|
|
47725
|
+
function structureSourceLocator(query) {
|
|
47726
|
+
if (query.locatorKind === "node") {
|
|
47727
|
+
return { kind: "node", nodeId: requiredQuery(query.nodeId, "nodeId") };
|
|
47728
|
+
}
|
|
47729
|
+
if (query.locatorKind === "edge") {
|
|
47730
|
+
const anchorIndex = nonnegativeIndexSchema.safeParse(query.anchorIndex);
|
|
47731
|
+
if (!anchorIndex.success) {
|
|
47732
|
+
throw new RvwError("INVALID_INPUT", "anchorIndex query\u306F0\u4EE5\u4E0A\u306E\u6574\u6570\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
47733
|
+
}
|
|
47734
|
+
return {
|
|
47735
|
+
kind: "edge",
|
|
47736
|
+
edgeId: requiredQuery(query.edgeId, "edgeId"),
|
|
47737
|
+
anchorIndex: anchorIndex.data
|
|
47738
|
+
};
|
|
47739
|
+
}
|
|
47740
|
+
throw new RvwError("INVALID_INPUT", "locatorKind query\u306Fnode\u307E\u305F\u306Fedge\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
47741
|
+
}
|
|
47578
47742
|
function isWriteMethod(method) {
|
|
47579
47743
|
return method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE";
|
|
47580
47744
|
}
|
|
@@ -47866,6 +48030,18 @@ function createApp(service, options) {
|
|
|
47866
48030
|
structures: service.listStructures(context.req.param("id"))
|
|
47867
48031
|
})
|
|
47868
48032
|
);
|
|
48033
|
+
app.get("/api/pull-requests/:id/structure-references", async (context) => {
|
|
48034
|
+
const sourceOid = oidQuery(context.req.query("sourceOid"), "sourceOid");
|
|
48035
|
+
const filePath = requiredQuery(context.req.query("path"), "path");
|
|
48036
|
+
return context.json({
|
|
48037
|
+
ok: true,
|
|
48038
|
+
references: await service.listFileStructureReferences(
|
|
48039
|
+
context.req.param("id"),
|
|
48040
|
+
sourceOid,
|
|
48041
|
+
filePath
|
|
48042
|
+
)
|
|
48043
|
+
});
|
|
48044
|
+
});
|
|
47869
48045
|
app.get(
|
|
47870
48046
|
"/api/pull-requests/:id/structures/:structureId",
|
|
47871
48047
|
(context) => context.json({
|
|
@@ -47873,6 +48049,21 @@ function createApp(service, options) {
|
|
|
47873
48049
|
structure: service.getStructure(context.req.param("id"), context.req.param("structureId"))
|
|
47874
48050
|
})
|
|
47875
48051
|
);
|
|
48052
|
+
app.get("/api/pull-requests/:id/structures/:structureId/anchors/resolve", async (context) => {
|
|
48053
|
+
return context.json({
|
|
48054
|
+
ok: true,
|
|
48055
|
+
resolution: await service.resolveStructureSource(
|
|
48056
|
+
context.req.param("id"),
|
|
48057
|
+
context.req.param("structureId"),
|
|
48058
|
+
structureSourceLocator({
|
|
48059
|
+
locatorKind: context.req.query("locatorKind"),
|
|
48060
|
+
nodeId: context.req.query("nodeId"),
|
|
48061
|
+
edgeId: context.req.query("edgeId"),
|
|
48062
|
+
anchorIndex: context.req.query("anchorIndex")
|
|
48063
|
+
})
|
|
48064
|
+
)
|
|
48065
|
+
});
|
|
48066
|
+
});
|
|
47876
48067
|
app.delete("/api/pull-requests/:id/structures/:structureId", async (context) => {
|
|
47877
48068
|
const input = structureDeleteSchema.parse(await context.req.json());
|
|
47878
48069
|
return context.json({
|