@graphcommerce/docs 3.1.4 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/{content/framework → framework}/deployment.md +10 -6
- package/{content/framework → framework}/environment-variables.md +0 -0
- package/{content/framework → framework}/favicon.md +3 -1
- package/{content/framework → framework}/graphcms.md +10 -4
- package/{content/framework → framework}/icons.md +0 -0
- package/{content/framework → framework}/readme.md +0 -0
- package/{content/framework → framework}/seo.md +0 -0
- package/{content/framework → framework}/static-file-serving.md +0 -0
- package/{content/framework → framework}/static-generation.md +0 -0
- package/{content/framework → framework}/theming.md +1 -1
- package/{content/framework → framework}/translations.md +3 -1
- package/{content/framework → framework}/troubleshooting.md +0 -0
- package/{content/framework → framework}/typography.md +0 -0
- package/{content/getting-started → getting-started}/create.md +7 -3
- package/{content/getting-started → getting-started}/graphcms-component.md +30 -10
- package/{content/getting-started → getting-started}/header.md +17 -7
- package/{content/getting-started → getting-started}/pages.md +12 -4
- package/{content/getting-started → getting-started}/readme.md +3 -2
- package/{content/getting-started → getting-started}/start-building.md +2 -2
- package/{content/getting-started → getting-started}/vscode.md +0 -0
- package/package.json +6 -51
- package/{content/readme.md → readme.md} +1 -1
- package/{content/roadmap.md → roadmap.md} +0 -0
- package/.babelrc +0 -4
- package/components/Layout/LayoutFull.tsx +0 -85
- package/components/Layout/Logo.tsx +0 -19
- package/components/Layout/graphcommerce.svg +0 -34
- package/components/Search.tsx +0 -37
- package/components/SearchForm.tsx +0 -110
- package/components/SidebarMenu/index.tsx +0 -101
- package/components/prism.css +0 -274
- package/components/rehype-prism-plus.css +0 -49
- package/components/theme.ts +0 -410
- package/lib/DocumentIndexer.ts +0 -59
- package/lib/files.ts +0 -168
- package/lib/instantSearch.ts +0 -26
- package/lib/typesense/IndexerHandler.ts +0 -47
- package/lib/typesense/Leaves.ts +0 -37
- package/lib/typesense/SearchIndexer.ts +0 -64
- package/lib/typesense/batchInterable.ts +0 -13
- package/lib/typesense/createInstantSearchProps.ts +0 -36
- package/lib/typesense/typesenseClientConf.ts +0 -23
- package/lib/typesense/typesenseIndexerHandler.ts +0 -23
- package/next-env.d.ts +0 -5
- package/next.config.js +0 -21
- package/pages/[[...url]].tsx +0 -391
- package/pages/_app.tsx +0 -26
- package/pages/_document.tsx +0 -22
- package/pages/api/reindex.ts +0 -4
- package/pages/menu/[[...url]].tsx +0 -69
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +0 -12
- package/public/link.svg +0 -4
- package/public/manifest/favicon-192.png +0 -0
- package/public/manifest/favicon-512.png +0 -0
- package/public/manifest.webmanifest +0 -20
package/lib/typesense/Leaves.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export type Leaves<T, D extends number = 10> = [D] extends [never]
|
|
2
|
-
? never
|
|
3
|
-
: T extends object
|
|
4
|
-
? { [K in keyof T]-?: Join<K, Leaves<T[K], Prev[D]>> }[keyof T]
|
|
5
|
-
: ''
|
|
6
|
-
|
|
7
|
-
type Prev = [
|
|
8
|
-
never,
|
|
9
|
-
0,
|
|
10
|
-
1,
|
|
11
|
-
2,
|
|
12
|
-
3,
|
|
13
|
-
4,
|
|
14
|
-
5,
|
|
15
|
-
6,
|
|
16
|
-
7,
|
|
17
|
-
8,
|
|
18
|
-
9,
|
|
19
|
-
10,
|
|
20
|
-
11,
|
|
21
|
-
12,
|
|
22
|
-
13,
|
|
23
|
-
14,
|
|
24
|
-
15,
|
|
25
|
-
16,
|
|
26
|
-
17,
|
|
27
|
-
18,
|
|
28
|
-
19,
|
|
29
|
-
20,
|
|
30
|
-
...0[]
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
type Join<K, P> = K extends string | number
|
|
34
|
-
? P extends string | number
|
|
35
|
-
? `${K}${'' extends P ? '' : '.'}${P}`
|
|
36
|
-
: never
|
|
37
|
-
: never
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { ConditionalExcept, Get } from 'type-fest'
|
|
2
|
-
import { CollectionFieldSchema } from 'typesense/lib/Typesense/Collection'
|
|
3
|
-
import { CollectionCreateSchema } from 'typesense/lib/Typesense/Collections'
|
|
4
|
-
import { Leaves } from './Leaves'
|
|
5
|
-
|
|
6
|
-
type FieldValues = Record<string, any>
|
|
7
|
-
|
|
8
|
-
type SchemaType<
|
|
9
|
-
TFieldValues extends FieldValues,
|
|
10
|
-
TFieldPath extends Leaves<TFieldValues>,
|
|
11
|
-
T = Get<TFieldValues, TFieldPath>,
|
|
12
|
-
> = T extends object
|
|
13
|
-
? never
|
|
14
|
-
: T extends string
|
|
15
|
-
? 'string'
|
|
16
|
-
: T extends number
|
|
17
|
-
? 'number'
|
|
18
|
-
: T extends boolean
|
|
19
|
-
? 'boolean'
|
|
20
|
-
: T
|
|
21
|
-
|
|
22
|
-
type OptionalType<
|
|
23
|
-
TFieldValues extends FieldValues,
|
|
24
|
-
TFieldPath extends Leaves<TFieldValues>,
|
|
25
|
-
T = Get<TFieldValues, TFieldPath>,
|
|
26
|
-
> = T extends undefined ? true : never
|
|
27
|
-
|
|
28
|
-
export type BaseDocument = {
|
|
29
|
-
id: string
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type CreateSchema<Schema extends BaseDocument> = Omit<CollectionCreateSchema, 'fields'> & {
|
|
33
|
-
fields: {
|
|
34
|
-
[K in Leaves<Schema>]: ConditionalExcept<
|
|
35
|
-
{
|
|
36
|
-
type: SchemaType<Schema, K>
|
|
37
|
-
optional: OptionalType<Schema, K>
|
|
38
|
-
} & Omit<CollectionFieldSchema, 'type' | 'optional' | 'name'>,
|
|
39
|
-
never
|
|
40
|
-
>
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export abstract class SearchIndexer<T extends BaseDocument> {
|
|
45
|
-
name: string
|
|
46
|
-
|
|
47
|
-
schema: CollectionCreateSchema
|
|
48
|
-
|
|
49
|
-
constructor(schema: CreateSchema<T>) {
|
|
50
|
-
this.name = schema.name
|
|
51
|
-
|
|
52
|
-
const fields = Object.entries(schema.fields).map(
|
|
53
|
-
([name, field]) =>
|
|
54
|
-
({
|
|
55
|
-
name,
|
|
56
|
-
...(field as Omit<CollectionFieldSchema, 'name'>),
|
|
57
|
-
} as CollectionFieldSchema),
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
this.schema = { ...schema, fields }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
abstract all(): AsyncGenerator<T>
|
|
64
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export async function* batchIterable<T>(iterable: AsyncIterableIterator<T>, batchSize: number) {
|
|
2
|
-
let items: T[] = []
|
|
3
|
-
for await (const item of iterable) {
|
|
4
|
-
items.push(item)
|
|
5
|
-
if (items.length >= batchSize) {
|
|
6
|
-
yield items
|
|
7
|
-
items = []
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
if (items.length !== 0) {
|
|
11
|
-
yield items
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { InstantSearchProps } from 'react-instantsearch-hooks'
|
|
2
|
-
import TypesenseInstantSearchAdapter from 'typesense-instantsearch-adapter'
|
|
3
|
-
import { Leaves } from './Leaves'
|
|
4
|
-
import { BaseDocument } from './SearchIndexer'
|
|
5
|
-
import { typesenseClientConf } from './typesenseClientConf'
|
|
6
|
-
|
|
7
|
-
type BaseParams = Omit<
|
|
8
|
-
NonNullable<
|
|
9
|
-
ConstructorParameters<typeof TypesenseInstantSearchAdapter>[0]['additionalSearchParameters']
|
|
10
|
-
>,
|
|
11
|
-
'query_by' | 'query_by_weight'
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
type InstantSearchClientParams<Document extends BaseDocument> = BaseParams & {
|
|
15
|
-
query_by: {
|
|
16
|
-
[key in Leaves<Document>]?: number
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function createInstantSearchProps<Document extends BaseDocument>(
|
|
21
|
-
indexName: string,
|
|
22
|
-
params: InstantSearchClientParams<Document>,
|
|
23
|
-
): InstantSearchProps {
|
|
24
|
-
const { query_by, ...rest } = params
|
|
25
|
-
|
|
26
|
-
const { searchClient } = new TypesenseInstantSearchAdapter({
|
|
27
|
-
server: typesenseClientConf(),
|
|
28
|
-
additionalSearchParameters: {
|
|
29
|
-
query_by: Object.keys(query_by).join(','),
|
|
30
|
-
query_by_weights: Object.values(query_by).join(','),
|
|
31
|
-
...rest,
|
|
32
|
-
},
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
return { searchClient, indexName }
|
|
36
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { ConfigurationOptions } from 'typesense/lib/Typesense/Configuration'
|
|
2
|
-
|
|
3
|
-
export function typesenseClientConf() {
|
|
4
|
-
// Be sure to use an API key that only allows searches, in production
|
|
5
|
-
const apiKey = process.env.NEXT_PUBLIC_TYPESENSE_SEARCH_ONLY_API_KEY
|
|
6
|
-
const host = process.env.NEXT_PUBLIC_TYPESENSE_HOST
|
|
7
|
-
const port = Number(process.env.NEXT_PUBLIC_TYPESENSE_PORT)
|
|
8
|
-
const protocol = process.env.NEXT_PUBLIC_TYPESENSE_PROTOCOL
|
|
9
|
-
|
|
10
|
-
if (!apiKey) throw Error('Please provide NEXT_PUBLIC_TYPESENSE_SEARCH_ONLY_API_KEY')
|
|
11
|
-
if (!host) throw Error('Please provide NEXT_PUBLIC_TYPESENSE_HOST')
|
|
12
|
-
if (!port) throw Error('Please provide NEXT_PUBLIC_TYPESENSE_PORT')
|
|
13
|
-
if (!protocol) throw Error('Please provide NEXT_PUBLIC_TYPESENSE_PROTOCOL')
|
|
14
|
-
|
|
15
|
-
const conf: ConfigurationOptions = {
|
|
16
|
-
apiKey,
|
|
17
|
-
nodes: [{ host, port, protocol }],
|
|
18
|
-
numRetries: 8,
|
|
19
|
-
connectionTimeoutSeconds: 1,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return conf
|
|
23
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
2
|
-
import { TypesenseError } from 'typesense/lib/Typesense/Errors'
|
|
3
|
-
import { IndexerHandler } from './IndexerHandler'
|
|
4
|
-
import { BaseDocument, SearchIndexer } from './SearchIndexer'
|
|
5
|
-
import { typesenseClientConf } from './typesenseClientConf'
|
|
6
|
-
|
|
7
|
-
export function typesenseIndexerHandler(indexers: SearchIndexer<BaseDocument>[]) {
|
|
8
|
-
return async (req: NextApiRequest, res: NextApiResponse) => {
|
|
9
|
-
const handler = new IndexerHandler(typesenseClientConf(), indexers)
|
|
10
|
-
try {
|
|
11
|
-
const count = await handler.all()
|
|
12
|
-
res.status(200).json({ status: 'success', count })
|
|
13
|
-
} catch (e) {
|
|
14
|
-
if (e instanceof TypesenseError) {
|
|
15
|
-
res.json(e)
|
|
16
|
-
}
|
|
17
|
-
console.log(e)
|
|
18
|
-
res.status(500)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
res.end()
|
|
22
|
-
}
|
|
23
|
-
}
|
package/next-env.d.ts
DELETED
package/next.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
const withYarn1Workspaces = require('@graphcommerce/next-config').withYarn1Scopes()
|
|
3
|
-
|
|
4
|
-
/** @type {import('next').NextConfig} */
|
|
5
|
-
const nextConfig = {
|
|
6
|
-
// https://nextjs.org/docs/api-reference/next.config.js/configuring-onDemandEntries
|
|
7
|
-
onDemandEntries: {
|
|
8
|
-
maxInactiveAge: 10 * 60 * 1000, // 10 minutes
|
|
9
|
-
},
|
|
10
|
-
eslint: {
|
|
11
|
-
ignoreDuringBuilds: true,
|
|
12
|
-
},
|
|
13
|
-
typescript: {
|
|
14
|
-
ignoreBuildErrors: true,
|
|
15
|
-
},
|
|
16
|
-
experimental: {
|
|
17
|
-
scrollRestoration: true,
|
|
18
|
-
},
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
module.exports = withYarn1Workspaces(nextConfig)
|
package/pages/[[...url]].tsx
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
import { PageOptions } from '@graphcommerce/framer-next-pages'
|
|
2
|
-
import { PageMeta } from '@graphcommerce/next-ui'
|
|
3
|
-
import {
|
|
4
|
-
Container,
|
|
5
|
-
Divider,
|
|
6
|
-
Typography,
|
|
7
|
-
Link,
|
|
8
|
-
alpha,
|
|
9
|
-
Table,
|
|
10
|
-
TableBody,
|
|
11
|
-
TableRow,
|
|
12
|
-
TableHead,
|
|
13
|
-
TableCell,
|
|
14
|
-
TableContainer,
|
|
15
|
-
Paper,
|
|
16
|
-
darken,
|
|
17
|
-
Box,
|
|
18
|
-
} from '@mui/material'
|
|
19
|
-
import { GetStaticPaths, GetStaticProps } from 'next'
|
|
20
|
-
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
|
|
21
|
-
import { serialize } from 'next-mdx-remote/serialize'
|
|
22
|
-
import PageLink from 'next/link'
|
|
23
|
-
import { useRouter } from 'next/router'
|
|
24
|
-
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
|
25
|
-
import rehypePrism from 'rehype-prism-plus'
|
|
26
|
-
import rehypeSlug from 'rehype-slug'
|
|
27
|
-
import remarkGfm from 'remark-gfm'
|
|
28
|
-
import { SetRequired } from 'type-fest'
|
|
29
|
-
import { LayoutFull, LayoutFullProps } from '../components/Layout/LayoutFull'
|
|
30
|
-
import {
|
|
31
|
-
getDirectoryPaths,
|
|
32
|
-
getDirectoryTree,
|
|
33
|
-
getFileContents,
|
|
34
|
-
MatterFields,
|
|
35
|
-
urlToPath,
|
|
36
|
-
} from '../lib/files'
|
|
37
|
-
|
|
38
|
-
type MDXSource = SetRequired<MDXRemoteSerializeResult, 'frontmatter'>
|
|
39
|
-
type Props = { source: MDXSource } & LayoutFullProps
|
|
40
|
-
type Param = { url: string[] }
|
|
41
|
-
type GetStatic = GetStaticProps<Props, Param>
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Handle relative hrefs
|
|
45
|
-
*
|
|
46
|
-
* - If a link doesn't start with a slash OR it starts with './' it should replace the latest slug
|
|
47
|
-
* with the new path
|
|
48
|
-
* - If a link starts with a slash it shouldn't be relative
|
|
49
|
-
* - If a link starts with '../' it should move one segment up.
|
|
50
|
-
* - If a link starts with '../../' it should move two segments up, so this should be recursive
|
|
51
|
-
*/
|
|
52
|
-
function relativeUrl(href: string[], currentHref: string[]): string[] {
|
|
53
|
-
if (href[0].startsWith('http') || href[0].startsWith('/')) return href
|
|
54
|
-
|
|
55
|
-
if (href[0].startsWith('#')) return [...currentHref, href[0]]
|
|
56
|
-
|
|
57
|
-
if (href[0] === 'readme') return relativeUrl(['', ...href.slice(1)], currentHref)
|
|
58
|
-
|
|
59
|
-
if (href[0] === '..') {
|
|
60
|
-
return relativeUrl(href.slice(1), currentHref.slice(0, -1))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (href[0] === '.') {
|
|
64
|
-
return ['', ...currentHref.slice(0, -1), ...href.slice(1)]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return relativeUrl(['.', ...href], currentHref)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function RelativeLink(props: Omit<JSX.IntrinsicElements['a'], 'ref'>) {
|
|
71
|
-
const asPath = useRouter().asPath?.split('?')[0].split('#')[0]
|
|
72
|
-
const { href = '', children, ...otherProps } = props
|
|
73
|
-
|
|
74
|
-
let newUrl = href.replace('.mdx', '')
|
|
75
|
-
newUrl = newUrl.replace('.md', '')
|
|
76
|
-
newUrl = newUrl.replace('readme', '')
|
|
77
|
-
|
|
78
|
-
newUrl = relativeUrl(newUrl.split('/'), asPath.split('/').slice(1)).join('/')
|
|
79
|
-
|
|
80
|
-
if (newUrl.startsWith('/packages') || newUrl.startsWith('/examples')) {
|
|
81
|
-
newUrl = `https://github.com/ho-nl/m2-pwa/tree/master${newUrl}`
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const isExternal = newUrl.startsWith('http')
|
|
85
|
-
|
|
86
|
-
if (!newUrl.startsWith('/') && !isExternal) newUrl = `/${newUrl}`
|
|
87
|
-
if (newUrl.endsWith('/')) newUrl = newUrl.slice(0, -1)
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<PageLink href={newUrl} passHref>
|
|
91
|
-
<Link {...otherProps} target={isExternal ? '_blank' : undefined}>
|
|
92
|
-
{children}
|
|
93
|
-
</Link>
|
|
94
|
-
</PageLink>
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const mdxComponents: React.ComponentProps<typeof MDXRemote>['components'] = {
|
|
99
|
-
h1: ({ ref, ...props }) => (
|
|
100
|
-
<Typography
|
|
101
|
-
component='h1'
|
|
102
|
-
variant='h1'
|
|
103
|
-
{...props}
|
|
104
|
-
sx={{ mt: '2em', mb: '1em', '&:first-of-type': { mt: '1em' } }}
|
|
105
|
-
/>
|
|
106
|
-
),
|
|
107
|
-
h2: ({ ref, ...props }) => (
|
|
108
|
-
<Typography
|
|
109
|
-
component='h2'
|
|
110
|
-
variant='h2'
|
|
111
|
-
{...props}
|
|
112
|
-
sx={{ mt: '2em', mb: '0.5em', borderBottom: (theme) => `1px solid ${theme.palette.divider}` }}
|
|
113
|
-
/>
|
|
114
|
-
),
|
|
115
|
-
h3: ({ ref, ...props }) => (
|
|
116
|
-
<Typography component='h3' variant='h3' {...props} sx={{ mt: '2em', mb: '0.5em' }} />
|
|
117
|
-
),
|
|
118
|
-
h4: ({ ref, ...props }) => <Typography component='h4' variant='h4' {...props} sx={{}} />,
|
|
119
|
-
h5: ({ ref, ...props }) => <Typography component='h5' variant='h5' {...props} sx={{}} />,
|
|
120
|
-
h6: ({ ref, ...props }) => <Typography component='h6' variant='h6' {...props} sx={{}} />,
|
|
121
|
-
p: ({ ref, ...props }) => (
|
|
122
|
-
<Typography variant='body1' {...props} sx={{ mt: '0.5em', mb: '1em' }} />
|
|
123
|
-
),
|
|
124
|
-
// img: ({ ref, src, ...props }) => {
|
|
125
|
-
// if (!src) return null
|
|
126
|
-
// return <Image layout={!props.width ? 'intrinsic' : 'responsive'} src={src} {...props} />
|
|
127
|
-
// },
|
|
128
|
-
hr: ({ ref, ...props }) => (
|
|
129
|
-
<Divider {...props} variant='middle' sx={(theme) => ({ my: theme.spacings.md })} />
|
|
130
|
-
),
|
|
131
|
-
blockquote: ({ ref, ...props }) => (
|
|
132
|
-
<Typography
|
|
133
|
-
variant='body1'
|
|
134
|
-
component='blockquote'
|
|
135
|
-
{...props}
|
|
136
|
-
sx={[
|
|
137
|
-
(theme) => ({
|
|
138
|
-
display: 'inline-block',
|
|
139
|
-
mt: '1em',
|
|
140
|
-
mb: '0.5em',
|
|
141
|
-
fontStyle: 'italic',
|
|
142
|
-
pl: '1em',
|
|
143
|
-
pr: '1em',
|
|
144
|
-
pt: '0.5em',
|
|
145
|
-
borderRadius: 2,
|
|
146
|
-
backgroundColor: alpha(theme.palette.primary.main, 0.1),
|
|
147
|
-
border: `1px solid ${theme.palette.primary.main}`,
|
|
148
|
-
boxShadow: 4,
|
|
149
|
-
'&:first-of-type': { mt: '2em' },
|
|
150
|
-
}),
|
|
151
|
-
]}
|
|
152
|
-
/>
|
|
153
|
-
),
|
|
154
|
-
pre: ({ ref, ...props }) => (
|
|
155
|
-
<Box
|
|
156
|
-
component='pre'
|
|
157
|
-
{...props}
|
|
158
|
-
sx={{
|
|
159
|
-
fontFamily: `Menlo, Monaco, Consolas, 'Andale Mono', 'Ubuntu Mono', 'Courier New', monospace`,
|
|
160
|
-
borderRadius: 1.5,
|
|
161
|
-
maxWidth: (theme) => `calc(100vw - ${theme.page.horizontal} * 2)`,
|
|
162
|
-
|
|
163
|
-
// "&:not([class*='language-'])": {
|
|
164
|
-
// backgroundColor: (theme) => [alpha(theme.palette.text.primary, 0.08), '!important'],
|
|
165
|
-
// p: '1em',
|
|
166
|
-
// },
|
|
167
|
-
|
|
168
|
-
"&[class*='language-']": {
|
|
169
|
-
backgroundImage: 'linear-gradient(to top, #003c6780, #00264180 )',
|
|
170
|
-
},
|
|
171
|
-
'&.language-txt': {
|
|
172
|
-
background: 'none',
|
|
173
|
-
border: (theme) => `1px solid ${theme.palette.divider}`,
|
|
174
|
-
'& code': {
|
|
175
|
-
color: (theme) => [theme.palette.text.primary, '!important'],
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
}}
|
|
179
|
-
/>
|
|
180
|
-
),
|
|
181
|
-
code: ({ ref, ...props }) => (
|
|
182
|
-
<Box
|
|
183
|
-
component='code'
|
|
184
|
-
{...props}
|
|
185
|
-
sx={{
|
|
186
|
-
fontSize: '0.85em',
|
|
187
|
-
"&:not([class*='language-'])": {
|
|
188
|
-
fontFamily: `Menlo, Monaco, Consolas, 'Andale Mono', 'Ubuntu Mono', 'Courier New', monospace`,
|
|
189
|
-
borderRadius: 1.5,
|
|
190
|
-
pt: 0.1,
|
|
191
|
-
pb: 0.3,
|
|
192
|
-
px: 0.7,
|
|
193
|
-
backgroundColor: (theme) => [alpha(theme.palette.text.primary, 0.08), '!important'],
|
|
194
|
-
},
|
|
195
|
-
}}
|
|
196
|
-
/>
|
|
197
|
-
),
|
|
198
|
-
a: RelativeLink,
|
|
199
|
-
table: ({ ref, ...props }) => (
|
|
200
|
-
<TableContainer component={Paper} elevation={4} sx={{ mb: 5 }}>
|
|
201
|
-
<Table {...props} size='small' aria-label='a dense table' />
|
|
202
|
-
</TableContainer>
|
|
203
|
-
),
|
|
204
|
-
thead: ({ ref, ...props }) => <TableHead {...props} />,
|
|
205
|
-
tbody: ({ ref, ...props }) => <TableBody {...props} />,
|
|
206
|
-
tr: ({ ref, ...props }) => <TableRow {...props} />,
|
|
207
|
-
th: ({ ref, align, ...props }) => <TableCell {...props} />,
|
|
208
|
-
td: ({ ref, align, ...props }) => <TableCell {...props} />,
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function IndexPage(props: Props) {
|
|
212
|
-
const { source } = props
|
|
213
|
-
const { metaTitle, menu, metaDescription } = source.frontmatter as MatterFields
|
|
214
|
-
const prettyRoute = useRouter()
|
|
215
|
-
.asPath.split('?')[0]
|
|
216
|
-
.split('/')
|
|
217
|
-
.map((v) => v.replace(/-/g, ' ').replace(/^./, (x) => x.toUpperCase()))
|
|
218
|
-
.reverse()
|
|
219
|
-
.filter(Boolean)
|
|
220
|
-
|
|
221
|
-
return (
|
|
222
|
-
<>
|
|
223
|
-
<PageMeta
|
|
224
|
-
title={metaTitle ?? menu ?? prettyRoute.join(' - ')}
|
|
225
|
-
metaDescription={metaDescription}
|
|
226
|
-
/>
|
|
227
|
-
<Container
|
|
228
|
-
maxWidth='md'
|
|
229
|
-
sx={(theme) => ({
|
|
230
|
-
position: 'relative',
|
|
231
|
-
'& figure': {
|
|
232
|
-
display: 'block',
|
|
233
|
-
margin: '0 auto',
|
|
234
|
-
maxWidth: '100%',
|
|
235
|
-
mb: 8,
|
|
236
|
-
mt: 8,
|
|
237
|
-
aspectRatio: '16 / 9',
|
|
238
|
-
width: '100%',
|
|
239
|
-
},
|
|
240
|
-
'& img, & video': {
|
|
241
|
-
display: 'block',
|
|
242
|
-
margin: '0 auto',
|
|
243
|
-
maxWidth: '100%',
|
|
244
|
-
boxShadow: '0 0px 40px 0 rgba(0,0,0,0.15)',
|
|
245
|
-
},
|
|
246
|
-
'& strong': {
|
|
247
|
-
fontVariationSettings: "'wght' 600",
|
|
248
|
-
},
|
|
249
|
-
'& pre': {
|
|
250
|
-
borderRadius: 2,
|
|
251
|
-
mt: '1em !important',
|
|
252
|
-
mb: '1em !important',
|
|
253
|
-
},
|
|
254
|
-
'& figure > figcaption': {
|
|
255
|
-
paddingLeft: '1em',
|
|
256
|
-
marginTop: '1em',
|
|
257
|
-
typography: 'caption',
|
|
258
|
-
color: 'text.secondary',
|
|
259
|
-
},
|
|
260
|
-
'& > details': {
|
|
261
|
-
width: '100%',
|
|
262
|
-
mt: '2em',
|
|
263
|
-
mb: '0.5em',
|
|
264
|
-
p: '1em',
|
|
265
|
-
borderRadius: 2,
|
|
266
|
-
backgroundColor: alpha(theme.palette.primary.dark, 0.1),
|
|
267
|
-
border: `1px solid ${theme.palette.primary.dark}`,
|
|
268
|
-
boxShadow: 4,
|
|
269
|
-
a: {
|
|
270
|
-
color: theme.palette.primary.dark,
|
|
271
|
-
textDecorationColor: theme.palette.primary.dark,
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
'& > div > details': {
|
|
275
|
-
summary: {
|
|
276
|
-
mb: 1,
|
|
277
|
-
},
|
|
278
|
-
h3: {
|
|
279
|
-
...theme.typography.h3,
|
|
280
|
-
display: 'inline-block',
|
|
281
|
-
},
|
|
282
|
-
a: {
|
|
283
|
-
color: theme.palette.text.primary,
|
|
284
|
-
textDecorationColor: theme.palette.text.primary,
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
'& hr': {
|
|
288
|
-
m: 0,
|
|
289
|
-
mt: 5,
|
|
290
|
-
mb: 5,
|
|
291
|
-
},
|
|
292
|
-
'& figure > p': { display: 'none' },
|
|
293
|
-
|
|
294
|
-
'& .icon.icon-link': {
|
|
295
|
-
background: 'url(/link.svg) no-repeat',
|
|
296
|
-
backgroundSize: 'contain',
|
|
297
|
-
display: 'inline-block',
|
|
298
|
-
verticalAlign: 'middle',
|
|
299
|
-
fontSize: '0.8em',
|
|
300
|
-
mr: '0.2em',
|
|
301
|
-
width: '1.1em',
|
|
302
|
-
height: '1.2em',
|
|
303
|
-
ml: `calc(-0.2em - 1.2em)`,
|
|
304
|
-
opacity: 0.0,
|
|
305
|
-
},
|
|
306
|
-
'& .contains-task-list': {
|
|
307
|
-
padding: 0,
|
|
308
|
-
'& li': {
|
|
309
|
-
listStyle: 'none',
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
'& h2:last-of-type': {
|
|
313
|
-
pl: 3,
|
|
314
|
-
pr: 3,
|
|
315
|
-
pt: 2,
|
|
316
|
-
pb: 2,
|
|
317
|
-
background: alpha(theme.palette.divider, 0.05),
|
|
318
|
-
mb: 0,
|
|
319
|
-
mt: 8,
|
|
320
|
-
borderTopLeftRadius: 10,
|
|
321
|
-
borderTopRightRadius: 10,
|
|
322
|
-
border: 0,
|
|
323
|
-
},
|
|
324
|
-
'& ul:last-of-type': {
|
|
325
|
-
pl: 3,
|
|
326
|
-
pr: 3,
|
|
327
|
-
pt: 0,
|
|
328
|
-
pb: 3,
|
|
329
|
-
mt: 0,
|
|
330
|
-
background: alpha(theme.palette.divider, 0.05),
|
|
331
|
-
borderBottomLeftRadius: 10,
|
|
332
|
-
borderBottomRightRadius: 10,
|
|
333
|
-
'& li': {
|
|
334
|
-
listStyle: 'none',
|
|
335
|
-
'&:before': {
|
|
336
|
-
content: '"— "',
|
|
337
|
-
mr: 1,
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
'& h1:hover .icon.icon-link, & h2:hover .icon.icon-link, & h3:hover .icon.icon-link, & h4:hover .icon.icon-link, & h5:hover .icon.icon-link, & h6:hover .icon.icon-link':
|
|
342
|
-
{ opacity: 0.5 },
|
|
343
|
-
})}
|
|
344
|
-
>
|
|
345
|
-
<MDXRemote {...source} components={mdxComponents} />
|
|
346
|
-
</Container>
|
|
347
|
-
</>
|
|
348
|
-
)
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const pageOptions: PageOptions<LayoutFullProps> = {
|
|
352
|
-
Layout: LayoutFull,
|
|
353
|
-
}
|
|
354
|
-
IndexPage.pageOptions = pageOptions
|
|
355
|
-
|
|
356
|
-
export default IndexPage
|
|
357
|
-
|
|
358
|
-
export const getStaticPaths: GetStaticPaths<{ url: string[] }> = async () => {
|
|
359
|
-
const paths = await getDirectoryPaths('content')
|
|
360
|
-
|
|
361
|
-
return {
|
|
362
|
-
fallback: 'blocking',
|
|
363
|
-
paths: paths.map((p) => ({ params: { url: p.split('/') } })),
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
export const getStaticProps: GetStatic = async ({ params }) => {
|
|
368
|
-
const url = params?.url ?? []
|
|
369
|
-
const menuData = await getDirectoryTree('content')
|
|
370
|
-
if (!menuData) return { notFound: true }
|
|
371
|
-
|
|
372
|
-
const filePath = urlToPath(url, menuData)
|
|
373
|
-
if (!filePath) return { notFound: true }
|
|
374
|
-
|
|
375
|
-
const res = await getFileContents('content', filePath)
|
|
376
|
-
|
|
377
|
-
if (res === false) return { notFound: true }
|
|
378
|
-
|
|
379
|
-
// todo: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins
|
|
380
|
-
// todo: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins
|
|
381
|
-
const source = (await serialize(res, {
|
|
382
|
-
mdxOptions: {
|
|
383
|
-
format: 'detect',
|
|
384
|
-
remarkPlugins: [remarkGfm],
|
|
385
|
-
rehypePlugins: [rehypePrism, rehypeSlug, rehypeAutolinkHeadings],
|
|
386
|
-
},
|
|
387
|
-
parseFrontmatter: true,
|
|
388
|
-
})) as MDXSource
|
|
389
|
-
|
|
390
|
-
return { props: { menuData, source } }
|
|
391
|
-
}
|
package/pages/_app.tsx
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { FramerNextPages } from '@graphcommerce/framer-next-pages'
|
|
2
|
-
// import { GoogleAnalyticsScript } from '@graphcommerce/googleanalytics'
|
|
3
|
-
// import { GoogleRecaptchaV3Script } from '@graphcommerce/googlerecaptcha'
|
|
4
|
-
// import { GoogleTagManagerScript } from '@graphcommerce/googletagmanager'
|
|
5
|
-
import { CssAndFramerMotionProvider, GlobalHead, PageLoadIndicator } from '@graphcommerce/next-ui'
|
|
6
|
-
import { CssBaseline, ThemeProvider } from '@mui/material'
|
|
7
|
-
import { AppProps } from 'next/app'
|
|
8
|
-
import { lightTheme } from '../components/theme'
|
|
9
|
-
import '../components/prism.css'
|
|
10
|
-
import '../components/rehype-prism-plus.css'
|
|
11
|
-
|
|
12
|
-
export default function ThemedApp(props: AppProps) {
|
|
13
|
-
return (
|
|
14
|
-
<CssAndFramerMotionProvider>
|
|
15
|
-
<ThemeProvider theme={lightTheme}>
|
|
16
|
-
{/* <GoogleAnalyticsScript /> */}
|
|
17
|
-
{/* <GoogleRecaptchaV3Script /> */}
|
|
18
|
-
{/* <GoogleTagManagerScript /> */}
|
|
19
|
-
<GlobalHead name='GraphCommerce Docs' />
|
|
20
|
-
<CssBaseline />
|
|
21
|
-
<PageLoadIndicator />
|
|
22
|
-
<FramerNextPages {...props} fallbackRoute='/[[...url]]' />
|
|
23
|
-
</ThemeProvider>
|
|
24
|
-
</CssAndFramerMotionProvider>
|
|
25
|
-
)
|
|
26
|
-
}
|
package/pages/_document.tsx
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// import { GoogleTagManagerNoScript } from '@graphcommerce/googletagmanager'
|
|
2
|
-
import { EmotionCacheProps, withEmotionCache } from '@graphcommerce/next-ui'
|
|
3
|
-
import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
|
|
4
|
-
|
|
5
|
-
class Document extends NextDocument<EmotionCacheProps> {
|
|
6
|
-
render() {
|
|
7
|
-
return (
|
|
8
|
-
<Html>
|
|
9
|
-
<Head>
|
|
10
|
-
{/* Inject MUI styles first to match with the prepend: true configuration. */}
|
|
11
|
-
{this.props.emotionStyleTags}
|
|
12
|
-
</Head>
|
|
13
|
-
<body>
|
|
14
|
-
<Main />
|
|
15
|
-
<NextScript />
|
|
16
|
-
</body>
|
|
17
|
-
</Html>
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default withEmotionCache(Document)
|
package/pages/api/reindex.ts
DELETED