@uniweb/build 0.1.4 → 0.1.5
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/package.json +3 -3
- package/src/docs.js +217 -0
- package/src/index.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"sharp": "^0.33.2"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
|
-
"@uniweb/content-reader": "1.0.
|
|
45
|
+
"@uniweb/content-reader": "1.0.3"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
49
49
|
"react": "^18.0.0 || ^19.0.0",
|
|
50
50
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
51
|
-
"@uniweb/core": "0.1.
|
|
51
|
+
"@uniweb/core": "0.1.4"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
|
54
54
|
"vite": {
|
package/src/docs.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documentation Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates markdown documentation from foundation schema.json
|
|
5
|
+
* or directly from component meta files.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
9
|
+
import { existsSync } from 'node:fs'
|
|
10
|
+
import { join } from 'node:path'
|
|
11
|
+
import { buildSchema } from './schema.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate markdown documentation for a single component
|
|
15
|
+
*
|
|
16
|
+
* @param {string} name - Component name
|
|
17
|
+
* @param {Object} meta - Component metadata
|
|
18
|
+
* @returns {string} Markdown content
|
|
19
|
+
*/
|
|
20
|
+
function generateComponentDocs(name, meta) {
|
|
21
|
+
const lines = []
|
|
22
|
+
|
|
23
|
+
// Component header
|
|
24
|
+
lines.push(`## ${name}`)
|
|
25
|
+
lines.push('')
|
|
26
|
+
|
|
27
|
+
// Description
|
|
28
|
+
if (meta.description) {
|
|
29
|
+
lines.push(meta.description)
|
|
30
|
+
lines.push('')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Category badge
|
|
34
|
+
if (meta.category) {
|
|
35
|
+
lines.push(`**Category:** ${meta.category}`)
|
|
36
|
+
lines.push('')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Content Elements
|
|
40
|
+
if (meta.elements && Object.keys(meta.elements).length > 0) {
|
|
41
|
+
lines.push('### Content Elements')
|
|
42
|
+
lines.push('')
|
|
43
|
+
lines.push('| Element | Label | Required | Description |')
|
|
44
|
+
lines.push('|---------|-------|----------|-------------|')
|
|
45
|
+
|
|
46
|
+
for (const [key, element] of Object.entries(meta.elements)) {
|
|
47
|
+
const label = element.label || key
|
|
48
|
+
const required = element.required ? 'Yes' : ''
|
|
49
|
+
const description = element.description || ''
|
|
50
|
+
lines.push(`| \`${key}\` | ${label} | ${required} | ${description} |`)
|
|
51
|
+
}
|
|
52
|
+
lines.push('')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Parameters/Properties
|
|
56
|
+
if (meta.properties && Object.keys(meta.properties).length > 0) {
|
|
57
|
+
lines.push('### Parameters')
|
|
58
|
+
lines.push('')
|
|
59
|
+
lines.push('| Parameter | Type | Default | Description |')
|
|
60
|
+
lines.push('|-----------|------|---------|-------------|')
|
|
61
|
+
|
|
62
|
+
for (const [key, prop] of Object.entries(meta.properties)) {
|
|
63
|
+
const type = prop.type || 'string'
|
|
64
|
+
const defaultVal = prop.default !== undefined ? `\`${prop.default}\`` : ''
|
|
65
|
+
let description = prop.label || ''
|
|
66
|
+
|
|
67
|
+
// Add options for select type
|
|
68
|
+
if (prop.type === 'select' && prop.options) {
|
|
69
|
+
const optionValues = prop.options.map(o =>
|
|
70
|
+
typeof o === 'object' ? o.value : o
|
|
71
|
+
).join(', ')
|
|
72
|
+
description += description ? ` (${optionValues})` : optionValues
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
lines.push(`| \`${key}\` | ${type} | ${defaultVal} | ${description} |`)
|
|
76
|
+
}
|
|
77
|
+
lines.push('')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Presets
|
|
81
|
+
if (meta.presets && meta.presets.length > 0) {
|
|
82
|
+
lines.push('### Presets')
|
|
83
|
+
lines.push('')
|
|
84
|
+
|
|
85
|
+
for (const preset of meta.presets) {
|
|
86
|
+
const settings = preset.settings
|
|
87
|
+
? Object.entries(preset.settings)
|
|
88
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
89
|
+
.join(', ')
|
|
90
|
+
: ''
|
|
91
|
+
lines.push(`- **${preset.name}** - ${preset.label || ''} ${settings ? `(${settings})` : ''}`)
|
|
92
|
+
}
|
|
93
|
+
lines.push('')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return lines.join('\n')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Generate full markdown documentation for a foundation
|
|
101
|
+
*
|
|
102
|
+
* @param {Object} schema - Foundation schema object
|
|
103
|
+
* @param {Object} options - Generation options
|
|
104
|
+
* @param {string} [options.title] - Document title
|
|
105
|
+
* @returns {string} Complete markdown documentation
|
|
106
|
+
*/
|
|
107
|
+
export function generateDocsFromSchema(schema, options = {}) {
|
|
108
|
+
const { title = 'Foundation Components' } = options
|
|
109
|
+
const lines = []
|
|
110
|
+
|
|
111
|
+
// Header
|
|
112
|
+
lines.push(`# ${title}`)
|
|
113
|
+
lines.push('')
|
|
114
|
+
|
|
115
|
+
// Foundation info
|
|
116
|
+
const foundationMeta = schema._self
|
|
117
|
+
if (foundationMeta) {
|
|
118
|
+
if (foundationMeta.name) {
|
|
119
|
+
lines.push(`**${foundationMeta.name}**`)
|
|
120
|
+
lines.push('')
|
|
121
|
+
}
|
|
122
|
+
if (foundationMeta.description) {
|
|
123
|
+
lines.push(foundationMeta.description)
|
|
124
|
+
lines.push('')
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
lines.push('---')
|
|
129
|
+
lines.push('')
|
|
130
|
+
|
|
131
|
+
// Table of contents
|
|
132
|
+
const componentNames = Object.keys(schema).filter(k => k !== '_self')
|
|
133
|
+
|
|
134
|
+
if (componentNames.length > 0) {
|
|
135
|
+
lines.push('## Components')
|
|
136
|
+
lines.push('')
|
|
137
|
+
for (const name of componentNames) {
|
|
138
|
+
const meta = schema[name]
|
|
139
|
+
const title = meta.title || name
|
|
140
|
+
lines.push(`- [${title}](#${name.toLowerCase()}) - ${meta.description || ''}`)
|
|
141
|
+
}
|
|
142
|
+
lines.push('')
|
|
143
|
+
lines.push('---')
|
|
144
|
+
lines.push('')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Component documentation
|
|
148
|
+
for (const name of componentNames) {
|
|
149
|
+
const meta = schema[name]
|
|
150
|
+
lines.push(generateComponentDocs(name, meta))
|
|
151
|
+
lines.push('---')
|
|
152
|
+
lines.push('')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Footer
|
|
156
|
+
lines.push('*Generated from foundation schema*')
|
|
157
|
+
|
|
158
|
+
return lines.join('\n')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Generate documentation for a foundation directory
|
|
163
|
+
*
|
|
164
|
+
* Can read from existing schema.json or build schema from source.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} foundationDir - Path to foundation directory
|
|
167
|
+
* @param {Object} options - Options
|
|
168
|
+
* @param {string} [options.output] - Output file path (default: COMPONENTS.md)
|
|
169
|
+
* @param {boolean} [options.fromSource] - Build schema from source instead of dist
|
|
170
|
+
* @returns {Promise<{outputPath: string, componentCount: number}>}
|
|
171
|
+
*/
|
|
172
|
+
export async function generateDocs(foundationDir, options = {}) {
|
|
173
|
+
const {
|
|
174
|
+
output = 'COMPONENTS.md',
|
|
175
|
+
fromSource = false,
|
|
176
|
+
} = options
|
|
177
|
+
|
|
178
|
+
let schema
|
|
179
|
+
|
|
180
|
+
// Try to load schema.json from dist
|
|
181
|
+
const schemaPath = join(foundationDir, 'dist', 'schema.json')
|
|
182
|
+
|
|
183
|
+
if (!fromSource && existsSync(schemaPath)) {
|
|
184
|
+
// Load from existing schema.json
|
|
185
|
+
const schemaContent = await readFile(schemaPath, 'utf-8')
|
|
186
|
+
schema = JSON.parse(schemaContent)
|
|
187
|
+
} else {
|
|
188
|
+
// Build schema from source
|
|
189
|
+
const srcDir = join(foundationDir, 'src')
|
|
190
|
+
if (!existsSync(srcDir)) {
|
|
191
|
+
throw new Error(`Source directory not found: ${srcDir}`)
|
|
192
|
+
}
|
|
193
|
+
schema = await buildSchema(srcDir)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Get foundation name for title
|
|
197
|
+
const pkgPath = join(foundationDir, 'package.json')
|
|
198
|
+
let title = 'Foundation Components'
|
|
199
|
+
if (existsSync(pkgPath)) {
|
|
200
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'))
|
|
201
|
+
if (pkg.name) {
|
|
202
|
+
title = `${pkg.name} Components`
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Generate markdown
|
|
207
|
+
const markdown = generateDocsFromSchema(schema, { title })
|
|
208
|
+
|
|
209
|
+
// Write output
|
|
210
|
+
const outputPath = join(foundationDir, output)
|
|
211
|
+
await writeFile(outputPath, markdown)
|
|
212
|
+
|
|
213
|
+
// Count components
|
|
214
|
+
const componentCount = Object.keys(schema).filter(k => k !== '_self').length
|
|
215
|
+
|
|
216
|
+
return { outputPath, componentCount }
|
|
217
|
+
}
|
package/src/index.js
CHANGED
|
@@ -40,5 +40,11 @@ export {
|
|
|
40
40
|
prerenderSite,
|
|
41
41
|
} from './prerender.js'
|
|
42
42
|
|
|
43
|
+
// Documentation generation
|
|
44
|
+
export {
|
|
45
|
+
generateDocs,
|
|
46
|
+
generateDocsFromSchema,
|
|
47
|
+
} from './docs.js'
|
|
48
|
+
|
|
43
49
|
// Default export is the combined Vite plugin
|
|
44
50
|
export { default } from './vite-foundation-plugin.js'
|