@clidey/dory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +4 -0
- package/.github/ISSUE_TEMPLATE/anything-else.md +10 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/dependabot.yml +11 -0
- package/.github/workflows/claude.yml +37 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +91 -0
- package/LICENSE +201 -0
- package/README.md +185 -0
- package/SECURITY.md +11 -0
- package/assets/dory_logo.png +0 -0
- package/bin/dory.js +131 -0
- package/docs/README.md +2 -0
- package/docs/configuration/app-settings/feature-flags.mdx +157 -0
- package/docs/configuration/app-settings/user-settings.mdx +201 -0
- package/docs/configuration/installation-setup/env-vars.mdx +198 -0
- package/docs/configuration/installation-setup/installation.mdx +127 -0
- package/docs/dory.json +162 -0
- package/docs/integrations/analytics-monitoring/error-tracking.mdx +199 -0
- package/docs/integrations/analytics-monitoring/notifications.mdx +189 -0
- package/docs/integrations/analytics-monitoring/user-analytics.mdx +182 -0
- package/docs/integrations/shopify-integration/shopify-setup.mdx +226 -0
- package/docs/integrations/shopify-integration/shopify-webhooks.mdx +207 -0
- package/docs/overview/developer-overview/dev-architecture.mdx +292 -0
- package/docs/overview/product-intro/app-overview.mdx +167 -0
- package/docs/overview/product-intro/architecture.mdx +203 -0
- package/docs/overview/product-intro/core-concepts.mdx +267 -0
- package/docs/platform-admin/billing-subscriptions/billing.mdx +176 -0
- package/docs/platform-admin/system-maintenance/db-migrations.mdx +184 -0
- package/docs/platform-admin/system-maintenance/health-monitoring.mdx +222 -0
- package/docs/platform-admin/system-maintenance/queue-management.mdx +234 -0
- package/docs/platform-admin/user-team-management/teams.mdx +170 -0
- package/docs/platform-admin/user-team-management/users.mdx +185 -0
- package/docs/support/legal/dependency-analysis.mdx +132 -0
- package/docs/support/legal/privacy-terms.mdx +73 -0
- package/docs/support/troubleshooting/common-issues.mdx +159 -0
- package/docs/usage/api-usage/api-inventory.mdx +213 -0
- package/docs/usage/api-usage/api-products.mdx +249 -0
- package/docs/usage/api-usage/api-purchase-orders.mdx +289 -0
- package/docs/usage/api-usage/api-reports.mdx +227 -0
- package/docs/usage/api-usage/api-suppliers.mdx +171 -0
- package/docs/usage/api-usage/api-user-management.mdx +171 -0
- package/docs/usage/ui-workflows/bundles.mdx +157 -0
- package/docs/usage/ui-workflows/demand-planning.mdx +210 -0
- package/docs/usage/ui-workflows/favorites.mdx +167 -0
- package/docs/usage/ui-workflows/inventory-management.mdx +179 -0
- package/docs/usage/ui-workflows/onboarding.mdx +215 -0
- package/docs/usage/ui-workflows/purchase-orders.mdx +200 -0
- package/docs/usage/ui-workflows/reports.mdx +257 -0
- package/index.html +54 -0
- package/k8s/Dockerfile +15 -0
- package/k8s/config/nginx-default.conf +22 -0
- package/k8s/dev.Dockerfile +16 -0
- package/package.json +71 -0
- package/src/app.css +3 -0
- package/src/app.tsx +13 -0
- package/src/components/dark-mode-toggle.tsx +25 -0
- package/src/components/dropdown.tsx +49 -0
- package/src/components/hooks.tsx +28 -0
- package/src/components/loading.tsx +23 -0
- package/src/components/mdx-provider.tsx +13 -0
- package/src/components/navigation.tsx +53 -0
- package/src/components/notification.tsx +97 -0
- package/src/components/routes.tsx +89 -0
- package/src/components/search-index.ts +43 -0
- package/src/components/search.tsx +508 -0
- package/src/components/store.ts +144 -0
- package/src/index.css +24 -0
- package/src/main.tsx +18 -0
- package/src/mdx/accordion.tsx +48 -0
- package/src/mdx/api-playground.tsx +674 -0
- package/src/mdx/api.tsx +354 -0
- package/src/mdx/callout.tsx +80 -0
- package/src/mdx/card.tsx +48 -0
- package/src/mdx/code.tsx +289 -0
- package/src/mdx/expandable.tsx +40 -0
- package/src/mdx/fence.tsx +73 -0
- package/src/mdx/icon.tsx +73 -0
- package/src/mdx/latex.tsx +26 -0
- package/src/mdx/list.tsx +7 -0
- package/src/mdx/mdx.tsx +43 -0
- package/src/mdx/mermaid.tsx +102 -0
- package/src/mdx/open-api.tsx +325 -0
- package/src/mdx/source.tsx +47 -0
- package/src/mdx/step.tsx +49 -0
- package/src/mdx/table.tsx +15 -0
- package/src/mdx/tag.tsx +66 -0
- package/src/mdx/text.tsx +98 -0
- package/src/plugins/sanitize.ts +15 -0
- package/src/theme.scss +124 -0
- package/src/ui/header.tsx +88 -0
- package/src/ui/layout.tsx +167 -0
- package/src/ui/mobile-navigation.tsx +91 -0
- package/src/ui/prev-next-link.tsx +74 -0
- package/src/ui/table-of-content.tsx +166 -0
- package/src/utils/fonts.ts +20 -0
- package/src/utils/functions.ts +12 -0
- package/src/utils/hooks.ts +46 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.app.json +32 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +25 -0
- package/vite.config.ts +27 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
|
|
4
|
+
export type Section = {
|
|
5
|
+
id: string
|
|
6
|
+
title: string
|
|
7
|
+
children: Array<Subsection>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type Subsection = {
|
|
11
|
+
id: string
|
|
12
|
+
title: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function TableOfContents() {
|
|
16
|
+
const [currentSection, setCurrentSection] = useState<string>('')
|
|
17
|
+
const [sections, setSections] = useState<Section[]>([])
|
|
18
|
+
const [isContentLoaded, setIsContentLoaded] = useState(false)
|
|
19
|
+
|
|
20
|
+
const collectHeadings = useCallback(() => {
|
|
21
|
+
const article = document.querySelector('article')
|
|
22
|
+
if (!article) return
|
|
23
|
+
|
|
24
|
+
// Wait for content to be loaded
|
|
25
|
+
const observer = new MutationObserver(() => {
|
|
26
|
+
const headings = article.querySelectorAll('h2:not([style*="display: none"]), h3:not([style*="display: none"])')
|
|
27
|
+
const sections: Section[] = []
|
|
28
|
+
let currentSection: Section | null = null
|
|
29
|
+
|
|
30
|
+
headings.forEach((heading) => {
|
|
31
|
+
// Check if heading is visible
|
|
32
|
+
const style = window.getComputedStyle(heading)
|
|
33
|
+
if (style.display === 'none' || style.visibility === 'hidden') return
|
|
34
|
+
|
|
35
|
+
const id = heading.id || heading.textContent?.toLowerCase().replace(/\s+/g, '-') || ''
|
|
36
|
+
heading.id = id
|
|
37
|
+
|
|
38
|
+
if (heading.tagName === 'H2') {
|
|
39
|
+
currentSection = {
|
|
40
|
+
id,
|
|
41
|
+
title: heading.textContent || '',
|
|
42
|
+
children: []
|
|
43
|
+
}
|
|
44
|
+
sections.push(currentSection)
|
|
45
|
+
} else if (heading.tagName === 'H3' && currentSection) {
|
|
46
|
+
currentSection.children.push({
|
|
47
|
+
id,
|
|
48
|
+
title: heading.textContent || ''
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
setSections(sections)
|
|
54
|
+
setIsContentLoaded(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
observer.observe(article, {
|
|
58
|
+
childList: true,
|
|
59
|
+
subtree: true,
|
|
60
|
+
attributes: true,
|
|
61
|
+
attributeFilter: ['style', 'class']
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return () => observer.disconnect()
|
|
65
|
+
}, [])
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const cleanup = collectHeadings()
|
|
69
|
+
return () => cleanup?.()
|
|
70
|
+
}, [collectHeadings])
|
|
71
|
+
|
|
72
|
+
const getHeadings = useCallback(() => {
|
|
73
|
+
return sections
|
|
74
|
+
.flatMap((section) => [section.id, ...section.children.map((child) => child.id)])
|
|
75
|
+
.map((id) => {
|
|
76
|
+
const el = document.getElementById(id)
|
|
77
|
+
if (!el) return null
|
|
78
|
+
const top = window.scrollY + el.getBoundingClientRect().top
|
|
79
|
+
return { id, top }
|
|
80
|
+
})
|
|
81
|
+
.filter((x): x is { id: string; top: number } => x !== null)
|
|
82
|
+
}, [sections])
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (!isContentLoaded || sections.length === 0) return
|
|
86
|
+
const headings = getHeadings()
|
|
87
|
+
|
|
88
|
+
function onScroll() {
|
|
89
|
+
const top = window.scrollY
|
|
90
|
+
let current = headings[0].id
|
|
91
|
+
for (const heading of headings) {
|
|
92
|
+
if (top >= heading.top - 10) {
|
|
93
|
+
current = heading.id
|
|
94
|
+
} else {
|
|
95
|
+
break
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
setCurrentSection(current)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
window.addEventListener('scroll', onScroll, { passive: true })
|
|
102
|
+
onScroll()
|
|
103
|
+
return () => {
|
|
104
|
+
window.removeEventListener('scroll', onScroll)
|
|
105
|
+
}
|
|
106
|
+
}, [getHeadings, sections, isContentLoaded])
|
|
107
|
+
|
|
108
|
+
function isActive(section: Section | Subsection) {
|
|
109
|
+
return section.id === currentSection
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!isContentLoaded) {
|
|
113
|
+
return null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<div className="hidden xl:sticky xl:top-[4.75rem] xl:-mr-6 xl:block xl:h-[calc(100vh-4.75rem)] xl:flex-none xl:overflow-y-auto xl:py-16 xl:pr-6">
|
|
118
|
+
<nav aria-labelledby="on-this-page-title" className="w-56">
|
|
119
|
+
{sections.length > 0 && (
|
|
120
|
+
<>
|
|
121
|
+
<h2
|
|
122
|
+
id="on-this-page-title"
|
|
123
|
+
className="font-display text-sm font-medium text-slate-900 dark:text-white"
|
|
124
|
+
>
|
|
125
|
+
On this page
|
|
126
|
+
</h2>
|
|
127
|
+
<ol role="list" className="mt-4 space-y-3 text-sm">
|
|
128
|
+
{sections.map((section) => (
|
|
129
|
+
<li key={section.id}>
|
|
130
|
+
<h3>
|
|
131
|
+
<a
|
|
132
|
+
href={`#${section.id}`}
|
|
133
|
+
className={classNames({
|
|
134
|
+
"text-sky-500": isActive(section),
|
|
135
|
+
"font-normal text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-300": !isActive(section),
|
|
136
|
+
})}>
|
|
137
|
+
{section.title}
|
|
138
|
+
</a>
|
|
139
|
+
</h3>
|
|
140
|
+
{section.children.length > 0 && (
|
|
141
|
+
<ol role="list" className="mt-2 space-y-3 pl-5 text-slate-500 dark:text-slate-400">
|
|
142
|
+
{section.children.map((subSection) => (
|
|
143
|
+
<li key={subSection.id}>
|
|
144
|
+
<a
|
|
145
|
+
href={`#${subSection.id}`}
|
|
146
|
+
className={
|
|
147
|
+
isActive(subSection)
|
|
148
|
+
? 'text-sky-500'
|
|
149
|
+
: 'hover:text-slate-600 dark:hover:text-slate-300'
|
|
150
|
+
}
|
|
151
|
+
>
|
|
152
|
+
{subSection.title}
|
|
153
|
+
</a>
|
|
154
|
+
</li>
|
|
155
|
+
))}
|
|
156
|
+
</ol>
|
|
157
|
+
)}
|
|
158
|
+
</li>
|
|
159
|
+
))}
|
|
160
|
+
</ol>
|
|
161
|
+
</>
|
|
162
|
+
)}
|
|
163
|
+
</nav>
|
|
164
|
+
</div>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import docsConfig from '../../docs/dory.json';
|
|
2
|
+
|
|
3
|
+
export function loadFonts() {
|
|
4
|
+
const { fonts } = docsConfig;
|
|
5
|
+
if (!fonts) return;
|
|
6
|
+
|
|
7
|
+
// Create a style element for the font face
|
|
8
|
+
const style = document.createElement('style');
|
|
9
|
+
style.textContent = `
|
|
10
|
+
@font-face {
|
|
11
|
+
font-family: '${fonts.family}';
|
|
12
|
+
src: url('${fonts.source}') format('${fonts.format}');
|
|
13
|
+
font-display: swap;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
document.head.appendChild(style);
|
|
17
|
+
|
|
18
|
+
// Apply the font family to the root element
|
|
19
|
+
document.documentElement.style.fontFamily = fonts.family;
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function slugifyWithCounter() {
|
|
2
|
+
const counter = new Map<string, number>();
|
|
3
|
+
return (text: string) => {
|
|
4
|
+
const count = counter.get(text) ?? 0;
|
|
5
|
+
counter.set(text, count + 1);
|
|
6
|
+
return count === 0 ? text : `${text}-${count}`;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function toTitleCase(text: string) {
|
|
11
|
+
return text.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
|
|
12
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useState } from 'preact/hooks';
|
|
2
|
+
|
|
3
|
+
export function useDarkMode() {
|
|
4
|
+
// Check localStorage and system preference on initial load
|
|
5
|
+
const [isDark, setIsDark] = useState(() => {
|
|
6
|
+
if (typeof window === 'undefined') return false;
|
|
7
|
+
|
|
8
|
+
const stored = localStorage.getItem('darkMode');
|
|
9
|
+
if (stored !== null) {
|
|
10
|
+
return JSON.parse(stored);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Update the HTML class and localStorage when isDark changes
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const body = document.querySelector('body');
|
|
19
|
+
if (!body) return;
|
|
20
|
+
if (isDark) {
|
|
21
|
+
body.classList.add('dark');
|
|
22
|
+
} else {
|
|
23
|
+
body.classList.remove('dark');
|
|
24
|
+
}
|
|
25
|
+
localStorage.setItem('darkMode', JSON.stringify(isDark));
|
|
26
|
+
}, [isDark]);
|
|
27
|
+
|
|
28
|
+
// Listen for system theme changes
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
31
|
+
const handleChange = (e: MediaQueryListEvent) => {
|
|
32
|
+
// Only update if user hasn't manually set a preference
|
|
33
|
+
const stored = localStorage.getItem('darkMode');
|
|
34
|
+
if (stored === null) {
|
|
35
|
+
setIsDark(e.matches);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
40
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const toggleDarkMode = () => setIsDark(!isDark);
|
|
44
|
+
|
|
45
|
+
return { isDark, toggleDarkMode };
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"paths": {
|
|
10
|
+
"react": ["./node_modules/preact/compat/"],
|
|
11
|
+
"react-dom": ["./node_modules/preact/compat/"]
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
/* Bundler mode */
|
|
15
|
+
"moduleResolution": "bundler",
|
|
16
|
+
"allowImportingTsExtensions": true,
|
|
17
|
+
"verbatimModuleSyntax": true,
|
|
18
|
+
"moduleDetection": "force",
|
|
19
|
+
"noEmit": true,
|
|
20
|
+
"jsx": "react-jsx",
|
|
21
|
+
"jsxImportSource": "preact",
|
|
22
|
+
|
|
23
|
+
/* Linting */
|
|
24
|
+
"strict": true,
|
|
25
|
+
"noUnusedLocals": true,
|
|
26
|
+
"noUnusedParameters": true,
|
|
27
|
+
"erasableSyntaxOnly": true,
|
|
28
|
+
"noFallthroughCasesInSwitch": true,
|
|
29
|
+
"noUncheckedSideEffectImports": true
|
|
30
|
+
},
|
|
31
|
+
"include": ["src"]
|
|
32
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"erasableSyntaxOnly": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedSideEffectImports": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["vite.config.ts"]
|
|
25
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import preact from '@preact/preset-vite';
|
|
3
|
+
import mdx from '@mdx-js/rollup';
|
|
4
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
5
|
+
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import { remarkSafeVars } from './src/plugins/sanitize';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
plugins: [
|
|
10
|
+
preact(),
|
|
11
|
+
mdx({
|
|
12
|
+
providerImportSource: '@mdx-js/preact',
|
|
13
|
+
remarkPlugins: [remarkGfm, remarkSafeVars],
|
|
14
|
+
}),
|
|
15
|
+
tailwindcss(),
|
|
16
|
+
],
|
|
17
|
+
resolve: {
|
|
18
|
+
alias: {
|
|
19
|
+
react: 'preact/compat',
|
|
20
|
+
'react-dom': 'preact/compat'
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
publicDir: "docs",
|
|
24
|
+
server: {
|
|
25
|
+
allowedHosts: true,
|
|
26
|
+
},
|
|
27
|
+
});
|