@effected/github 0.12.0 → 0.14.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/GitHubError.js +113 -11
- package/README.md +16 -1
- package/index.d.ts +71 -0
- package/index.js +2 -2
- package/internal/crypto.js +5 -4
- package/package.json +4 -4
package/GitHubError.js
CHANGED
|
@@ -25,6 +25,53 @@ const GitHubErrorKind = Schema.Literals([
|
|
|
25
25
|
"decode"
|
|
26
26
|
]);
|
|
27
27
|
/**
|
|
28
|
+
* The validation codes GitHub documents for a 422's `errors[].code`.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* The complete documented set. Only `already_exists` earns its own
|
|
32
|
+
* {@link GitHubErrorKind}; every other code classifies as `rejected`, and a
|
|
33
|
+
* caller that needs to tell them apart reads {@link GitHubError}'s `validation`
|
|
34
|
+
* or uses {@link GitHubError.hasValidationCode}.
|
|
35
|
+
*
|
|
36
|
+
* `missing` is the one that looks like `notFound` and is not: it names a
|
|
37
|
+
* resource the request *referred to* — a commit sha, an assignee — not the one
|
|
38
|
+
* it acted on. Routing it to `notFound` would let every
|
|
39
|
+
* `catchIf(GitHubError.hasKind("notFound"), …)` recovery swallow a bad argument.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
const GitHubValidationCode = Schema.Literals([
|
|
44
|
+
"missing",
|
|
45
|
+
"missing_field",
|
|
46
|
+
"invalid",
|
|
47
|
+
"already_exists",
|
|
48
|
+
"unprocessable",
|
|
49
|
+
"custom"
|
|
50
|
+
]);
|
|
51
|
+
/**
|
|
52
|
+
* One entry from a failed response's `data.errors` array, as GitHub sent it.
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Every field is optional because GitHub's entries vary by endpoint: the
|
|
56
|
+
* releases endpoint sends `resource`, `code` and `field` with no `message`,
|
|
57
|
+
* while a `custom` entry may carry only a `message`. `code` is a plain string
|
|
58
|
+
* rather than {@link GitHubValidationCode} so an unexpected code cannot make
|
|
59
|
+
* the error itself fail to construct: a refused request must still surface as
|
|
60
|
+
* a `GitHubError`, never as a defect.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
var GitHubValidationEntry = class extends Schema.Class("GitHubValidationEntry")({
|
|
65
|
+
/** The resource type GitHub validated, e.g. `"Release"`. */
|
|
66
|
+
resource: Schema.optionalKey(Schema.String),
|
|
67
|
+
/** The parameter at fault, e.g. `"tag_name"`. */
|
|
68
|
+
field: Schema.optionalKey(Schema.String),
|
|
69
|
+
/** GitHub's validation code — one of {@link GitHubValidationCode} when documented. */
|
|
70
|
+
code: Schema.optionalKey(Schema.String),
|
|
71
|
+
/** GitHub's prose, when it sent any. */
|
|
72
|
+
message: Schema.optionalKey(Schema.String)
|
|
73
|
+
}) {};
|
|
74
|
+
/**
|
|
28
75
|
* Every REST failure this package produces, from every resource.
|
|
29
76
|
*
|
|
30
77
|
* @remarks
|
|
@@ -60,6 +107,15 @@ var GitHubError = class GitHubError extends Schema.TaggedError()("GitHubError",
|
|
|
60
107
|
* `retryable` boolean it used to travel with is now a derived getter.
|
|
61
108
|
*/
|
|
62
109
|
retryAfterMillis: Schema.optionalKey(Schema.Int),
|
|
110
|
+
/**
|
|
111
|
+
* GitHub's validation entries, when the failed response carried any.
|
|
112
|
+
*
|
|
113
|
+
* @remarks
|
|
114
|
+
* The structured half of a 422: branch on an entry's `code` and `field`
|
|
115
|
+
* rather than on `reason`. Absent when GitHub sent no `errors` array — some
|
|
116
|
+
* 422s ("Update is not a fast forward") are prose only.
|
|
117
|
+
*/
|
|
118
|
+
validation: Schema.optionalKey(Schema.Array(GitHubValidationEntry)),
|
|
63
119
|
/** The underlying throwable, when one exists. */
|
|
64
120
|
cause: Schema.optionalKey(Schema.Defect())
|
|
65
121
|
}) {
|
|
@@ -138,6 +194,7 @@ var GitHubError = class GitHubError extends Schema.TaggedError()("GitHubError",
|
|
|
138
194
|
reason: facts.reason,
|
|
139
195
|
...facts.status !== void 0 ? { status: facts.status } : {},
|
|
140
196
|
...retryAfterMillis !== void 0 ? { retryAfterMillis } : {},
|
|
197
|
+
...facts.validation.length > 0 ? { validation: facts.validation } : {},
|
|
141
198
|
cause: error
|
|
142
199
|
});
|
|
143
200
|
}
|
|
@@ -160,6 +217,30 @@ var GitHubError = class GitHubError extends Schema.TaggedError()("GitHubError",
|
|
|
160
217
|
const set = new Set(kinds);
|
|
161
218
|
return (error) => set.has(error.kind);
|
|
162
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* A predicate over GitHub's validation codes, for `Effect.catchIf`.
|
|
222
|
+
*
|
|
223
|
+
* @remarks
|
|
224
|
+
* Matches when any entry in {@link GitHubError}'s `validation` carries one of
|
|
225
|
+
* the codes. Use it for the distinctions {@link GitHubErrorKind} deliberately
|
|
226
|
+
* does not draw, such as a `missing_field` against an `invalid`.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* import { GitHubError } from "@effected/github";
|
|
231
|
+
* import { Effect } from "effect";
|
|
232
|
+
*
|
|
233
|
+
* declare const create: Effect.Effect<void, GitHubError>;
|
|
234
|
+
*
|
|
235
|
+
* const tolerant = create.pipe(
|
|
236
|
+
* Effect.catchIf(GitHubError.hasValidationCode("missing"), () => Effect.void),
|
|
237
|
+
* );
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
static hasValidationCode(...codes) {
|
|
241
|
+
const set = new Set(codes);
|
|
242
|
+
return (error) => error.validation?.some((entry) => entry.code !== void 0 && set.has(entry.code)) ?? false;
|
|
243
|
+
}
|
|
163
244
|
};
|
|
164
245
|
/**
|
|
165
246
|
* Read an unknown throwable structurally.
|
|
@@ -176,7 +257,7 @@ const readThrowable = (error) => {
|
|
|
176
257
|
status: void 0,
|
|
177
258
|
headers: void 0,
|
|
178
259
|
reason: String(error),
|
|
179
|
-
|
|
260
|
+
validation: []
|
|
180
261
|
};
|
|
181
262
|
const record = error;
|
|
182
263
|
const response = asRecord(record.response);
|
|
@@ -186,7 +267,7 @@ const readThrowable = (error) => {
|
|
|
186
267
|
status: typeof record.status === "number" ? record.status : void 0,
|
|
187
268
|
headers,
|
|
188
269
|
reason: sanitizeReason(typeof record.message === "string" ? record.message : String(error)),
|
|
189
|
-
|
|
270
|
+
validation: readValidation(data)
|
|
190
271
|
};
|
|
191
272
|
};
|
|
192
273
|
const asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
@@ -205,18 +286,32 @@ const sanitizeReason = (message) => {
|
|
|
205
286
|
return trimmed;
|
|
206
287
|
};
|
|
207
288
|
const MAX_REASON_LENGTH = 500;
|
|
208
|
-
/** GitHub's validation failures arrive as `data.errors[].
|
|
209
|
-
const
|
|
289
|
+
/** GitHub's validation failures arrive as `data.errors[]` entries. */
|
|
290
|
+
const readValidation = (data) => {
|
|
210
291
|
const errors = data?.errors;
|
|
211
292
|
if (!Array.isArray(errors)) return [];
|
|
212
|
-
const
|
|
213
|
-
for (const
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
293
|
+
const entries = [];
|
|
294
|
+
for (const raw of errors) {
|
|
295
|
+
const record = asRecord(raw);
|
|
296
|
+
if (record === void 0) continue;
|
|
297
|
+
const resource = stringField(record, "resource");
|
|
298
|
+
const field = stringField(record, "field");
|
|
299
|
+
const code = stringField(record, "code");
|
|
300
|
+
const message = stringField(record, "message");
|
|
301
|
+
if (resource === void 0 && field === void 0 && code === void 0 && message === void 0) continue;
|
|
302
|
+
entries.push(GitHubValidationEntry.make({
|
|
303
|
+
...resource !== void 0 ? { resource } : {},
|
|
304
|
+
...field !== void 0 ? { field } : {},
|
|
305
|
+
...code !== void 0 ? { code } : {},
|
|
306
|
+
...message !== void 0 ? { message } : {}
|
|
307
|
+
}));
|
|
216
308
|
}
|
|
217
|
-
return
|
|
309
|
+
return entries;
|
|
218
310
|
};
|
|
311
|
+
const stringField = (record, key) => typeof record[key] === "string" ? record[key] : void 0;
|
|
219
312
|
const ALREADY_EXISTS = "already exists";
|
|
313
|
+
/** GitHub's documented validation-error code for a duplicate resource. */
|
|
314
|
+
const ALREADY_EXISTS_CODE = "already_exists";
|
|
220
315
|
const classify = (facts, retryAfterMillis) => {
|
|
221
316
|
const { status } = facts;
|
|
222
317
|
if (status === void 0) return "transport";
|
|
@@ -228,9 +323,16 @@ const classify = (facts, retryAfterMillis) => {
|
|
|
228
323
|
if (status === 422 || status === 409) return saysAlreadyExists(facts) ? "alreadyExists" : "rejected";
|
|
229
324
|
return "rejected";
|
|
230
325
|
};
|
|
326
|
+
/**
|
|
327
|
+
* @remarks
|
|
328
|
+
* The structured code is the authority — the releases endpoint sends it with
|
|
329
|
+
* no message at all. The prose checks cover endpoints that say so only in
|
|
330
|
+
* words, such as `/git/refs` answering "Reference already exists".
|
|
331
|
+
*/
|
|
231
332
|
const saysAlreadyExists = (facts) => {
|
|
333
|
+
if (facts.validation.some((entry) => entry.code === ALREADY_EXISTS_CODE)) return true;
|
|
232
334
|
if (facts.reason.toLowerCase().includes(ALREADY_EXISTS)) return true;
|
|
233
|
-
return facts.
|
|
335
|
+
return facts.validation.some((entry) => entry.message?.toLowerCase().includes(ALREADY_EXISTS) ?? false);
|
|
234
336
|
};
|
|
235
337
|
/**
|
|
236
338
|
* Re-exported for the client, which reads the same headers on the **success**
|
|
@@ -251,4 +353,4 @@ const readRateLimitHeaders = (headers) => {
|
|
|
251
353
|
};
|
|
252
354
|
|
|
253
355
|
//#endregion
|
|
254
|
-
export { GitHubError, GitHubErrorKind, readRateLimitHeaders };
|
|
356
|
+
export { GitHubError, GitHubErrorKind, GitHubValidationCode, GitHubValidationEntry, readRateLimitHeaders };
|
package/README.md
CHANGED
|
@@ -238,6 +238,21 @@ const program = upsertBranch.pipe(
|
|
|
238
238
|
);
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
+
A 422 also carries GitHub's validation entries as `validation`, each a `GitHubValidationEntry` with the `resource`, `field`, `code` and `message` GitHub sent. Only `already_exists` gets a `kind` of its own; for the other documented codes (`GitHubValidationCode`), branch with `hasValidationCode` rather than reading `reason`:
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
import { GitHubError } from "@effected/github";
|
|
245
|
+
import { Effect } from "effect";
|
|
246
|
+
|
|
247
|
+
declare const createRelease: Effect.Effect<void, GitHubError>;
|
|
248
|
+
|
|
249
|
+
const program = createRelease.pipe(
|
|
250
|
+
Effect.catchIf(GitHubError.hasValidationCode("missing_field", "invalid"), (error) =>
|
|
251
|
+
Effect.logError(`bad release parameters: ${error.validation?.map((entry) => entry.field).join(", ")}`),
|
|
252
|
+
),
|
|
253
|
+
);
|
|
254
|
+
```
|
|
255
|
+
|
|
241
256
|
Retrying is handled once, in the client: `RetryPolicy.default` retries a `transport` or `rateLimited` failure with full-jitter backoff, honoring GitHub's `retry-after` header up to a configurable ceiling. `RetryPolicy.none` disables it. A `notFound`, `rejected` or `unauthorized` failure never retries — it cannot change its mind between attempts.
|
|
242
257
|
|
|
243
258
|
## Testing
|
|
@@ -282,7 +297,7 @@ const TestClient = GitHubClient.layerFixture(fixtures);
|
|
|
282
297
|
- `Repo` / `RepoRef` — the `{ owner, repo }` coordinate, resolved per call through `R`, with `Repo.provide` for multi-repository programs.
|
|
283
298
|
- `GitHubRepository` — the repository's settings as GitHub's own generated type, plus `defaultBranch`, `nodeId`, `ownerType` for gating organization-only fields, and `applySettings` reporting the keys it actually sent.
|
|
284
299
|
- `repositoryPatch` / `RepositoryPatchDraft` — build an `updateSettings` patch from fields that may be `undefined`, under `exactOptionalPropertyTypes`, without a cast.
|
|
285
|
-
- `GitHubError` / `GitHubGraphQLError` — one error per transport, `kind`-routed with `hasKind` for `Effect.catchIf`.
|
|
300
|
+
- `GitHubError` / `GitHubGraphQLError` — one error per transport, `kind`-routed with `hasKind` for `Effect.catchIf`; a REST 422's validation entries ride on `validation`, matched with `hasValidationCode`.
|
|
286
301
|
- `RetryPolicy` — the client's one retry policy: full-jitter backoff, server-advised delays honored up to a ceiling.
|
|
287
302
|
- `GitHubApp` — App JWT signing, installation token minting/revocation, app and installation identity, and `clientLayer` for an App-authenticated `GitHubClient`.
|
|
288
303
|
- `GitBranch` / `GitTag` — Git Database API refs, with `upsert` collapsing the create-or-reset dance to one call and `GitTag.latestSemver` picking the newest version-shaped tag in one pass.
|
package/index.d.ts
CHANGED
|
@@ -19,6 +19,47 @@ import { SemVer } from "@effected/semver";
|
|
|
19
19
|
* @public
|
|
20
20
|
*/
|
|
21
21
|
export declare const GitHubErrorKind: Schema.Literals<readonly ["notFound", "alreadyExists", "rejected", "unauthorized", "rateLimited", "transport", "decode"]>;
|
|
22
|
+
/**
|
|
23
|
+
* The validation codes GitHub documents for a 422's `errors[].code`.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* The complete documented set. Only `already_exists` earns its own
|
|
27
|
+
* {@link GitHubErrorKind}; every other code classifies as `rejected`, and a
|
|
28
|
+
* caller that needs to tell them apart reads {@link GitHubError}'s `validation`
|
|
29
|
+
* or uses {@link GitHubError.hasValidationCode}.
|
|
30
|
+
*
|
|
31
|
+
* `missing` is the one that looks like `notFound` and is not: it names a
|
|
32
|
+
* resource the request *referred to* — a commit sha, an assignee — not the one
|
|
33
|
+
* it acted on. Routing it to `notFound` would let every
|
|
34
|
+
* `catchIf(GitHubError.hasKind("notFound"), …)` recovery swallow a bad argument.
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export declare const GitHubValidationCode: Schema.Literals<readonly ["missing", "missing_field", "invalid", "already_exists", "unprocessable", "custom"]>;
|
|
39
|
+
declare const GitHubValidationEntry_base: Schema.Class<GitHubValidationEntry, Schema.Struct<{
|
|
40
|
+
/** The resource type GitHub validated, e.g. `"Release"`. */
|
|
41
|
+
readonly resource: Schema.optionalKey<Schema.String>;
|
|
42
|
+
/** The parameter at fault, e.g. `"tag_name"`. */
|
|
43
|
+
readonly field: Schema.optionalKey<Schema.String>;
|
|
44
|
+
/** GitHub's validation code — one of {@link GitHubValidationCode} when documented. */
|
|
45
|
+
readonly code: Schema.optionalKey<Schema.String>;
|
|
46
|
+
/** GitHub's prose, when it sent any. */
|
|
47
|
+
readonly message: Schema.optionalKey<Schema.String>;
|
|
48
|
+
}>, {}>;
|
|
49
|
+
/**
|
|
50
|
+
* One entry from a failed response's `data.errors` array, as GitHub sent it.
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* Every field is optional because GitHub's entries vary by endpoint: the
|
|
54
|
+
* releases endpoint sends `resource`, `code` and `field` with no `message`,
|
|
55
|
+
* while a `custom` entry may carry only a `message`. `code` is a plain string
|
|
56
|
+
* rather than {@link GitHubValidationCode} so an unexpected code cannot make
|
|
57
|
+
* the error itself fail to construct: a refused request must still surface as
|
|
58
|
+
* a `GitHubError`, never as a defect.
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export declare class GitHubValidationEntry extends GitHubValidationEntry_base {}
|
|
22
63
|
declare const GitHubError_base: Schema.Class<GitHubError, Schema.TaggedStruct<"GitHubError", {
|
|
23
64
|
/** Structural routing. Branch on this, never on the rendered message. */
|
|
24
65
|
readonly kind: Schema.Literals<readonly ["notFound", "alreadyExists", "rejected", "unauthorized", "rateLimited", "transport", "decode"]>;
|
|
@@ -38,6 +79,15 @@ declare const GitHubError_base: Schema.Class<GitHubError, Schema.TaggedStruct<"G
|
|
|
38
79
|
* `retryable` boolean it used to travel with is now a derived getter.
|
|
39
80
|
*/
|
|
40
81
|
readonly retryAfterMillis: Schema.optionalKey<Schema.Int>;
|
|
82
|
+
/**
|
|
83
|
+
* GitHub's validation entries, when the failed response carried any.
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* The structured half of a 422: branch on an entry's `code` and `field`
|
|
87
|
+
* rather than on `reason`. Absent when GitHub sent no `errors` array — some
|
|
88
|
+
* 422s ("Update is not a fast forward") are prose only.
|
|
89
|
+
*/
|
|
90
|
+
readonly validation: Schema.optionalKey<Schema.$Array<typeof GitHubValidationEntry>>;
|
|
41
91
|
/** The underlying throwable, when one exists. */
|
|
42
92
|
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
43
93
|
}>, import("effect/Cause").YieldableError>;
|
|
@@ -109,6 +159,27 @@ export declare class GitHubError extends GitHubError_base {
|
|
|
109
159
|
* ```
|
|
110
160
|
*/
|
|
111
161
|
static hasKind(...kinds: ReadonlyArray<(typeof GitHubErrorKind.literals)[number]>): (error: GitHubError) => boolean;
|
|
162
|
+
/**
|
|
163
|
+
* A predicate over GitHub's validation codes, for `Effect.catchIf`.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Matches when any entry in {@link GitHubError}'s `validation` carries one of
|
|
167
|
+
* the codes. Use it for the distinctions {@link GitHubErrorKind} deliberately
|
|
168
|
+
* does not draw, such as a `missing_field` against an `invalid`.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* import { GitHubError } from "@effected/github";
|
|
173
|
+
* import { Effect } from "effect";
|
|
174
|
+
*
|
|
175
|
+
* declare const create: Effect.Effect<void, GitHubError>;
|
|
176
|
+
*
|
|
177
|
+
* const tolerant = create.pipe(
|
|
178
|
+
* Effect.catchIf(GitHubError.hasValidationCode("missing"), () => Effect.void),
|
|
179
|
+
* );
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
static hasValidationCode(...codes: ReadonlyArray<(typeof GitHubValidationCode.literals)[number]>): (error: GitHubError) => boolean;
|
|
112
183
|
}
|
|
113
184
|
//#endregion
|
|
114
185
|
//#region src/GraphQL.d.ts
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GitHubError, GitHubErrorKind } from "./GitHubError.js";
|
|
1
|
+
import { GitHubError, GitHubErrorKind, GitHubValidationCode, GitHubValidationEntry } from "./GitHubError.js";
|
|
2
2
|
import { GitHubGraphQLError, GraphQLDocument, GraphQLErrorEntry } from "./GraphQL.js";
|
|
3
3
|
import { RateLimitSnapshot, RetryPolicy } from "./Resilience.js";
|
|
4
4
|
import { GitHubClient } from "./GitHubClient.js";
|
|
@@ -28,4 +28,4 @@ import { ExtraPermission, PermissionGap, PermissionLevel, PermissionResult, Toke
|
|
|
28
28
|
import { WorkflowDispatch, WorkflowRunStatus } from "./WorkflowDispatch.js";
|
|
29
29
|
import { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
|
|
30
30
|
|
|
31
|
-
export { Annotation, AnnotationLevel, AppIdentity, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, BotIdentity, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeploymentEnvironment, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, ReleaseAsset, ReleaseInfo, Repo, RepoRef, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
|
|
31
|
+
export { Annotation, AnnotationLevel, AppIdentity, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, BotIdentity, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeploymentEnvironment, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitHubValidationCode, GitHubValidationEntry, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, ReleaseAsset, ReleaseInfo, Repo, RepoRef, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
|
package/internal/crypto.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Result } from "effect";
|
|
2
2
|
import blakejs from "blakejs";
|
|
3
|
+
import * as Base64 from "effect/encoding/Base64";
|
|
3
4
|
import nacl from "tweetnacl";
|
|
4
5
|
|
|
5
6
|
//#region src/internal/crypto.ts
|
|
@@ -29,7 +30,7 @@ const utf8 = new TextEncoder();
|
|
|
29
30
|
*
|
|
30
31
|
* ## Nothing here is Node-specific
|
|
31
32
|
*
|
|
32
|
-
* Base64 goes through core's `
|
|
33
|
+
* Base64 goes through core's `Base64` and text through `TextEncoder`, so this
|
|
33
34
|
* module imports **no builtin**. That is deliberate: an earlier draft used
|
|
34
35
|
* `node:buffer` and was the only thing in this package's reachable graph tying
|
|
35
36
|
* it to a runtime — neither `blakejs` (pure JS; its `util` is a *relative*
|
|
@@ -46,7 +47,7 @@ const utf8 = new TextEncoder();
|
|
|
46
47
|
*
|
|
47
48
|
* @internal
|
|
48
49
|
*/
|
|
49
|
-
const encryptSecret = (publicKey, secretValue) => Result.map(
|
|
50
|
+
const encryptSecret = (publicKey, secretValue) => Result.map(Base64.decode(publicKey), (publicKeyBytes) => {
|
|
50
51
|
const ephemeralKeyPair = nacl.box.keyPair();
|
|
51
52
|
const nonceInput = /* @__PURE__ */ new Uint8Array(64);
|
|
52
53
|
nonceInput.set(ephemeralKeyPair.publicKey);
|
|
@@ -56,7 +57,7 @@ const encryptSecret = (publicKey, secretValue) => Result.map(Encoding.decodeBase
|
|
|
56
57
|
const sealed = new Uint8Array(ephemeralKeyPair.publicKey.length + ciphertext.length);
|
|
57
58
|
sealed.set(ephemeralKeyPair.publicKey);
|
|
58
59
|
sealed.set(ciphertext, ephemeralKeyPair.publicKey.length);
|
|
59
|
-
return
|
|
60
|
+
return Base64.encode(sealed);
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Typed GitHub REST and GraphQL services over the octokit core request surface, with app auth and resource helpers.",
|
|
6
6
|
"keywords": [
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"./package.json": "./package.json"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@effected/github-references": "^0.
|
|
42
|
-
"@effected/semver": "^0.
|
|
41
|
+
"@effected/github-references": "^0.6.0",
|
|
42
|
+
"@effected/semver": "^0.10.0",
|
|
43
43
|
"@octokit/core": "^7.0.6",
|
|
44
44
|
"@octokit/plugin-paginate-rest": "^15.0.0",
|
|
45
45
|
"@octokit/types": "^18.0.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"universal-github-app-jwt": "^2.2.2"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"effect": "4.0.0-rc.
|
|
51
|
+
"effect": "4.0.0-rc.118"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=24.11.0"
|