chore: remove theme workspace and merge all files into root
Luke Karrys committed
Oct 15, 2023 at 14:41 UTC
183f1203ce0f19d8e4321d9e84bf03d223f82036
60 files changed
+348
-669
.eslintrc.js
-7
@@ -12,15 +12,8 @@ module.exports = {
12
'plugin:import/recommended',
13
'prettier',
14
],
15
- settings: {
16
- import: {
17
- ignore: ['^theme$'],
18
- },
19
- },
15
rules: {
16
'react/prop-types': 'off',
22
- // our theme use exports which dont work with import/no-unresolved
23
- 'import/no-unresolved': ['error', {ignore: ['^theme$']}],
17
},
18
overrides: [
19
{
.github/workflows/ci-theme.yml
deleted
-175
@@ -1,175 +0,0 @@
1
-# This file is automatically added by @npmcli/template-oss. Do not edit.
2
-
3
-name: CI - theme
4
-
5
-on:
6
- workflow_dispatch:
7
- pull_request:
8
- paths:
9
- - theme/**
10
- push:
11
- branches:
12
- - main
13
- paths:
14
- - theme/**
15
- schedule:
16
- # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
17
- - cron: "0 9 * * 1"
18
-
19
-jobs:
20
- lint:
21
- name: Lint
22
- if: github.repository_owner == 'npm'
23
- runs-on: ubuntu-latest
24
- defaults:
25
- run:
26
- shell: bash
27
- steps:
28
- - name: Checkout
29
- uses: actions/checkout@v3
30
- - name: Setup Git User
31
- run: |
32
- git config --global user.email "npm-cli+bot@github.com"
33
- git config --global user.name "npm CLI robot"
34
- - name: Setup Node
35
- uses: actions/setup-node@v3
36
- id: node
37
- with:
38
- node-version: 18.x
39
- check-latest: contains('18.x', '.x')
40
- cache: npm
41
-
42
- # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
43
- - name: Update Windows npm
44
- if: |
45
- matrix.platform.os == 'windows-latest' && (
46
- startsWith(steps.node.outputs.node-version, 'v10.') || startsWith(steps.node.outputs.node-version, 'v12.') || startsWith(steps.node.outputs.node-version, 'v14.')
47
- )
48
- run: |
49
- curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
50
- tar xf npm-7.5.4.tgz
51
- cd package
52
- node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
53
- cd ..
54
- rmdir /s /q package
55
-
56
- # Start on Node 10 because we dont test on anything lower
57
- - name: Install npm@7 on Node 10
58
- shell: bash
59
- if: startsWith(steps.node.outputs.node-version, 'v10.')
60
- id: npm-7
61
- run: |
62
- npm i --prefer-online --no-fund --no-audit -g npm@7
63
- echo "updated=true" >> "$GITHUB_OUTPUT"
64
-
65
- - name: Install npm@8 on Node 12
66
- shell: bash
67
- if: startsWith(steps.node.outputs.node-version, 'v12.')
68
- id: npm-8
69
- run: |
70
- npm i --prefer-online --no-fund --no-audit -g npm@8
71
- echo "updated=true" >> "$GITHUB_OUTPUT"
72
-
73
- - name: Install npm@9 on Node 14/16/18.0
74
- shell: bash
75
- if: startsWith(steps.node.outputs.node-version, 'v14.') || startsWith(steps.node.outputs.node-version, 'v16.') || startsWith(steps.node.outputs.node-version, 'v18.0.')
76
- id: npm-9
77
- run: |
78
- npm i --prefer-online --no-fund --no-audit -g npm@9
79
- echo "updated=true" >> "$GITHUB_OUTPUT"
80
-
81
- - name: Install npm@latest on Node
82
- if: ${{ !(steps.npm-7.outputs.updated || steps.npm-8.outputs.updated || steps.npm-9.outputs.updated) }}
83
- run: npm i --prefer-online --no-fund --no-audit -g npm@latest
84
-
85
- - name: npm Version
86
- run: npm -v
87
- - name: Install Dependencies
88
- run: npm i --no-audit --no-fund
89
- - name: Lint
90
- run: npm run lint --ignore-scripts -w theme
91
- - name: Post Lint
92
- run: npm run postlint --ignore-scripts -w theme
93
-
94
- test:
95
- name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
96
- if: github.repository_owner == 'npm'
97
- strategy:
98
- fail-fast: false
99
- matrix:
100
- platform:
101
- - name: Linux
102
- os: ubuntu-latest
103
- shell: bash
104
- node-version:
105
- - 18.x
106
- runs-on: ${{ matrix.platform.os }}
107
- defaults:
108
- run:
109
- shell: ${{ matrix.platform.shell }}
110
- steps:
111
- - name: Checkout
112
- uses: actions/checkout@v3
113
- - name: Setup Git User
114
- run: |
115
- git config --global user.email "npm-cli+bot@github.com"
116
- git config --global user.name "npm CLI robot"
117
- - name: Setup Node
118
- uses: actions/setup-node@v3
119
- id: node
120
- with:
121
- node-version: ${{ matrix.node-version }}
122
- check-latest: contains(matrix.node-version, '.x')
123
- cache: npm
124
-
125
- # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows
126
- - name: Update Windows npm
127
- if: |
128
- matrix.platform.os == 'windows-latest' && (
129
- startsWith(steps.node.outputs.node-version, 'v10.') || startsWith(steps.node.outputs.node-version, 'v12.') || startsWith(steps.node.outputs.node-version, 'v14.')
130
- )
131
- run: |
132
- curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
133
- tar xf npm-7.5.4.tgz
134
- cd package
135
- node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
136
- cd ..
137
- rmdir /s /q package
138
-
139
- # Start on Node 10 because we dont test on anything lower
140
- - name: Install npm@7 on Node 10
141
- shell: bash
142
- if: startsWith(steps.node.outputs.node-version, 'v10.')
143
- id: npm-7
144
- run: |
145
- npm i --prefer-online --no-fund --no-audit -g npm@7
146
- echo "updated=true" >> "$GITHUB_OUTPUT"
147
-
148
- - name: Install npm@8 on Node 12
149
- shell: bash
150
- if: startsWith(steps.node.outputs.node-version, 'v12.')
151
- id: npm-8
152
- run: |
153
- npm i --prefer-online --no-fund --no-audit -g npm@8
154
- echo "updated=true" >> "$GITHUB_OUTPUT"
155
-
156
- - name: Install npm@9 on Node 14/16/18.0
157
- shell: bash
158
- if: startsWith(steps.node.outputs.node-version, 'v14.') || startsWith(steps.node.outputs.node-version, 'v16.') || startsWith(steps.node.outputs.node-version, 'v18.0.')
159
- id: npm-9
160
- run: |
161
- npm i --prefer-online --no-fund --no-audit -g npm@9
162
- echo "updated=true" >> "$GITHUB_OUTPUT"
163
-
164
- - name: Install npm@latest on Node
165
- if: ${{ !(steps.npm-7.outputs.updated || steps.npm-8.outputs.updated || steps.npm-9.outputs.updated) }}
166
- run: npm i --prefer-online --no-fund --no-audit -g npm@latest
167
-
168
- - name: npm Version
169
- run: npm -v
170
- - name: Install Dependencies
171
- run: npm i --no-audit --no-fund
172
- - name: Add Problem Matcher
173
- run: echo "::add-matcher::.github/matchers/tap.json"
174
- - name: Test
175
- run: npm test --ignore-scripts -w theme
.github/workflows/ci.yml
-2
@@ -7,13 +7,11 @@ on:
7
pull_request:
8
paths-ignore:
9
- cli/**
10
- - theme/**
10
push:
11
branches:
12
- main
13
paths-ignore:
14
- cli/**
16
- - theme/**
15
schedule:
16
# "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
17
- cron: "0 9 * * 1"
.gitignore
-1
@@ -39,4 +39,3 @@
39
!/tap-snapshots/
40
!/test/
41
!/cli/
42
-!/theme/
CONTRIBUTING.md
+2
-7
@@ -10,11 +10,10 @@ This is the documentation for [https://docs.npmjs.com/](https://docs.npmjs.com/)
10
- [Navigation](#navigation)
11
- [CLI](#cli)
12
- [Deploying changes](#deploying-changes)
13
-- [Theme](#theme)
13
14
## Quick start
15
17
-1. `npm install` to download Gatsby, our theme, and the dependencies
16
+1. `npm install` to download Gatsby and all the dependencies
17
2. `npm run develop`: starts the test server at `http://localhost:8000`.
18
3. Update the content - it's MDX, which is like Markdown - in the `content` directory.
19
4. Review your content at `http://localhost:8000`. (Gatsby watches the filesystem and will reload your content changes immediately.)
@@ -109,7 +108,7 @@ The content pages should include [frontmatter](https://jekyllrb.com/docs/front-m
108
109
## Navigation
110
112
-The site's navigation (on the left-hand sidebar of the site) is controlled by `src/theme/nav.yml`. If you add or remove a page from the site, you'll also want to add or remove it from the navigation configuration.
111
+The site's navigation (on the left-hand sidebar of the site) is controlled by `src/nav.yml`. If you add or remove a page from the site, you'll also want to add or remove it from the navigation configuration.
112
113
## CLI
114
@@ -147,7 +146,3 @@ The docs site (https://docs.npmjs.com/) is published from a [GitHub Actions work
146
3. Merge that pull request
147
148
On step three, your changes will be published live! 🎉
150
-
151
-## Theme
152
-
153
-The Gatsby theme used here is located in the [`theme/`](./theme) directory. It is a variation of [doctocat](https://github.com/primer/doctocat) with some theme changes for npm's design language and additional components to support multiple versions of the CLI documentation.
README.md
-4
@@ -18,10 +18,6 @@ This is the documentation for [https://docs.npmjs.com/](https://docs.npmjs.com/)
18
19
Do you want to know more? Check out our [contributing guide](CONTRIBUTING.md).
20
21
-## Theme
22
-
23
-The gatsby theme used here is located in the [`theme/`](./theme) directory. It is a variation of [doctocat](https://github.com/primer/doctocat) with some theme changes for npm's design language and additional components to support multiple versions of the CLI documentation.
24
-
21
## License
22
23
The npm product documentation in the content, and static folders are licensed under a [CC-BY 4.0 license](LICENSE).
gatsby-browser.js
renamed
gatsby-config.js
+67
-6
@@ -1,3 +1,45 @@
1
+const path = require('path')
2
+const fs = require('fs')
3
+
4
+const {NODE_ENV, GATSBY_PARTIAL_CONTENT, GATSBY_CONTENT_DIR = 'content'} = process.env
5
+const DEV = NODE_ENV === 'development'
6
+const CONTENT_DIR = path.resolve(__dirname, '..', GATSBY_CONTENT_DIR)
7
+
8
+const walkDirs = dir => {
9
+ const dirs = fs
10
+ .readdirSync(dir)
11
+ .filter(d => fs.statSync(path.join(dir, d)).isDirectory())
12
+ .map(p => path.join(dir, p))
13
+ const nested = dirs.flatMap(d => walkDirs(d))
14
+ return [...dirs, ...nested]
15
+}
16
+
17
+const getContentOptions = () => {
18
+ if (!DEV || !GATSBY_PARTIAL_CONTENT) {
19
+ return
20
+ }
21
+
22
+ const partialContent = (GATSBY_PARTIAL_CONTENT ?? '').split(',')
23
+
24
+ const paths = walkDirs(CONTENT_DIR)
25
+ .map(p => path.relative(CONTENT_DIR, p))
26
+ .sort()
27
+ .reduce(
28
+ (acc, p) => {
29
+ const include = partialContent.some(partial => partial.startsWith(p))
30
+ acc[include ? 'include' : 'ignore'].push(p)
31
+ return acc
32
+ },
33
+ {include: [], ignore: []},
34
+ )
35
+
36
+ console.log(`Only including the following partial content in dev mode:\n - ${paths.include.join('\n - ')}`)
37
+
38
+ return {
39
+ ignore: paths.ignore,
40
+ }
41
+}
42
+
43
module.exports = {
44
trailingSlash: 'never',
45
siteMetadata: {
@@ -10,15 +52,34 @@ module.exports = {
52
},
53
plugins: [
54
{
13
- resolve: './theme',
55
+ resolve: 'gatsby-plugin-styled-components',
56
+ },
57
+ 'gatsby-plugin-react-helmet',
58
+ 'gatsby-plugin-catch-links',
59
+ 'gatsby-transformer-yaml',
60
+ {
61
+ resolve: 'gatsby-plugin-mdx',
62
options: {
15
- icon: './src/images/favicon.png',
16
- showContributors: false,
17
- repo: {
18
- url: 'https://github.com/npm/documentation',
19
- defaultBranch: 'main',
63
+ extensions: ['.mdx', '.md'],
64
+ defaultLayouts: {
65
+ default: require.resolve('./src/layout/default.js'),
66
},
67
},
68
},
69
+ {
70
+ resolve: 'gatsby-source-filesystem',
71
+ options: {
72
+ name: 'content',
73
+ path: CONTENT_DIR,
74
+ ...getContentOptions(),
75
+ },
76
+ },
77
+ {
78
+ resolve: 'gatsby-plugin-manifest',
79
+ options: {
80
+ icon: path.resolve('./src/images/favicon.png'),
81
+ },
82
+ },
83
+ 'gatsby-plugin-meta-redirect',
84
],
85
}
gatsby-node.js
+219
@@ -1,5 +1,12 @@
1
const path = require('path')
2
3
+const DEV = process.env.NODE_ENV === 'development'
4
+const SHOW_CONTRIBUTORS = false
5
+const REPO = {
6
+ url: 'https://github.com/npm/documentation',
7
+ defaultBranch: 'main',
8
+}
9
+
10
exports.onCreateNode = ({node, actions, getNode}) => {
11
if (node.internal.type === 'Mdx') {
12
const {name, relativeDirectory: dir} = getNode(node.parent)
@@ -31,3 +38,215 @@ exports.onCreateWebpackConfig = ({actions}) => {
38
},
39
})
40
}
41
+
42
+exports.createSchemaCustomization = ({actions: {createTypes}}) => {
43
+ createTypes(`
44
+ type Mdx implements Node {
45
+ frontmatter: MdxFrontmatter
46
+ fields: MdxFields
47
+ }
48
+ type MdxFrontmatter {
49
+ github_repo: String,
50
+ github_branch: String,
51
+ github_path: String,
52
+ edit_on_github: Boolean,
53
+ slug: String,
54
+ redirect_from: [String]
55
+ }
56
+ type MdxFields {
57
+ slug: String
58
+ }
59
+ `)
60
+}
61
+
62
+exports.createPages = async ({graphql, actions}) => {
63
+ const rootAbsolutePath = process.cwd()
64
+
65
+ const {data} = await graphql(`
66
+ {
67
+ allMdx {
68
+ nodes {
69
+ id
70
+ fileAbsolutePath
71
+ fields {
72
+ slug
73
+ }
74
+ frontmatter {
75
+ title
76
+ github_repo
77
+ github_branch
78
+ github_path
79
+ edit_on_github
80
+ slug
81
+ redirect_from
82
+ }
83
+ tableOfContents
84
+ parent {
85
+ ... on File {
86
+ relativeDirectory
87
+ name
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ `)
94
+
95
+ // Turn every MDX file into a page.
96
+ return Promise.all(
97
+ data.allMdx.nodes.map(async node => {
98
+ const {id, frontmatter, fileAbsolutePath, tableOfContents = {}} = node
99
+
100
+ const pagePath = getPath(node)
101
+ const relativePath = path.relative(rootAbsolutePath, fileAbsolutePath)
102
+ const editUrl = getEditUrl(REPO, relativePath, frontmatter)
103
+
104
+ const contributors = SHOW_CONTRIBUTORS ? await fetchContributors(REPO, relativePath, frontmatter) : {}
105
+
106
+ // Fix some old CLI pages which have mismatched headings at the top level.
107
+ // All top level headings should be the same level.
108
+ const toc = tableOfContents.items?.reduce((acc, item) => {
109
+ if (!item.url && Array.isArray(item.items)) {
110
+ acc.push(...item.items)
111
+ } else {
112
+ acc.push(item)
113
+ }
114
+ return acc
115
+ }, [])
116
+
117
+ actions.createPage({
118
+ path: pagePath,
119
+ component: fileAbsolutePath,
120
+ context: {
121
+ mdxId: id,
122
+ editUrl,
123
+ contributors,
124
+ tableOfContents: toc,
125
+ repositoryUrl: REPO.url,
126
+ },
127
+ })
128
+
129
+ if (!DEV) {
130
+ for (const from of frontmatter.redirect_from ?? []) {
131
+ actions.createRedirect({
132
+ fromPath: from,
133
+ toPath: `/${pagePath}`,
134
+ isPermanent: true,
135
+ redirectInBrowser: true,
136
+ })
137
+
138
+ if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
139
+ actions.createRedirect({
140
+ fromPath: `${from}.html`,
141
+ toPath: `/${pagePath}`,
142
+ isPermanent: true,
143
+ redirectInBrowser: true,
144
+ })
145
+ }
146
+ }
147
+ }
148
+ }),
149
+ )
150
+}
151
+
152
+function getPath(node) {
153
+ // sites can programmatically override slug, that takes priority
154
+ if (node.fields && node.fields.slug) {
155
+ return node.fields.slug
156
+ }
157
+
158
+ // then a slug specified in frontmatter
159
+ if (node.frontmatter && node.frontmatter.slug) {
160
+ return node.frontmatter.slug
161
+ }
162
+
163
+ // finally, we'll just use the path on disk
164
+ return path
165
+ .join(node.parent.relativeDirectory, node.parent.name === 'index' ? '/' : node.parent.name)
166
+ .replace(/\\/g, '/') // Windows paths to forward slashes
167
+}
168
+
169
+function getGitHubData(repo, overrideData, filePath) {
170
+ const gh = {
171
+ nwo: new URL(repo.url).pathname.slice(1).split('/'),
172
+ branch: 'master',
173
+ }
174
+
175
+ if (overrideData.github_repo) {
176
+ gh.nwo = overrideData.github_repo
177
+ }
178
+
179
+ if (overrideData.github_branch) {
180
+ gh.branch = overrideData.github_branch
181
+ } else if (repo.defaultBranch) {
182
+ gh.branch = repo.defaultBranch
183
+ }
184
+
185
+ if (overrideData.github_path) {
186
+ gh.path = overrideData.github_path
187
+ } else {
188
+ gh.path = filePath
189
+ }
190
+
191
+ return gh
192
+}
193
+
194
+function getEditUrl(repo, filePath, overrideData = {}) {
195
+ if (overrideData.edit_on_github === false) {
196
+ return null
197
+ }
198
+
199
+ const gh = getGitHubData(repo, overrideData, filePath)
200
+ return `https://github.com/${gh.nwo}/edit/${gh.branch}/${gh.path}`
201
+}
202
+
203
+const CONTRIBUTOR_CACHE = new Map()
204
+
205
+async function fetchContributors(repo, filePath, overrideData = {}) {
206
+ if (!process.env.GITHUB_TOKEN) {
207
+ console.warn('Skipping fetching contributors because no github token was set')
208
+ return
209
+ }
210
+
211
+ const gh = getGitHubData(repo, overrideData, filePath)
212
+ const key = JSON.stringify(gh)
213
+
214
+ const cached = CONTRIBUTOR_CACHE.get(key)
215
+ if (cached) {
216
+ return cached
217
+ }
218
+
219
+ try {
220
+ const resp = await fetch(
221
+ `https://api.github.com/repos/${gh.nwo}/commits?path=${gh.path}&sha=${gh.branch}&per_page=100`,
222
+ {
223
+ headers: {
224
+ Authorization: `token ${process.env.GITHUB_TOKEN}`,
225
+ },
226
+ },
227
+ )
228
+
229
+ const logins = new Set()
230
+ let latestCommit = null
231
+
232
+ for (const item of await resp.json().then(r => r.data)) {
233
+ if (item.author?.login) {
234
+ logins.add(item.author.login)
235
+ if (!latestCommit) {
236
+ latestCommit = {
237
+ login: item.author.login,
238
+ date: item.commit.author.date,
239
+ url: item.html_url,
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ const result = {logins: [...logins], latestCommit}
246
+ CONTRIBUTOR_CACHE.set(key, result)
247
+ return result
248
+ } catch (error) {
249
+ console.error(`[ERROR] Unable to fetch contributors for ${filePath}. ${error.message}`)
250
+ return []
251
+ }
252
+}
gatsby-ssr.js
renamed
package-lock.json
+26
-7
@@ -8,15 +8,37 @@
8
"name": "documentation",
9
"version": "1.0.0",
10
"workspaces": [
11
- "cli/",
12
- "theme/"
11
+ "cli/"
12
],
13
"dependencies": {
14
+ "@mdx-js/mdx": "^1.6.22",
15
+ "@mdx-js/react": "^1.6.22",
16
+ "@primer/octicons-react": "^19.8.0",
17
"@primer/react": "^35.31.0",
18
+ "babel-plugin-styled-components": "^2.1.4",
19
+ "copy-to-clipboard": "^3.3.3",
20
+ "details-element-polyfill": "^2.4.0",
21
+ "downshift": "^8.2.2",
22
+ "framer-motion": "^3.10.6",
23
+ "fuse.js": "^3.6.1",
24
"gatsby": "^4.25.7",
25
+ "gatsby-plugin-catch-links": "^4.25.0",
26
+ "gatsby-plugin-manifest": "^4.25.0",
27
+ "gatsby-plugin-mdx": "^3.20.0",
28
+ "gatsby-plugin-meta-redirect": "^1.1.1",
29
+ "gatsby-plugin-react-helmet": "^5.25.0",
30
+ "gatsby-plugin-styled-components": "^5.25.0",
31
+ "gatsby-source-filesystem": "^4.25.0",
32
+ "gatsby-transformer-yaml": "^4.25.0",
33
+ "github-slugger": "^2.0.0",
34
+ "lodash.debounce": "4.0.8",
35
+ "prism-react-renderer": "^0.2.0",
36
"react": "^17.0.2",
37
+ "react-addons-text-content": "^0.0.4",
38
"react-dom": "^17.0.2",
19
- "theme": "^1.0.0"
39
+ "react-focus-on": "^3.9.1",
40
+ "react-helmet": "^6.1.0",
41
+ "styled-components": "^5.3.11"
42
},
43
"devDependencies": {
44
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
@@ -32149,10 +32171,6 @@
32171
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
32172
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
32173
},
32152
- "node_modules/theme": {
32153
- "resolved": "theme",
32154
- "link": true
32155
- },
32174
"node_modules/through": {
32175
"version": "2.3.8",
32176
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -34353,6 +34371,7 @@
34371
},
34372
"theme": {
34373
"version": "1.0.0",
34374
+ "extraneous": true,
34375
"license": "MIT",
34376
"dependencies": {
34377
"@mdx-js/mdx": "^1.6.22",
package.json
+25
-3
@@ -24,15 +24,37 @@
24
"format": "prettier --write ."
25
},
26
"workspaces": [
27
- "cli/",
28
- "theme/"
27
+ "cli/"
28
],
29
"dependencies": {
30
+ "@mdx-js/mdx": "^1.6.22",
31
+ "@mdx-js/react": "^1.6.22",
32
+ "@primer/octicons-react": "^19.8.0",
33
"@primer/react": "^35.31.0",
34
+ "babel-plugin-styled-components": "^2.1.4",
35
+ "copy-to-clipboard": "^3.3.3",
36
+ "details-element-polyfill": "^2.4.0",
37
+ "downshift": "^8.2.2",
38
+ "framer-motion": "^3.10.6",
39
+ "fuse.js": "^3.6.1",
40
"gatsby": "^4.25.7",
41
+ "gatsby-plugin-catch-links": "^4.25.0",
42
+ "gatsby-plugin-manifest": "^4.25.0",
43
+ "gatsby-plugin-mdx": "^3.20.0",
44
+ "gatsby-plugin-meta-redirect": "^1.1.1",
45
+ "gatsby-plugin-react-helmet": "^5.25.0",
46
+ "gatsby-plugin-styled-components": "^5.25.0",
47
+ "gatsby-source-filesystem": "^4.25.0",
48
+ "gatsby-transformer-yaml": "^4.25.0",
49
+ "github-slugger": "^2.0.0",
50
+ "lodash.debounce": "4.0.8",
51
+ "prism-react-renderer": "^0.2.0",
52
"react": "^17.0.2",
53
+ "react-addons-text-content": "^0.0.4",
54
"react-dom": "^17.0.2",
35
- "theme": "^1.0.0"
55
+ "react-focus-on": "^3.9.1",
56
+ "react-helmet": "^6.1.0",
57
+ "styled-components": "^5.3.11"
58
},
59
"devDependencies": {
60
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
src/components/__tests__/contributors.test.js
renamed
src/components/__tests__/page-footer.test.js
renamed
src/components/clipboard-copy.js
renamed
src/components/container.js
renamed
src/components/contributors.js
renamed
src/components/dark-button.js
renamed
src/components/dark-text-input.js
renamed
src/components/drawer.js
renamed
src/components/head.js
renamed
src/components/header.js
renamed
+1
-1
@@ -30,7 +30,7 @@ function Header({location, repositoryUrl}) {
30
}
31
32
return (
33
- <Box position="sticky" role="banner">
33
+ <Box position="sticky" top={0} sx={{zIndex: 1}} role="banner">
34
<NpmHeaderBar />
35
<Box
36
display="flex"
src/components/hero.js
renamed
src/components/mobile-search.js
renamed
src/components/nav-drawer.js
renamed
src/components/nav-items.js
renamed
+4
-13
@@ -5,19 +5,14 @@ import {LinkExternalIcon} from '@primer/octicons-react'
5
import styled from 'styled-components'
6
import NavHierarchy from '../util/nav-hierarchy'
7
8
-const getActiveProps = className => props => {
8
+const getActiveClass = props => {
9
const location = NavHierarchy.getLocation(props.location.pathname)
10
const href = NavHierarchy.getLocation(props.href)
11
-
12
- if (NavHierarchy.isActiveUrl(location, href)) {
13
- return {className: `${className} active`}
14
- }
15
-
16
- return {className: `${className}`}
11
+ return NavHierarchy.isActiveUrl(location, href) ? 'active' : ''
12
}
13
14
const ActiveLink = ({className, children, ...props}) => (
20
- <Link as={GatsbyLink} getProps={getActiveProps(className)} {...props}>
15
+ <Link as={GatsbyLink} getProps={p => ({className: `${className} ${getActiveClass(p)}`})} {...props}>
16
{children}
17
</Link>
18
)
@@ -126,11 +121,7 @@ function secondLevelItems(items, path) {
121
<Box key={item.title} role="listitem">
122
<SecondLevelLink key={item.url} to={item.url}>
123
{item.title}
129
- {item.description != null ? (
130
- <>
131
- <Description>{item.description}</Description>
132
- </>
133
- ) : null}
124
+ {item.description != null ? <Description>{item.description}</Description> : null}
125
</SecondLevelLink>
126
{thirdLevelItems(children, path)}
127
</Box>
src/components/npm-logo.js
renamed
src/components/page-footer.js
renamed
src/components/search-results.js
renamed
src/components/search.js
renamed
src/components/sidebar.js
renamed
src/components/table-of-contents.js
renamed
src/components/variant-select.js
renamed
src/header-nav.yml
renamed
src/hooks/use-breakpoint.js
renamed
src/hooks/use-scroll-size.js
renamed
src/hooks/use-search.js
renamed
+3
@@ -4,6 +4,9 @@ import {navigate, graphql, useStaticQuery} from 'gatsby'
4
import {useIsMobile} from './use-breakpoint'
5
6
const useSearchData = () => {
7
+ // TODO: this static query runs for all pages changes in dev mode.
8
+ // When not testing search explicitly it should be replaced with
9
+ // some static data.
10
const rawData = useStaticQuery(graphql`
11
{
12
allMdx {
src/hooks/use-site-metadata.js
renamed
src/hooks/use-slugger.js
renamed
src/layout/default.js
renamed
src/layout/hero.js
renamed
src/mdx/code.js
renamed
src/mdx/index.js
renamed
src/mdx/nav-hierarchy.js
renamed
src/nav.yml
renamed
src/page-element.js
renamed
src/root-element.js
renamed
src/shared.js
+1
-1
@@ -1,5 +1,5 @@
1
import React from 'react'
2
-import {Link, Note, Screenshot} from 'theme'
2
+import {Link, Note, Screenshot} from './mdx'
3
4
const shared = {
5
/* User login */
src/util/aria-live.js
renamed
src/util/nav-hierarchy.js
renamed
src/util/search.worker.js
renamed
theme/.gitignore
deleted
-23
@@ -1,23 +0,0 @@
1
-# This file is automatically added by @npmcli/template-oss. Do not edit.
2
-
3
-# ignore everything in the root
4
-/*
5
-
6
-# keep these
7
-!**/.gitignore
8
-!/.eslintrc.js
9
-!/.eslintrc.local.*
10
-!/.gitignore
11
-!/bin/
12
-!/CHANGELOG*
13
-!/docs/
14
-!/gatsby-*.js
15
-!/lib/
16
-!/LICENSE*
17
-!/map.js
18
-!/package.json
19
-!/README*
20
-!/scripts/
21
-!/src
22
-!/tap-snapshots/
23
-!/test/
theme/LICENSE
deleted
-22
@@ -1,22 +0,0 @@
1
-Copyright (c) GitHub, Inc.
2
-
3
-Permission is hereby granted, free of charge, to any person
4
-obtaining a copy of this software and associated documentation
5
-files (the "Software"), to deal in the Software without
6
-restriction, including without limitation the rights to use,
7
-copy, modify, merge, publish, distribute, sublicense, and/or sell
8
-copies of the Software, and to permit persons to whom the
9
-Software is furnished to do so, subject to the following
10
-conditions:
11
-
12
-The above copyright notice and this permission notice shall be
13
-included in all copies or substantial portions of the Software.
14
-
15
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
-OTHER DEALINGS IN THE SOFTWARE.
theme/README.md
deleted
-29
@@ -1,29 +0,0 @@
1
-# theme
2
-
3
-```javascript
4
-// gatsby-config.js
5
-
6
-module.exports = {
7
- plugins: [
8
- {
9
- resolve: './theme',
10
- options: {
11
- icon: './path/to/favicon.png',
12
- showContributors: false,
13
- repo: {
14
- url: 'https://github.com/org/repo',
15
- defaultBranch: 'main',
16
- },
17
- },
18
- },
19
- ],
20
-}
21
-```
22
-
23
-## Theme Options
24
-
25
-| Option | Required | Default | Type | Description |
26
-| ---------------- | -------- | ------- | ------- | ------------------------------------------------------- |
27
-| icon | yes | n/a | string | The favicon to display |
28
-| showContributors | yes | n/a | boolean | Determines if the repository contributors are displayed |
29
-| repo | yes | n/a | object | `url` and `defaultBranch` to repository |
theme/gatsby-config.js
deleted
-76
@@ -1,76 +0,0 @@
1
-const path = require('path')
2
-const fs = require('fs')
3
-
4
-const {NODE_ENV, GATSBY_PARTIAL_CONTENT, GATSBY_CONTENT_DIR = 'content'} = process.env
5
-const DEV = NODE_ENV === 'development'
6
-const CONTENT_DIR = path.resolve(__dirname, '..', GATSBY_CONTENT_DIR)
7
-
8
-const walkDirs = dir => {
9
- const dirs = fs
10
- .readdirSync(dir)
11
- .filter(d => fs.statSync(path.join(dir, d)).isDirectory())
12
- .map(p => path.join(dir, p))
13
- const nested = dirs.flatMap(d => walkDirs(d))
14
- return [...dirs, ...nested]
15
-}
16
-
17
-const getContentOptions = () => {
18
- if (!DEV || !GATSBY_PARTIAL_CONTENT) {
19
- return
20
- }
21
-
22
- const partialContent = (GATSBY_PARTIAL_CONTENT ?? '').split(',')
23
-
24
- const paths = walkDirs(CONTENT_DIR)
25
- .map(p => path.relative(CONTENT_DIR, p))
26
- .sort()
27
- .reduce(
28
- (acc, p) => {
29
- const include = partialContent.some(partial => partial.startsWith(p))
30
- acc[include ? 'include' : 'ignore'].push(p)
31
- return acc
32
- },
33
- {include: [], ignore: []},
34
- )
35
-
36
- console.log(`Only including the following partial content in dev mode:\n - ${paths.include.join('\n - ')}`)
37
-
38
- return {
39
- ignore: paths.ignore,
40
- }
41
-}
42
-
43
-module.exports = ({icon}) => ({
44
- plugins: [
45
- {
46
- resolve: 'gatsby-plugin-styled-components',
47
- },
48
- 'gatsby-plugin-react-helmet',
49
- 'gatsby-plugin-catch-links',
50
- 'gatsby-transformer-yaml',
51
- {
52
- resolve: 'gatsby-plugin-mdx',
53
- options: {
54
- extensions: ['.mdx', '.md'],
55
- defaultLayouts: {
56
- default: require.resolve('./src/layout/default.js'),
57
- },
58
- },
59
- },
60
- {
61
- resolve: 'gatsby-source-filesystem',
62
- options: {
63
- name: 'content',
64
- path: CONTENT_DIR,
65
- ...getContentOptions(),
66
- },
67
- },
68
- {
69
- resolve: 'gatsby-plugin-manifest',
70
- options: {
71
- icon: path.resolve(icon),
72
- },
73
- },
74
- 'gatsby-plugin-meta-redirect',
75
- ],
76
-})
theme/gatsby-node.js
deleted
-215
@@ -1,215 +0,0 @@
1
-const path = require('path')
2
-
3
-const DEV = process.env.NODE_ENV === 'development'
4
-
5
-exports.createSchemaCustomization = ({actions: {createTypes}}) => {
6
- createTypes(`
7
- type Mdx implements Node {
8
- frontmatter: MdxFrontmatter
9
- fields: MdxFields
10
- }
11
- type MdxFrontmatter {
12
- github_repo: String,
13
- github_branch: String,
14
- github_path: String,
15
- edit_on_github: Boolean,
16
- slug: String,
17
- redirect_from: [String]
18
- }
19
- type MdxFields {
20
- slug: String
21
- }
22
- `)
23
-}
24
-
25
-exports.createPages = async ({graphql, actions}, {repo, showContributors}) => {
26
- const rootAbsolutePath = process.cwd()
27
-
28
- const {data} = await graphql(`
29
- {
30
- allMdx {
31
- nodes {
32
- id
33
- fileAbsolutePath
34
- fields {
35
- slug
36
- }
37
- frontmatter {
38
- title
39
- github_repo
40
- github_branch
41
- github_path
42
- edit_on_github
43
- slug
44
- redirect_from
45
- }
46
- tableOfContents
47
- parent {
48
- ... on File {
49
- relativeDirectory
50
- name
51
- }
52
- }
53
- }
54
- }
55
- }
56
- `)
57
-
58
- // Turn every MDX file into a page.
59
- return Promise.all(
60
- data.allMdx.nodes.map(async node => {
61
- const {id, frontmatter, fileAbsolutePath, tableOfContents = {}} = node
62
-
63
- const pagePath = getPath(node)
64
- const relativePath = path.relative(rootAbsolutePath, fileAbsolutePath)
65
- const editUrl = getEditUrl(repo, relativePath, frontmatter)
66
-
67
- const contributors = showContributors ? await fetchContributors(repo, relativePath, frontmatter) : {}
68
-
69
- // Fix some old CLI pages which have mismatched headings at the top level.
70
- // All top level headings should be the same level.
71
- const toc = tableOfContents.items?.reduce((acc, item) => {
72
- if (!item.url && Array.isArray(item.items)) {
73
- acc.push(...item.items)
74
- } else {
75
- acc.push(item)
76
- }
77
- return acc
78
- }, [])
79
-
80
- actions.createPage({
81
- path: pagePath,
82
- component: fileAbsolutePath,
83
- context: {
84
- mdxId: id,
85
- editUrl,
86
- contributors,
87
- tableOfContents: toc,
88
- repositoryUrl: repo.url,
89
- },
90
- })
91
-
92
- if (!DEV) {
93
- for (const from of frontmatter.redirect_from ?? []) {
94
- actions.createRedirect({
95
- fromPath: from,
96
- toPath: `/${pagePath}`,
97
- isPermanent: true,
98
- redirectInBrowser: true,
99
- })
100
-
101
- if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
102
- actions.createRedirect({
103
- fromPath: `${from}.html`,
104
- toPath: `/${pagePath}`,
105
- isPermanent: true,
106
- redirectInBrowser: true,
107
- })
108
- }
109
- }
110
- }
111
- }),
112
- )
113
-}
114
-
115
-function getPath(node) {
116
- // sites can programmatically override slug, that takes priority
117
- if (node.fields && node.fields.slug) {
118
- return node.fields.slug
119
- }
120
-
121
- // then a slug specified in frontmatter
122
- if (node.frontmatter && node.frontmatter.slug) {
123
- return node.frontmatter.slug
124
- }
125
-
126
- // finally, we'll just use the path on disk
127
- return path
128
- .join(node.parent.relativeDirectory, node.parent.name === 'index' ? '/' : node.parent.name)
129
- .replace(/\\/g, '/') // Windows paths to forward slashes
130
-}
131
-
132
-function getGitHubData(repo, overrideData, filePath) {
133
- const gh = {
134
- nwo: new URL(repo.url).pathname.slice(1).split('/'),
135
- branch: 'master',
136
- }
137
-
138
- if (overrideData.github_repo) {
139
- gh.nwo = overrideData.github_repo
140
- }
141
-
142
- if (overrideData.github_branch) {
143
- gh.branch = overrideData.github_branch
144
- } else if (repo.defaultBranch) {
145
- gh.branch = repo.defaultBranch
146
- }
147
-
148
- if (overrideData.github_path) {
149
- gh.path = overrideData.github_path
150
- } else {
151
- gh.path = filePath
152
- }
153
-
154
- return gh
155
-}
156
-
157
-function getEditUrl(repo, filePath, overrideData = {}) {
158
- if (overrideData.edit_on_github === false) {
159
- return null
160
- }
161
-
162
- const gh = getGitHubData(repo, overrideData, filePath)
163
- return `https://github.com/${gh.nwo}/edit/${gh.branch}/${gh.path}`
164
-}
165
-
166
-const CONTRIBUTOR_CACHE = new Map()
167
-
168
-async function fetchContributors(repo, filePath, overrideData = {}) {
169
- if (!process.env.GITHUB_TOKEN) {
170
- console.warn('Skipping fetching contributors because no github token was set')
171
- return
172
- }
173
-
174
- const gh = getGitHubData(repo, overrideData, filePath)
175
- const key = JSON.stringify(gh)
176
-
177
- const cached = CONTRIBUTOR_CACHE.get(key)
178
- if (cached) {
179
- return cached
180
- }
181
-
182
- try {
183
- const resp = await fetch(
184
- `https://api.github.com/repos/${gh.nwo}/commits?path=${gh.path}&sha=${gh.branch}&per_page=100`,
185
- {
186
- headers: {
187
- Authorization: `token ${process.env.GITHUB_TOKEN}`,
188
- },
189
- },
190
- )
191
-
192
- const logins = new Set()
193
- let latestCommit = null
194
-
195
- for (const item of await resp.json().then(r => r.data)) {
196
- if (item.author?.login) {
197
- logins.add(item.author.login)
198
- if (!latestCommit) {
199
- latestCommit = {
200
- login: item.author.login,
201
- date: item.commit.author.date,
202
- url: item.html_url,
203
- }
204
- }
205
- }
206
- }
207
-
208
- const result = {logins: [...logins], latestCommit}
209
- CONTRIBUTOR_CACHE.set(key, result)
210
- return result
211
- } catch (error) {
212
- console.error(`[ERROR] Unable to fetch contributors for ${filePath}. ${error.message}`)
213
- return []
214
- }
215
-}
theme/package.json
deleted
-69
@@ -1,69 +0,0 @@
1
-{
2
- "name": "theme",
3
- "version": "1.0.0",
4
- "repository": {
5
- "url": "https://github.com/npm/documentation.git",
6
- "directory": "theme",
7
- "type": "git"
8
- },
9
- "private": true,
10
- "exports": {
11
- ".": "./src/mdx/index.js",
12
- "./layout/*.js": "./src/layout/*.js"
13
- },
14
- "license": "MIT",
15
- "scripts": {
16
- "test": "jest",
17
- "lint": "eslint \"**/*.js\"",
18
- "postlint": "template-oss-check",
19
- "template-oss-apply": "template-oss-apply --force",
20
- "lintfix": "npm run lint -- --fix",
21
- "snap": "tap",
22
- "posttest": "npm run lint",
23
- "format": "prettier --write ."
24
- },
25
- "peerDependencies": {
26
- "gatsby": "^4.25.7",
27
- "react": "^17.0.2",
28
- "react-dom": "^17.0.2"
29
- },
30
- "dependencies": {
31
- "@mdx-js/mdx": "^1.6.22",
32
- "@mdx-js/react": "^1.6.22",
33
- "@primer/octicons-react": "^19.8.0",
34
- "@primer/react": "^35.31.0",
35
- "babel-plugin-styled-components": "^2.1.4",
36
- "copy-to-clipboard": "^3.3.3",
37
- "details-element-polyfill": "^2.4.0",
38
- "downshift": "^8.2.2",
39
- "framer-motion": "^3.10.6",
40
- "fuse.js": "^3.6.1",
41
- "gatsby-plugin-catch-links": "^4.25.0",
42
- "gatsby-plugin-manifest": "^4.25.0",
43
- "gatsby-plugin-mdx": "^3.20.0",
44
- "gatsby-plugin-meta-redirect": "^1.1.1",
45
- "gatsby-plugin-react-helmet": "^5.25.0",
46
- "gatsby-plugin-styled-components": "^5.25.0",
47
- "gatsby-source-filesystem": "^4.25.0",
48
- "gatsby-transformer-yaml": "^4.25.0",
49
- "github-slugger": "^2.0.0",
50
- "lodash.debounce": "4.0.8",
51
- "prism-react-renderer": "^0.2.0",
52
- "react-addons-text-content": "^0.0.4",
53
- "react-focus-on": "^3.9.1",
54
- "react-helmet": "^6.1.0",
55
- "styled-components": "^5.3.11"
56
- },
57
- "devDependencies": {
58
- "@npmcli/template-oss": "4.19.0"
59
- },
60
- "author": "GitHub Inc.",
61
- "engines": {
62
- "node": ">=18.0.0"
63
- },
64
- "templateOSS": {
65
- "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
66
- "version": "4.19.0",
67
- "content": "./scripts/template-oss"
68
- }
69
-}
theme/scripts/template-oss/index.js
deleted
-4
@@ -1,4 +0,0 @@
1
-module.exports = {
2
- ...require('../../../scripts/template-oss'),
3
- allowPaths: ['/src', '/gatsby-*.js'],
4
-}
theme/src/header-nav.yml
deleted
-2
@@ -1,2 +0,0 @@
1
-# For shadowing only
2
-[]
theme/src/nav.yml
deleted
-2
@@ -1,2 +0,0 @@
1
-# For shadowing only
2
-[]