@effected/github 0.25.0 → 0.26.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/DeploymentEnvironment.js +7 -2
- package/GitHubApp.js +10 -1
- package/GitHubClient.js +68 -19
- package/GitHubError.js +13 -2
- package/GitHubRelease.js +23 -6
- package/GitHubRepository.js +74 -22
- package/GraphQL.js +7 -1
- package/index.d.ts +249 -27
- package/internal/confinement.js +62 -0
- package/internal/octokit.js +95 -5
- package/internal/requestOptions.js +84 -0
- package/internal/scrub.js +113 -0
- package/internal/uploads.js +70 -0
- package/package.json +6 -5
- package/tsdoc-metadata.json +1 -1
package/index.d.ts
CHANGED
|
@@ -272,7 +272,7 @@ declare const GitHubError_base: Schema.Class<GitHubError, Schema.TaggedStruct<"G
|
|
|
272
272
|
* 422s ("Update is not a fast forward") are prose only.
|
|
273
273
|
*/
|
|
274
274
|
readonly validation: Schema.optionalKey<Schema.$Array<typeof GitHubValidationEntry>>;
|
|
275
|
-
/** The underlying throwable, when one exists. */
|
|
275
|
+
/** The underlying throwable, when one exists; an octokit throwable is kept as a credential-free copy. */
|
|
276
276
|
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
277
277
|
}>, import("effect/Cause").YieldableError>;
|
|
278
278
|
/**
|
|
@@ -318,6 +318,16 @@ export declare class GitHubError extends GitHubError_base {
|
|
|
318
318
|
* epoch second, and turning it into a delay needs a "now" the caller controls.
|
|
319
319
|
* The client supplies `Clock.currentTimeMillis`, which is the `TestClock`
|
|
320
320
|
* under test.
|
|
321
|
+
*
|
|
322
|
+
* The kept `cause` is a credential-free copy of the throwable, not the
|
|
323
|
+
* throwable itself. octokit redacts only the `authorization` credential and
|
|
324
|
+
* two query values; the copy also drops the request body (a webhook secret,
|
|
325
|
+
* GraphQL variables), the per-request options and the response body beyond
|
|
326
|
+
* its top-level `message` and `documentation_url`, drops `set-cookie`, and
|
|
327
|
+
* reads `REDACTED` for every other credential-bearing header. It keeps the
|
|
328
|
+
* prototype (so `instanceof` still answers), `name`, `message`, `status`,
|
|
329
|
+
* the method, the redacted url and the remaining headers. A throwable with
|
|
330
|
+
* no `request`, `response` or `headers` field is kept as it is.
|
|
321
331
|
*/
|
|
322
332
|
static fromOctokit(operation: string, error: unknown, nowMillis: number): GitHubError;
|
|
323
333
|
/**
|
|
@@ -437,6 +447,11 @@ export declare class GitHubGraphQLError extends GitHubGraphQLError_base {
|
|
|
437
447
|
* failure with a `status`. Both arrive as throwables and both are read
|
|
438
448
|
* structurally, for the same reason the REST classifier does it — the error
|
|
439
449
|
* classes live in packages this one does not declare.
|
|
450
|
+
*
|
|
451
|
+
* The kept `cause` is the same credential-free copy
|
|
452
|
+
* {@link GitHubError.fromOctokit} keeps: the GraphQL document, its variables
|
|
453
|
+
* and any partial `data` are dropped with the rest of the request and response
|
|
454
|
+
* bodies.
|
|
440
455
|
*/
|
|
441
456
|
static fromThrowable(operation: string, error: unknown, nowMillis: number): GitHubGraphQLError;
|
|
442
457
|
}
|
|
@@ -649,17 +664,22 @@ export declare class RetryPolicy extends RetryPolicy_base {
|
|
|
649
664
|
*/
|
|
650
665
|
type Route = keyof Endpoints;
|
|
651
666
|
/**
|
|
652
|
-
* Transport knobs octokit accepts on any route, narrowed to the
|
|
667
|
+
* Transport knobs octokit accepts on any route, narrowed to the two this
|
|
653
668
|
* package allows.
|
|
654
669
|
*
|
|
655
670
|
* @remarks
|
|
656
671
|
* octokit's own `RequestParameters` carries an `[parameter: string]: unknown`
|
|
657
672
|
* index signature, so intersecting it would silently accept every misspelled
|
|
658
|
-
* parameter. These
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
*
|
|
673
|
+
* parameter. These two are the ones callers need: `headers` for a release
|
|
674
|
+
* asset's `content-type` and the attestations API version pin, and
|
|
675
|
+
* `mediaType.format` for raw content reads. Everything else a caller might
|
|
676
|
+
* reach for is a real endpoint parameter and is already typed.
|
|
677
|
+
*
|
|
678
|
+
* There is no knob that moves a request: **a client's token only ever goes to
|
|
679
|
+
* the host it was configured with.** octokit reads `baseUrl` and `url` off the
|
|
680
|
+
* flat parameters as the request's host, so the raw surface refuses either
|
|
681
|
+
* name, and an absolute-URL route, with a `rejected` `GitHubError` and nothing
|
|
682
|
+
* sent. A request to another GitHub host is a second client configured for it.
|
|
663
683
|
*
|
|
664
684
|
* @public
|
|
665
685
|
*/
|
|
@@ -670,16 +690,21 @@ interface RequestExtras {
|
|
|
670
690
|
readonly mediaType?: {
|
|
671
691
|
readonly format?: string;
|
|
672
692
|
};
|
|
673
|
-
/** Overrides the API host for this one request. */
|
|
674
|
-
readonly baseUrl?: string;
|
|
675
693
|
}
|
|
676
694
|
/**
|
|
677
695
|
* The parameters `Route` accepts — path, query and body parameters from
|
|
678
696
|
* GitHub's OpenAPI description, plus the extras below.
|
|
679
697
|
*
|
|
698
|
+
* @remarks
|
|
699
|
+
* `baseUrl` is typed `never`, so passing one is a compile error: the request
|
|
700
|
+
* goes to the client's configured host and nowhere else. One that arrives
|
|
701
|
+
* through a cast is refused at runtime.
|
|
702
|
+
*
|
|
680
703
|
* @public
|
|
681
704
|
*/
|
|
682
|
-
type Params<R extends Route> = Endpoints[R]["parameters"] & RequestExtras
|
|
705
|
+
type Params<R extends Route> = Endpoints[R]["parameters"] & RequestExtras & {
|
|
706
|
+
readonly baseUrl?: never;
|
|
707
|
+
};
|
|
683
708
|
/**
|
|
684
709
|
* The full response `Route` returns, including `status`, `headers` and `data`.
|
|
685
710
|
*
|
|
@@ -770,6 +795,12 @@ interface GitHubClientShape {
|
|
|
770
795
|
/**
|
|
771
796
|
* One request. The route types both the parameters and the returned `data`.
|
|
772
797
|
*
|
|
798
|
+
* @remarks
|
|
799
|
+
* The request carries this client's token to the configured base URL and
|
|
800
|
+
* nowhere else. A `baseUrl` or `url` parameter (through a cast), or a
|
|
801
|
+
* route that resolves to another origin, fails `kind: "rejected"` with no
|
|
802
|
+
* status and nothing sent.
|
|
803
|
+
*
|
|
773
804
|
* @example
|
|
774
805
|
* ```ts
|
|
775
806
|
* import { GitHubClient } from "@effected/github";
|
|
@@ -794,13 +825,29 @@ interface GitHubClientShape {
|
|
|
794
825
|
* checked. The attestations read uses it, because pinning
|
|
795
826
|
* `X-GitHub-Api-Version` puts the response on a contract the generated types
|
|
796
827
|
* do not describe.
|
|
828
|
+
*
|
|
829
|
+
* The token goes to the configured base URL and nowhere else. An
|
|
830
|
+
* absolute-URL route (`"POST https://host/path"`, which octokit would send
|
|
831
|
+
* as written) on another origin, a `baseUrl`, `url`, `request` or `method`
|
|
832
|
+
* parameter, or a template that expands to another host fails
|
|
833
|
+
* `kind: "rejected"` with no status and nothing sent. A body field octokit
|
|
834
|
+
* would otherwise read as an option, such as a webhook configuration's
|
|
835
|
+
* `url`, goes inside `data`, which is sent as the whole body.
|
|
797
836
|
*/
|
|
798
|
-
readonly requestDecoded: <A, I>(route: string, params: Record<string, unknown> & RequestExtras
|
|
837
|
+
readonly requestDecoded: <A, I>(route: string, params: Record<string, unknown> & RequestExtras & {
|
|
838
|
+
readonly baseUrl?: never;
|
|
839
|
+
}, schema: Schema.Codec<A, I>) => Effect.Effect<A, GitHubError>;
|
|
799
840
|
/**
|
|
800
841
|
* Collect every page of a paginating route, honoring {@link PageOptions}.
|
|
801
842
|
*
|
|
802
843
|
* @remarks
|
|
803
844
|
* Handing this a non-paginating route is a compile error.
|
|
845
|
+
*
|
|
846
|
+
* Every page goes to the configured host. A route or parameter that
|
|
847
|
+
* resolves elsewhere is refused before the first request, and a `Link`
|
|
848
|
+
* header whose next page names another origin fails the walk
|
|
849
|
+
* `kind: "rejected"` before that page is requested, rather than sending the
|
|
850
|
+
* token there or ending the walk early as if the collection were complete.
|
|
804
851
|
*/
|
|
805
852
|
readonly paginate: <R extends PaginatingRoute>(route: R, params: Params<R>, options?: PageOptions) => Effect.Effect<ReadonlyArray<Item<R>>, GitHubError>;
|
|
806
853
|
/**
|
|
@@ -808,7 +855,8 @@ interface GitHubClientShape {
|
|
|
808
855
|
*
|
|
809
856
|
* @remarks
|
|
810
857
|
* Lazy in requests: a downstream `Stream.take` stops the walk rather than
|
|
811
|
-
* filtering pages that were already fetched.
|
|
858
|
+
* filtering pages that were already fetched. Confined to the configured
|
|
859
|
+
* host exactly as {@link GitHubClientShape.paginate} is.
|
|
812
860
|
*/
|
|
813
861
|
readonly paginateStream: <R extends PaginatingRoute>(route: R, params: Params<R>, options?: PageOptions) => Stream.Stream<Item<R>, GitHubError>;
|
|
814
862
|
/** Run an owned GraphQL document and decode its answer. */
|
|
@@ -1116,6 +1164,12 @@ export declare class GitHubClient extends GitHubClient_base {
|
|
|
1116
1164
|
* `rateLimit` answers `Option.none()` and `apiVersion` the live default,
|
|
1117
1165
|
* because a real client legitimately answers both without a request.
|
|
1118
1166
|
*
|
|
1167
|
+
* It refuses what the live client refuses, before any override runs: a
|
|
1168
|
+
* `baseUrl`, `url`, `request` or `method` parameter (a body field called
|
|
1169
|
+
* `url` goes inside `data`), or a route that resolves off github.com's REST
|
|
1170
|
+
* root, fails `kind: "rejected"` with no status. A double has no
|
|
1171
|
+
* configured base, so an absolute-URL route must name `api.github.com`.
|
|
1172
|
+
*
|
|
1119
1173
|
* For recorded responses that page for real, use
|
|
1120
1174
|
* {@link GitHubClient.layerFixture}.
|
|
1121
1175
|
*/
|
|
@@ -1140,6 +1194,11 @@ export declare class GitHubClient extends GitHubClient_base {
|
|
|
1140
1194
|
* one fixture both records the calls and classifies a raw failure the way
|
|
1141
1195
|
* the live client would; there is no need to classify by hand inside a
|
|
1142
1196
|
* {@link GitHubClient.layerTest} handler.
|
|
1197
|
+
*
|
|
1198
|
+
* It refuses what the live client refuses, exactly as
|
|
1199
|
+
* {@link GitHubClient.makeTest} does. A refused call fails
|
|
1200
|
+
* `kind: "rejected"` and is **not** recorded in `requested`: it is never
|
|
1201
|
+
* served, as a refused live call never reaches the wire.
|
|
1143
1202
|
*/
|
|
1144
1203
|
static readonly layerFixture: (fixtures: GitHubFixtures) => Layer.Layer<GitHubClient>;
|
|
1145
1204
|
}
|
|
@@ -2090,6 +2149,14 @@ interface DeploymentEnvironmentShape {
|
|
|
2090
2149
|
* `config` stays an open record because the protection-rule body is a moving
|
|
2091
2150
|
* target: wait timers, reviewers, deployment-branch policies and whatever
|
|
2092
2151
|
* GitHub adds next.
|
|
2152
|
+
*
|
|
2153
|
+
* It is sent as the request BODY and nothing else. octokit reads `baseUrl`,
|
|
2154
|
+
* `url`, `method`, `headers`, `request` and `mediaType` off a call's flat
|
|
2155
|
+
* parameters as the request itself, and a `data` key as the whole body, so a
|
|
2156
|
+
* config spread beside the coordinates could send the authenticated `PUT` to
|
|
2157
|
+
* another host with the token attached. A config naming one of those, the
|
|
2158
|
+
* route's own `owner`, `repo` or `environment_name`, or `__proto__`, dies
|
|
2159
|
+
* with a `RangeError` before any request is made.
|
|
2093
2160
|
*/
|
|
2094
2161
|
readonly upsert: (name: string, config?: Record<string, unknown>) => Effect.Effect<void, GitHubError, Repo>;
|
|
2095
2162
|
/** The repository's deployment environments. */
|
|
@@ -3470,7 +3537,15 @@ declare const ReleaseInfo_base: Schema.Class<ReleaseInfo, Schema.Struct<{
|
|
|
3470
3537
|
readonly prerelease: Schema.Boolean;
|
|
3471
3538
|
/** The web URL. */
|
|
3472
3539
|
readonly url: Schema.String;
|
|
3473
|
-
/**
|
|
3540
|
+
/**
|
|
3541
|
+
* The templated upload endpoint GitHub hands back for assets.
|
|
3542
|
+
*
|
|
3543
|
+
* @remarks
|
|
3544
|
+
* {@link GitHubReleaseShape.uploadAsset} never routes by this value: it is
|
|
3545
|
+
* response data. It only cross-checks that its origin is the upload host
|
|
3546
|
+
* derived from the client's configured base URL, and refuses the upload
|
|
3547
|
+
* when it is not.
|
|
3548
|
+
*/
|
|
3474
3549
|
readonly uploadUrl: Schema.String;
|
|
3475
3550
|
}>, {}>;
|
|
3476
3551
|
/**
|
|
@@ -3528,9 +3603,9 @@ interface GitHubReleaseShape {
|
|
|
3528
3603
|
*
|
|
3529
3604
|
* @remarks
|
|
3530
3605
|
* The one route in this package that is **not** in GitHub's generated
|
|
3531
|
-
* endpoint map: asset upload goes to
|
|
3532
|
-
* body, and the map omits it. So it
|
|
3533
|
-
*
|
|
3606
|
+
* endpoint map: asset upload goes to a separate upload host with a raw
|
|
3607
|
+
* binary body, and the map omits it. So it is decoded against an owned
|
|
3608
|
+
* schema — the escape hatch is from the route table, never from typing.
|
|
3534
3609
|
*
|
|
3535
3610
|
* Being outside the map cuts the other way too: octokit has no schema
|
|
3536
3611
|
* saying `name` is a **query** parameter, so the route template must carry
|
|
@@ -3538,6 +3613,29 @@ interface GitHubReleaseShape {
|
|
|
3538
3613
|
* `Invalid name for request` — a hand-written route owns its query
|
|
3539
3614
|
* parameters in the template, always. `label` is the endpoint's optional
|
|
3540
3615
|
* display label, shown in place of the file name on the release page.
|
|
3616
|
+
*
|
|
3617
|
+
* The upload host is derived from the base URL the client was **configured**
|
|
3618
|
+
* with, so the token only goes where the caller pointed it: github.com
|
|
3619
|
+
* (`https://api.github.com`, or no `baseUrl`) uploads to
|
|
3620
|
+
* `https://uploads.github.com`, GitHub Enterprise Server
|
|
3621
|
+
* (`https://<host>/api/v3`) to `https://<host>/api/uploads`, and any other
|
|
3622
|
+
* base to itself. The release's own `uploadUrl` is response data, so it is
|
|
3623
|
+
* never the route; its origin must equal the derived host's, or the call
|
|
3624
|
+
* fails `kind: "rejected"` with no status and nothing is sent.
|
|
3625
|
+
*
|
|
3626
|
+
* The client's public `requestDecoded` cannot reach the upload host: it
|
|
3627
|
+
* refuses every host but the configured API host. A client this package
|
|
3628
|
+
* built uploads through a private channel it carries off its public type,
|
|
3629
|
+
* which takes no host from anyone. A shape spread from a built client
|
|
3630
|
+
* (`{ ...client, requestDecoded }`) keeps that channel, so its upload does
|
|
3631
|
+
* **not** go through an overridden `requestDecoded`.
|
|
3632
|
+
*
|
|
3633
|
+
* A client shape this package did not build (`GitHubClient.makeTest`,
|
|
3634
|
+
* `layerFixture`, a hand-written double) has no channel: it is read as
|
|
3635
|
+
* github.com for the `uploadUrl` check, and the upload is handed to its own
|
|
3636
|
+
* `requestDecoded`, so a double records and answers it as usual. Before
|
|
3637
|
+
* these checks, a GitHub Enterprise Server client's upload sent its token to
|
|
3638
|
+
* `uploads.github.com`.
|
|
3541
3639
|
*/
|
|
3542
3640
|
readonly uploadAsset: (release: ReleaseInfo, asset: {
|
|
3543
3641
|
readonly name: string;
|
|
@@ -3593,11 +3691,20 @@ export declare class GitHubRelease extends GitHubRelease_base {
|
|
|
3593
3691
|
*/
|
|
3594
3692
|
type RepositorySettings = Data<"GET /repos/{owner}/{repo}">;
|
|
3595
3693
|
/**
|
|
3596
|
-
* The fields `PATCH /repos/{owner}/{repo}` accepts, minus the coordinate
|
|
3694
|
+
* The fields `PATCH /repos/{owner}/{repo}` accepts, minus the coordinate and
|
|
3695
|
+
* the per-request transport options.
|
|
3696
|
+
*
|
|
3697
|
+
* @remarks
|
|
3698
|
+
* A patch is the request **body** and nothing else. `GitHubRepository`
|
|
3699
|
+
* sends it as octokit's `data` option, so no key in it is ever read as a
|
|
3700
|
+
* request option (`baseUrl`, `url`, `headers`, `request`, `mediaType`) or as
|
|
3701
|
+
* the route's `owner` / `repo`. The transport knobs of `Rest.RequestExtras`
|
|
3702
|
+
* are therefore left out of the type: carried in a patch they would be body
|
|
3703
|
+
* fields, not the options they are named after.
|
|
3597
3704
|
*
|
|
3598
3705
|
* @public
|
|
3599
3706
|
*/
|
|
3600
|
-
type RepositoryPatch = Omit<Params<"PATCH /repos/{owner}/{repo}">, "owner" | "repo">;
|
|
3707
|
+
type RepositoryPatch = Omit<Params<"PATCH /repos/{owner}/{repo}">, "owner" | "repo" | keyof RequestExtras>;
|
|
3601
3708
|
/**
|
|
3602
3709
|
* A {@link RepositoryPatch} under construction, where an absent field may be
|
|
3603
3710
|
* spelled as an explicit `undefined`.
|
|
@@ -3613,9 +3720,66 @@ type RepositoryPatch = Omit<Params<"PATCH /repos/{owner}/{repo}">, "owner" | "re
|
|
|
3613
3720
|
* @public
|
|
3614
3721
|
*/
|
|
3615
3722
|
type RepositoryPatchDraft = { readonly [K in keyof RepositoryPatch]?: RepositoryPatch[K] | undefined; };
|
|
3723
|
+
/**
|
|
3724
|
+
* Repository settings the generated {@link RepositoryPatch} type does not know
|
|
3725
|
+
* yet, for {@link RepositoryPatchOptions.extra}.
|
|
3726
|
+
*
|
|
3727
|
+
* @remarks
|
|
3728
|
+
* An open map minus every key `RepositoryPatch` declares: a known key written
|
|
3729
|
+
* here is a compile error, so it has to go in the draft, where its value is
|
|
3730
|
+
* checked against octokit's type. Only what octokit has not caught up with
|
|
3731
|
+
* travels unchecked. The guard holds for a literal; a value already typed
|
|
3732
|
+
* `Record<string, unknown>` assigns anyway (an index signature does not meet an
|
|
3733
|
+
* optional property), which is why {@link repositoryPatch} checks again at
|
|
3734
|
+
* runtime.
|
|
3735
|
+
*
|
|
3736
|
+
* @public
|
|
3737
|
+
*/
|
|
3738
|
+
type RepositoryPatchExtra = {
|
|
3739
|
+
readonly [key: string]: unknown;
|
|
3740
|
+
} & { readonly [K in keyof RepositoryPatch]?: never; } & { readonly [K in RepositoryPatchReservedKey]?: never; };
|
|
3741
|
+
/**
|
|
3742
|
+
* Names {@link repositoryPatch} refuses in a draft or an extra.
|
|
3743
|
+
*
|
|
3744
|
+
* @remarks
|
|
3745
|
+
* octokit takes a route's path parameters, body fields and transport options
|
|
3746
|
+
* in one flat object, and `@octokit/endpoint` reads these names as the request
|
|
3747
|
+
* itself: `baseUrl` and `url` pick the host the authenticated request goes to,
|
|
3748
|
+
* `headers` its headers, `request` the fetch implementation, `data` the whole
|
|
3749
|
+
* body, `method` the verb, and `owner` / `repo` the path of
|
|
3750
|
+
* `PATCH /repos/{owner}/{repo}`. `__proto__` would set the patch's prototype
|
|
3751
|
+
* instead of a field. None of them is a repository setting.
|
|
3752
|
+
*
|
|
3753
|
+
* @public
|
|
3754
|
+
*/
|
|
3755
|
+
type RepositoryPatchReservedKey = "method" | "baseUrl" | "url" | "headers" | "request" | "mediaType" | "data" | "owner" | "repo" | "__proto__";
|
|
3756
|
+
/**
|
|
3757
|
+
* Options for {@link repositoryPatch}.
|
|
3758
|
+
*
|
|
3759
|
+
* @public
|
|
3760
|
+
*/
|
|
3761
|
+
interface RepositoryPatchOptions {
|
|
3762
|
+
/**
|
|
3763
|
+
* Settings GitHub accepts that octokit's generated types do not declare
|
|
3764
|
+
* yet, sent verbatim.
|
|
3765
|
+
*
|
|
3766
|
+
* @remarks
|
|
3767
|
+
* **GitHub may ignore them silently.** The REST `PATCH` answers 200 for a
|
|
3768
|
+
* field it does not recognise, so a misspelled extra reads as applied while
|
|
3769
|
+
* nothing changed: read the setting back when it matters. An `undefined`
|
|
3770
|
+
* value is dropped, as in the draft. A key the PATCH body already declares,
|
|
3771
|
+
* or a GraphQL-only setting (`has_sponsorships`, `has_pull_requests`,
|
|
3772
|
+
* `has_discussions`, which this patch cannot set; use
|
|
3773
|
+
* `GitHubRepository.applySettings`), throws a `RangeError` naming it, as
|
|
3774
|
+
* does a {@link RepositoryPatchReservedKey}: an octokit request option
|
|
3775
|
+
* (`baseUrl`, `url`, `headers`, `request`, `data`, and so on), the route's
|
|
3776
|
+
* own `owner` / `repo`, or `__proto__`.
|
|
3777
|
+
*/
|
|
3778
|
+
readonly extra?: RepositoryPatchExtra | undefined;
|
|
3779
|
+
}
|
|
3616
3780
|
/**
|
|
3617
3781
|
* A {@link RepositoryPatch} from a draft, dropping every explicitly-`undefined`
|
|
3618
|
-
* field.
|
|
3782
|
+
* field, plus any settings octokit's types do not know yet.
|
|
3619
3783
|
*
|
|
3620
3784
|
* @remarks
|
|
3621
3785
|
* The supported spelling for "apply only what was configured" — the natural
|
|
@@ -3625,6 +3789,13 @@ type RepositoryPatchDraft = { readonly [K in keyof RepositoryPatch]?: Repository
|
|
|
3625
3789
|
* `PATCH` treats an absent field as "leave it alone", while an explicit `null`
|
|
3626
3790
|
* or `undefined` is a value.
|
|
3627
3791
|
*
|
|
3792
|
+
* `options.extra` is the typed escape hatch for a setting GitHub accepts
|
|
3793
|
+
* before octokit's generated types declare it: the draft stays checked, and
|
|
3794
|
+
* only the extras ride unchecked. The result is still typed `RepositoryPatch`,
|
|
3795
|
+
* and `GitHubRepository.updateSettings` sends every key it carries. A known key
|
|
3796
|
+
* passed through `extra` throws a `RangeError` rather than skipping the draft's
|
|
3797
|
+
* type check (see {@link RepositoryPatchOptions.extra}).
|
|
3798
|
+
*
|
|
3628
3799
|
* A key-by-key loop still defeats TypeScript's correlation between two indexed
|
|
3629
3800
|
* accesses (`draft[key] = source[key]` over a union `key`), which no helper can
|
|
3630
3801
|
* fix — build the draft as a literal where you can.
|
|
@@ -3634,19 +3805,24 @@ type RepositoryPatchDraft = { readonly [K in keyof RepositoryPatch]?: Repository
|
|
|
3634
3805
|
* import { repositoryPatch } from "@effected/github";
|
|
3635
3806
|
*
|
|
3636
3807
|
* // `config.has_issues` is `boolean | undefined`; absent fields drop out.
|
|
3637
|
-
* const patch = repositoryPatch(
|
|
3638
|
-
*
|
|
3639
|
-
*
|
|
3640
|
-
*
|
|
3641
|
-
*
|
|
3808
|
+
* const patch = repositoryPatch(
|
|
3809
|
+
* {
|
|
3810
|
+
* has_issues: config.has_issues,
|
|
3811
|
+
* has_wiki: config.has_wiki,
|
|
3812
|
+
* description: config.description,
|
|
3813
|
+
* },
|
|
3814
|
+
* // A setting GitHub accepts before octokit's types declare it.
|
|
3815
|
+
* { extra: { has_new_feature: true } },
|
|
3816
|
+
* );
|
|
3642
3817
|
* ```
|
|
3643
3818
|
*
|
|
3644
3819
|
* @param draft - The fields to apply, any of which may be `undefined`.
|
|
3820
|
+
* @param options - `extra`: settings the generated type does not declare.
|
|
3645
3821
|
* @returns A patch carrying only the fields that were actually set.
|
|
3646
3822
|
*
|
|
3647
3823
|
* @public
|
|
3648
3824
|
*/
|
|
3649
|
-
export declare const repositoryPatch: (draft: RepositoryPatchDraft) => RepositoryPatch;
|
|
3825
|
+
export declare const repositoryPatch: (draft: RepositoryPatchDraft, options?: RepositoryPatchOptions) => RepositoryPatch;
|
|
3650
3826
|
/**
|
|
3651
3827
|
* Whether an account is a user or an organization.
|
|
3652
3828
|
*
|
|
@@ -3741,8 +3917,50 @@ interface AppliedSettings {
|
|
|
3741
3917
|
* REST `PATCH` ignores unknown fields and answers 200, so the key would be
|
|
3742
3918
|
* reported applied while the repository never changed. A caller that wants
|
|
3743
3919
|
* an unknown key to fail the run checks this list.
|
|
3920
|
+
*
|
|
3921
|
+
* Under `unknownKeys: "send"` an undescribed key is sent instead and named
|
|
3922
|
+
* in {@link AppliedSettings.unverified}; a key the api-version removed is
|
|
3923
|
+
* still ignored, because the description says GitHub drops it.
|
|
3924
|
+
*
|
|
3925
|
+
* Under either mode, a name octokit reads as a request option rather than
|
|
3926
|
+
* a body field (`baseUrl`, `url`, `headers`, `request`, `mediaType`,
|
|
3927
|
+
* `method`, `data`), the route's own `owner` / `repo`, and `__proto__` are
|
|
3928
|
+
* never sent and land here.
|
|
3744
3929
|
*/
|
|
3745
3930
|
readonly ignored: ReadonlyArray<string>;
|
|
3931
|
+
/**
|
|
3932
|
+
* Keys sent on the REST patch that GitHub's description does not declare,
|
|
3933
|
+
* so nothing confirms GitHub acted on them. Always a subset of
|
|
3934
|
+
* {@link AppliedSettings.rest}, and empty unless the call passed
|
|
3935
|
+
* `unknownKeys: "send"`.
|
|
3936
|
+
*
|
|
3937
|
+
* @remarks
|
|
3938
|
+
* The REST `PATCH` answers 200 whether or not it recognised a field, so a
|
|
3939
|
+
* key here may have changed the repository or done nothing. Read the setting
|
|
3940
|
+
* back when it matters.
|
|
3941
|
+
*/
|
|
3942
|
+
readonly unverified: ReadonlyArray<string>;
|
|
3943
|
+
}
|
|
3944
|
+
/**
|
|
3945
|
+
* Options for {@link GitHubRepositoryShape.applySettings}.
|
|
3946
|
+
*
|
|
3947
|
+
* @public
|
|
3948
|
+
*/
|
|
3949
|
+
interface ApplySettingsOptions {
|
|
3950
|
+
/**
|
|
3951
|
+
* What to do with a key neither API declares. `"ignore"` (the default)
|
|
3952
|
+
* leaves it unsent and reports it in {@link AppliedSettings.ignored};
|
|
3953
|
+
* `"send"` forwards it on the REST patch verbatim and reports it in
|
|
3954
|
+
* {@link AppliedSettings.rest} and {@link AppliedSettings.unverified}.
|
|
3955
|
+
*
|
|
3956
|
+
* @remarks
|
|
3957
|
+
* `"send"` is for a sync tool applying settings a user declared that GitHub
|
|
3958
|
+
* accepts before its OpenAPI description, and octokit's types, catch up.
|
|
3959
|
+
* The cost is that a typo is sent too and answered 200, so it is only as
|
|
3960
|
+
* safe as the caller's own validation. GraphQL-only keys still route to
|
|
3961
|
+
* GraphQL, and a key the client's api-version removed is still ignored.
|
|
3962
|
+
*/
|
|
3963
|
+
readonly unknownKeys?: "ignore" | "send" | undefined;
|
|
3746
3964
|
}
|
|
3747
3965
|
/**
|
|
3748
3966
|
* Read and update a repository's settings and topics, and look up its default
|
|
@@ -3809,8 +4027,12 @@ interface GitHubRepositoryShape {
|
|
|
3809
4027
|
* in `ignored`, rather than forwarded to a `PATCH` that would ignore it and
|
|
3810
4028
|
* answer 200. It does not fail the call, so additive GitHub API growth never
|
|
3811
4029
|
* breaks a run; a caller that owns a schema should still validate first.
|
|
4030
|
+
*
|
|
4031
|
+
* A setting GitHub accepts before its description declares it is sent with
|
|
4032
|
+
* `{ unknownKeys: "send" }` ({@link ApplySettingsOptions}), and reported in
|
|
4033
|
+
* `unverified` as well as `rest`, because a 200 does not say GitHub used it.
|
|
3812
4034
|
*/
|
|
3813
|
-
readonly applySettings: (settings: Record<string, unknown
|
|
4035
|
+
readonly applySettings: (settings: Record<string, unknown>, options?: ApplySettingsOptions) => Effect.Effect<AppliedSettings, GitHubError | GitHubGraphQLError, Repo>;
|
|
3814
4036
|
/**
|
|
3815
4037
|
* The repository's topics, as GitHub stores them.
|
|
3816
4038
|
*
|
|
@@ -4959,5 +5181,5 @@ export declare class WorkflowDispatch extends WorkflowDispatch_base {
|
|
|
4959
5181
|
/** {@link WorkflowDispatch.makeTest} behind a `Layer`. */
|
|
4960
5182
|
static readonly layerTest: (overrides?: Partial<WorkflowDispatchShape>) => Layer.Layer<WorkflowDispatch>;
|
|
4961
5183
|
}
|
|
4962
|
-
export { type ActionsOidcVerifyOptions, type AppCredentials, type AppliedSettings, type ArtifactMetadataShape, type AttestationShape, type AuthenticatedAppShape, type BareLineReference, type BotUserRequest, type BranchOutcome, CLOSING_KEYWORDS, type CachedToken, type CachedTokenRequest, type CheckRunShape, type ClosingKeyword, type CodeScanningSetup, type CodeScanningShape, type CompleteCheckRunOptions, type ConcludeCheckRun, type CreateCheckRunOptions, type DeliveriesOptions, type DeploymentEnvironmentInfo, type DeploymentEnvironmentShape, type GitBranchShape, type GitCommitShape, type GitHubAppOptions, type GitHubAppShape, type GitHubClientOptions, type GitHubClientShape, type GitHubCommitShape, type GitHubContentShape, type GitHubIssueShape, type GitHubReleaseShape, type GitHubRepositoryShape, type GitTagShape, type InstallationTokenStoreShape, type IssueReference, type LatestSemverOptions, type ListCheckRunsOptions, type OwnerType, type PollOptions, type PullRequestCommentShape, type PullRequestShape, type RecordedCall, type RepositoryPatch, type RepositoryPatchDraft, type RepositorySecretShape, type RepositorySecurityShape, type RepositorySettings, type RepositoryVariableShape, type Data as RestData, type RequestExtras as RestExtras, type Item as RestItem, type PaginatingRoute as RestPaginatingRoute, type Params as RestParams, type Response as RestResponse, type Route as RestRoute, type RetryableFailure, type RulesetInfo, type RulesetPayload, type RulesetShape, type SecretInfo, type SecretScope, type TokenRequest, type UpdateCheckRunOptions, type UpsertedPullRequest, type VariableInfo, type VersionFromTag, type WorkflowDispatchShape, type WorkflowInfo, harvestIssueReferences, parseBareLineReference };
|
|
5184
|
+
export { type ActionsOidcVerifyOptions, type AppCredentials, type AppliedSettings, type ApplySettingsOptions, type ArtifactMetadataShape, type AttestationShape, type AuthenticatedAppShape, type BareLineReference, type BotUserRequest, type BranchOutcome, CLOSING_KEYWORDS, type CachedToken, type CachedTokenRequest, type CheckRunShape, type ClosingKeyword, type CodeScanningSetup, type CodeScanningShape, type CompleteCheckRunOptions, type ConcludeCheckRun, type CreateCheckRunOptions, type DeliveriesOptions, type DeploymentEnvironmentInfo, type DeploymentEnvironmentShape, type GitBranchShape, type GitCommitShape, type GitHubAppOptions, type GitHubAppShape, type GitHubClientOptions, type GitHubClientShape, type GitHubCommitShape, type GitHubContentShape, type GitHubIssueShape, type GitHubReleaseShape, type GitHubRepositoryShape, type GitTagShape, type InstallationTokenStoreShape, type IssueReference, type LatestSemverOptions, type ListCheckRunsOptions, type OwnerType, type PollOptions, type PullRequestCommentShape, type PullRequestShape, type RecordedCall, type RepositoryPatch, type RepositoryPatchDraft, type RepositoryPatchExtra, type RepositoryPatchOptions, type RepositoryPatchReservedKey, type RepositorySecretShape, type RepositorySecurityShape, type RepositorySettings, type RepositoryVariableShape, type Data as RestData, type RequestExtras as RestExtras, type Item as RestItem, type PaginatingRoute as RestPaginatingRoute, type Params as RestParams, type Response as RestResponse, type Route as RestRoute, type RetryableFailure, type RulesetInfo, type RulesetPayload, type RulesetShape, type SecretInfo, type SecretScope, type TokenRequest, type UpdateCheckRunOptions, type UpsertedPullRequest, type VariableInfo, type VersionFromTag, type WorkflowDispatchShape, type WorkflowInfo, harvestIssueReferences, parseBareLineReference };
|
|
4963
5185
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { GitHubError } from "../GitHubError.js";
|
|
2
|
+
import { reservedRawParam } from "./requestOptions.js";
|
|
3
|
+
import { originOf } from "./uploads.js";
|
|
4
|
+
|
|
5
|
+
// src/internal/confinement.ts
|
|
6
|
+
/**
|
|
7
|
+
* Why one of the caller's parameters may not be sent, or `undefined`.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Checked against the CALLER's parameters, before anything the transport adds
|
|
11
|
+
* (`per_page`, a signal, the upload base): `baseUrl` and `url` move the host,
|
|
12
|
+
* `request` swaps the fetch, `method` rewrites the verb.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
const reservedParamReason = (params) => {
|
|
17
|
+
for (const key of Object.keys(params)) {
|
|
18
|
+
const reason = reservedRawParam(key);
|
|
19
|
+
if (reason !== void 0) return `the parameter "${key}" ${reason}`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Why `route` with `params` may not be sent to the origin `allowed`, or
|
|
24
|
+
* `undefined` when it may.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* The URL checked is the one `expand` builds, which is the one octokit itself
|
|
28
|
+
* would send, so no spelling of the route reaches a host this check did not
|
|
29
|
+
* see.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
const routeReason = (expand, route, params, allowed) => {
|
|
34
|
+
let url;
|
|
35
|
+
try {
|
|
36
|
+
url = expand(route, params).url;
|
|
37
|
+
} catch {
|
|
38
|
+
return "the route does not expand to a URL";
|
|
39
|
+
}
|
|
40
|
+
if (allowed === void 0) return "the configured base URL is not an absolute URL";
|
|
41
|
+
const origin = originOf(url);
|
|
42
|
+
return origin === allowed ? void 0 : `the route resolves to ${origin ?? "a URL that does not parse"}, not the configured host ${allowed}; refusing to send the token there`;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Why a raw-surface call may not be sent to `allowed`, or `undefined`: a
|
|
46
|
+
* reserved parameter first, then the route's resolved origin.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
const rawRequestRefusal = (expand, route, params, allowed) => reservedParamReason(params) ?? routeReason(expand, route, params, allowed);
|
|
51
|
+
/**
|
|
52
|
+
* The error a refused call fails with: `kind: "rejected"`, no status.
|
|
53
|
+
*
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
const refusedRequest = (operation, reason) => new GitHubError({
|
|
57
|
+
kind: "rejected",
|
|
58
|
+
operation,
|
|
59
|
+
reason
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export { rawRequestRefusal, refusedRequest, reservedParamReason, routeReason };
|
package/internal/octokit.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { GitHubError, readRateLimitHeaders } from "../GitHubError.js";
|
|
2
2
|
import { GitHubGraphQLError } from "../GraphQL.js";
|
|
3
|
+
import { DOTCOM_API_BASE_URL, originOf } from "./uploads.js";
|
|
4
|
+
import { rawRequestRefusal, refusedRequest, reservedParamReason, routeReason } from "./confinement.js";
|
|
3
5
|
import { RateLimitSnapshot } from "../Resilience.js";
|
|
4
6
|
import { Clock, Effect, Option, Redacted, Ref } from "effect";
|
|
5
7
|
import { Octokit } from "@octokit/core";
|
|
@@ -40,6 +42,19 @@ const makeOctokit = (options) => {
|
|
|
40
42
|
});
|
|
41
43
|
return octokit;
|
|
42
44
|
};
|
|
45
|
+
let dotcomExpand;
|
|
46
|
+
/**
|
|
47
|
+
* octokit's URL expansion against github.com's REST root, for the shipped
|
|
48
|
+
* doubles, which have no transport of their own but must refuse exactly what
|
|
49
|
+
* an unconfigured live client refuses.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* Built on first use, from an octokit instance that never sends anything.
|
|
53
|
+
*/
|
|
54
|
+
const expandOnDotcom = (route, params) => {
|
|
55
|
+
dotcomExpand ??= new Octokit({ log: SILENT_LOG }).request.endpoint;
|
|
56
|
+
return dotcomExpand(route, params);
|
|
57
|
+
};
|
|
43
58
|
/**
|
|
44
59
|
* Build a transport over a freshly constructed octokit instance.
|
|
45
60
|
*
|
|
@@ -72,11 +87,36 @@ const makeTransport = (options) => Effect.gen(function* () {
|
|
|
72
87
|
return yield* Effect.fail(classify(error, now));
|
|
73
88
|
})));
|
|
74
89
|
const withRetry = (operation, effect) => effect.pipe(Effect.tapError((error) => policy.retries(error) ? Effect.logDebug("github.retry").pipe(Effect.annotateLogs({ operation })) : Effect.void), Effect.retry(policy.schedule()));
|
|
75
|
-
const
|
|
90
|
+
const apiOrigin = originOf(options.baseUrl ?? "https://api.github.com");
|
|
91
|
+
const expand = (route, params) => octokit.request.endpoint(route, params);
|
|
92
|
+
const refused = refusedRequest;
|
|
93
|
+
const send = (operation, route, params) => withRetry(operation, attempt((signal) => octokit.request(route, withSignal(params, signal)), (error, now) => GitHubError.fromOctokit(operation, error, now)).pipe(Effect.tap((response) => record(response.headers))));
|
|
94
|
+
const request = (operation, route, params) => Effect.suspend(() => {
|
|
95
|
+
const reason = rawRequestRefusal(expand, route, params, apiOrigin);
|
|
96
|
+
return reason !== void 0 ? Effect.fail(refused(operation, reason)) : send(operation, route, params);
|
|
97
|
+
});
|
|
98
|
+
const requestAt = (operation, route, params, baseUrl) => Effect.suspend(() => {
|
|
99
|
+
const target = {
|
|
100
|
+
...params,
|
|
101
|
+
baseUrl
|
|
102
|
+
};
|
|
103
|
+
const reason = reservedParamReason(params) ?? routeReason(expand, route, target, originOf(baseUrl));
|
|
104
|
+
return reason !== void 0 ? Effect.fail(refused(operation, reason)) : send(operation, route, target);
|
|
105
|
+
});
|
|
76
106
|
const pageSource = (operation, route, params) => {
|
|
77
|
-
const
|
|
107
|
+
const reason = rawRequestRefusal(expand, route, params, apiOrigin);
|
|
108
|
+
if (reason !== void 0) return { next: Effect.fail(refused(operation, reason)) };
|
|
109
|
+
let signal;
|
|
110
|
+
const onApiHost = Object.assign((page) => {
|
|
111
|
+
const origin = originOf(page.url);
|
|
112
|
+
return origin === apiOrigin ? octokit.request(signal === void 0 ? page : withSignal(page, signal)) : Promise.reject(new CrossOriginPage(origin, apiOrigin));
|
|
113
|
+
}, { endpoint: (parameters) => octokit.request.endpoint(route, parameters) });
|
|
114
|
+
const iterator = composePaginateRest.iterator(octokit, onApiHost, params)[Symbol.asyncIterator]();
|
|
78
115
|
let finished = false;
|
|
79
|
-
return { next: Effect.suspend(() => finished ? Effect.succeed(Option.none()) : withRetry(operation, attempt(() =>
|
|
116
|
+
return { next: Effect.suspend(() => finished ? Effect.succeed(Option.none()) : withRetry(operation, attempt((pageSignal) => {
|
|
117
|
+
signal = pageSignal;
|
|
118
|
+
return iterator.next();
|
|
119
|
+
}, (error, now) => error instanceof CrossOriginPage ? refused(operation, error.message) : GitHubError.fromOctokit(operation, error, now)).pipe(Effect.flatMap((result) => {
|
|
80
120
|
if (result.done === true || result.value === void 0) {
|
|
81
121
|
finished = true;
|
|
82
122
|
return Effect.succeed(Option.none());
|
|
@@ -85,14 +125,64 @@ const makeTransport = (options) => Effect.gen(function* () {
|
|
|
85
125
|
return record(response.headers).pipe(Effect.as(Option.some(response.data)));
|
|
86
126
|
})))) };
|
|
87
127
|
};
|
|
88
|
-
const
|
|
128
|
+
const graphqlUrl = graphqlEndpoint(options.baseUrl);
|
|
129
|
+
const graphql = (operation, document, variables) => withRetry(operation, attempt((signal) => octokit.request("POST /graphql", {
|
|
130
|
+
...graphqlUrl !== void 0 ? { url: graphqlUrl } : {},
|
|
131
|
+
data: Object.keys(variables).length > 0 ? {
|
|
132
|
+
query: document,
|
|
133
|
+
variables
|
|
134
|
+
} : { query: document },
|
|
135
|
+
request: { signal }
|
|
136
|
+
}).then((response) => readGraphQLResponse(response)), (error, now) => GitHubGraphQLError.fromThrowable(operation, error, now)));
|
|
89
137
|
return {
|
|
90
138
|
request,
|
|
139
|
+
requestAt,
|
|
91
140
|
pageSource,
|
|
92
141
|
graphql,
|
|
93
142
|
rateLimit: Ref.get(snapshot)
|
|
94
143
|
};
|
|
95
144
|
});
|
|
145
|
+
/**
|
|
146
|
+
* The GraphQL endpoint for a GitHub Enterprise Server base URL, or `undefined`
|
|
147
|
+
* for the route's own `/graphql` under the configured base.
|
|
148
|
+
*
|
|
149
|
+
* @remarks
|
|
150
|
+
* GHES serves REST under `/api/v3` and GraphQL under `/api/graphql`, so
|
|
151
|
+
* `<base>/graphql` would miss it. This is the rewrite `@octokit/graphql`
|
|
152
|
+
* applies, kept because the call no longer goes through it. The result is
|
|
153
|
+
* derived from the configured base alone, so it never names another host.
|
|
154
|
+
*/
|
|
155
|
+
const graphqlEndpoint = (baseUrl) => baseUrl !== void 0 && GHES_V3_SUFFIX.test(baseUrl) ? baseUrl.replace(GHES_V3_SUFFIX, "/api/graphql") : void 0;
|
|
156
|
+
const GHES_V3_SUFFIX = /\/api\/v3\/?$/;
|
|
157
|
+
/**
|
|
158
|
+
* The `data` of a GraphQL answer, or a throw carrying its `errors`.
|
|
159
|
+
*
|
|
160
|
+
* @remarks
|
|
161
|
+
* GitHub answers a GraphQL failure with HTTP 200 and an `errors` array. The
|
|
162
|
+
* throw carries `errors` and the response `headers` — the fields
|
|
163
|
+
* `GitHubGraphQLError.fromThrowable` reads structurally — so it classifies
|
|
164
|
+
* exactly as `@octokit/graphql`'s `GraphqlResponseError` did.
|
|
165
|
+
*/
|
|
166
|
+
const readGraphQLResponse = (response) => {
|
|
167
|
+
const body = typeof response.data === "object" && response.data !== null ? response.data : {};
|
|
168
|
+
if (body.errors !== void 0) {
|
|
169
|
+
const messages = (Array.isArray(body.errors) ? body.errors : []).map((entry) => typeof entry === "object" && entry !== null && typeof entry.message === "string" ? ` - ${entry.message}` : ` - ${String(entry)}`);
|
|
170
|
+
throw Object.assign(/* @__PURE__ */ new Error(`Request failed due to following response errors:\n${messages.join("\n")}`), {
|
|
171
|
+
name: "GraphqlResponseError",
|
|
172
|
+
errors: body.errors,
|
|
173
|
+
headers: response.headers,
|
|
174
|
+
data: body.data
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return body.data;
|
|
178
|
+
};
|
|
179
|
+
/** A paginated walk's next page named a host other than the configured one. */
|
|
180
|
+
var CrossOriginPage = class extends Error {
|
|
181
|
+
constructor(origin, allowed) {
|
|
182
|
+
super(`a next page is on ${origin ?? "a URL that does not parse"}, not the configured host ${allowed ?? "(none)"}; refusing to send the token there`);
|
|
183
|
+
this.name = "CrossOriginPage";
|
|
184
|
+
}
|
|
185
|
+
};
|
|
96
186
|
/** Merge our abort signal into octokit's per-request options without clobbering them. */
|
|
97
187
|
const withSignal = (params, signal) => {
|
|
98
188
|
const existing = typeof params.request === "object" && params.request !== null ? params.request : {};
|
|
@@ -113,4 +203,4 @@ const readThrownHeaders = (error) => {
|
|
|
113
203
|
return typeof headers === "object" && headers !== null ? headers : void 0;
|
|
114
204
|
};
|
|
115
205
|
|
|
116
|
-
export { DEFAULT_API_VERSION, makeTransport };
|
|
206
|
+
export { DEFAULT_API_VERSION, expandOnDotcom, makeTransport };
|