add first version of tailwind docs
5333
generator/api-back.mdx
Normal file
23
generator/api.json/.swagger-codegen-ignore
Normal 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
|
||||
1
generator/api.json/.swagger-codegen/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
3.0.42
|
||||
0
generator/api.json/README.md
Normal file
4425
generator/api.mdx
Normal file
200
generator/api.ts
Normal 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
@@ -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
@@ -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
2105
generator/openapi.yml
Normal file
123
generator/templates/ApiTemplate.ts
Normal 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
|
||||
144
generator/templates/ApiTemplateBack.ts
Normal 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
@@ -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"]
|
||||
}
|
||||
34
generator/types/CliSpec.ts
Normal 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[]
|
||||
}
|
||||
36
generator/types/ConfigSpec.ts
Normal 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[]
|
||||
}
|
||||
75
generator/types/SdkSpec.ts
Normal 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
@@ -0,0 +1,6 @@
|
||||
import { Url } from 'url'
|
||||
|
||||
export type SpecLink = {
|
||||
name: string
|
||||
url: Url
|
||||
}
|
||||
8
jsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
19
mdx/recma.mjs
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
'postcss-focus-visible': {
|
||||
replaceWith: '[data-focus-visible-added]',
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
5
prettier.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
semi: false,
|
||||
plugins: [require('prettier-plugin-tailwindcss')],
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/architecture/acls.png
Normal file
|
After Width: | Height: | Size: 130 KiB |
BIN
public/img/architecture/high-level-dia.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/img/architecture/management.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
public/img/architecture/mesh.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
public/img/architecture/netbird-peer-auto-tagging-newkey.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
public/img/architecture/peer-auto-tagging-setupkey.gif
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/img/architecture/relay.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/img/architecture/setup-keys.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
public/img/architecture/signal.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/img/examples/wiretrustee-on-aws-ecs.png
Normal file
|
After Width: | Height: | Size: 222 KiB |
BIN
public/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
public/img/getting-started/add-peer.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
public/img/getting-started/auth.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
public/img/getting-started/device-confirmation.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/img/getting-started/empty-peers.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
public/img/getting-started/high-level-dia.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/img/getting-started/logo-full.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
public/img/getting-started/logo.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/img/getting-started/netbird-sso-login-cmd.gif
Normal file
|
After Width: | Height: | Size: 386 KiB |
BIN
public/img/getting-started/netbird-sso-login-ui.gif
Normal file
|
After Width: | Height: | Size: 327 KiB |
BIN
public/img/getting-started/netbird-up.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
public/img/getting-started/peerA.gif
Normal file
|
After Width: | Height: | Size: 409 KiB |
BIN
public/img/getting-started/peerB.gif
Normal file
|
After Width: | Height: | Size: 526 KiB |
BIN
public/img/getting-started/peers.gif
Normal file
|
After Width: | Height: | Size: 5.9 MiB |
BIN
public/img/getting-started/peers.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
public/img/getting-started/systray.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/img/how-to-guides/activity-monitoring.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
public/img/how-to-guides/individual-peer-login-expiration.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-add-button.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-all-group.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-custom.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 163 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-remote-resolver.png
Normal file
|
After Width: | Height: | Size: 152 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-remote-route.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-remote-rule.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 51 KiB |
BIN
public/img/how-to-guides/netbird-nameserver-selection-view.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-add-button.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-create-ha.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-create.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-masquerading.png
Normal file
|
After Width: | Height: | Size: 273 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-saved-new-ha.png
Normal file
|
After Width: | Height: | Size: 194 KiB |
BIN
public/img/how-to-guides/netbird-network-routes-saved-new.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
public/img/how-to-guides/netbird-network-routes.png
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
public/img/how-to-guides/peer-login-expiration.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
public/img/how-to-guides/peer-needs-login.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/img/how-to-guides/user-invites.gif
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
BIN
public/img/integrations/identity-providers/self-hosted/azure_api_scope.png
Executable file
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 670 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 63 KiB |
121
public/img/logo-dark.svg
Normal 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
@@ -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 |