add first version of tailwind docs

This commit is contained in:
Pascal Fischer
2023-05-03 19:00:56 +02:00
parent 9d42e075f7
commit 86b1890396
189 changed files with 26622 additions and 0 deletions

5333
generator/api-back.mdx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
# Swagger Codegen Ignore
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@@ -0,0 +1 @@
3.0.42

View File

4425
generator/api.mdx Normal file

File diff suppressed because it is too large Load Diff

200
generator/api.ts Normal file
View File

@@ -0,0 +1,200 @@
import template from './templates/ApiTemplate'
import { slugify, toArrayWithKey, toTitle, writeToDisk } from './helpers'
import { OpenAPIV3, OpenAPIV2 } from 'openapi-types'
import * as yaml from 'yaml';
import * as fs from 'fs'
import * as ejs from 'ejs'
export default async function gen(inputFileName: string, outputDir: string, apiUrl: string) {
const specRaw = fs.readFileSync(inputFileName, 'utf8')
const spec = yaml.parse(specRaw) as any
// console.log('spec', spec)
switch (spec.openapi || spec.swagger) {
case '3.0.0':
case '3.0.1':
case '3.0.3':
await gen_v3(spec, outputDir, { apiUrl })
break
default:
console.log('Unrecognized specification version:', spec.openapi)
break
}
}
/**
* Versioned Generator
*/
// OPENAPI-SPEC-VERSION: 3.0.0
type v3OperationWithPath = OpenAPIV3.OperationObject & {
path: string
}
export type enrichedOperation = OpenAPIV3.OperationObject & {
path: string
fullPath: string
operationId: string
}
export type schemaParameter = {
name: string
type: string
description: string
required: boolean
minimum?: number
maximum?: number
minLength?: number
maxLength?: number
enum?: string[]
}
export type schemaObject = {
examples: Object
parameters: schemaParameter[]
}
async function gen_v3(spec: OpenAPIV3.Document, dest: string, { apiUrl }: { apiUrl: string }) {
const specLayout = spec.tags || []
// const operations: enrichedOperation[] = []
const tagGroups = new Map<string, enrichedOperation[]>()
Object.entries(spec.paths).forEach(([key, val]) => {
const fullPath = `${apiUrl}${key}`
toArrayWithKey(val!, 'operation').forEach((o) => {
const operation = o as v3OperationWithPath
const enriched = {
...operation,
path: key,
fullPath,
operationId: slugify(operation.summary!),
responseList: toArrayWithKey(operation.responses!, 'responseCode') || [],
}
let tag = operation.tags.pop()
let tagOperations = tagGroups.get(tag) ?? []
tagGroups.set(tag, tagOperations.concat(enriched))
})
})
let schemas = new Map<string, schemaObject>();
Object.entries(spec.components?.schemas).forEach(([key, val]) => {
const schema = val as OpenAPIV3.SchemaObject
let examples = new Map<string, any>();
let parameters : schemaParameter[] = []
if(schema.allOf){
schema.allOf.forEach((item) => {
if((item as OpenAPIV3.ReferenceObject).$ref){
let schemaObject = schemas.get((item as OpenAPIV3.ReferenceObject).$ref.split('/').pop())
let examplesMap = new Map(Object.entries(schemaObject.examples))
examplesMap.forEach((value, key) => {
examples.set(key, value)
})
parameters = parameters.concat(schemaObject.parameters)
}
if((item as OpenAPIV3.SchemaObject).properties){
Object.entries((item as OpenAPIV3.SchemaObject).properties).forEach(([key, val]) => {
let property = val as OpenAPIV3.SchemaObject
let type
if (property.type === "array") {
type = new Array(resolveType(property.items, spec.components?.schemas))
} else {
type = resolveType(property, spec.components?.schemas)
}
examples.set(key, type)
let parameter: schemaParameter = {
name: key,
type: property.type === "array" ? ((property.items as OpenAPIV3.SchemaObject).type || (property.items as OpenAPIV3.ReferenceObject).$ref.split('/').pop()) + "[]" : property.type,
description: property.description,
required: schema.required?.includes(key) || false,
minimum: property.minimum,
maximum: property.maximum,
minLength: property.minLength,
maxLength: property.maxLength,
enum: property.enum
}
parameters.push(parameter)
})
}
})
} else {
Object.entries(schema.properties).forEach(([key, val]) => {
let property = val as OpenAPIV3.SchemaObject
let type
if(property.type === "array"){
type = new Array(resolveType(property.items, spec.components?.schemas))
} else {
type = resolveType(property, spec.components?.schemas)
}
examples.set(key, type)
let parameter : schemaParameter = {
name: key,
type: property.type === "array" ? ((property.items as OpenAPIV3.SchemaObject).type || (property.items as OpenAPIV3.ReferenceObject).$ref.split('/').pop()) + "[]" : property.type,
description: property.description,
required: schema.required?.includes(key) || false,
minimum: property.minimum,
maximum: property.maximum,
minLength: property.minLength,
maxLength: property.maxLength,
enum: property.enum
}
parameters.push(parameter)
})
}
let output : schemaObject = {
examples: Object.fromEntries(examples),
parameters: parameters
}
schemas.set(key, output)
})
tagGroups.forEach((value: enrichedOperation[], key: string) => {
const operations = value
const sections = specLayout.map((section) => {
return {
...section,
title: toTitle(section.name),
id: slugify(section.name),
operations: operations,
}
})
const content = ejs.render(template, {
info: spec.info,
sections,
operations,
schemas,
})
// Write to disk
let outputFile = dest + "/" + key.toLowerCase().replace(" ", "-") + ".mdx"
writeToDisk(outputFile, content)
// console.log('Saved: ', outputFile)
})
}
function resolveType(items: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject | OpenAPIV3.NonArraySchemaObjectType, schemas) : any {
if((items as OpenAPIV3.ReferenceObject).$ref){
let ref = (items as OpenAPIV3.ReferenceObject).$ref
let map = new Map<string, any>()
Object.entries(schemas[ref.split('/').pop()].properties).forEach(([key, val]) => {
let property = val as OpenAPIV3.SchemaObject
let type
if(property.type === "array"){
type = new Array(resolveType(property.items, schemas))
} else {
type = resolveType(property, schemas)
}
map.set(key, type)
})
return Object.fromEntries(map)
}
return (items as OpenAPIV3.ArraySchemaObject).type
}

