Add contributors to pages

Luke Karrys committed Oct 20, 2023 at 14:39 UTC caacd022bbdea51dbb38170d41e7a7757741749d
7 files changed +756 -294
gatsby-node.js
+146 -99
@@ -1,10 +1,44 @@
1 -const {resolve, join: _join, relative} = require('path')
2 -const join = (...paths) => _join(...paths).replace(/\\/g, '/')
1 +const {resolve, join, relative} = require('path')
2 +const {Octokit: CoreOctokit} = require('@octokit/rest')
3 +const {throttling} = require('@octokit/plugin-throttling')
4 +const {retry} = require('@octokit/plugin-retry')
5
4 -const SHOW_CONTRIBUTORS = false
5 -const REPO = {
6 - url: 'https://github.com/npm/documentation',
7 - defaultBranch: 'main',
6 +const PROD = process.env.NODE_ENV === 'production'
7 +const REPO_URL = 'https://github.com/npm/documentation'
8 +const NWO = new URL(REPO_URL).pathname.slice(1)
9 +const REPO_BRANCH = 'main'
10 +const CWD = process.cwd()
11 +const TEST_CONTRIBUTORS = [
12 + {
13 + author: {login: 'mona'},
14 + commit: {author: {date: new Date('2023-03-21').toJSON()}},
15 + html_url: REPO_URL,
16 + },
17 +]
18 +
19 +const createOctokit = ({reporter}) => {
20 + const Octokit = CoreOctokit.plugin(throttling).plugin(retry)
21 + return new Octokit({
22 + log: {
23 + debug: () => {},
24 + info: reporter.info,
25 + warn: reporter.warn,
26 + error: reporter.error,
27 + },
28 + auth: process.env.GITHUB_TOKEN,
29 + throttle: {
30 + onRateLimit: (retryAfter, options, {log}, retryCount) => {
31 + log.warn(`Request quota exhausted for request ${options.method} ${options.url}`)
32 + if (retryCount < 2) {
33 + log.info(`Retrying after ${retryAfter} seconds`)
34 + return true
35 + }
36 + },
37 + onSecondaryRateLimit: (_, options, {log}) => {
38 + log.warn(`SecondaryRateLimit detected for request ${options.method} ${options.url}`)
39 + },
40 + },
41 + })
42 }
43
44 exports.onCreateNode = ({node, actions, getNode}) => {
@@ -60,8 +94,8 @@ exports.createSchemaCustomization = ({actions: {createTypes}}) => {
94 `)
95 }
96
63 -exports.createPages = async ({graphql, actions}) => {
64 - const {data} = await graphql(`
97 +exports.createPages = async ({graphql, actions, reporter}) => {
98 + const response = await graphql(`
99 {
100 allMdx {
101 nodes {
@@ -93,67 +127,79 @@ exports.createPages = async ({graphql, actions}) => {
127 }
128 `)
129
130 + if (response.errors) {
131 + reporter.panic('Error getting allMdx', response.errors)
132 + return
133 + }
134 +
135 + const octokit = createOctokit({reporter})
136 +
137 // Turn every MDX file into a page.
97 - return Promise.all(data.allMdx.nodes.map(node => createPage(node, actions)))
138 + return Promise.all(
139 + response.data.allMdx.nodes.map(async node => {
140 + try {
141 + node.fields ||= {}
142 + node.frontmatter ||= {}
143 + node.frontmatter.redirect_from ||= []
144 + node.tableOfContents ||= {}
145 + node.tableOfContents.items ||= []
146 + return await createPage(node, {actions, reporter, octokit})
147 + } catch (err) {
148 + reporter.panic(`Error creating page: ${JSON.stringify(node, null, 2)}`, err)
149 + }
150 + }),
151 + )
152 }
153
100 -async function createPage(
154 +const createPage = async (
155 {
156 id,
157 internal: {contentFilePath},
104 - fields: {slug} = {},
158 + fields: {slug},
159 frontmatter = {},
160 tableOfContents = {},
161 parent: {relativeDirectory, name: parentName},
162 },
109 - actions,
110 -) {
163 + {actions, reporter, octokit},
164 +) => {
165 + const path = relative(CWD, contentFilePath)
166 // sites can programmatically override slug, that takes priority
167 // then a slug specified in frontmatter
168 // finally, we'll just use the path on disk
114 - const pagePath = slug ?? frontmatter.slug ?? join(relativeDirectory, parentName === 'index' ? '/' : parentName)
169 + const pageSlug =
170 + slug ?? frontmatter.slug ?? join(relativeDirectory, parentName === 'index' ? '/' : parentName).replace(/\\/g, '/')
171
116 - const relativePath = relative(process.cwd(), contentFilePath)
117 -
118 - const editUrl = getEditUrl(REPO, relativePath, frontmatter)
119 -
120 - const contributors = SHOW_CONTRIBUTORS ? await fetchContributors(REPO, relativePath, frontmatter) : {}
121 -
122 - // Fix some old CLI pages which have mismatched headings at the top level.
123 - // All top level headings should be the same level.
124 - const toc = tableOfContents.items?.reduce((acc, item) => {
125 - if (!item.url && Array.isArray(item.items)) {
126 - acc.push(...item.items)
127 - } else {
128 - acc.push(item)
129 - }
130 - return acc
131 - }, [])
172 + const context = {
173 + mdxId: id,
174 + tableOfContents: getTableOfConents(tableOfContents),
175 + repositoryUrl: REPO_URL,
176 + }
177 + // edit_on_github: false in frontmatter will not include editUrl and contributors
178 + // on the page. this is used for policy pages as well as some index pages that don't
179 + // have any editable content
180 + if (frontmatter.edit_on_github !== false) {
181 + context.editUrl = getRepo(path, frontmatter).replace(`https://github.com/{nwo}/edit/{branch}/{path}`)
182 + Object.assign(context, await fetchContributors(path, frontmatter, {reporter, octokit}))
183 + }
184
185 actions.createPage({
134 - path: pagePath,
186 + path: pageSlug,
187 component: contentFilePath,
136 - context: {
137 - mdxId: id,
138 - editUrl,
139 - contributors,
140 - tableOfContents: toc,
141 - repositoryUrl: REPO.url,
142 - },
188 + context,
189 })
190
145 - for (const from of frontmatter.redirect_from ?? []) {
191 + for (const from of frontmatter.redirect_from) {
192 actions.createRedirect({
193 fromPath: from,
148 - toPath: `/${pagePath}`,
194 + toPath: `/${pageSlug}`,
195 isPermanent: true,
196 redirectInBrowser: true,
197 })
198
153 - if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
199 + if (pageSlug.startsWith('cli/') && !from.endsWith('index')) {
200 actions.createRedirect({
201 fromPath: `${from}.html`,
156 - toPath: `/${pagePath}`,
202 + toPath: `/${pageSlug}`,
203 isPermanent: true,
204 redirectInBrowser: true,
205 })
@@ -161,72 +207,72 @@ async function createPage(
207 }
208 }
209
164 -function getGitHubData(repo, overrideData, filePath) {
165 - const gh = {
166 - nwo: new URL(repo.url).pathname.slice(1).split('/'),
167 - branch: 'master',
168 - }
169 -
170 - if (overrideData.github_repo) {
171 - gh.nwo = overrideData.github_repo
172 - }
173 -
174 - if (overrideData.github_branch) {
175 - gh.branch = overrideData.github_branch
176 - } else if (repo.defaultBranch) {
177 - gh.branch = repo.defaultBranch
178 - }
210 +const getTableOfConents = ({items}) => {
211 + // Fix some old CLI pages which have mismatched headings at the top level.
212 + // All top level headings should be the same level.
213 + const tableOfContents = items.reduce((acc, item) => {
214 + if (!item.url && Array.isArray(item.items)) {
215 + acc.push(...item.items)
216 + } else {
217 + acc.push(item)
218 + }
219 + return acc
220 + }, [])
221
180 - if (overrideData.github_path) {
181 - gh.path = overrideData.github_path
182 - } else {
183 - gh.path = filePath
222 + if (tableOfContents.length) {
223 + return tableOfContents
224 }
185 -
186 - return gh
225 }
226
189 -function getEditUrl(repo, filePath, overrideData = {}) {
190 - if (overrideData.edit_on_github === false) {
191 - return null
227 +const getRepo = (path, fm) => {
228 + const result = {
229 + nwo: NWO,
230 + branch: REPO_BRANCH,
231 + ...(fm.github_repo ? {nwo: fm.github_repo} : {}),
232 + ...(fm.github_branch ? {branch: fm.github_branch} : {}),
233 + path: fm.github_path || path,
234 }
193 -
194 - const {nwo, branch, path} = getGitHubData(repo, overrideData, filePath)
195 - return `https://github.com/${nwo}/edit/${branch}/${path}`
235 + const [owner, repo] = result.nwo.split('/')
236 + result.owner = owner
237 + result.repo = repo
238 + result.replace = str => str.replace(/\{([a-z]+)\}/g, (_, name) => result[name])
239 + return result
240 }
241
198 -const CONTRIBUTOR_CACHE = new Map()
199 -
200 -async function fetchContributors(repo, filePath, overrideData = {}) {
201 - if (!process.env.GITHUB_TOKEN) {
202 - console.warn('Skipping fetching contributors because no github token was set')
203 - return
204 - }
205 -
206 - const gh = getGitHubData(repo, overrideData, filePath)
207 - const key = JSON.stringify(gh)
242 +let warnOnNoContributors = true
243 +const fetchContributors = async (path, fm, {reporter, octokit}) => {
244 + const noAuth = (await octokit.auth()).type === 'unauthenticated'
245 + if (noAuth) {
246 + const msg = `Cannot fetch contributors without GitHub authentication.`
247 + if (PROD) {
248 + reporter.panic(msg)
249 + return
250 + }
251
209 - const cached = CONTRIBUTOR_CACHE.get(key)
210 - if (cached) {
211 - return cached
252 + if (warnOnNoContributors) {
253 + warnOnNoContributors = false
254 + reporter.warn(`${msg} Pages will be include test contributor data.`)
255 + }
256 }
257
258 try {
215 - const resp = await fetch(
216 - `https://api.github.com/repos/${gh.nwo}/commits?path=${gh.path}&sha=${gh.branch}&per_page=100`,
217 - {
218 - headers: {
219 - Authorization: `token ${process.env.GITHUB_TOKEN}`,
220 - },
221 - },
222 - )
259 + const repo = getRepo(path, fm)
260 + const resp = noAuth
261 + ? {data: TEST_CONTRIBUTORS}
262 + : await octokit.rest.repos.listCommits({
263 + repo: repo.repo,
264 + owner: repo.owner,
265 + path: repo.path,
266 + sha: repo.branch,
267 + per_page: 100,
268 + })
269
224 - const logins = new Set()
270 + const contributors = new Set()
271 let latestCommit = null
272
227 - for (const item of await resp.json().then(r => r.data)) {
273 + for (const item of resp.data) {
274 if (item.author?.login) {
229 - logins.add(item.author.login)
275 + contributors.add(item.author.login)
276 if (!latestCommit) {
277 latestCommit = {
278 login: item.author.login,
@@ -237,11 +283,12 @@ async function fetchContributors(repo, filePath, overrideData = {}) {
283 }
284 }
285
240 - const result = {logins: [...logins], latestCommit}
241 - CONTRIBUTOR_CACHE.set(key, result)
242 - return result
243 - } catch (error) {
244 - console.error(`[ERROR] Unable to fetch contributors for ${filePath}. ${error.message}`)
245 - return []
286 + return {
287 + contributors: [...contributors],
288 + latestCommit,
289 + }
290 + } catch (err) {
291 + reporter[PROD ? 'panic' : 'error'](`Error fetching contributors for ${path}`, err)
292 + return
293 }
294 }
package-lock.json
+585 -176
@@ -13,6 +13,9 @@
13 "dependencies": {
14 "@mdx-js/mdx": "^2.3.0",
15 "@mdx-js/react": "^2.3.0",
16 + "@octokit/plugin-retry": "^6.0.1",
17 + "@octokit/plugin-throttling": "^8.0.0",
18 + "@octokit/rest": "^20.0.2",
19 "@primer/octicons-react": "^19.8.0",
20 "@primer/react": "^35.32.1",
21 "babel-plugin-styled-components": "^2.1.4",
@@ -23,7 +26,6 @@
26 "framer-motion": "^10.16.4",
27 "fuse.js": "^3.6.1",
28 "gatsby": "^5.12.7",
26 - "gatsby-plugin-catch-links": "^5.12.0",
29 "gatsby-plugin-manifest": "^5.12.1",
30 "gatsby-plugin-mdx": "^5.12.1",
31 "gatsby-plugin-meta-redirect": "^1.1.1",
@@ -87,75 +89,6 @@
89 "node": ">=18.0.0"
90 }
91 },
90 - "cli/node_modules/@octokit/core": {
91 - "version": "5.0.1",
92 - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz",
93 - "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==",
94 - "dependencies": {
95 - "@octokit/auth-token": "^4.0.0",
96 - "@octokit/graphql": "^7.0.0",
97 - "@octokit/request": "^8.0.2",
98 - "@octokit/request-error": "^5.0.0",
99 - "@octokit/types": "^12.0.0",
100 - "before-after-hook": "^2.2.0",
101 - "universal-user-agent": "^6.0.0"
102 - },
103 - "engines": {
104 - "node": ">= 18"
105 - }
106 - },
107 - "cli/node_modules/@octokit/plugin-paginate-rest": {
108 - "version": "9.0.0",
109 - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
110 - "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
111 - "dependencies": {
112 - "@octokit/types": "^12.0.0"
113 - },
114 - "engines": {
115 - "node": ">= 18"
116 - },
117 - "peerDependencies": {
118 - "@octokit/core": ">=5"
119 - }
120 - },
121 - "cli/node_modules/@octokit/plugin-request-log": {
122 - "version": "4.0.0",
123 - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
124 - "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==",
125 - "engines": {
126 - "node": ">= 18"
127 - },
128 - "peerDependencies": {
129 - "@octokit/core": ">=5"
130 - }
131 - },
132 - "cli/node_modules/@octokit/plugin-rest-endpoint-methods": {
133 - "version": "10.0.1",
134 - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.1.tgz",
135 - "integrity": "sha512-fgS6HPkPvJiz8CCliewLyym9qAx0RZ/LKh3sATaPfM41y/O2wQ4Z9MrdYeGPVh04wYmHFmWiGlKPC7jWVtZXQA==",
136 - "dependencies": {
137 - "@octokit/types": "^12.0.0"
138 - },
139 - "engines": {
140 - "node": ">= 18"
141 - },
142 - "peerDependencies": {
143 - "@octokit/core": ">=5"
144 - }
145 - },
146 - "cli/node_modules/@octokit/rest": {
147 - "version": "20.0.2",
148 - "license": "MIT",
149 - "dependencies": {
150 - "@octokit/core": "^5.0.0",
151 - "@octokit/plugin-paginate-rest": "^9.0.0",
152 - "@octokit/plugin-request-log": "^4.0.0",
153 - "@octokit/plugin-rest-endpoint-methods": "^10.0.0"
154 - },
155 - "engines": {
156 - "node": ">= 18"
157 - }
158 - },
92 "cli/node_modules/semver": {
93 "version": "7.5.4",
94 "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -3176,12 +3109,162 @@
3109 "node": ">= 14"
3110 }
3111 },
3112 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/auth-token": {
3113 + "version": "3.0.4",
3114 + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
3115 + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
3116 + "dev": true,
3117 + "engines": {
3118 + "node": ">= 14"
3119 + }
3120 + },
3121 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/core": {
3122 + "version": "4.2.4",
3123 + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
3124 + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
3125 + "dev": true,
3126 + "dependencies": {
3127 + "@octokit/auth-token": "^3.0.0",
3128 + "@octokit/graphql": "^5.0.0",
3129 + "@octokit/request": "^6.0.0",
3130 + "@octokit/request-error": "^3.0.0",
3131 + "@octokit/types": "^9.0.0",
3132 + "before-after-hook": "^2.2.0",
3133 + "universal-user-agent": "^6.0.0"
3134 + },
3135 + "engines": {
3136 + "node": ">= 14"
3137 + }
3138 + },
3139 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/endpoint": {
3140 + "version": "7.0.6",
3141 + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz",
3142 + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==",
3143 + "dev": true,
3144 + "dependencies": {
3145 + "@octokit/types": "^9.0.0",
3146 + "is-plain-object": "^5.0.0",
3147 + "universal-user-agent": "^6.0.0"
3148 + },
3149 + "engines": {
3150 + "node": ">= 14"
3151 + }
3152 + },
3153 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/graphql": {
3154 + "version": "5.0.6",
3155 + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz",
3156 + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==",
3157 + "dev": true,
3158 + "dependencies": {
3159 + "@octokit/request": "^6.0.0",
3160 + "@octokit/types": "^9.0.0",
3161 + "universal-user-agent": "^6.0.0"
3162 + },
3163 + "engines": {
3164 + "node": ">= 14"
3165 + }
3166 + },
3167 "node_modules/@google-automations/git-file-utils/node_modules/@octokit/openapi-types": {
3168 "version": "18.1.1",
3169 "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
3170 "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
3171 "dev": true
3172 },
3173 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-paginate-rest": {
3174 + "version": "6.1.2",
3175 + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
3176 + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
3177 + "dev": true,
3178 + "dependencies": {
3179 + "@octokit/tsconfig": "^1.0.2",
3180 + "@octokit/types": "^9.2.3"
3181 + },
3182 + "engines": {
3183 + "node": ">= 14"
3184 + },
3185 + "peerDependencies": {
3186 + "@octokit/core": ">=4"
3187 + }
3188 + },
3189 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-request-log": {
3190 + "version": "1.0.4",
3191 + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
3192 + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
3193 + "dev": true,
3194 + "peerDependencies": {
3195 + "@octokit/core": ">=3"
3196 + }
3197 + },
3198 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-rest-endpoint-methods": {
3199 + "version": "7.2.3",
3200 + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
3201 + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
3202 + "dev": true,
3203 + "dependencies": {
3204 + "@octokit/types": "^10.0.0"
3205 + },
3206 + "engines": {
3207 + "node": ">= 14"
3208 + },
3209 + "peerDependencies": {
3210 + "@octokit/core": ">=3"
3211 + }
3212 + },
3213 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
3214 + "version": "10.0.0",
3215 + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
3216 + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
3217 + "dev": true,
3218 + "dependencies": {
3219 + "@octokit/openapi-types": "^18.0.0"
3220 + }
3221 + },
3222 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/request": {
3223 + "version": "6.2.8",
3224 + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz",
3225 + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==",
3226 + "dev": true,
3227 + "dependencies": {
3228 + "@octokit/endpoint": "^7.0.0",
3229 + "@octokit/request-error": "^3.0.0",
3230 + "@octokit/types": "^9.0.0",
3231 + "is-plain-object": "^5.0.0",
3232 + "node-fetch": "^2.6.7",
3233 + "universal-user-agent": "^6.0.0"
3234 + },
3235 + "engines": {
3236 + "node": ">= 14"
3237 + }
3238 + },
3239 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/request-error": {
3240 + "version": "3.0.3",
3241 + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
3242 + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
3243 + "dev": true,
3244 + "dependencies": {
3245 + "@octokit/types": "^9.0.0",
3246 + "deprecation": "^2.0.0",
3247 + "once": "^1.4.0"
3248 + },
3249 + "engines": {
3250 + "node": ">= 14"
3251 + }
3252 + },
3253 + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/rest": {
3254 + "version": "19.0.13",
3255 + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
3256 + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
3257 + "dev": true,
3258 + "dependencies": {
3259 + "@octokit/core": "^4.2.1",
3260 + "@octokit/plugin-paginate-rest": "^6.1.2",
3261 + "@octokit/plugin-request-log": "^1.0.4",
3262 + "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
3263 + },
3264 + "engines": {
3265 + "node": ">= 14"
3266 + }
3267 + },
3268 "node_modules/@google-automations/git-file-utils/node_modules/@octokit/types": {
3269 "version": "9.3.2",
3270 "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
@@ -6465,30 +6548,16 @@
6548 "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
6549 }
6550 },
6468 - "node_modules/@npmcli/template-oss/node_modules/semver": {
6469 - "version": "7.5.4",
6470 - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
6471 - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
6551 + "node_modules/@npmcli/template-oss/node_modules/@octokit/auth-token": {
6552 + "version": "3.0.4",
6553 + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
6554 + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
6555 "dev": true,
6473 - "dependencies": {
6474 - "lru-cache": "^6.0.0"
6475 - },
6476 - "bin": {
6477 - "semver": "bin/semver.js"
6478 - },
6479 - "engines": {
6480 - "node": ">=10"
6481 - }
6482 - },
6483 - "node_modules/@octokit/auth-token": {
6484 - "version": "4.0.0",
6485 - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
6486 - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
6556 "engines": {
6488 - "node": ">= 18"
6557 + "node": ">= 14"
6558 }
6559 },
6491 - "node_modules/@octokit/core": {
6560 + "node_modules/@npmcli/template-oss/node_modules/@octokit/core": {
6561 "version": "4.2.4",
6562 "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
6563 "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
@@ -6506,16 +6575,7 @@
6575 "node": ">= 14"
6576 }
6577 },
6509 - "node_modules/@octokit/core/node_modules/@octokit/auth-token": {
6510 - "version": "3.0.4",
6511 - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
6512 - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
6513 - "dev": true,
6514 - "engines": {
6515 - "node": ">= 14"
6516 - }
6517 - },
6518 - "node_modules/@octokit/core/node_modules/@octokit/endpoint": {
6578 + "node_modules/@npmcli/template-oss/node_modules/@octokit/endpoint": {
6579 "version": "7.0.6",
6580 "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz",
6581 "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==",
@@ -6529,7 +6589,7 @@
6589 "node": ">= 14"
6590 }
6591 },
6532 - "node_modules/@octokit/core/node_modules/@octokit/graphql": {
6592 + "node_modules/@npmcli/template-oss/node_modules/@octokit/graphql": {
6593 "version": "5.0.6",
6594 "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz",
6595 "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==",
@@ -6543,13 +6603,62 @@
6603 "node": ">= 14"
6604 }
6605 },
6546 - "node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
6606 + "node_modules/@npmcli/template-oss/node_modules/@octokit/openapi-types": {
6607 "version": "18.1.1",
6608 "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
6609 "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
6610 "dev": true
6611 },
6552 - "node_modules/@octokit/core/node_modules/@octokit/request": {
6612 + "node_modules/@npmcli/template-oss/node_modules/@octokit/plugin-paginate-rest": {
6613 + "version": "6.1.2",
6614 + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
6615 + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
6616 + "dev": true,
6617 + "dependencies": {
6618 + "@octokit/tsconfig": "^1.0.2",
6619 + "@octokit/types": "^9.2.3"
6620 + },
6621 + "engines": {
6622 + "node": ">= 14"
6623 + },
6624 + "peerDependencies": {
6625 + "@octokit/core": ">=4"
6626 + }
6627 + },
6628 + "node_modules/@npmcli/template-oss/node_modules/@octokit/plugin-request-log": {
6629 + "version": "1.0.4",
6630 + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
6631 + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
6632 + "dev": true,
6633 + "peerDependencies": {
6634 + "@octokit/core": ">=3"
6635 + }
6636 + },
6637 + "node_modules/@npmcli/template-oss/node_modules/@octokit/plugin-rest-endpoint-methods": {
6638 + "version": "7.2.3",
6639 + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
6640 + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
6641 + "dev": true,
6642 + "dependencies": {
6643 + "@octokit/types": "^10.0.0"
6644 + },
6645 + "engines": {
6646 + "node": ">= 14"
6647 + },
6648 + "peerDependencies": {
6649 + "@octokit/core": ">=3"
6650 + }
6651 + },
6652 + "node_modules/@npmcli/template-oss/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
6653 + "version": "10.0.0",
6654 + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
6655 + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
6656 + "dev": true,
6657 + "dependencies": {
6658 + "@octokit/openapi-types": "^18.0.0"
6659 + }
6660 + },
6661 + "node_modules/@npmcli/template-oss/node_modules/@octokit/request": {
6662 "version": "6.2.8",
6663 "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz",
6664 "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==",
@@ -6566,7 +6675,7 @@
6675 "node": ">= 14"
6676 }
6677 },
6569 - "node_modules/@octokit/core/node_modules/@octokit/request-error": {
6678 + "node_modules/@npmcli/template-oss/node_modules/@octokit/request-error": {
6679 "version": "3.0.3",
6680 "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
6681 "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
@@ -6580,7 +6689,22 @@
6689 "node": ">= 14"
6690 }
6691 },
6583 - "node_modules/@octokit/core/node_modules/@octokit/types": {
6692 + "node_modules/@npmcli/template-oss/node_modules/@octokit/rest": {
6693 + "version": "19.0.13",
6694 + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
6695 + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
6696 + "dev": true,
6697 + "dependencies": {
6698 + "@octokit/core": "^4.2.1",
6699 + "@octokit/plugin-paginate-rest": "^6.1.2",
6700 + "@octokit/plugin-request-log": "^1.0.4",
6701 + "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
6702 + },
6703 + "engines": {
6704 + "node": ">= 14"
6705 + }
6706 + },
6707 + "node_modules/@npmcli/template-oss/node_modules/@octokit/types": {
6708 "version": "9.3.2",
6709 "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
6710 "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==",
@@ -6589,6 +6713,46 @@
6713 "@octokit/openapi-types": "^18.0.0"
6714 }
6715 },
6716 + "node_modules/@npmcli/template-oss/node_modules/semver": {
6717 + "version": "7.5.4",
6718 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
6719 + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
6720 + "dev": true,
6721 + "dependencies": {
6722 + "lru-cache": "^6.0.0"
6723 + },
6724 + "bin": {
6725 + "semver": "bin/semver.js"
6726 + },
6727 + "engines": {
6728 + "node": ">=10"
6729 + }
6730 + },
6731 + "node_modules/@octokit/auth-token": {
6732 + "version": "4.0.0",
6733 + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
6734 + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
6735 + "engines": {
6736 + "node": ">= 18"
6737 + }
6738 + },
6739 + "node_modules/@octokit/core": {
6740 + "version": "5.0.1",
6741 + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz",
6742 + "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==",
6743 + "dependencies": {
6744 + "@octokit/auth-token": "^4.0.0",
6745 + "@octokit/graphql": "^7.0.0",
6746 + "@octokit/request": "^8.0.2",
6747 + "@octokit/request-error": "^5.0.0",
6748 + "@octokit/types": "^12.0.0",
6749 + "before-after-hook": "^2.2.0",
6750 + "universal-user-agent": "^6.0.0"
6751 + },
6752 + "engines": {
6753 + "node": ">= 18"
6754 + }
6755 + },
6756 "node_modules/@octokit/endpoint": {
6757 "version": "9.0.1",
6758 "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz",
@@ -6621,73 +6785,73 @@
6785 "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
6786 },
6787 "node_modules/@octokit/plugin-paginate-rest": {
6624 - "version": "6.1.2",
6625 - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
6626 - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
6627 - "dev": true,
6788 + "version": "9.0.0",
6789 + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
6790 + "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
6791 "dependencies": {
6629 - "@octokit/tsconfig": "^1.0.2",
6630 - "@octokit/types": "^9.2.3"
6792 + "@octokit/types": "^12.0.0"
6793 },
6794 "engines": {
6633 - "node": ">= 14"
6795 + "node": ">= 18"
6796 },
6797 "peerDependencies": {
6636 - "@octokit/core": ">=4"
6637 - }
6638 - },
6639 - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
6640 - "version": "18.1.1",
6641 - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
6642 - "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
6643 - "dev": true
6644 - },
6645 - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
6646 - "version": "9.3.2",
6647 - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
6648 - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==",
6649 - "dev": true,
6650 - "dependencies": {
6651 - "@octokit/openapi-types": "^18.0.0"
6798 + "@octokit/core": ">=5"
6799 }
6800 },
6801 "node_modules/@octokit/plugin-request-log": {
6655 - "version": "1.0.4",
6656 - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
6657 - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
6658 - "dev": true,
6802 + "version": "4.0.0",
6803 + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
6804 + "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==",
6805 + "engines": {
6806 + "node": ">= 18"
6807 + },
6808 "peerDependencies": {
6660 - "@octokit/core": ">=3"
6809 + "@octokit/core": ">=5"
6810 }
6811 },
6812 "node_modules/@octokit/plugin-rest-endpoint-methods": {
6664 - "version": "7.2.3",
6665 - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
6666 - "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
6667 - "dev": true,
6813 + "version": "10.0.1",
6814 + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.1.tgz",
6815 + "integrity": "sha512-fgS6HPkPvJiz8CCliewLyym9qAx0RZ/LKh3sATaPfM41y/O2wQ4Z9MrdYeGPVh04wYmHFmWiGlKPC7jWVtZXQA==",
6816 "dependencies": {
6669 - "@octokit/types": "^10.0.0"
6817 + "@octokit/types": "^12.0.0"
6818 },
6819 "engines": {
6672 - "node": ">= 14"
6820 + "node": ">= 18"
6821 },
6822 "peerDependencies": {
6675 - "@octokit/core": ">=3"
6823 + "@octokit/core": ">=5"
6824 }
6825 },
6678 - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
6679 - "version": "18.1.1",
6680 - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
6681 - "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
6682 - "dev": true
6826 + "node_modules/@octokit/plugin-retry": {
6827 + "version": "6.0.1",
6828 + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz",
6829 + "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==",
6830 + "dependencies": {
6831 + "@octokit/request-error": "^5.0.0",
6832 + "@octokit/types": "^12.0.0",
6833 + "bottleneck": "^2.15.3"
6834 + },
6835 + "engines": {
6836 + "node": ">= 18"
6837 + },
6838 + "peerDependencies": {
6839 + "@octokit/core": ">=5"
6840 + }
6841 },
6684 - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
6685 - "version": "10.0.0",
6686 - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
6687 - "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
6688 - "dev": true,
6842 + "node_modules/@octokit/plugin-throttling": {
6843 + "version": "8.0.0",
6844 + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.0.0.tgz",
6845 + "integrity": "sha512-OkMbHYUidj81q92YRkPzWmwXkEtsI3KOcSkNm763aqUOh9IEplyX05XjKAdZFANAvaYH0Q4JBZwu4h2VnPVXZA==",
6846 "dependencies": {
6690 - "@octokit/openapi-types": "^18.0.0"
6847 + "@octokit/types": "^12.0.0",
6848 + "bottleneck": "^2.15.3"
6849 + },
6850 + "engines": {
6851 + "node": ">= 18"
6852 + },
6853 + "peerDependencies": {
6854 + "@octokit/core": "^5.0.0"
6855 }
6856 },
6857 "node_modules/@octokit/request": {
@@ -6719,18 +6883,17 @@
6883 }
6884 },
6885 "node_modules/@octokit/rest": {
6722 - "version": "19.0.13",
6723 - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
6724 - "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
6725 - "dev": true,
6726 - "dependencies": {
6727 - "@octokit/core": "^4.2.1",
6728 - "@octokit/plugin-paginate-rest": "^6.1.2",
6729 - "@octokit/plugin-request-log": "^1.0.4",
6730 - "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
6886 + "version": "20.0.2",
6887 + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz",
6888 + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==",
6889 + "dependencies": {
6890 + "@octokit/core": "^5.0.0",
6891 + "@octokit/plugin-paginate-rest": "^9.0.0",
6892 + "@octokit/plugin-request-log": "^4.0.0",
6893 + "@octokit/plugin-rest-endpoint-methods": "^10.0.0"
6894 },
6895 "engines": {
6733 - "node": ">= 14"
6896 + "node": ">= 18"
6897 }
6898 },
6899 "node_modules/@octokit/tsconfig": {
@@ -11071,6 +11234,11 @@
11234 "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
11235 "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
11236 },
11237 + "node_modules/bottleneck": {
11238 + "version": "2.19.5",
11239 + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
11240 + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
11241 + },
11242 "node_modules/boxen": {
11243 "version": "5.1.2",
11244 "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
@@ -12002,6 +12170,171 @@
12170 "node": ">=14.0.0"
12171 }
12172 },
12173 + "node_modules/code-suggester/node_modules/@octokit/auth-token": {
12174 + "version": "3.0.4",
12175 + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
12176 + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
12177 + "dev": true,
12178 + "engines": {
12179 + "node": ">= 14"
12180 + }
12181 + },
12182 + "node_modules/code-suggester/node_modules/@octokit/core": {
12183 + "version": "4.2.4",
12184 + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
12185 + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
12186 + "dev": true,
12187 + "dependencies": {
12188 + "@octokit/auth-token": "^3.0.0",
12189 + "@octokit/graphql": "^5.0.0",
12190 + "@octokit/request": "^6.0.0",
12191 + "@octokit/request-error": "^3.0.0",
12192 + "@octokit/types": "^9.0.0",
12193 + "before-after-hook": "^2.2.0",
12194 + "universal-user-agent": "^6.0.0"
12195 + },
12196 + "engines": {
12197 + "node": ">= 14"
12198 + }
12199 + },
12200 + "node_modules/code-suggester/node_modules/@octokit/endpoint": {
12201 + "version": "7.0.6",
12202 + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz",
12203 + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==",
12204 + "dev": true,
12205 + "dependencies": {
12206 + "@octokit/types": "^9.0.0",
12207 + "is-plain-object": "^5.0.0",
12208 + "universal-user-agent": "^6.0.0"
12209 + },
12210 + "engines": {
12211 + "node": ">= 14"
12212 + }
12213 + },
12214 + "node_modules/code-suggester/node_modules/@octokit/graphql": {
12215 + "version": "5.0.6",
12216 + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz",
12217 + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==",
12218 + "dev": true,
12219 + "dependencies": {
12220 + "@octokit/request": "^6.0.0",
12221 + "@octokit/types": "^9.0.0",
12222 + "universal-user-agent": "^6.0.0"
12223 + },
12224 + "engines": {
12225 + "node": ">= 14"
12226 + }
12227 + },
12228 + "node_modules/code-suggester/node_modules/@octokit/openapi-types": {
12229 + "version": "18.1.1",
12230 + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
12231 + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
12232 + "dev": true
12233 + },
12234 + "node_modules/code-suggester/node_modules/@octokit/plugin-paginate-rest": {
12235 + "version": "6.1.2",
12236 + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
12237 + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
12238 + "dev": true,
12239 + "dependencies": {
12240 + "@octokit/tsconfig": "^1.0.2",
12241 + "@octokit/types": "^9.2.3"
12242 + },
12243 + "engines": {
12244 + "node": ">= 14"
12245 + },
12246 + "peerDependencies": {
12247 + "@octokit/core": ">=4"
12248 + }
12249 + },
12250 + "node_modules/code-suggester/node_modules/@octokit/plugin-request-log": {
12251 + "version": "1.0.4",
12252 + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
12253 + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
12254 + "dev": true,
12255 + "peerDependencies": {
12256 + "@octokit/core": ">=3"
12257 + }
12258 + },
12259 + "node_modules/code-suggester/node_modules/@octokit/plugin-rest-endpoint-methods": {
12260 + "version": "7.2.3",
12261 + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
12262 + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
12263 + "dev": true,
12264 + "dependencies": {
12265 + "@octokit/types": "^10.0.0"
12266 + },
12267 + "engines": {
12268 + "node": ">= 14"
12269 + },
12270 + "peerDependencies": {
12271 + "@octokit/core": ">=3"
12272 + }
12273 + },
12274 + "node_modules/code-suggester/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
12275 + "version": "10.0.0",
12276 + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
12277 + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
12278 + "dev": true,
12279 + "dependencies": {
12280 + "@octokit/openapi-types": "^18.0.0"
12281 + }
12282 + },
12283 + "node_modules/code-suggester/node_modules/@octokit/request": {
12284 + "version": "6.2.8",
12285 + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz",
12286 + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==",
12287 + "dev": true,
12288 + "dependencies": {
12289 + "@octokit/endpoint": "^7.0.0",
12290 + "@octokit/request-error": "^3.0.0",
12291 + "@octokit/types": "^9.0.0",
12292 + "is-plain-object": "^5.0.0",
12293 + "node-fetch": "^2.6.7",
12294 + "universal-user-agent": "^6.0.0"
12295 + },
12296 + "engines": {
12297 + "node": ">= 14"
12298 + }
12299 + },
12300 + "node_modules/code-suggester/node_modules/@octokit/request-error": {
12301 + "version": "3.0.3",
12302 + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
12303 + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
12304 + "dev": true,
12305 + "dependencies": {
12306 + "@octokit/types": "^9.0.0",
12307 + "deprecation": "^2.0.0",
12308 + "once": "^1.4.0"
12309 + },
12310 + "engines": {
12311 + "node": ">= 14"
12312 + }
12313 + },
12314 + "node_modules/code-suggester/node_modules/@octokit/rest": {
12315 + "version": "19.0.13",
12316 + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
12317 + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
12318 + "dev": true,
12319 + "dependencies": {
12320 + "@octokit/core": "^4.2.1",
12321 + "@octokit/plugin-paginate-rest": "^6.1.2",
12322 + "@octokit/plugin-request-log": "^1.0.4",
12323 + "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
12324 + },
12325 + "engines": {
12326 + "node": ">= 14"
12327 + }
12328 + },
12329 + "node_modules/code-suggester/node_modules/@octokit/types": {
12330 + "version": "9.3.2",
12331 + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
12332 + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==",
12333 + "dev": true,
12334 + "dependencies": {
12335 + "@octokit/openapi-types": "^18.0.0"
12336 + }
12337 + },
12338 "node_modules/code-suggester/node_modules/@types/yargs": {
12339 "version": "16.0.6",
12340 "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.6.tgz",
@@ -17216,21 +17549,6 @@
17549 "@parcel/core": "^2.0.0"
17550 }
17551 },
17219 - "node_modules/gatsby-plugin-catch-links": {
17220 - "version": "5.12.0",
17221 - "resolved": "https://registry.npmjs.org/gatsby-plugin-catch-links/-/gatsby-plugin-catch-links-5.12.0.tgz",
17222 - "integrity": "sha512-00qLnXgZbKmnaRHtZRbwovJAMZQlQ+DoLBTXXr3zE3SDsmgO9NBmlv2q7e43ovHj7MZ9pqQdJYDWweqrcBA9EQ==",
17223 - "dependencies": {
17224 - "@babel/runtime": "^7.20.13",
17225 - "escape-string-regexp": "^1.0.5"
17226 - },
17227 - "engines": {
17228 - "node": ">=18.0.0"
17229 - },
17230 - "peerDependencies": {
17231 - "gatsby": "^5.0.0-next"
17232 - }
17233 - },
17552 "node_modules/gatsby-plugin-manifest": {
17553 "version": "5.12.1",
17554 "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-5.12.1.tgz",
@@ -28388,6 +28706,33 @@
28706 "node": ">=14.0.0"
28707 }
28708 },
28709 + "node_modules/release-please/node_modules/@octokit/auth-token": {
28710 + "version": "3.0.4",
28711 + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
28712 + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
28713 + "dev": true,
28714 + "engines": {
28715 + "node": ">= 14"
28716 + }
28717 + },
28718 + "node_modules/release-please/node_modules/@octokit/core": {
28719 + "version": "4.2.4",
28720 + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
28721 + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
28722 + "dev": true,
28723 + "dependencies": {
28724 + "@octokit/auth-token": "^3.0.0",
28725 + "@octokit/graphql": "^5.0.0",
28726 + "@octokit/request": "^6.0.0",
28727 + "@octokit/request-error": "^3.0.0",
28728 + "@octokit/types": "^9.0.0",
28729 + "before-after-hook": "^2.2.0",
28730 + "universal-user-agent": "^6.0.0"
28731 + },
28732 + "engines": {
28733 + "node": ">= 14"
28734 + }
28735 + },
28736 "node_modules/release-please/node_modules/@octokit/endpoint": {
28737 "version": "7.0.6",
28738 "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz",
@@ -28422,6 +28767,55 @@
28767 "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==",
28768 "dev": true
28769 },
28770 + "node_modules/release-please/node_modules/@octokit/plugin-paginate-rest": {
28771 + "version": "6.1.2",
28772 + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
28773 + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
28774 + "dev": true,
28775 + "dependencies": {
28776 + "@octokit/tsconfig": "^1.0.2",
28777 + "@octokit/types": "^9.2.3"
28778 + },
28779 + "engines": {
28780 + "node": ">= 14"
28781 + },
28782 + "peerDependencies": {
28783 + "@octokit/core": ">=4"
28784 + }
28785 + },
28786 + "node_modules/release-please/node_modules/@octokit/plugin-request-log": {
28787 + "version": "1.0.4",
28788 + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
28789 + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
28790 + "dev": true,
28791 + "peerDependencies": {
28792 + "@octokit/core": ">=3"
28793 + }
28794 + },
28795 + "node_modules/release-please/node_modules/@octokit/plugin-rest-endpoint-methods": {
28796 + "version": "7.2.3",
28797 + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
28798 + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
28799 + "dev": true,
28800 + "dependencies": {
28801 + "@octokit/types": "^10.0.0"
28802 + },
28803 + "engines": {
28804 + "node": ">= 14"
28805 + },
28806 + "peerDependencies": {
28807 + "@octokit/core": ">=3"
28808 + }
28809 + },
28810 + "node_modules/release-please/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
28811 + "version": "10.0.0",
28812 + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
28813 + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
28814 + "dev": true,
28815 + "dependencies": {
28816 + "@octokit/openapi-types": "^18.0.0"
28817 + }
28818 + },
28819 "node_modules/release-please/node_modules/@octokit/request": {
28820 "version": "6.2.8",
28821 "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz",
@@ -28453,6 +28847,21 @@
28847 "node": ">= 14"
28848 }
28849 },
28850 + "node_modules/release-please/node_modules/@octokit/rest": {
28851 + "version": "19.0.13",
28852 + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
28853 + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
28854 + "dev": true,
28855 + "dependencies": {
28856 + "@octokit/core": "^4.2.1",
28857 + "@octokit/plugin-paginate-rest": "^6.1.2",
28858 + "@octokit/plugin-request-log": "^1.0.4",
28859 + "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
28860 + },
28861 + "engines": {
28862 + "node": ">= 14"
28863 + }
28864 + },
28865 "node_modules/release-please/node_modules/@octokit/types": {
28866 "version": "9.3.2",
28867 "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
package.json
+4
@@ -8,6 +8,7 @@
8 "private": true,
9 "scripts": {
10 "develop": "gatsby develop",
11 + "develop:ssr": "DEV_SSR=true gatsby develop",
12 "build": "gatsby build --verbose --log-pages",
13 "clean": "gatsby clean",
14 "serve": "gatsby serve",
@@ -27,6 +28,9 @@
28 "dependencies": {
29 "@mdx-js/mdx": "^2.3.0",
30 "@mdx-js/react": "^2.3.0",
31 + "@octokit/plugin-retry": "^6.0.1",
32 + "@octokit/plugin-throttling": "^8.0.0",
33 + "@octokit/rest": "^20.0.2",
34 "@primer/octicons-react": "^19.8.0",
35 "@primer/react": "^35.32.1",
36 "babel-plugin-styled-components": "^2.1.4",
src/components/__tests__/contributors.test.js
+2 -2
@@ -5,7 +5,7 @@ import Contributors from '../contributors'
5 test('renders contributors', () => {
6 const {queryByText} = render(
7 <Contributors
8 - logins={['colebemis', 'emplums']}
8 + contributors={['colebemis', 'emplums']}
9 latestCommit={{
10 login: 'colebemis',
11 url: '#',
@@ -21,7 +21,7 @@ test('renders contributors', () => {
21 })
22
23 test('does not render "last edited by" if latest contributor does not have a latest commit', () => {
24 - const {queryByText} = render(<Contributors logins={['ashygee']} />)
24 + const {queryByText} = render(<Contributors contributors={['ashygee']} />)
25
26 expect(queryByText(/1 contributor/)).toBeInTheDocument()
27 expect(queryByText(/Last edited by/)).toBeNull()
src/components/__tests__/page-footer.test.js
+11 -10
@@ -1,9 +1,16 @@
1 import {render} from '@testing-library/react'
2 import React from 'react'
3 -import PageFooter from '../page-footer'
3 +import PageFooterComponent from '../page-footer'
4 +import {PageProvider} from '../../hooks/use-page'
5 +
6 +const PageFooter = pageContext => (
7 + <PageProvider value={{pageContext}}>
8 + <PageFooterComponent />
9 + </PageProvider>
10 +)
11
12 test('renders correctly when editUrl and contributors are defined', () => {
6 - const {queryByText} = render(<PageFooter editUrl="#" contributors={{logins: ['broccolini']}} />)
13 + const {queryByText} = render(<PageFooter editUrl="#" contributors={['broccolini']} />)
14
15 expect(queryByText(/Edit this page on GitHub/)).toBeInTheDocument()
16 expect(queryByText(/contributor/)).toBeInTheDocument()
@@ -24,20 +31,14 @@ test('renders correctly when editUrl is defined but contributors is undefined',
31 })
32
33 test('renders correctly when contributors is defined but editUrl is undefined', () => {
27 - const {queryByText} = render(<PageFooter contributors={{logins: ['broccolini']}} />)
34 + const {queryByText} = render(<PageFooter contributors={['broccolini']} />)
35
36 expect(queryByText(/Edit this page on GitHub/)).toBeNull()
37 expect(queryByText(/contributor/)).toBeInTheDocument()
38 })
39
40 test('does not render contributors if contributors is an empty array', () => {
34 - const {queryByText} = render(<PageFooter contributors={{logins: []}} />)
35 -
36 - expect(queryByText(/contributor/)).toBeNull()
37 -})
38 -
39 -test('does not render contributors if contributors is empty object', () => {
40 - const {queryByText} = render(<PageFooter contributors={{}} />)
41 + const {queryByText} = render(<PageFooter contributors={[]} />)
42
43 expect(queryByText(/contributor/)).toBeNull()
44 })
src/components/contributors.js
+3 -3
@@ -21,14 +21,14 @@ const format = d => `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`
21
22 const pluralize = (word, count) => `${word}${count === 1 ? '' : 's'}`
23
24 -function Contributors({logins, latestCommit}) {
24 +function Contributors({contributors = [], latestCommit}) {
25 return (
26 <div>
27 <Box sx={{display: 'flex', alignItems: 'center'}}>
28 <Text sx={{mr: 2}}>
29 - {logins.length} {pluralize('contributor', logins.length)}
29 + {contributors.length} {pluralize('contributor', contributors.length)}
30 </Text>
31 - {logins.map(login => (
31 + {contributors.map(login => (
32 <Link key={login} href={`https://github.com/${login}`} sx={{lineHeight: 'condensedUltra', mr: 2}}>
33 {/* eslint-disable-next-line primer-react/a11y-tooltip-interactive-trigger */}
34 <Tooltip key={login} aria-label={login}>
src/components/page-footer.js
+5 -4
@@ -3,10 +3,11 @@ import {Box, Octicon} from '@primer/react'
3 import {PencilIcon} from '@primer/octicons-react'
4 import Link from './link'
5 import Contributors from './contributors'
6 +import usePage from '../hooks/use-page'
7
7 -function PageFooter({editUrl, contributors = {}}) {
8 - const {logins = [], latestCommit} = contributors
9 - return editUrl || logins.length ? (
8 +function PageFooter() {
9 + const {editUrl, latestCommit, contributors = []} = usePage().pageContext
10 + return editUrl || contributors.length ? (
11 <Box
12 sx={{
13 borderWidth: 0,
@@ -25,7 +26,7 @@ function PageFooter({editUrl, contributors = {}}) {
26 Edit this page on GitHub
27 </Link>
28 ) : null}
28 - {logins.length ? <Contributors logins={logins} latestCommit={latestCommit} /> : null}
29 + {contributors.length ? <Contributors contributors={contributors} latestCommit={latestCommit} /> : null}
30 </Box>
31 </Box>
32 ) : null