specra 0.2.11 → 0.2.13
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/config/svelte-config.js +35 -4
- package/dist/components/docs/Header.svelte +17 -2
- package/dist/components/docs/Header.svelte.d.ts +15 -2
- package/dist/mdx.js +9 -1
- package/dist/utils.d.ts +6 -8
- package/dist/utils.js +8 -15
- package/package.json +4 -2
package/config/svelte-config.js
CHANGED
|
@@ -44,11 +44,35 @@ export function specraMdsvexConfig(options = {}) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Read the deployment basePath from specra.config.json if present.
|
|
49
|
+
* Falls back to the BASE_PATH environment variable, then empty string.
|
|
50
|
+
*/
|
|
51
|
+
function resolveBasePath(configPath = path.join(process.cwd(), 'specra.config.json')) {
|
|
52
|
+
// Environment variable takes priority
|
|
53
|
+
if (process.env.BASE_PATH) return process.env.BASE_PATH
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
if (fs.existsSync(configPath)) {
|
|
57
|
+
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'))
|
|
58
|
+
if (raw.deployment?.basePath) {
|
|
59
|
+
const bp = raw.deployment.basePath
|
|
60
|
+
// If custom domain is set, ignore basePath
|
|
61
|
+
if (raw.deployment?.customDomain) return ''
|
|
62
|
+
return bp.startsWith('/') ? bp : `/${bp}`
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
// Ignore parse errors
|
|
67
|
+
}
|
|
68
|
+
return ''
|
|
69
|
+
}
|
|
70
|
+
|
|
47
71
|
/**
|
|
48
72
|
* Scan the docs/ directory and return prerender entries for all version root pages.
|
|
49
73
|
* This ensures adapter-static discovers and prerenders every version, not just the active one.
|
|
50
74
|
*/
|
|
51
|
-
function discoverVersionEntries(docsDir = path.join(process.cwd(), 'docs')) {
|
|
75
|
+
function discoverVersionEntries(basePath = '', docsDir = path.join(process.cwd(), 'docs')) {
|
|
52
76
|
const entries = ['/']
|
|
53
77
|
try {
|
|
54
78
|
if (!fs.existsSync(docsDir)) return entries
|
|
@@ -56,7 +80,7 @@ function discoverVersionEntries(docsDir = path.join(process.cwd(), 'docs')) {
|
|
|
56
80
|
const items = fs.readdirSync(docsDir, { withFileTypes: true })
|
|
57
81
|
for (const item of items) {
|
|
58
82
|
if (item.isDirectory() && /^v\d/.test(item.name)) {
|
|
59
|
-
entries.push(
|
|
83
|
+
entries.push(`${basePath}/docs/${item.name}`)
|
|
60
84
|
}
|
|
61
85
|
}
|
|
62
86
|
} catch {
|
|
@@ -66,11 +90,14 @@ function discoverVersionEntries(docsDir = path.join(process.cwd(), 'docs')) {
|
|
|
66
90
|
}
|
|
67
91
|
|
|
68
92
|
/**
|
|
69
|
-
* Create a full SvelteKit config with Specra defaults
|
|
93
|
+
* Create a full SvelteKit config with Specra defaults.
|
|
94
|
+
* Automatically reads deployment.basePath from specra.config.json
|
|
95
|
+
* for GitHub Pages deployments.
|
|
70
96
|
*/
|
|
71
97
|
export function specraConfig(options = {}) {
|
|
72
98
|
const { vitePreprocess } = options.vitePreprocess || {}
|
|
73
99
|
const userPrerender = options.kit?.prerender || {}
|
|
100
|
+
const basePath = options.kit?.paths?.base ?? resolveBasePath()
|
|
74
101
|
|
|
75
102
|
return {
|
|
76
103
|
extensions: ['.svelte', '.md', '.svx', '.mdx'],
|
|
@@ -80,11 +107,15 @@ export function specraConfig(options = {}) {
|
|
|
80
107
|
],
|
|
81
108
|
kit: {
|
|
82
109
|
...options.kit,
|
|
110
|
+
paths: {
|
|
111
|
+
...options.kit?.paths,
|
|
112
|
+
base: basePath,
|
|
113
|
+
},
|
|
83
114
|
prerender: {
|
|
84
115
|
handleHttpError: 'warn',
|
|
85
116
|
handleMissingId: 'warn',
|
|
86
117
|
handleUnseenRoutes: 'warn',
|
|
87
|
-
entries: discoverVersionEntries(),
|
|
118
|
+
entries: discoverVersionEntries(basePath),
|
|
88
119
|
...userPrerender,
|
|
89
120
|
}
|
|
90
121
|
}
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
hidden?: boolean;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
/** Flat shape (from page components) */
|
|
25
|
+
interface ProductItemFlat {
|
|
25
26
|
slug: string;
|
|
26
27
|
label: string;
|
|
27
28
|
icon?: string;
|
|
@@ -30,13 +31,27 @@
|
|
|
30
31
|
isDefault: boolean;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
/** Nested shape (from SDK getProducts()) */
|
|
35
|
+
interface ProductItemNested {
|
|
36
|
+
slug: string;
|
|
37
|
+
config: {
|
|
38
|
+
label: string;
|
|
39
|
+
icon?: string;
|
|
40
|
+
badge?: string;
|
|
41
|
+
activeVersion?: string;
|
|
42
|
+
};
|
|
43
|
+
isDefault: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type ProductInput = ProductItemFlat | ProductItemNested;
|
|
47
|
+
|
|
33
48
|
interface Props {
|
|
34
49
|
currentVersion: string;
|
|
35
50
|
versions: string[];
|
|
36
51
|
versionsMeta?: VersionMeta[];
|
|
37
52
|
versionBanner?: BannerConfig;
|
|
38
53
|
config?: SpecraConfig;
|
|
39
|
-
products?:
|
|
54
|
+
products?: ProductInput[];
|
|
40
55
|
currentProduct?: string;
|
|
41
56
|
subheader?: Snippet;
|
|
42
57
|
}
|
|
@@ -7,7 +7,8 @@ interface VersionMeta {
|
|
|
7
7
|
badge?: string;
|
|
8
8
|
hidden?: boolean;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/** Flat shape (from page components) */
|
|
11
|
+
interface ProductItemFlat {
|
|
11
12
|
slug: string;
|
|
12
13
|
label: string;
|
|
13
14
|
icon?: string;
|
|
@@ -15,13 +16,25 @@ interface ProductItem {
|
|
|
15
16
|
activeVersion?: string;
|
|
16
17
|
isDefault: boolean;
|
|
17
18
|
}
|
|
19
|
+
/** Nested shape (from SDK getProducts()) */
|
|
20
|
+
interface ProductItemNested {
|
|
21
|
+
slug: string;
|
|
22
|
+
config: {
|
|
23
|
+
label: string;
|
|
24
|
+
icon?: string;
|
|
25
|
+
badge?: string;
|
|
26
|
+
activeVersion?: string;
|
|
27
|
+
};
|
|
28
|
+
isDefault: boolean;
|
|
29
|
+
}
|
|
30
|
+
type ProductInput = ProductItemFlat | ProductItemNested;
|
|
18
31
|
interface Props {
|
|
19
32
|
currentVersion: string;
|
|
20
33
|
versions: string[];
|
|
21
34
|
versionsMeta?: VersionMeta[];
|
|
22
35
|
versionBanner?: BannerConfig;
|
|
23
36
|
config?: SpecraConfig;
|
|
24
|
-
products?:
|
|
37
|
+
products?: ProductInput[];
|
|
25
38
|
currentProduct?: string;
|
|
26
39
|
subheader?: Snippet;
|
|
27
40
|
}
|
package/dist/mdx.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import matter from "gray-matter";
|
|
4
|
+
import yaml from "js-yaml";
|
|
4
5
|
import { unified } from "unified";
|
|
5
6
|
import remarkParse from "remark-parse";
|
|
6
7
|
import remarkGfm from "remark-gfm";
|
|
@@ -1135,7 +1136,14 @@ function readDocFromFile(filePath, originalSlug) {
|
|
|
1135
1136
|
return null;
|
|
1136
1137
|
}
|
|
1137
1138
|
const fileContents = fs.readFileSync(filePath, "utf8");
|
|
1138
|
-
const { data, content } = matter(fileContents
|
|
1139
|
+
const { data, content } = matter(fileContents, {
|
|
1140
|
+
engines: {
|
|
1141
|
+
yaml: {
|
|
1142
|
+
parse: (str) => yaml.load(str),
|
|
1143
|
+
stringify: (obj) => yaml.dump(obj),
|
|
1144
|
+
},
|
|
1145
|
+
},
|
|
1146
|
+
});
|
|
1139
1147
|
// Security: Validate MDX content for dangerous patterns
|
|
1140
1148
|
const securityCheck = validateMDXSecurity(content, {
|
|
1141
1149
|
strictMode: process.env.NODE_ENV === 'production',
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type ClassValue } from 'clsx';
|
|
2
2
|
export declare function cn(...inputs: ClassValue[]): string;
|
|
3
3
|
/**
|
|
4
|
-
* Get the correct asset path based on deployment configuration
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - GitHub Pages without custom domain: Uses basePath from config
|
|
8
|
-
* - Static hosting with custom domain: No basePath needed
|
|
4
|
+
* Get the correct asset path based on deployment configuration.
|
|
5
|
+
* Uses SvelteKit's base path (from kit.paths.base) which is resolved
|
|
6
|
+
* from deployment.basePath in specra.config.json or the BASE_PATH env var.
|
|
9
7
|
*
|
|
10
|
-
* @param
|
|
11
|
-
* @returns The properly formatted asset path
|
|
8
|
+
* @param assetPath - The asset path (can start with or without '/')
|
|
9
|
+
* @returns The properly formatted asset path with base prefix
|
|
12
10
|
*/
|
|
13
|
-
export declare function getAssetPath(
|
|
11
|
+
export declare function getAssetPath(assetPath: string): string;
|
package/dist/utils.js
CHANGED
|
@@ -4,27 +4,20 @@ export function cn(...inputs) {
|
|
|
4
4
|
return twMerge(clsx(inputs));
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
* Get the correct asset path based on deployment configuration
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* - GitHub Pages without custom domain: Uses basePath from config
|
|
11
|
-
* - Static hosting with custom domain: No basePath needed
|
|
7
|
+
* Get the correct asset path based on deployment configuration.
|
|
8
|
+
* Uses SvelteKit's base path (from kit.paths.base) which is resolved
|
|
9
|
+
* from deployment.basePath in specra.config.json or the BASE_PATH env var.
|
|
12
10
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @returns The properly formatted asset path
|
|
11
|
+
* @param assetPath - The asset path (can start with or without '/')
|
|
12
|
+
* @returns The properly formatted asset path with base prefix
|
|
15
13
|
*/
|
|
16
|
-
export function getAssetPath(
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
// Normalize the input path: ensure it starts with '/'
|
|
20
|
-
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
21
|
-
// If we have a basePath (GitHub Pages without custom domain), prepend it
|
|
14
|
+
export function getAssetPath(assetPath) {
|
|
15
|
+
const basePath = process.env.BASE_PATH || '';
|
|
16
|
+
const normalizedPath = assetPath.startsWith('/') ? assetPath : `/${assetPath}`;
|
|
22
17
|
if (basePath) {
|
|
23
|
-
// Normalize basePath: remove trailing slash, ensure leading slash
|
|
24
18
|
const normalizedBase = basePath.startsWith('/') ? basePath : `/${basePath}`;
|
|
25
19
|
const cleanBase = normalizedBase.replace(/\/$/, '');
|
|
26
20
|
return `${cleanBase}${normalizedPath}`;
|
|
27
21
|
}
|
|
28
|
-
// Default: return the normalized path (works for Vercel, custom domains, and dev)
|
|
29
22
|
return normalizedPath;
|
|
30
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specra",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "A modern documentation library for SvelteKit with built-in versioning, API reference generation, full-text search, and MDX support",
|
|
5
5
|
"svelte": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -78,13 +78,14 @@
|
|
|
78
78
|
"date-fns": "^4.1.0",
|
|
79
79
|
"embla-carousel-svelte": "^8.5.1",
|
|
80
80
|
"gray-matter": "^4.0.3",
|
|
81
|
+
"hast-util-to-html": "^9.0.0",
|
|
82
|
+
"js-yaml": "^4.1.1",
|
|
81
83
|
"katex": "^0.16.27",
|
|
82
84
|
"lucide-svelte": "^0.454.0",
|
|
83
85
|
"mdsvex": "^0.12.0",
|
|
84
86
|
"meilisearch": "^0.54.0",
|
|
85
87
|
"mermaid": "^11.12.2",
|
|
86
88
|
"mode-watcher": "^0.5.0",
|
|
87
|
-
"hast-util-to-html": "^9.0.0",
|
|
88
89
|
"rehype-katex": "^7.0.1",
|
|
89
90
|
"rehype-raw": "^7.0.0",
|
|
90
91
|
"rehype-slug": "^6.0.0",
|
|
@@ -103,6 +104,7 @@
|
|
|
103
104
|
"@sveltejs/kit": "^2.0.0",
|
|
104
105
|
"@sveltejs/package": "^2.0.0",
|
|
105
106
|
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
107
|
+
"@types/js-yaml": "^4.0.9",
|
|
106
108
|
"@types/node": "^22",
|
|
107
109
|
"svelte": "^5.0.0",
|
|
108
110
|
"svelte-check": "^4.0.0",
|