42
generator/helpers.ts Normal file
View File

@@ -0,0 +1,42 @@
import * as _ from 'lodash'
import * as fs from 'fs'
export const slugify = (text: string) => {
if (!text) return ''
return text
.toString()
.toLowerCase()
.replace(/[. )(]/g, '-') // Replace spaces and brackets -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, '') // Trim - from end of text
}
// Uppercase the first letter of a string
export const toTitle = (text: string) => {
return text.charAt(0).toUpperCase() + text.slice(1)
}
/**
* writeToDisk()
*/
export const writeToDisk = (fileName: string, content: any) => {
return new Promise((resolve, reject) => {
fs.writeFile(fileName, content, (err: any) => {
if (err) return reject(err)
else return resolve(true)
})
})
}
/**
* Convert Object to Array of values
*/
export const toArrayWithKey = (obj: object, keyAs: string) =>
_.values(
_.mapValues(obj, (value: any, key: string) => {
value[keyAs] = key
return value
})
)

45
generator/index.ts Normal file
View File

@@ -0,0 +1,45 @@
import ApiGenerator from './api'
const main = (command: string[], options: any) => {
handleInput(command[0], options)
}
// Run everything
const argv = require('minimist')(process.argv.slice(2))
main(argv['_'], argv)
function handleInput(command: string, options: any) {
switch (command) {
case 'gen':
DocGenerator(options)
break
default:
console.log('Unrecognized command:', command)
break
}
}
export default async function DocGenerator({
input,
output,
type,
url,
}: {
input: string
output: string
type: 'api'
url?: string
}) {
switch (type) {
case 'api':
await ApiGenerator(input, output, url || '')
break
default:
await console.log('Unrecognized type: ', type)
break
}
return 'Done'
}

3153
generator/openapi.json Normal file

File diff suppressed because it is too large Load Diff

