@effected/github 0.4.1 → 0.4.3

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/GitHubIssue.js CHANGED
@@ -107,6 +107,30 @@ var GitHubIssue = class GitHubIssue extends Context.Service()("@effected/github/
107
107
  const unstubbed = (member) => {
108
108
  throw new Error(`GitHubIssue.makeTest: ${member}() was called but not stubbed — pass an override.`);
109
109
  };
110
+ /**
111
+ * The REST calendar version this module's requests pin.
112
+ *
113
+ * @remarks
114
+ * The routes are not deprecated — the **default api-version** is. When no
115
+ * `x-github-api-version` header is sent (octokit sends none), GitHub serves
116
+ * calendar version 2022-11-28, which it deprecated when 2026-03-10 shipped and
117
+ * sunsets on 2028-03-10. Every response from an endpoint the new version
118
+ * changed then carries a `Deprecation` header, which `@octokit/request` prints
119
+ * straight to the consumer's console — the constructor's `log` option cannot
120
+ * silence it, because the fetch wrapper resolves `request.log ?? console`.
121
+ * `PATCH /repos/{owner}/{repo}/issues/{issue_number}` is on that list (the
122
+ * singular `assignee` parameter was removed), so every `close` warned once per
123
+ * issue in consumer workflow logs (effected#189).
124
+ *
125
+ * Nothing this module sends or reads changed in 2026-03-10: `state` and
126
+ * `state_reason` are untouched, and the projections read only fields both
127
+ * versions carry. Pinning the current version is therefore the whole fix, and
128
+ * it deliberately does **not** hide future deprecations — when GitHub
129
+ * deprecates 2026-03-10 in turn, the header comes back and octokit warns
130
+ * again. Verified live 2026-08-14: the pinned request answers with no
131
+ * `Deprecation`/`Sunset` headers.
132
+ */
133
+ const API_VERSION_HEADERS = { "x-github-api-version": "2026-03-10" };
110
134
  /** GitHub sends a label as either a string or an object; callers want the name. */
111
135
  const labelNames = (labels) => labels.flatMap((label) => typeof label === "string" ? [label] : label.name !== void 0 ? [label.name] : []);
112
136
  const project = (raw) => IssueInfo.make({
@@ -128,7 +152,8 @@ const make = (client) => ({
128
152
  const raw = yield* client.request("GET /repos/{owner}/{repo}/issues/{issue_number}", {
129
153
  owner,
130
154
  repo,
131
- issue_number: number
155
+ issue_number: number,
156
+ headers: API_VERSION_HEADERS
132
157
  });
133
158
  return project(raw);
134
159
  }),
@@ -142,7 +167,8 @@ const make = (client) => ({
142
167
  owner,
143
168
  repo,
144
169
  ...options?.state !== void 0 ? { state: options.state } : {},
145
- ...options?.labels !== void 0 ? { labels: options.labels.join(",") } : {}
170
+ ...options?.labels !== void 0 ? { labels: options.labels.join(",") } : {},
171
+ headers: API_VERSION_HEADERS
146
172
  }, options?.page)).map(project);
147
173
  }),
148
174
  close: Effect.fn("GitHubIssue.close")(function* (number, reason) {
@@ -157,7 +183,8 @@ const make = (client) => ({
157
183
  repo,
158
184
  issue_number: number,
159
185
  state: "closed",
160
- ...reason !== void 0 ? { state_reason: reason } : {}
186
+ ...reason !== void 0 ? { state_reason: reason } : {},
187
+ headers: API_VERSION_HEADERS
161
188
  });
162
189
  }),
163
190
  comment: Effect.fn("GitHubIssue.comment")(function* (number, body) {
@@ -171,7 +198,8 @@ const make = (client) => ({
171
198
  owner,
172
199
  repo,
173
200
  issue_number: number,
174
- body
201
+ body,
202
+ headers: API_VERSION_HEADERS
175
203
  })).id;
176
204
  }),
