@effected/github 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ActionsOidc.js +180 -0
- package/CheckRun.js +87 -19
- package/GitHubApp.js +253 -35
- package/GitHubClient.js +52 -3
- package/GitHubContent.js +10 -2
- package/GitHubError.js +50 -20
- package/InstallationTokenStore.js +51 -0
- package/README.md +1 -1
- package/Repo.js +16 -1
- package/WorkflowDispatch.js +36 -20
- package/index.d.ts +628 -25
- package/index.js +4 -2
- package/internal/crypto.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Hand-rolled octokit wrappers tend to converge on the same shape: a `rest<T>(oper
|
|
|
25
25
|
|
|
26
26
|
The error model gets the same treatment. `GitHubError.kind` is a literal union (`notFound`, `alreadyExists`, `rejected`, `unauthorized`, `rateLimited`, `transport`, `decode`) produced by one classification step, `GitHubError.fromOctokit`, instead of one hand-written mapper per resource. `kind: "alreadyExists"` is what makes `GitBranch.upsert` and `GitTag.upsert` a single round trip in the common case, rather than a create-then-catch-then-check-then-reset dance repeated at every call site that needs it.
|
|
27
27
|
|
|
28
|
-
This package also owns the octokit runtime so nothing downstream has to. `@octokit/rest` and `@octokit/auth-app` are deliberately absent — the rest wrapper is a request-logging plugin plus 1.4 MB of duplicate endpoint types, and `auth-app` drags in `createOAuthUserAuth`, roughly 492 KB of OAuth machinery this package never calls. GitHub App JWTs are signed by
|
|
28
|
+
This package also owns the octokit runtime so nothing downstream has to. `@octokit/rest` and `@octokit/auth-app` are deliberately absent — the rest wrapper is a request-logging plugin plus 1.4 MB of duplicate endpoint types, and `auth-app` drags in `createOAuthUserAuth`, roughly 492 KB of OAuth machinery this package never calls. GitHub App JWTs are signed by the kit's own `@effected/jwt` instead: WebCrypto RS256 with no runtime dependencies, so App auth runs on Cloudflare Workers as well as Node. A consumer that only authenticates with a token it already holds never links the JWT signer at all: the App-authenticated layer lives in its own module (`GitHubApp`), and nothing here is gathered into a namespace object that would defeat that split.
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
package/Repo.js
CHANGED
|
@@ -16,6 +16,15 @@ input: Schema.String }) {
|
|
|
16
16
|
/**
|
|
17
17
|
* Which repository an operation acts on.
|
|
18
18
|
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* **`RepoRef.make` validates at construction and throws** on an empty `owner`
|
|
21
|
+
* or `repo`, so inside an `Effect` a bad value dies rather than failing. That
|
|
22
|
+
* is right for a coordinate the program itself spells out, and wrong for one
|
|
23
|
+
* built from data: for a slug read from a database row, a config file or a
|
|
24
|
+
* webhook, use {@link RepoRef.parse}, which fails with a typed
|
|
25
|
+
* {@link InvalidRepoRefError} instead (or {@link RepoRef.parseResult}
|
|
26
|
+
* outside an `Effect`).
|
|
27
|
+
*
|
|
19
28
|
* @public
|
|
20
29
|
*/
|
|
21
30
|
var RepoRef = class RepoRef extends Schema.Class("RepoRef")({
|
|
@@ -41,7 +50,13 @@ var RepoRef = class RepoRef extends Schema.Class("RepoRef")({
|
|
|
41
50
|
repo
|
|
42
51
|
}));
|
|
43
52
|
}
|
|
44
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Parse `"owner/repo"`, failing with a typed {@link InvalidRepoRefError}.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* The typed path for building a `Repo` from stored data, such as a stored
|
|
58
|
+
* `full_name`: a malformed value fails here, where `make` would die.
|
|
59
|
+
*/
|
|
45
60
|
static parse = Effect.fn("RepoRef.parse")((slug) => Effect.fromResult(RepoRef.parseResult(slug)));
|
|
46
61
|
/** `"owner/repo"`. */
|
|
47
62
|
get slug() {
|
package/WorkflowDispatch.js
CHANGED
|
@@ -61,6 +61,7 @@ var WorkflowDispatch = class WorkflowDispatch extends Context.Service()("@effect
|
|
|
61
61
|
static makeTest = (overrides = {}) => ({
|
|
62
62
|
dispatch: overrides.dispatch ?? (() => unstubbed("dispatch")),
|
|
63
63
|
runStatus: overrides.runStatus ?? (() => unstubbed("runStatus")),
|
|
64
|
+
cancelRun: overrides.cancelRun ?? (() => unstubbed("cancelRun")),
|
|
64
65
|
list: overrides.list ?? Effect.sync(() => unstubbed("list")),
|
|
65
66
|
dispatchAndWait: overrides.dispatchAndWait ?? (() => unstubbed("dispatchAndWait"))
|
|
66
67
|
});
|
|
@@ -93,38 +94,53 @@ const make = (client) => {
|
|
|
93
94
|
...inputs !== void 0 ? { inputs } : {}
|
|
94
95
|
});
|
|
95
96
|
});
|
|
97
|
+
const runStatus = Effect.fn("WorkflowDispatch.runStatus")(function* (runId) {
|
|
98
|
+
const { owner, repo } = yield* Repo;
|
|
99
|
+
yield* Effect.annotateCurrentSpan({
|
|
100
|
+
owner,
|
|
101
|
+
repo,
|
|
102
|
+
runId
|
|
103
|
+
});
|
|
104
|
+
const raw = yield* client.request("GET /repos/{owner}/{repo}/actions/runs/{run_id}", {
|
|
105
|
+
owner,
|
|
106
|
+
repo,
|
|
107
|
+
run_id: runId
|
|
108
|
+
});
|
|
109
|
+
return statusOf(raw);
|
|
110
|
+
});
|
|
111
|
+
const list = Effect.fn("WorkflowDispatch.list")(function* () {
|
|
112
|
+
const { owner, repo } = yield* Repo;
|
|
113
|
+
yield* Effect.annotateCurrentSpan({
|
|
114
|
+
owner,
|
|
115
|
+
repo
|
|
116
|
+
});
|
|
117
|
+
return (yield* client.paginate("GET /repos/{owner}/{repo}/actions/workflows", {
|
|
118
|
+
owner,
|
|
119
|
+
repo
|
|
120
|
+
})).map((workflow) => ({
|
|
121
|
+
id: workflow.id,
|
|
122
|
+
name: workflow.name,
|
|
123
|
+
path: workflow.path,
|
|
124
|
+
state: workflow.state
|
|
125
|
+
}));
|
|
126
|
+
});
|
|
96
127
|
return {
|
|
97
128
|
dispatch,
|
|
98
|
-
runStatus
|
|
129
|
+
runStatus,
|
|
130
|
+
cancelRun: Effect.fn("WorkflowDispatch.cancelRun")(function* (runId) {
|
|
99
131
|
const { owner, repo } = yield* Repo;
|
|
100
132
|
yield* Effect.annotateCurrentSpan({
|
|
101
133
|
owner,
|
|
102
134
|
repo,
|
|
103
135
|
runId
|
|
104
136
|
});
|
|
105
|
-
|
|
137
|
+
return yield* client.request("POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel", {
|
|
106
138
|
owner,
|
|
107
139
|
repo,
|
|
108
140
|
run_id: runId
|
|
109
|
-
});
|
|
110
|
-
return statusOf(raw);
|
|
141
|
+
}).pipe(Effect.as("cancelled"), Effect.catchIf((error) => error.status === 409, () => Effect.succeed("alreadyCompleted")));
|
|
111
142
|
}),
|
|
112
|
-
list:
|
|
113
|
-
const { owner, repo } = yield* Repo;
|
|
114
|
-
yield* Effect.annotateCurrentSpan({
|
|
115
|
-
owner,
|
|
116
|
-
repo
|
|
117
|
-
});
|
|
118
|
-
return (yield* client.paginate("GET /repos/{owner}/{repo}/actions/workflows", {
|
|
119
|
-
owner,
|
|
120
|
-
repo
|
|
121
|
-
})).map((workflow) => ({
|
|
122
|
-
id: workflow.id,
|
|
123
|
-
name: workflow.name,
|
|
124
|
-
path: workflow.path,
|
|
125
|
-
state: workflow.state
|
|
126
|
-
}));
|
|
127
|
-
})(),
|
|
143
|
+
list: list(),
|
|
128
144
|
dispatchAndWait: Effect.fn("WorkflowDispatch.dispatchAndWait")(function* (workflow, ref, options) {
|
|
129
145
|
const { owner, repo } = yield* Repo;
|
|
130
146
|
const interval = options?.poll?.interval ?? DEFAULT_INTERVAL;
|