2105
generator/openapi.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
const template = `
---
<% operations.forEach(function(operation){ %>
## <%- operation.summary %> {{ tag: '<%- operation.operation.toUpperCase() %>' , label: '<%- operation.path %>' }}
<Row>
<Col>
<%- operation.description %>
<% if(operation.parameters && operation.parameters.filter((parameter) => parameter.in === 'path').length > 0){ %>
#### Path Parameters
<Properties>
<% operation.parameters.filter((parameter) => parameter.in === 'path').forEach(function(parameter){ %>
<Property name="<%- parameter.name %>" type="string" required=\{true\}>
<%- parameter.description %>
</Property>
<% }); -%>
</Properties>
<% }; -%>
<% if(operation.parameters && operation.parameters.filter((parameter) => parameter.in === 'query').length > 0){ %>
#### Query Parameters
<Properties>
<% operation.parameters.filter((parameter) => parameter.in === 'query').forEach(function(parameter){ %>
<Property name="<%- parameter.name %>" type="<%- parameter.schema.type %>" required=\{false\}>
<%- parameter.description %>
</Property>
<% }); -%>
</Properties>
<% }; -%>
<% if(operation.requestBody?.content && operation.requestBody?.content['application/json']){ %>
#### Request-Body Parameters
<Properties>
<% schemas.get(operation.requestBody?.content['application/json'].schema.$ref.split('/').pop())?.parameters.forEach(function(parameter){ %>
<Property name="<%- parameter.name %>" type="<%- parameter.type %>" required=\{<%- parameter.required %>\}
<% if(parameter.enum){ %>
enumList="<%- parameter.enum %>"
<% }; -%>
<% if(parameter.minimum){ %>
min=\{<%- parameter.minimum %>\}
<% }; -%>
<% if(parameter.maximum){ %>
max=\{<%- parameter.maximum %>\}
<% }; -%>
<% if(parameter.minLength){ %>
minLen=\{<%- parameter.minLength %>\}
<% }; -%>
<% if(parameter.maxLength){ %>
maxLen=\{<%- parameter.maxLength %>\}
<% }; -%> >
<%- parameter.description %>
</Property>
<% }); -%>
</Properties>
<% }; -%>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="<%- operation.operation.toUpperCase() %>" label="<%- operation.path %>">
\`\`\`bash {{ title: 'cURL' }}
curl -X <%- operation.operation.toUpperCase() %> <%- operation.fullPath %> \\
-H "Authorization: Bearer {token}" \\
<% if(operation.responseList[0].content && operation.responseList[0].content['application/json']){ -%>
-H 'Accept: application/json' \\<% }; %>
<% if(operation.requestBody?.content && operation.requestBody?.content['application/json']){ -%>
-H 'Content-Type: application/json' \\
--data-raw '<%- JSON.stringify(schemas.get(operation.requestBody?.content['application/json'].schema.$ref?.split('/').pop())?.examples, null, 2) %>'<% }; %>
\`\`\`
\`\`\`js
import ApiClient from '@example/protocol-api'
const client = new ApiClient(token)
await client.contacts.update('WAz8eIbvDR60rouK', {
display_name: 'UncleFrank',
})
\`\`\`
\`\`\`python
from protocol_api import ApiClient
client = ApiClient(token)
client.contacts.update("WAz8eIbvDR60rouK", display_name="UncleFrank")
\`\`\`
\`\`\`php
$client = new \\Protocol\\ApiClient($token);
$client->contacts->update('WAz8eIbvDR60rouK', [
'display_name' => 'UncleFrank',
]);
\`\`\`
</CodeGroup>
<% operation.responseList.forEach(function(response){ %>
<% if(response?.content && response?.content['application/json']){ %>
<% if(response?.content['application/json'].schema.type === 'array'){ %>
<CodeGroup title="Response">
\`\`\`json {{ title: '200' }}
<%- JSON.stringify(new Array(schemas.get(response?.content['application/json'].schema.items.$ref?.split('/').pop())?.examples), null, 2) %>
\`\`\`
</CodeGroup>
<% } else { %>
<CodeGroup title="Response">
\`\`\`json {{ title: '200' }}
<%- JSON.stringify(schemas.get(response?.content['application/json'].schema.$ref?.split('/').pop())?.examples, null, 2) %>
\`\`\`
</CodeGroup>
<% }; -%>
<% }; -%>
<% }); -%>
</Col>
</Row>
---
<% }); -%>
`.trim()
export default template