177
205
  linkedIssues: Effect.fn("GitHubIssue.linkedIssues")(function* (prNumber) {
@@ -29,14 +29,23 @@ const SECURITY_ANALYSIS_STATUS_FIELDS = /* @__PURE__ */ new Set([
29
29
  * mapped from snake_case keys to camelCase GraphQL input fields.
30
30
  *
31
31
  * @remarks
32
- * GitHub never exposed these two on the REST repository endpoint. Setting
33
- * either forces a second round trip to learn the repository's node id.
32
+ * GitHub never exposed these on the REST repository endpoint — the
33
+ * `PATCH /repos/{owner}/{repo}` route accepts none of them, and
34
+ * `has_discussions` is the treacherous one: the REST **read** returns it, so
35
+ * routing its write to the PATCH looks symmetric, but the PATCH silently
36
+ * ignores unknown body fields and answers 200 — reported as applied on every
37
+ * run while the repository never changed (effected#358). Setting any of these
38
+ * forces a second round trip to learn the repository's node id.
39
+ *
40
+ * Field names verified against `UpdateRepositoryInput` by live introspection,
41
+ * 2026-08-15.
34
42
  *
35
43
  * @public
36
44
  */
37
45
  const GRAPHQL_ONLY_SETTINGS = {
38
46
  has_sponsorships: "hasSponsorshipsEnabled",
39
- has_pull_requests: "hasPullRequestsEnabled"
47
+ has_pull_requests: "hasPullRequestsEnabled",
48
+ has_discussions: "hasDiscussionsEnabled"
40
49
  };
41
50
  /** `{ status: "enabled" | "disabled" }` — the form GitHub accepts and the type declares. */
42
51
  const isStatusObject = (raw) => {
package/index.d.ts CHANGED
@@ -2009,6 +2009,19 @@ interface GitHubIssueShape {
2009
2009
  * @remarks
2010
2010
  * The idempotence guard one consumer wrote a bespoke timeline query for,
2011
2011
  * so that re-running a workflow does not comment twice.
2012
+ *
2013
+ * Two hazards before building on it (effected#306):
2014
+ *
2015
+ * - **An issue obtained from `linkedIssues(pr)` answers `true` from the
2016
+ * outset** — the closing link itself puts a cross-reference on the
2017
+ * issue's timeline. As a "have I commented yet?" guard on those issues
2018
+ * the answer is always yes, and the comment is never posted. Guard a
2019
+ * comment by looking for the comment (a marker in its body), not for a
2020
+ * cross-reference.
2021
+ * - **It observes `CROSS_REFERENCED_EVENT` only, not `ConnectedEvent`** —
2022
+ * an issue a human attached through the sidebar's Development section is
2023
+ * connected, not cross-referenced, and reads `false` here even though
2024
+ * GitHub's UI shows the link.
2012
2025
  */
2013
2026
  readonly isCrossReferencedBy: (issueNumber: number, prNumber: number) => Effect.Effect<boolean, GitHubGraphQLError, Repo>;
2014
2027
  }
@@ -2166,8 +2179,16 @@ declare const SECURITY_ANALYSIS_STATUS_FIELDS: ReadonlySet<string>;
2166
2179
  * mapped from snake_case keys to camelCase GraphQL input fields.
2167
2180
  *
2168
2181
  * @remarks
2169
- * GitHub never exposed these two on the REST repository endpoint. Setting
2170
- * either forces a second round trip to learn the repository's node id.
2182
+ * GitHub never exposed these on the REST repository endpoint — the
2183
+ * `PATCH /repos/{owner}/{repo}` route accepts none of them, and
2184
+ * `has_discussions` is the treacherous one: the REST **read** returns it, so
2185
+ * routing its write to the PATCH looks symmetric, but the PATCH silently
2186
+ * ignores unknown body fields and answers 200 — reported as applied on every
2187
+ * run while the repository never changed (effected#358). Setting any of these
2188
+ * forces a second round trip to learn the repository's node id.
2189
+ *
2190
+ * Field names verified against `UpdateRepositoryInput` by live introspection,
2191
+ * 2026-08-15.
2171
2192
  *
2172
2193
  * @public
2173
2194
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/github",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
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": [