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 -[]