View File

@@ -0,0 +1,144 @@
const template = `
---
id: usage
slug: /usage
title: Usage
toc_max_heading_level: 3
---
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
<%- info.description %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
<% sections.forEach(function(section){ %>
## <%- section.title %> [#<%= section.id %>]
<%- section.description %>
<% section.operations.forEach(function(operation){ %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
### <%- operation.summary %> [#<%- operation.operationId %>]
\`\`\`
<%- operation.operation.toUpperCase() %> <%- operation.fullPath %>
\`\`\`
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
<% if(operation.parameters && operation.parameters.filter((parameter) => parameter.in === 'path').length > 0){ %>
#### Path Parameters
<ul className="method-list-group not-prose">
<% operation.parameters
.filter((parameter) => parameter.in === 'path').forEach(function(parameter){ %>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
<%- parameter.name %>
</span>
<span className="method-list-item-label-badge">
<%- parameter.required ? 'required' : 'optional' %>
</span>
<span className="method-list-item-validation">
<%- parameter.type %>
</span>
</h4>
<% if(parameter.example){ %>
<h4 className="method-list-item-label">
Example:
<span className="method-list-item-label-badge">
<%- parameter.example %>
</span>
</h4>
<% } %>
<div class="method-list-item-description">
<%- parameter.description %>
</div>
</li>
<% }); %>
</ul>
<% }; %>
<% if(operation.parameters && operation.parameters.filter((parameter) => parameter.in === 'header').length > 0){ %>
#### Header Parameters
<ul className="method-list-group not-prose">
<% operation.parameters
.filter((parameter) => parameter.in === 'header').forEach(function(parameter){ %>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
<%- parameter.name %>
</span>
<span className="method-list-item-label-badge">
<%- parameter.required ? 'required' : 'optional' %>
</span>
<span className="method-list-item-validation">
<%- parameter.type %>
</span>
</h4>
<% if(parameter.example){ %>
<h4 className="method-list-item-label">
Example:
<span className="method-list-item-label-badge">
<%- parameter.example %>
</span>
</h4>
<% } %>
<div class="method-list-item-description">
<%- parameter.description %>
</div>
</li>
<% }); %>
</ul>
<% }; %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
<% if(operation.requestBody?.content && operation.requestBody?.content['application/json']){ %>
#### Body Parameters
\`\`\`json
<%- JSON.stringify(operation.requestBody?.content['application/json'], null, 2) %>
\`\`\`
<% }; %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
#### Responses
<Tabs scrollable size="small" type="underlined" defaultActiveId="<%- operation.responseList[0].responseCode %>">
<% operation.responseList.forEach(function(response){ %>
<TabPanel id="<%- response.responseCode %>" label="<%- response.responseCode %>">
<%- response.description %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
<% if(response?.content && response?.content['application/json']){ %>
\`\`\`json
<%- JSON.stringify(response.content['application/json'], null, 2) %>
\`\`\`
<% }; %>
<!-- AUTOGENERATED: DO NOT EDIT DIRECTLY IF THIS IS VERSION "next" -->
</TabPanel>
<% }); %>
</Tabs>
<br />
<% }); %>
<% }); %>
`.trim()
export default template

