@reviewflow/sdk 0.0.0-stage → 6.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +86 -2
  3. package/build/files-node.mjs +70 -0
  4. package/build/git-node.mjs +1792 -0
  5. package/build/index-browser.es.js +3328 -0
  6. package/build/index-node.mjs +3328 -0
  7. package/package.json +135 -3
  8. package/src/api/pullRequest.ts +617 -0
  9. package/src/config/insertCheckoutEntry.ts +54 -0
  10. package/src/diff/diffPaths.ts +78 -0
  11. package/src/diff/impacts.ts +47 -0
  12. package/src/diff/readingOrder.ts +428 -0
  13. package/src/diff/themes.ts +105 -0
  14. package/src/diff/types.ts +141 -0
  15. package/src/files/editableFile.ts +163 -0
  16. package/src/files.ts +13 -0
  17. package/src/git/groupDiffPaths.ts +134 -0
  18. package/src/git/manifests.ts +96 -0
  19. package/src/git/moduleBindings.ts +571 -0
  20. package/src/git/pullRequestDiff.ts +159 -0
  21. package/src/git/readBranchDiff.ts +359 -0
  22. package/src/git/readImpacts.ts +797 -0
  23. package/src/git/readingOrder.ts +190 -0
  24. package/src/git/run.ts +213 -0
  25. package/src/git.ts +38 -0
  26. package/src/github/applySuggestions.ts +399 -0
  27. package/src/github/editPullRequest.ts +790 -0
  28. package/src/github/fetchCompareDiff.ts +21 -0
  29. package/src/github/imageProxies.ts +43 -0
  30. package/src/github/lineDiff.ts +145 -0
  31. package/src/github/prQuery.ts +298 -0
  32. package/src/github/pullRequestDetail.ts +1347 -0
  33. package/src/github/pullRequestHead.ts +65 -0
  34. package/src/github/pullRequestRevisions.ts +124 -0
  35. package/src/github/transport.ts +171 -0
  36. package/src/index.ts +35 -0
  37. package/src/reviewflow/board.ts +333 -0
  38. package/src/reviewflow/changedParts.ts +80 -0
  39. package/src/reviewflow/checksFromReviewflow.ts +75 -0
  40. package/src/reviewflow/client.ts +589 -0
  41. package/src/reviewflow/follow.ts +345 -0
  42. package/src/reviewflow/status.ts +17 -0
  43. package/src/reviewflow/stream.ts +199 -0
  44. package/src/types/entities.ts +8 -0
  45. package/src/types/ids.ts +1 -0
  46. package/src/types/reviewflow.ts +32 -0
  47. package/src/utils/pullRequestEdit.ts +108 -0
  48. package/src/utils/pullRequestPart.ts +12 -0
  49. package/src/utils/pullRequestReaction.ts +19 -0
  50. package/src/utils/pullRequestSuggestion.ts +148 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Copyright (c) 2026 Christophe Hurpeau <302891+christophehurpeau@users.noreply.github.com> (https://christophe.hurpeau.com)
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for
4
+ any purpose with or without fee is hereby granted, provided that the
5
+ above copyright notice and this permission notice appear in all
6
+ copies.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9
+ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10
+ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
+ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13
+ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,87 @@
1
- # Temporary Holding Version
1
+ # @reviewflow/sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The pull request model behind the [reviewflow](https://github.com/christophehurpeau/reviewflow)
4
+ local app: diff and api types, pure utils, the GitHub layer behind a transport you
5
+ supply, the reviewflow api client, and (node only) reading a pull request diff
6
+ from a local git checkout.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install @reviewflow/sdk
12
+ ```
13
+
14
+ ESM only. The node entries need node `>=24.14.1`; the root entry also has a
15
+ browser build.
16
+
17
+ ## Entry points
18
+
19
+ | Import | Runs on | What |
20
+ | ----------------------- | ------------- | --------------------------------------------------------------------------------- |
21
+ | `@reviewflow/sdk` | node, browser | types, utils, GitHub queries and edits, reviewflow api client and stream |
22
+ | `@reviewflow/sdk/git` | node | read a diff, reading order and impacts from a local checkout (runs `git`) |
23
+ | `@reviewflow/sdk/files` | node | read and save a text file in place, behind validation and a changed-on-disk check |
24
+
25
+ `@reviewflow/sdk/git` needs a `git` executable on `PATH`.
26
+
27
+ ## Wiring
28
+
29
+ The sdk never authenticates nor picks an HTTP client: you inject them.
30
+
31
+ ```ts
32
+ import {
33
+ createGitHubTransport,
34
+ createReviewflowClient,
35
+ fetchPullRequestPart,
36
+ } from "@reviewflow/sdk";
37
+
38
+ // GitHub: you send the bytes, the sdk builds the GraphQL, REST and diff calls.
39
+ const transport = createGitHubTransport(
40
+ async ({ method, path, accept, body }) => {
41
+ const response = await fetch(`https://api.github.com/${path}`, {
42
+ method,
43
+ headers: { authorization: `Bearer ${token}`, accept },
44
+ body,
45
+ });
46
+ return { status: response.status, body: await response.text() };
47
+ },
48
+ );
49
+
50
+ const detail = await fetchPullRequestPart(
51
+ transport,
52
+ { ownerRepo: "octocat/hello-world", number: 1 },
53
+ "detail",
54
+ );
55
+
56
+ // reviewflow's read api, with a user's api token (`fetch` is injectable too).
57
+ const reviewflow = createReviewflowClient({
58
+ url: "https://reviewflow.example",
59
+ token: apiToken,
60
+ });
61
+ ```
62
+
63
+ On node, `@reviewflow/sdk/git` reads the same pull request from a checkout and
64
+ falls back to GitHub through the same transport:
65
+
66
+ ```ts
67
+ import { readPullRequestDiff } from "@reviewflow/sdk/git";
68
+
69
+ const diff = await readPullRequestDiff({
70
+ checkout: "/path/to/clone", // or null to read from GitHub only
71
+ transport,
72
+ ref: { ownerRepo: "octocat/hello-world", number: 1 },
73
+ head: headSha,
74
+ base: baseSha,
75
+ });
76
+ ```
77
+
78
+ ## TypeScript
79
+
80
+ The `types` condition points at the TypeScript sources (`src/`), which import
81
+ each other with a `.ts` extension. Your `tsconfig.json` needs
82
+ `"allowImportingTsExtensions": true` (with `noEmit` or `emitDeclarationOnly`),
83
+ or the checker reports TS5097 inside this package.
84
+
85
+ ## License
86
+
87
+ ISC
@@ -0,0 +1,70 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { mkdirSync, realpathSync, writeFileSync, chmodSync, statSync, renameSync, unlinkSync, readFileSync } from 'node:fs';
3
+ import { dirname, join, basename } from 'node:path';
4
+
5
+ const isMissing = (error) => error.code === "ENOENT";
6
+ const readCurrent = (path) => {
7
+ try {
8
+ return readFileSync(path, "utf8");
9
+ } catch (error) {
10
+ if (isMissing(error)) return null;
11
+ throw error;
12
+ }
13
+ };
14
+ const readEditableFile = (path) => {
15
+ const source = readCurrent(path);
16
+ return source === null ? { source: "", exists: false } : { source, exists: true };
17
+ };
18
+ const validationOf = async (validate, source) => {
19
+ try {
20
+ return await validate(source);
21
+ } catch (error) {
22
+ return { error: error instanceof Error ? error.message : String(error) };
23
+ }
24
+ };
25
+ const saveEditableFile = async ({
26
+ path,
27
+ source,
28
+ expectedSource,
29
+ validate,
30
+ trailingNewline = true
31
+ }) => {
32
+ const text = trailingNewline && source !== "" && !source.endsWith("\n") ? `${source}
33
+ ` : source;
34
+ const validation = await validationOf(validate, text);
35
+ if ("error" in validation) {
36
+ return { status: "invalid", error: validation.error };
37
+ }
38
+ const current = readCurrent(path);
39
+ if (expectedSource !== void 0) {
40
+ const conflicts = expectedSource === null ? current !== null : (current ?? "") !== expectedSource;
41
+ if (conflicts) {
42
+ return {
43
+ status: "conflict",
44
+ source: current ?? "",
45
+ exists: current !== null
46
+ };
47
+ }
48
+ }
49
+ mkdirSync(dirname(path), { recursive: true });
50
+ const target = current === null ? path : realpathSync(path);
51
+ const temporary = join(
52
+ dirname(target),
53
+ `.${basename(target)}.${String(process.pid)}.${randomBytes(4).toString("hex")}.tmp`
54
+ );
55
+ try {
56
+ writeFileSync(temporary, text);
57
+ if (current !== null) chmodSync(temporary, statSync(target).mode & 4095);
58
+ renameSync(temporary, target);
59
+ } catch (error) {
60
+ try {
61
+ unlinkSync(temporary);
62
+ } catch {
63
+ }
64
+ throw error;
65
+ }
66
+ return { status: "saved", source: text, warnings: validation.warnings };
67
+ };
68
+
69
+ export { readEditableFile, saveEditableFile };
70
+ //# sourceMappingURL=files-node.mjs.map