mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Update docs module
This commit is contained in:
435
app/src/modules/docs/components/markdown.vue
Normal file
435
app/src/modules/docs/components/markdown.vue
Normal file
@@ -0,0 +1,435 @@
|
||||
<template>
|
||||
<div class="md" v-html="html" @click="onClick" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, watch, PropType, onMounted, onUpdated } from '@vue/composition-api';
|
||||
import marked, { Renderer } from 'marked';
|
||||
import highlight from 'highlight.js';
|
||||
|
||||
export default defineComponent({
|
||||
setup(props, { slots }) {
|
||||
const html = ref('');
|
||||
|
||||
onMounted(generateHTML);
|
||||
onUpdated(generateHTML);
|
||||
|
||||
return { html, onClick };
|
||||
|
||||
async function onClick($event: Event) {
|
||||
if ($event.target instanceof HTMLElement && $event.target.classList.contains('copy')) {
|
||||
await navigator.clipboard.writeText(
|
||||
window.location.href.split('#')[0] + $event.target.getAttribute('href')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function generateHTML() {
|
||||
if (slots.default === null || !slots.default()?.[0]?.text) {
|
||||
html.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let htmlString = slots.default()[0].text!;
|
||||
const hintRegex = /<p>:::(.*?) (.*?)\r?\n((\s|.)*?):::<\/p>/gm;
|
||||
|
||||
const renderer: Partial<Renderer> = {
|
||||
heading(text, level) {
|
||||
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
|
||||
|
||||
return `
|
||||
<h${level} id="${escapedText}">
|
||||
<a class="heading-link copy" href="#${escapedText}">#</a>
|
||||
${text}
|
||||
</h${level}>`;
|
||||
},
|
||||
};
|
||||
|
||||
// Marked merges it's default rendered with our extension. It's typed as a full rendered however
|
||||
marked.use({ renderer } as any);
|
||||
|
||||
htmlString = marked(htmlString, {
|
||||
highlight: (code, lang) => {
|
||||
return highlight.highlightAuto(code, [lang]).value;
|
||||
},
|
||||
});
|
||||
|
||||
htmlString = htmlString.replaceAll(
|
||||
hintRegex,
|
||||
(match: string, type: string, title: string, body: string) => {
|
||||
return `<div class="hint ${type}"><p class="hint-title">${title}</p><p class="hint-body">${body}</p></div>`;
|
||||
}
|
||||
);
|
||||
|
||||
html.value = htmlString;
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error {
|
||||
padding: 20vh 0;
|
||||
}
|
||||
|
||||
.md {
|
||||
::v-deep {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 27px;
|
||||
|
||||
& > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
& > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
position: relative;
|
||||
margin: 40px 0 8px;
|
||||
padding: 0;
|
||||
font-weight: 600;
|
||||
cursor: text;
|
||||
|
||||
a {
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
padding-right: 4px;
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover a {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 40px;
|
||||
font-size: 35px;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
font-size: 26px;
|
||||
line-height: 33px;
|
||||
border-bottom: 2px solid var(--border-subdued);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 0px;
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
color: var(--foreground-normal);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 16px 20px;
|
||||
overflow: auto;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
code,
|
||||
tt {
|
||||
margin: 0 1px;
|
||||
padding: 0 4px;
|
||||
font-size: 15px;
|
||||
font-family: var(--family-monospace);
|
||||
white-space: nowrap;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
pre code {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
pre code,
|
||||
pre tt {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
h1 tt,
|
||||
h1 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h2 tt,
|
||||
h2 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h3 tt,
|
||||
h3 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h4 tt,
|
||||
h4 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h5 tt,
|
||||
h5 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h6 tt,
|
||||
h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
p,
|
||||
blockquote,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
li,
|
||||
table,
|
||||
pre {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
|
||||
h3 + p {
|
||||
margin-block-start: 0.5em;
|
||||
}
|
||||
|
||||
& > h2:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
& > h1:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
& > h3:first-child,
|
||||
& > h4:first-child,
|
||||
& > h5:first-child,
|
||||
& > h6:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
a:first-child h1,
|
||||
a:first-child h2,
|
||||
a:first-child h3,
|
||||
a:first-child h4,
|
||||
a:first-child h5,
|
||||
a:first-child h6 {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h1 p,
|
||||
h2 p,
|
||||
h3 p,
|
||||
h4 p,
|
||||
h5 p,
|
||||
h6 p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 20px 0;
|
||||
padding-left: 20px;
|
||||
|
||||
li {
|
||||
margin: 8px 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 4px 0;
|
||||
|
||||
li {
|
||||
margin: 4px 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 0 20px;
|
||||
color: var(--foreground-subdued);
|
||||
font-size: 18px;
|
||||
border-left: 2px solid var(--background-normal);
|
||||
}
|
||||
|
||||
blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 100%;
|
||||
margin: 40px 0;
|
||||
padding: 0;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
table tr {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: white;
|
||||
border-top: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: var(--background-page);
|
||||
}
|
||||
|
||||
table tr th {
|
||||
margin: 0;
|
||||
padding: 8px 20px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
border: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr td {
|
||||
margin: 0;
|
||||
padding: 8px 20px;
|
||||
text-align: left;
|
||||
border: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr th :first-child,
|
||||
table tr td :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
table tr th :last-child,
|
||||
table tr td :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
margin: 20px 0;
|
||||
|
||||
&.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.shadow {
|
||||
box-shadow: 0px 5px 10px 0px rgba(23, 41, 64, 0.1), 0px 2px 40px 0px rgba(23, 41, 64, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.highlight pre {
|
||||
padding: 8px 20px;
|
||||
overflow: auto;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 40px auto;
|
||||
border: none;
|
||||
border-top: 2px solid var(--background-normal);
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hint {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
padding: 0 20px;
|
||||
background-color: var(--background-subdued);
|
||||
border-left: 2px solid var(--primary);
|
||||
|
||||
&-title {
|
||||
margin-bottom: 0.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-body {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
&.tip {
|
||||
border-left: 2px solid var(--success);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: var(--warning-10);
|
||||
border-left: 2px solid var(--warning);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: var(--danger-10);
|
||||
border-left: 2px solid var(--danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,20 +1,6 @@
|
||||
<template>
|
||||
<v-list-item v-if="section.children === undefined" :to="section.to" :dense="dense" :subdued="subdued">
|
||||
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-text>{{ section.name }}</v-list-item-text>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<div v-else-if="section.flat === true">
|
||||
<v-divider></v-divider>
|
||||
<navigation-list-item
|
||||
v-for="(childSection, index) in section.children"
|
||||
:key="index"
|
||||
:section="childSection"
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<v-list-group v-else>
|
||||
<v-divider v-if="section.divider" />
|
||||
<v-list-group v-else-if="section.children" :dense="dense">
|
||||
<template #activator>
|
||||
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
@@ -28,48 +14,30 @@
|
||||
dense
|
||||
/>
|
||||
</v-list-group>
|
||||
|
||||
<v-list-item v-else :to="`/docs${section.to}`" :dense="dense">
|
||||
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-text>{{ section.name }}</v-list-item-text>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from '@vue/composition-api';
|
||||
import { Section } from './sections';
|
||||
import { Link, Group } from '@directus/docs';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'navigation-list-item',
|
||||
props: {
|
||||
section: {
|
||||
type: Object as PropType<Section>,
|
||||
type: Object as PropType<Link | Group>,
|
||||
default: null,
|
||||
},
|
||||
dense: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
subdued: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.version {
|
||||
.v-icon {
|
||||
color: var(--foreground-subdued);
|
||||
transition: color var(--fast) var(--transition);
|
||||
}
|
||||
::v-deep .type-text {
|
||||
color: var(--foreground-subdued);
|
||||
transition: color var(--fast) var(--transition);
|
||||
}
|
||||
&:hover {
|
||||
.v-icon {
|
||||
color: var(--foreground-normal);
|
||||
}
|
||||
::v-deep .type-text {
|
||||
color: var(--foreground-normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<v-list large>
|
||||
<navigation-item v-for="item in sections" :key="item.to" :section="item"></navigation-item>
|
||||
<navigation-item v-for="item in navSections" :key="item.name" :section="item" />
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
import { defineComponent, PropType, computed } from '@vue/composition-api';
|
||||
import NavigationItem from './navigation-item.vue';
|
||||
import sections from './sections';
|
||||
import { nav } from '@directus/docs';
|
||||
|
||||
export default defineComponent({
|
||||
components: { NavigationItem },
|
||||
setup() {
|
||||
return { sections };
|
||||
return { navSections: nav.app };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
export type Section = {
|
||||
name: string;
|
||||
to: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
sectionIcon?: string;
|
||||
sectionName?: string;
|
||||
children?: Section[];
|
||||
default?: string;
|
||||
flat?: boolean;
|
||||
};
|
||||
|
||||
export const defaultSection = '/docs/getting-started/introduction';
|
||||
|
||||
const sections: Section[] = [
|
||||
{
|
||||
icon: 'play_arrow',
|
||||
name: 'Getting Started',
|
||||
to: '/docs/getting-started',
|
||||
default: '',
|
||||
children: [
|
||||
{
|
||||
name: 'Introduction',
|
||||
to: '/docs/getting-started/introduction',
|
||||
},
|
||||
{
|
||||
name: 'Support & FAQ',
|
||||
to: '/docs/getting-started/support',
|
||||
},
|
||||
{
|
||||
name: 'Contributing',
|
||||
to: '/docs/getting-started/contributing',
|
||||
},
|
||||
{
|
||||
name: 'Backing Directus',
|
||||
to: '/docs/getting-started/backing-directus',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'school',
|
||||
name: 'Concepts',
|
||||
to: '/docs/concepts',
|
||||
default: 'readme',
|
||||
children: [
|
||||
{
|
||||
name: 'Platform Overview',
|
||||
to: '/docs/concepts/platform-overview',
|
||||
},
|
||||
{
|
||||
name: 'App Overview',
|
||||
to: '/docs/concepts/app-overview',
|
||||
},
|
||||
{
|
||||
name: 'App Extensions',
|
||||
to: '/docs/concepts/app-extensions',
|
||||
},
|
||||
{
|
||||
name: 'Activity & Versions',
|
||||
to: '/docs/concepts/activity-and-versions',
|
||||
},
|
||||
{
|
||||
name: 'Files & Thumbnails',
|
||||
to: '/docs/concepts/files-and-thumbnails',
|
||||
},
|
||||
{
|
||||
name: 'Internationalization',
|
||||
to: '/docs/concepts/internationalization',
|
||||
},
|
||||
{
|
||||
name: 'Relationships',
|
||||
to: '/docs/concepts/relationships',
|
||||
},
|
||||
{
|
||||
name: 'Users, Roles & Permissions',
|
||||
to: '/docs/concepts/users-roles-and-permissions',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'article',
|
||||
name: 'Guides',
|
||||
to: '/docs/guides',
|
||||
default: 'readme',
|
||||
children: [
|
||||
{
|
||||
name: 'Collections',
|
||||
to: '/docs/guides/collections',
|
||||
},
|
||||
{
|
||||
name: 'Fields',
|
||||
to: '/docs/guides/fields',
|
||||
},
|
||||
{
|
||||
name: 'Presets',
|
||||
to: '/docs/guides/presets',
|
||||
},
|
||||
{
|
||||
name: 'Projects',
|
||||
to: '/docs/guides/projects',
|
||||
},
|
||||
{
|
||||
name: 'Roles & Permissions',
|
||||
to: '/docs/guides/roles-and-permissions',
|
||||
},
|
||||
{
|
||||
name: 'Users',
|
||||
to: '/docs/guides/users',
|
||||
},
|
||||
{
|
||||
name: 'Webhooks',
|
||||
to: '/docs/guides/webhooks',
|
||||
},
|
||||
{
|
||||
name: 'White-Labeling',
|
||||
to: '/docs/guides/white-labeling',
|
||||
},
|
||||
{
|
||||
name: 'Extensions',
|
||||
to: '/docs/guides/extensions',
|
||||
children: [
|
||||
{
|
||||
name: 'Custom Displays',
|
||||
to: '/docs/guides/extensions/creating-a-custom-display',
|
||||
},
|
||||
{
|
||||
name: 'Custom Interfaces',
|
||||
to: '/docs/guides/extensions/creating-a-custom-interface',
|
||||
},
|
||||
{
|
||||
name: 'Custom Layouts',
|
||||
to: '/docs/guides/extensions/creating-a-custom-layout',
|
||||
},
|
||||
{
|
||||
name: 'Custom Modules',
|
||||
to: '/docs/guides/extensions/creating-a-custom-module',
|
||||
},
|
||||
{
|
||||
name: 'Custom API Endpoints',
|
||||
to: '/docs/guides/extensions/creating-a-custom-api-endpoint',
|
||||
},
|
||||
{
|
||||
name: 'Custom API Hooks',
|
||||
to: '/docs/guides/extensions/creating-a-custom-api-hook',
|
||||
},
|
||||
{
|
||||
name: 'Custom Email Templates',
|
||||
to: '/docs/guides/extensions/creating-a-custom-email-template',
|
||||
},
|
||||
{
|
||||
name: 'Custom Storage Adapters',
|
||||
to: '/docs/guides/extensions/creating-a-custom-storage-adapter',
|
||||
},
|
||||
{
|
||||
name: 'Accessing Data',
|
||||
to: '/docs/guides/extensions/accessing-data',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'code',
|
||||
name: 'Reference',
|
||||
to: '/docs/reference',
|
||||
default: 'readme',
|
||||
children: [
|
||||
{
|
||||
name: 'Environment Variables',
|
||||
to: '/docs/reference/environment-variables',
|
||||
},
|
||||
{
|
||||
name: 'Command Line Interface',
|
||||
to: '/docs/reference/command-line-interface',
|
||||
},
|
||||
{
|
||||
name: 'Error Codes',
|
||||
to: '/docs/reference/error-codes',
|
||||
},
|
||||
{
|
||||
name: 'Item Rules',
|
||||
to: '/docs/reference/item-rules',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default sections;
|
||||
26
app/src/modules/docs/composables/use-spec.ts
Normal file
26
app/src/modules/docs/composables/use-spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import api from '@/api';
|
||||
import { ref } from '@vue/composition-api';
|
||||
import { OpenAPIObject } from 'openapi3-ts';
|
||||
|
||||
const spec = ref<OpenAPIObject>();
|
||||
const loading = ref(false);
|
||||
const error = ref<any>(null);
|
||||
|
||||
export function useSpec() {
|
||||
if (loading.value === false && !spec.value) fetchOAS();
|
||||
|
||||
return { spec, loading, error };
|
||||
|
||||
async function fetchOAS() {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const response = await api.get('/server/specs/oas');
|
||||
spec.value = response.data.data;
|
||||
} catch (err) {
|
||||
error.value = err;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,49 @@
|
||||
import { defineModule } from '@/modules/define';
|
||||
import Docs from './routes/docs.vue';
|
||||
import sections, { Section, defaultSection } from './components/sections';
|
||||
import { Route } from 'vue-router';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { RouteConfig } from 'vue-router';
|
||||
import { files, Directory } from '@directus/docs';
|
||||
import StaticDocs from './routes/static.vue';
|
||||
import NotFound from './routes/not-found.vue';
|
||||
|
||||
function urlSplitter(url: string) {
|
||||
if (url.startsWith('/docs')) url = url.replace('/docs', '');
|
||||
if (url.startsWith('/')) url = url.substr(1);
|
||||
return url.split('/');
|
||||
}
|
||||
|
||||
function urlToSection(urlSections: string[], sections: Section[]): Section | null {
|
||||
let section = sections.find((s) => urlSplitter(s.to).pop() === urlSections[0]);
|
||||
|
||||
if (section === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
section = cloneDeep(section);
|
||||
|
||||
if (urlSections.length === 1) {
|
||||
let finalSection = section;
|
||||
while (finalSection.children !== undefined) {
|
||||
finalSection = finalSection.children[0];
|
||||
}
|
||||
if (section.icon) finalSection.icon = section.icon;
|
||||
if (finalSection.sectionName === undefined) finalSection.sectionName = section.name;
|
||||
return finalSection;
|
||||
}
|
||||
|
||||
if (section.children === undefined) return null;
|
||||
|
||||
const sectionDeep = urlToSection(urlSections.slice(1), section.children);
|
||||
|
||||
if (sectionDeep !== null && sectionDeep.sectionName === undefined) {
|
||||
sectionDeep.sectionName = section.name;
|
||||
}
|
||||
|
||||
if (
|
||||
sectionDeep !== null &&
|
||||
sectionDeep.icon === undefined &&
|
||||
sectionDeep.sectionIcon === undefined &&
|
||||
section.icon !== undefined
|
||||
)
|
||||
sectionDeep.sectionIcon = section.icon;
|
||||
return sectionDeep;
|
||||
}
|
||||
|
||||
function props(route: Route) {
|
||||
const section = urlToSection(urlSplitter(route.path), sections);
|
||||
return { section };
|
||||
}
|
||||
|
||||
export default defineModule(({ i18n }) => ({
|
||||
id: 'docs',
|
||||
name: i18n.t('documentation'),
|
||||
icon: 'info',
|
||||
routes: [
|
||||
export default defineModule(({ i18n }) => {
|
||||
const routes: RouteConfig[] = [
|
||||
{
|
||||
path: '/',
|
||||
component: StaticDocs,
|
||||
},
|
||||
...parseRoutes(files),
|
||||
{
|
||||
path: '/*',
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (to.path === '/docs/') next(defaultSection);
|
||||
else next();
|
||||
},
|
||||
component: Docs,
|
||||
props: props,
|
||||
component: NotFound,
|
||||
},
|
||||
],
|
||||
order: 20,
|
||||
}));
|
||||
];
|
||||
|
||||
return {
|
||||
id: 'docs',
|
||||
name: i18n.t('documentation'),
|
||||
icon: 'info',
|
||||
routes,
|
||||
order: 20,
|
||||
};
|
||||
|
||||
function parseRoutes(directory: Directory): RouteConfig[] {
|
||||
const routes: RouteConfig[] = [];
|
||||
|
||||
for (const doc of directory.children) {
|
||||
if (doc.type === 'file') {
|
||||
routes.push({
|
||||
path: '/' + doc.path.replace('.md', ''),
|
||||
component: StaticDocs,
|
||||
});
|
||||
} else if (doc.type === 'directory') {
|
||||
routes.push({
|
||||
path: '/' + doc.path,
|
||||
redirect: '/' + doc.children![0].path.replace('.md', ''),
|
||||
});
|
||||
|
||||
routes.push(...parseRoutes(doc));
|
||||
}
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<private-view :title="notFound ? $t('page_not_found') : title">
|
||||
<template #headline>{{ $t('documentation') }}</template>
|
||||
|
||||
<template #title-outer:prepend>
|
||||
<v-button rounded disabled icon>
|
||||
<v-icon :name="isAPIReference ? 'code' : section.icon || section.sectionIcon" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #navigation>
|
||||
<docs-navigation />
|
||||
</template>
|
||||
|
||||
<div v-if="notFound" class="not-found">
|
||||
<v-info :title="$t('page_not_found')" icon="not_interested">
|
||||
{{ $t('page_not_found_body') }}
|
||||
</v-info>
|
||||
</div>
|
||||
|
||||
<markdown v-else>{{ mdString }}</markdown>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, watch, PropType } from '@vue/composition-api';
|
||||
import DocsNavigation from '../components/navigation.vue';
|
||||
import { Section } from '../components/sections';
|
||||
import Markdown from './markdown.vue';
|
||||
import i18n from '@/lang';
|
||||
|
||||
declare module '*.md';
|
||||
|
||||
export default defineComponent({
|
||||
components: { DocsNavigation, Markdown },
|
||||
props: {
|
||||
section: {
|
||||
type: Object as PropType<Section>,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const mdString = ref<string | null>(null);
|
||||
const loading = ref(true);
|
||||
const error = ref(null);
|
||||
|
||||
const isAPIReference = computed(() => props.section && props.section.to.startsWith('/docs/api-reference'));
|
||||
const notFound = computed(() => {
|
||||
return props.section === null || error.value !== null;
|
||||
});
|
||||
|
||||
const title = computed(() => {
|
||||
return isAPIReference.value ? i18n.t('api_reference') : props.section.sectionName;
|
||||
});
|
||||
|
||||
watch(() => props.section, loadMD, { immediate: true });
|
||||
|
||||
return { isAPIReference, notFound, title, mdString };
|
||||
|
||||
async function loadMD() {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
|
||||
if (props.section === null) {
|
||||
mdString.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const loadString = props.section.to.replace('/docs', '');
|
||||
|
||||
try {
|
||||
const md = await import(`raw-loader!@directus/docs${loadString}.md`);
|
||||
mdString.value = md.default;
|
||||
} catch (err) {
|
||||
mdString.value = null;
|
||||
error.value = err;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.v-info {
|
||||
padding: 20vh 0;
|
||||
}
|
||||
|
||||
.not-found {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20vh 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,407 +0,0 @@
|
||||
<template>
|
||||
<div class="docs selectable">
|
||||
<div class="md" v-html="html" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, watch, PropType, onMounted, onUpdated } from '@vue/composition-api';
|
||||
import marked from 'marked';
|
||||
import highlight from 'highlight.js';
|
||||
import 'highlight.js/styles/github.css'
|
||||
|
||||
export default defineComponent({
|
||||
setup(props, { slots }) {
|
||||
const html = ref('');
|
||||
|
||||
onMounted(generateHTML);
|
||||
onUpdated(generateHTML);
|
||||
|
||||
return { html };
|
||||
|
||||
function generateHTML() {
|
||||
if (slots.default === null || !slots.default()?.[0]?.text) {
|
||||
html.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let htmlString = slots.default()[0].text!;
|
||||
const hintRegex = /<p>:::(.*?) (.*?)\r?\n((\s|.)*?):::<\/p>/gm;
|
||||
|
||||
htmlString = marked(htmlString, {
|
||||
highlight: (code, lang) => {
|
||||
return highlight.highlightAuto(code, [lang]).value
|
||||
},
|
||||
});
|
||||
|
||||
htmlString = htmlString.replaceAll(
|
||||
hintRegex,
|
||||
(match: string, type: string, title: string, body: string) => {
|
||||
return `<div class="hint ${type}"><p class="hint-title">${title}</p><p class="hint-body">${body}</p></div>`;
|
||||
}
|
||||
);
|
||||
|
||||
html.value = htmlString;
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.error {
|
||||
padding: 20vh 0;
|
||||
}
|
||||
|
||||
.docs {
|
||||
padding: 0 var(--content-padding) var(--content-padding-bottom);
|
||||
|
||||
.md {
|
||||
max-width: 740px;
|
||||
|
||||
::v-deep {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 27px;
|
||||
|
||||
& > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
& > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
position: relative;
|
||||
margin: 40px 0 8px;
|
||||
padding: 0;
|
||||
font-weight: 600;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 40px;
|
||||
font-size: 35px;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
font-size: 26px;
|
||||
line-height: 33px;
|
||||
border-bottom: 2px solid var(--border-subdued);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 0px;
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
color: var(--foreground-normal);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 16px 20px;
|
||||
overflow: auto;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
code,
|
||||
tt {
|
||||
margin: 0 1px;
|
||||
padding: 0 4px;
|
||||
font-family: var(--family-monospace);
|
||||
font-size: 15px;
|
||||
white-space: nowrap;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
pre code {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
pre code,
|
||||
pre tt {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
h1 tt,
|
||||
h1 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h2 tt,
|
||||
h2 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h3 tt,
|
||||
h3 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h4 tt,
|
||||
h4 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
h5 tt,
|
||||
h5 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
h6 tt,
|
||||
h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
p,
|
||||
blockquote,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
li,
|
||||
table,
|
||||
pre {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
|
||||
h3 + p {
|
||||
margin-block-start: 0.5em;
|
||||
}
|
||||
|
||||
& > h2:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
& > h1:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
& > h3:first-child,
|
||||
& > h4:first-child,
|
||||
& > h5:first-child,
|
||||
& > h6:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
a:first-child h1,
|
||||
a:first-child h2,
|
||||
a:first-child h3,
|
||||
a:first-child h4,
|
||||
a:first-child h5,
|
||||
a:first-child h6 {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h1 p,
|
||||
h2 p,
|
||||
h3 p,
|
||||
h4 p,
|
||||
h5 p,
|
||||
h6 p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 20px 0;
|
||||
padding-left: 20px;
|
||||
|
||||
li {
|
||||
margin: 8px 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 4px 0;
|
||||
|
||||
li {
|
||||
margin: 4px 0;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-size: 18px;
|
||||
padding: 0 20px;
|
||||
color: var(--foreground-subdued);
|
||||
border-left: 2px solid var(--background-normal);
|
||||
}
|
||||
|
||||
blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 100%;
|
||||
margin: 40px 0;
|
||||
padding: 0;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
table tr {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: white;
|
||||
border-top: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: var(--background-page);
|
||||
}
|
||||
|
||||
table tr th {
|
||||
margin: 0;
|
||||
padding: 8px 20px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
border: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr td {
|
||||
margin: 0;
|
||||
padding: 8px 20px;
|
||||
text-align: left;
|
||||
border: 1px solid var(--background-normal);
|
||||
}
|
||||
|
||||
table tr th :first-child,
|
||||
table tr td :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
table tr th :last-child,
|
||||
table tr td :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
margin: 20px 0;
|
||||
|
||||
&.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.shadow {
|
||||
box-shadow: 0px 5px 10px 0px rgba(23,41,64,0.1),
|
||||
0px 2px 40px 0px rgba(23,41,64,0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.highlight pre {
|
||||
padding: 8px 20px;
|
||||
overflow: auto;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
background-color: var(--background-page);
|
||||
border: 1px solid var(--background-normal);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 40px auto;
|
||||
border: none;
|
||||
border-top: 2px solid var(--background-normal);
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hint {
|
||||
display: inline-block;
|
||||
margin: 20px 0;
|
||||
padding: 0 20px;
|
||||
background-color: var(--background-subdued);
|
||||
border-left: 2px solid var(--primary);
|
||||
width: 100%;
|
||||
|
||||
&-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
&-body {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
&.tip {
|
||||
border-left: 2px solid var(--success);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: var(--warning-10);
|
||||
border-left: 2px solid var(--warning);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: var(--danger-10);
|
||||
border-left: 2px solid var(--danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
13
app/src/modules/docs/routes/not-found.vue
Normal file
13
app/src/modules/docs/routes/not-found.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<private-view>
|
||||
<div>Not Found</div>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NotFound',
|
||||
});
|
||||
</script>
|
||||
84
app/src/modules/docs/routes/static.vue
Normal file
84
app/src/modules/docs/routes/static.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<private-view :title="title">
|
||||
<template #headline>Documentation</template>
|
||||
|
||||
<template #title-outer:prepend>
|
||||
<v-button rounded disabled icon>
|
||||
<v-icon name="info" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #navigation>
|
||||
<docs-navigation />
|
||||
</template>
|
||||
|
||||
<div class="content selectable">
|
||||
<markdown>{{ markdownWithoutTitle }}</markdown>
|
||||
</div>
|
||||
</private-view>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from '@vue/composition-api';
|
||||
import DocsNavigation from '../components/navigation.vue';
|
||||
import Markdown from '../components/markdown.vue';
|
||||
|
||||
async function getMarkdownForPath(path: string) {
|
||||
const pathParts = path.split('/');
|
||||
|
||||
while (pathParts.includes('docs')) {
|
||||
pathParts.shift();
|
||||
}
|
||||
|
||||
let docsPath = pathParts.join('/');
|
||||
|
||||
// Home
|
||||
if (!docsPath) {
|
||||
docsPath = 'readme';
|
||||
}
|
||||
|
||||
const mdModule = await import('raw-loader!@directus/docs/' + docsPath + '.md');
|
||||
|
||||
return mdModule.default;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'StaticDocs',
|
||||
components: { DocsNavigation, Markdown },
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
const md = await getMarkdownForPath(to.path);
|
||||
|
||||
next((vm) => {
|
||||
(vm as any).markdown = md;
|
||||
});
|
||||
},
|
||||
async beforeRouteUpdate(to, from, next) {
|
||||
this.markdown = await getMarkdownForPath(to.path);
|
||||
|
||||
next();
|
||||
},
|
||||
setup() {
|
||||
const markdown = ref('');
|
||||
|
||||
const title = computed(() => {
|
||||
const firstLine = markdown.value.split('\n').shift();
|
||||
return firstLine?.substring(2).trim();
|
||||
});
|
||||
|
||||
const markdownWithoutTitle = computed(() => {
|
||||
const lines = markdown.value.split('\n');
|
||||
lines.shift();
|
||||
return lines.join('\n');
|
||||
});
|
||||
|
||||
return { markdown, title, markdownWithoutTitle };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
max-width: 740px;
|
||||
padding: 0 var(--content-padding) var(--content-padding-bottom);
|
||||
}
|
||||
</style>
|
||||
147
package-lock.json
generated
147
package-lock.json
generated
@@ -1453,7 +1453,6 @@
|
||||
"mitt": "^2.1.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"nanoid": "^3.1.10",
|
||||
"openapi3-ts": "^1.4.0",
|
||||
"pinia": "^0.0.7",
|
||||
"portal-vue": "^2.1.7",
|
||||
"pretty-ms": "^7.0.0",
|
||||
@@ -7383,6 +7382,13 @@
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
@@ -7420,6 +7426,83 @@
|
||||
"worker-rpc": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"fork-ts-checker-webpack-plugin-v5": {
|
||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.0.tgz",
|
||||
"integrity": "sha512-NEKcI0+osT5bBFZ1SFGzJMQETjQWZrSvMO1g0nAR/w0t328Z41eN8BJEIZyFCl2HsuiJpa9AN474Nh2qLVwGLQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"chalk": "^4.1.0",
|
||||
"cosmiconfig": "^6.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fs-extra": "^9.0.0",
|
||||
"memfs": "^3.1.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"schema-utils": "2.7.0",
|
||||
"semver": "^7.3.2",
|
||||
"tapable": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globby": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
|
||||
@@ -7465,6 +7548,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"ajv": "^6.12.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
@@ -17457,51 +17552,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fork-ts-checker-webpack-plugin-v5": {
|
||||
"version": "npm:fork-ts-checker-webpack-plugin@5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.0.tgz",
|
||||
"integrity": "sha512-NEKcI0+osT5bBFZ1SFGzJMQETjQWZrSvMO1g0nAR/w0t328Z41eN8BJEIZyFCl2HsuiJpa9AN474Nh2qLVwGLQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.8.3",
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"chalk": "^4.1.0",
|
||||
"cosmiconfig": "^6.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fs-extra": "^9.0.0",
|
||||
"memfs": "^3.1.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"schema-utils": "2.7.0",
|
||||
"semver": "^7.3.2",
|
||||
"tapable": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"ajv": "^6.12.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
@@ -26347,11 +26397,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"openapi3-ts": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-1.4.0.tgz",
|
||||
"integrity": "sha512-8DmE2oKayvSkIR3XSZ4+pRliBsx19bSNeIzkTPswY8r4wvjX86bMxsORdqwAwMxE8PefOcSAT2auvi/0TZe9yA=="
|
||||
},
|
||||
"opencollective-postinstall": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||
|
||||
Reference in New Issue
Block a user