Skip to content

Commit 9a7a8a7

Browse files
author
Peter Bengtsson
authored
make lib/rest/index.js callable (#23214)
* Experiment with making the tarball smaller Part of #1248 * try this * stop debugging * delete translations too * delete heavy search indexes too * push and popd * try this hack * delete but leave directory * debug more * faster delete of translations * less loud * async await * async await * no tree * simplify * experimenting more * unfinished * only the large files * change order * brotli with level 6 * cope better with decorated rest json files * tidying * keep images * cleaning * cleaning up * refactored function * try this * better comment * remove console logging * more important changes * make lib/rest/index.js callable Part of #1177 * memoize * remove console logging
1 parent 9bfb1eb commit 9a7a8a7

File tree

4 files changed

+76
-58
lines changed

4 files changed

+76
-58
lines changed

lib/rest/index.js

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,66 +8,68 @@ import { readCompressedJsonFileFallback } from '../read-json-file.js'
88
const __dirname = path.dirname(fileURLToPath(import.meta.url))
99
const schemasPath = path.join(__dirname, 'static/decorated')
1010

11-
export const operations = {}
12-
fs.readdirSync(schemasPath).forEach((filename) => {
13-
// In staging deploys, the `.json` files might have been converted to
14-
// to `.json.br`. The `readCompressedJsonFileFallback()` function
15-
// can handle both but you need to call it with the `.json` filename.
16-
const key = path.parse(filename).name
17-
const value = readCompressedJsonFileFallback(path.join(schemasPath, filename))
18-
operations[key] = value
19-
})
20-
21-
// Get initial set of keys that will be deleted once new keys are set
22-
const openApiOperationKeys = Object.keys(operations)
11+
export default async function getRest() {
12+
const operations = {}
13+
fs.readdirSync(schemasPath).forEach((filename) => {
14+
// In staging deploys, the `.json` files might have been converted to
15+
// to `.json.br`. The `readCompressedJsonFileFallback()` function
16+
// can handle both but you need to call it with the `.json` filename.
17+
const key = path.parse(filename).name
18+
const value = readCompressedJsonFileFallback(path.join(schemasPath, filename))
19+
operations[key] = value
20+
})
2321

24-
let allCategories = []
25-
allVersionKeys.forEach((currentVersion) => {
26-
// Translate the versions from the openapi to versions used in the docs
27-
const openApiVersion = allVersions[currentVersion].openApiVersionName
22+
// Get initial set of keys that will be deleted once new keys are set
23+
const openApiOperationKeys = Object.keys(operations)
2824

29-
// Check that the openApiVersion is configured in OpenAPI
30-
if (!operations[openApiVersion]) return
25+
let allCategories = []
26+
allVersionKeys.forEach((currentVersion) => {
27+
// Translate the versions from the openapi to versions used in the docs
28+
const openApiVersion = allVersions[currentVersion].openApiVersionName
3129

32-
operations[currentVersion] = operations[openApiVersion]
30+
// Check that the openApiVersion is configured in OpenAPI
31+
if (!operations[openApiVersion]) return
3332

34-
// This list is generated for use in the tests,
35-
// so we can verify that the names of the markdown files
36-
// in content/rest/reference/*.md are congruous with the
37-
// set of REST resource names like activity, gists, repos, etc.
38-
allCategories = allCategories.concat(
39-
chain(operations[currentVersion]).map('category').sort().uniq().value()
40-
)
33+
operations[currentVersion] = operations[openApiVersion]
4134

42-
// Attach convenience properties to each operation that can't easily be created in Liquid
43-
operations[currentVersion].forEach((operation) => {
44-
operation.hasRequiredPreviews = get(operation, 'x-github.previews', []).some(
45-
(preview) => preview.required
35+
// This list is generated for use in the tests,
36+
// so we can verify that the names of the markdown files
37+
// in content/rest/reference/*.md are congruous with the
38+
// set of REST resource names like activity, gists, repos, etc.
39+
allCategories = allCategories.concat(
40+
chain(operations[currentVersion]).map('category').sort().uniq().value()
4641
)
42+
43+
// Attach convenience properties to each operation that can't easily be created in Liquid
44+
operations[currentVersion].forEach((operation) => {
45+
operation.hasRequiredPreviews = get(operation, 'x-github.previews', []).some(
46+
(preview) => preview.required
47+
)
48+
})
4749
})
48-
})
4950

50-
// Get the unique set of categories
51-
const categories = [...new Set(allCategories)]
51+
// Get the unique set of categories
52+
const categories = [...new Set(allCategories)]
5253

53-
// Remove openapi base name keys that have been replaced with version key
54-
openApiOperationKeys.forEach((openApiVersionName) => {
55-
delete operations[openApiVersionName]
56-
})
54+
// Remove openapi base name keys that have been replaced with version key
55+
openApiOperationKeys.forEach((openApiVersionName) => {
56+
delete operations[openApiVersionName]
57+
})
5758

58-
// This is a collection of operations that have `enabledForGitHubApps = true`
59-
// It's grouped by resource title to make rendering easier
60-
const operationsEnabledForGitHubApps = allVersionKeys.reduce((acc, currentVersion) => {
61-
acc[currentVersion] = chain(operations[currentVersion] || [])
62-
.filter((operation) => operation['x-github'].enabledForGitHubApps)
63-
.orderBy('category')
64-
.value()
65-
acc[currentVersion] = groupBy(acc[currentVersion], 'category')
66-
return acc
67-
}, {})
59+
// This is a collection of operations that have `enabledForGitHubApps = true`
60+
// It's grouped by resource title to make rendering easier
61+
const operationsEnabledForGitHubApps = allVersionKeys.reduce((acc, currentVersion) => {
62+
acc[currentVersion] = chain(operations[currentVersion] || [])
63+
.filter((operation) => operation['x-github'].enabledForGitHubApps)
64+
.orderBy('category')
65+
.value()
66+
acc[currentVersion] = groupBy(acc[currentVersion], 'category')
67+
return acc
68+
}, {})
6869

69-
export default {
70-
categories,
71-
operations,
72-
operationsEnabledForGitHubApps,
70+
return {
71+
categories,
72+
operations,
73+
operationsEnabledForGitHubApps,
74+
}
7375
}

middleware/contextualizers/rest.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import path from 'path'
2-
import rest from '../../lib/rest/index.js'
2+
import getRest from '../../lib/rest/index.js'
33
import removeFPTFromPath from '../../lib/remove-fpt-from-path.js'
44

5-
export default function restContext(req, res, next) {
5+
// Global cache to avoid calling getRest() more than once
6+
let rest = null
7+
8+
export default async function restContext(req, res, next) {
9+
// Bail early because these are pointless to contextualize
10+
if (req.path.startsWith('/_next/static')) return next()
11+
12+
if (!rest) {
13+
rest = await getRest()
14+
}
615
req.context.rest = rest
716

817
// link to include in `Works with GitHub Apps` notes

tests/rendering/rest.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import fs from 'fs/promises'
44
import { difference, isPlainObject } from 'lodash-es'
55
import { getJSON } from '../helpers/supertest.js'
66
import enterpriseServerReleases from '../../lib/enterprise-server-releases.js'
7-
import rest from '../../lib/rest/index.js'
7+
import getRest from '../../lib/rest/index.js'
88
import { jest } from '@jest/globals'
99

1010
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@@ -20,7 +20,7 @@ describe('REST references docs', () => {
2020
jest.setTimeout(3 * 60 * 1000)
2121

2222
test('markdown file exists for every operationId prefix in the api.github.com schema', async () => {
23-
const { categories } = rest
23+
const { categories } = await getRest()
2424
const referenceDir = path.join(__dirname, '../../content/rest/reference')
2525
const filenames = (await fs.readdir(referenceDir))
2626
.filter(
@@ -61,7 +61,7 @@ describe('REST references docs', () => {
6161
})
6262

6363
test('no wrongly detected AppleScript syntax highlighting in schema data', async () => {
64-
const { operations } = rest
64+
const { operations } = await getRest()
6565
expect(JSON.stringify(operations).includes('hljs language-applescript')).toBe(false)
6666
})
6767
})

tests/unit/openapi-schema.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ import walk from 'walk-sync'
44
import { get, isPlainObject } from 'lodash-es'
55
import { allVersions } from '../../lib/all-versions.js'
66
import nonEnterpriseDefaultVersion from '../../lib/non-enterprise-default-version.js'
7-
import { operations } from '../../lib/rest/index.js'
7+
import getRest from '../../lib/rest/index.js'
88
import dedent from 'dedent'
9+
import { beforeAll } from '@jest/globals'
910
const __dirname = path.dirname(fileURLToPath(import.meta.url))
1011
const schemasPath = path.join(__dirname, '../../lib/rest/static/decorated')
11-
const nonEnterpriseDefaultVersionSchema = operations[nonEnterpriseDefaultVersion]
12+
13+
let operations = null
14+
let nonEnterpriseDefaultVersionSchema = null
15+
beforeAll(async () => {
16+
operations = (await getRest()).operations
17+
nonEnterpriseDefaultVersionSchema = operations[nonEnterpriseDefaultVersion]
18+
})
1219

1320
describe('OpenAPI schema validation', () => {
1421
test('makes an object', () => {

0 commit comments

Comments
 (0)