13
generator/tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
// generator files need their own tsconfig.json because they don't like "module": "esnext" setting that nextjs requires in the main tsconfig
{
"compilerOptions": {
"incremental": true,
"noImplicitAny": false,
"baseUrl": ".",
"paths": {
"~/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,34 @@
import { SpecLink } from './Spec'
import { Url } from 'url'
export type CliInfo = {
id: string
version: string
title: string
language: string
source: Url
bugs: Url
spec: Url
description: string
options: string
}
export type CliCommand = {
id: string
title: string
summary: string
description: string
tags: string[]
links: SpecLink[]
usage: string
subcommands: string[]
options: string
}
export interface CliSpec {
clispec: '001'
info: CliInfo
commands: CliCommand[]
}

View File

@@ -0,0 +1,36 @@
import { SpecLink } from './Spec'
import { Url } from 'url'
export type Tag = {
id: string
title: string
description?: string
}
export type ConfigInfo = {
id: string
version: string
title: string
source: Url
bugs: Url
spec: Url
description: string
tags: Tag[]
}
export type ConfigParameter = {
id: string
title: string
tags: string[]
required: boolean
description: string
links: SpecLink[]
}
export interface ConfigSpec {
configspec: '001'
info: ConfigInfo
parameters: ConfigParameter[]
}

View File

@@ -0,0 +1,75 @@
import { SpecLink } from './Spec'
import { Url } from 'url'
export type SdkInfo = {
id: string
version: string
title: string
language: string
source: Url
bugs: Url
spec: Url
description: string
options: string
}
export type SdkType = {
id: string
title: string
summary: string
source: Url
value: string
ref?: SdkType
links: SpecLink[]
}
export type FunctionAttribute = {
id: string
title: string
required: boolean
description: string
type?: string[]
ref?: string // If a "type" is not supplied, a "ref" must be. This is a pointer to a type.
children: FunctionAttribute[]
}
export type FunctionReturn = {
id: string
title: string
value: string
description: string
ref?: string // This is a pointer to a type.
}
export type FunctionExample = {
id: string
title: string
description?: string
links: SpecLink[]
code: string
returns?: FunctionReturn
}
export type Function = {
id: string
title: string
summary: string
source: Url
description?: string
usage: string
tags: string[]
links: SpecLink[]
attributes?: FunctionAttribute[]
returns?: FunctionReturn[]
examples?: FunctionExample[]
}
export interface SdkSpec {
sdkspec: '001'
info: SdkInfo
functions: Function[]
types: SdkType[]
}

6
generator/types/Spec.ts Normal file
View File

@@ -0,0 +1,6 @@
import { Url } from 'url'
export type SpecLink = {
name: string
url: Url
}

8
jsconfig.json Normal file
View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}

19
mdx/recma.mjs Normal file
View File

@@ -0,0 +1,19 @@
import { mdxAnnotations } from 'mdx-annotations'
import recmaNextjsStaticProps from 'recma-nextjs-static-props'
function recmaRemoveNamedExports() {
return (tree) => {
tree.body = tree.body.map((node) => {
if (node.type === 'ExportNamedDeclaration') {
return node.declaration
}
return node
})
}
}
export const recmaPlugins = [
mdxAnnotations.recma,
recmaRemoveNamedExports,
recmaNextjsStaticProps,
]

126
mdx/rehype.mjs Normal file
View File

@@ -0,0 +1,126 @@
import { mdxAnnotations } from 'mdx-annotations'
import { visit } from 'unist-util-visit'
import rehypeMdxTitle from 'rehype-mdx-title'
import shiki from 'shiki'
import { toString } from 'mdast-util-to-string'
import * as acorn from 'acorn'
import { slugifyWithCounter } from '@sindresorhus/slugify'
function rehypeParseCodeBlocks() {
return (tree) => {
visit(tree, 'element', (node, _nodeIndex, parentNode) => {
if (node.tagName === 'code' && node.properties.className) {
parentNode.properties.language = node.properties.className[0]?.replace(
/^language-/,
''
)
}
})
}
}
let highlighter
function rehypeShiki() {
return async (tree) => {
highlighter =
highlighter ?? (await shiki.getHighlighter({ theme: 'css-variables' }))
visit(tree, 'element', (node) => {
if (node.tagName === 'pre' && node.children[0]?.tagName === 'code') {
let codeNode = node.children[0]
let textNode = codeNode.children[0]
node.properties.code = textNode.value
if (node.properties.language) {
let tokens = highlighter.codeToThemedTokens(
textNode.value,
node.properties.language
)
textNode.value = shiki.renderToHtml(tokens, {
elements: {
pre: ({ children }) => children,
code: ({ children }) => children,
line: ({ children }) => `<span>${children}</span>`,
},
})
}
}
})
}
}
function rehypeSlugify() {
return (tree) => {
let slugify = slugifyWithCounter()
visit(tree, 'element', (node) => {
if (node.tagName === 'h2' && !node.properties.id) {
node.properties.id = slugify(toString(node))
}
})
}
}
function rehypeAddMDXExports(getExports) {
return (tree) => {
let exports = Object.entries(getExports(tree))
for (let [name, value] of exports) {
for (let node of tree.children) {
if (
node.type === 'mdxjsEsm' &&
new RegExp(`export\\s+const\\s+${name}\\s*=`).test(node.value)
) {
return
}
}
let exportStr = `export const ${name} = ${value}`
tree.children.push({
type: 'mdxjsEsm',
value: exportStr,
data: {
estree: acorn.parse(exportStr, {
sourceType: 'module',
ecmaVersion: 'latest',
}),
},
})
}
}
}
function getSections(node) {
let sections = []
for (let child of node.children ?? []) {
if (child.type === 'element' && child.tagName === 'h2') {
sections.push(`{
title: ${JSON.stringify(toString(child))},
id: ${JSON.stringify(child.properties.id)},
...${child.properties.annotation}
}`)
} else if (child.children) {
sections.push(...getSections(child))
}
}
return sections
}
export const rehypePlugins = [
mdxAnnotations.rehype,
rehypeParseCodeBlocks,
rehypeShiki,
rehypeSlugify,
rehypeMdxTitle,
[
rehypeAddMDXExports,
(tree) => ({
sections: `[${getSections(tree).join()}]`,
}),
],
]

4
mdx/remark.mjs Normal file
View File

@@ -0,0 +1,4 @@
import { mdxAnnotations } from 'mdx-annotations'
import remarkGfm from 'remark-gfm'
export const remarkPlugins = [mdxAnnotations.remark, remarkGfm]

33
next.config.mjs Normal file
View File

@@ -0,0 +1,33 @@
import nextMDX from '@next/mdx'
import { remarkPlugins } from './mdx/remark.mjs'
import { rehypePlugins } from './mdx/rehype.mjs'
import { recmaPlugins } from './mdx/recma.mjs'
const withMDX = nextMDX({
options: {
remarkPlugins,
rehypePlugins,
recmaPlugins,
providerImportSource: '@mdx-js/react',
},
})
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'],
experimental: {
scrollRestoration: true,
},
redirects: async () => {
return [
{
source: '/',
destination: '/docs/introduction',
permanent: true,
},
]
}
}
export default withMDX(nextConfig)

50
package.json Normal file
View File

@@ -0,0 +1,50 @@
{
"name": "wiretrustee-docs",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"browserslist": "defaults, not ie <= 11",
"dependencies": {
"@algolia/autocomplete-core": "^1.7.3",
"@algolia/autocomplete-preset-algolia": "^1.7.3",
"@headlessui/react": "^1.7.13",
"@mdx-js/loader": "^2.1.5",
"@mdx-js/react": "^2.1.5",
"@next/mdx": "^13.0.3",
"@sindresorhus/slugify": "^2.1.1",
"@tailwindcss/typography": "^0.5.8",
"acorn": "^8.8.1",
"algoliasearch": "^4.14.2",
"autoprefixer": "^10.4.7",
"clsx": "^1.2.0",
"ejs": "^3.1.9",
"focus-visible": "^5.2.0",
"framer-motion": "7.8.1",
"lodash": "^4.17.21",
"mdast-util-to-string": "^3.1.0",
"mdx-annotations": "^0.1.1",
"next": "13.3.0",
"openapi-types": "^12.1.0",
"postcss-focus-visible": "^6.0.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"recma-nextjs-static-props": "^1.0.0",
"rehype-mdx-title": "^2.0.0",
"remark-gfm": "^3.0.1",
"shiki": "^0.11.1",
"tailwindcss": "^3.3.0",
"unist-util-visit": "^4.1.1",
"zustand": "^4.3.2"
},
"devDependencies": {
"eslint": "8.26.0",
"eslint-config-next": "13.0.2",
"prettier": "^2.8.7",
"prettier-plugin-tailwindcss": "^0.2.6"
}
}

9
postcss.config.js Normal file
View File

@@ -0,0 +1,9 @@
module.exports = {
plugins: {
tailwindcss: {},
'postcss-focus-visible': {
replaceWith: '[data-focus-visible-added]',
},
autoprefixer: {},
},
}

5
prettier.config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
semi: false,
plugins: [require('prettier-plugin-tailwindcss')],
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
public/img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

121
public/img/logo-dark.svg Normal file
View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="500"
height="90"
viewBox="0 0 132.29167 23.812502"
version="1.1"
id="svg1203"
inkscape:version="1.1.1 (1:1.1+202109281944+c3084ef5ed)"
sodipodi:docname="logo-dark.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1205"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
width="650px"
units="px"
inkscape:zoom="1.4289282"
inkscape:cx="334.86637"
inkscape:cy="27.993009"
inkscape:window-width="2560"
inkscape:window-height="1335"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:snap-global="false" />
<defs
id="defs1200">
<inkscape:path-effect
effect="fillet_chamfer"
id="path-effect57379"
is_visible="true"
lpeversion="1"
satellites_param="F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1"
unit="px"
method="auto"
mode="F"
radius="17"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#ffe6d5;stroke:none;stroke-width:1.4928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4955"
width="43"
height="18.151592"
x="87.122803"
y="2.9803145"
inkscape:export-filename="/home/braginini/Documents/projects/my/wiretrustee/wiretrustee.com-nextjs/public/brand-assets/logo.png"
inkscape:export-xdpi="100"
inkscape:export-ydpi="100"
sodipodi:type="rect"
d="m 91.620719,2.9803145 34.004171,0 a 4.4979167,4.4979167 45 0 1 4.49791,4.4979167 V 16.63399 a 4.4979167,4.4979167 135 0 1 -4.49791,4.497917 H 91.620719 A 4.4979167,4.4979167 45 0 1 87.122803,16.63399 V 7.4782312 a 4.4979167,4.4979167 135 0 1 4.497916,-4.4979167 z"
inkscape:path-effect="#path-effect57379" />
<text
xml:space="preserve"
style="font-size:10.9361px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;stroke-width:0.264583"
x="92.88604"
y="15.806503"
id="text3179"><tspan
sodipodi:role="line"
id="tspan3177"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.9361px;font-family:Poppins;-inkscape-font-specification:'Poppins Bold';fill:#fb923c;fill-opacity:1;stroke-width:0.264583"
x="92.88604"
y="15.806503">DOCS</tspan></text>
<text
xml:space="preserve"
style="font-size:16.9333px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#4d4d4d;stroke-width:0.0700042"
x="21.543421"
y="17.592438"
id="text1870"
inkscape:export-filename="/home/braginini/Downloads/netbird-logo-dark.png"
inkscape:export-xdpi="329.58896"
inkscape:export-ydpi="329.58896"><tspan
sodipodi:role="line"
id="tspan1868"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.9333px;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#e6e6e6;fill-opacity:1;stroke-width:0.0700042"
x="21.543421"
y="17.592438">netbird</tspan></text>
<g
id="g23427"
inkscape:export-filename="/home/braginini/Downloads/netbird-logo-dark.png"
inkscape:export-xdpi="329.58896"
inkscape:export-ydpi="329.58896"
style="font-size:16.9333px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#4d4d4d;stroke-width:0.264583"
transform="translate(-0.38486311,1.9008189)">
<path
d="m 15.348219,3.1412816 c -2.167926,0.2003778 -3.24418,1.4485057 -3.651956,2.078214 l -0.183409,0.3175001 c -0.01267,0.026458 -0.02096,0.044097 -0.02096,0.044097 l -0.0022,-0.00353 L 5.3599149,16.194095 H 13.003622 L 20.539697,3.1412816 h -5.191478"
style="fill:#f68330;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path30" />
<path
d="M 13.003622,16.194095 2.5842592,5.1401206 c 0,0 11.7850008,-3.1637113 12.9315288,6.7137144 l -2.512166,4.34026"
style="fill:#f68330;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path32" />
<path
d="m 11.460889,5.6273068 -3.1974364,5.5381882 4.7401694,5.0286 2.51079,-4.348409 C 15.117819,8.4488236 13.462092,6.5967402 11.460889,5.6273068"
style="fill:#f35e32;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path34" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

121
public/img/logo.svg Normal file
View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="500"
height="90"
viewBox="0 0 132.29167 23.812502"
version="1.1"
id="svg1203"
inkscape:version="1.1.1 (1:1.1+202109281944+c3084ef5ed)"
sodipodi:docname="logo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1205"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
width="650px"
units="px"
inkscape:zoom="1.4289282"
inkscape:cx="334.86637"
inkscape:cy="27.993009"
inkscape:window-width="2560"
inkscape:window-height="1335"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:snap-global="false" />
<defs
id="defs1200">
<inkscape:path-effect
effect="fillet_chamfer"
id="path-effect57379"
is_visible="true"
lpeversion="1"
satellites_param="F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1 @ F,0,0,1,0,4.4979167,0,1"
unit="px"
method="auto"
mode="F"
radius="17"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#ffe6d5;stroke:none;stroke-width:1.4928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4955"
width="43"
height="18.151592"
x="87.122803"
y="2.9803145"
inkscape:export-filename="/home/braginini/Documents/projects/my/wiretrustee/wiretrustee.com-nextjs/public/brand-assets/logo.png"
inkscape:export-xdpi="100"
inkscape:export-ydpi="100"
sodipodi:type="rect"
d="m 91.620719,2.9803145 34.004171,0 a 4.4979167,4.4979167 45 0 1 4.49791,4.4979167 V 16.63399 a 4.4979167,4.4979167 135 0 1 -4.49791,4.497917 H 91.620719 A 4.4979167,4.4979167 45 0 1 87.122803,16.63399 V 7.4782312 a 4.4979167,4.4979167 135 0 1 4.497916,-4.4979167 z"
inkscape:path-effect="#path-effect57379" />
<text
xml:space="preserve"
style="font-size:10.9361px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;stroke-width:0.264583"
x="92.88604"
y="15.806503"
id="text3179"><tspan
sodipodi:role="line"
id="tspan3177"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10.9361px;font-family:Poppins;-inkscape-font-specification:'Poppins Bold';fill:#fb923c;fill-opacity:1;stroke-width:0.264583"
x="92.88604"
y="15.806503">DOCS</tspan></text>
<text
xml:space="preserve"
style="font-size:16.9333px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#4d4d4d;stroke-width:0.0700042"
x="21.543421"
y="17.592438"
id="text1870"
inkscape:export-filename="/home/braginini/Downloads/netbird-logo-dark.png"
inkscape:export-xdpi="329.58896"
inkscape:export-ydpi="329.58896"><tspan
sodipodi:role="line"
id="tspan1868"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.9333px;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#4d4d4d;fill-opacity:1;stroke-width:0.0700042"
x="21.543421"
y="17.592438">netbird</tspan></text>
<g
id="g23427"
inkscape:export-filename="/home/braginini/Downloads/netbird-logo-dark.png"
inkscape:export-xdpi="329.58896"
inkscape:export-ydpi="329.58896"
style="font-size:16.9333px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;fill:#4d4d4d;stroke-width:0.264583"
transform="translate(-0.38486311,1.9008189)">
<path
d="m 15.348219,3.1412816 c -2.167926,0.2003778 -3.24418,1.4485057 -3.651956,2.078214 l -0.183409,0.3175001 c -0.01267,0.026458 -0.02096,0.044097 -0.02096,0.044097 l -0.0022,-0.00353 L 5.3599149,16.194095 H 13.003622 L 20.539697,3.1412816 h -5.191478"
style="fill:#f68330;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path30" />
<path
d="M 13.003622,16.194095 2.5842592,5.1401206 c 0,0 11.7850008,-3.1637113 12.9315288,6.7137144 l -2.512166,4.34026"
style="fill:#f68330;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path32" />
<path
d="m 11.460889,5.6273068 -3.1974364,5.5381882 4.7401694,5.0286 2.51079,-4.348409 C 15.117819,8.4488236 13.462092,6.5967402 11.460889,5.6273068"
style="fill:#f35e32;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0093339"
id="path34" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

Some files were not shown because too many files have changed in this diff Show More