@aravindc26/velu 0.11.9 → 0.11.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aravindc26/velu",
3
- "version": "0.11.9",
3
+ "version": "0.11.11",
4
4
  "description": "A modern documentation site generator powered by Markdown and JSON configuration",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -39,7 +39,7 @@ function printHelp() {
39
39
  velu lint Validate docs.json (or velu.json) and check referenced pages
40
40
  velu run [--port N] Build site and start dev server (default: 4321)
41
41
  velu build Build a deployable static site (SSG)
42
- velu paths Output all navigation paths and their source files as JSON
42
+ velu paths Output navigation paths and source files as JSON (grouped by language)
43
43
 
44
44
  Options:
45
45
  --port <number> Port for the dev server (default: 4321)
@@ -159,7 +159,7 @@ interface PathEntry {
159
159
  }
160
160
 
161
161
  async function paths(docsDir: string) {
162
- const { collectPages } = await import("./validate.js");
162
+ const { collectPagesByLanguage } = await import("./validate.js");
163
163
  const { normalizeConfigNavigation } = await import("./navigation-normalize.js");
164
164
  const { readFileSync, existsSync } = await import("node:fs");
165
165
  const { join } = await import("node:path");
@@ -172,25 +172,32 @@ async function paths(docsDir: string) {
172
172
 
173
173
  const raw = JSON.parse(readFileSync(configPath, "utf-8"));
174
174
  const config = normalizeConfigNavigation(raw);
175
- const pages = collectPages(config);
176
-
177
- const entries: PathEntry[] = pages.map((pagePath) => {
178
- // Check for .mdx first, then .md
179
- const mdxPath = join(docsDir, `${pagePath}.mdx`);
180
- const mdPath = join(docsDir, `${pagePath}.md`);
181
-
182
- if (existsSync(mdxPath)) {
183
- return { path: pagePath, file: `${pagePath}.mdx` };
184
- }
185
- if (existsSync(mdPath)) {
186
- return { path: pagePath, file: `${pagePath}.md` };
187
- }
188
- return { path: pagePath, file: null };
189
- });
175
+ const pagesByLanguage = collectPagesByLanguage(config);
176
+ const groupedEntries: Record<string, PathEntry[]> = {};
177
+ const flatEntries: PathEntry[] = [];
178
+
179
+ for (const [language, pages] of Object.entries(pagesByLanguage)) {
180
+ const entries: PathEntry[] = pages.map((pagePath) => {
181
+ // Check for .mdx first, then .md
182
+ const mdxPath = join(docsDir, `${pagePath}.mdx`);
183
+ const mdPath = join(docsDir, `${pagePath}.md`);
184
+
185
+ if (existsSync(mdxPath)) {
186
+ return { path: pagePath, file: `${pagePath}.mdx` };
187
+ }
188
+ if (existsSync(mdPath)) {
189
+ return { path: pagePath, file: `${pagePath}.md` };
190
+ }
191
+ return { path: pagePath, file: null };
192
+ });
193
+ groupedEntries[language] = entries;
194
+ flatEntries.push(...entries);
195
+ }
190
196
 
191
197
  const output = {
192
- paths: entries,
193
- count: entries.length,
198
+ pathsByLanguage: groupedEntries,
199
+ paths: flatEntries,
200
+ count: flatEntries.length,
194
201
  };
195
202
 
196
203
  console.log(JSON.stringify(output, null, 2));
@@ -936,21 +936,30 @@ export function getContextualOptions(): VeluContextualOption[] {
936
936
  const raw = config.contextual?.options;
937
937
 
938
938
  const ids = raw ?? DEFAULT_CONTEXTUAL_OPTIONS;
939
+ const options: VeluContextualOption[] = [];
939
940
 
940
- return ids.map((entry, index) => {
941
+ ids.forEach((entry, index) => {
941
942
  if (typeof entry === 'string') {
942
943
  const preset = CONTEXTUAL_PRESETS[entry];
943
- if (!preset) return null;
944
- return { id: entry, title: preset.title, description: preset.description, type: 'builtin' as const };
944
+ if (!preset) return;
945
+ options.push({ id: entry, title: preset.title, description: preset.description, type: 'builtin' });
946
+ return;
945
947
  }
946
- return {
948
+
949
+ const title = trimString(entry.title);
950
+ const href = trimString(entry.href);
951
+ if (!title || !href) return;
952
+
953
+ options.push({
947
954
  id: `custom-${index}`,
948
- title: entry.title,
949
- description: entry.description ?? '',
950
- href: entry.href,
951
- type: 'custom' as const,
952
- };
953
- }).filter((item): item is VeluContextualOption => item !== null);
955
+ title,
956
+ description: trimString(entry.description) ?? '',
957
+ href,
958
+ type: 'custom',
959
+ });
960
+ });
961
+
962
+ return options;
954
963
  }
955
964
 
956
965
  export function getSiteOrigin(): string {
package/src/validate.ts CHANGED
@@ -116,6 +116,7 @@ type VeluOpenApiSource = string | string[] | Record<string, unknown>;
116
116
  interface VeluConfig {
117
117
  $schema?: string;
118
118
  variables?: Record<string, string>;
119
+ languages?: string[];
119
120
  icons?: {
120
121
  library?: "fontawesome" | "lucide" | "tabler";
121
122
  };
@@ -262,6 +263,28 @@ function collectPages(config: VeluConfig): string[] {
262
263
  return collectPagesFromTabs(tabs);
263
264
  }
264
265
 
266
+ function collectPagesByLanguage(config: VeluConfig): Record<string, string[]> {
267
+ const grouped: Record<string, string[]> = {};
268
+
269
+ if (config.navigation.languages && config.navigation.languages.length > 0) {
270
+ for (const lang of config.navigation.languages) {
271
+ grouped[lang.language] = collectPagesFromTabs(lang.tabs);
272
+ }
273
+ return grouped;
274
+ }
275
+
276
+ const basePages = collectPagesFromTabs(config.navigation.tabs ?? []);
277
+ if (config.languages && config.languages.length > 0) {
278
+ for (const lang of config.languages) {
279
+ grouped[lang] = [...basePages];
280
+ }
281
+ return grouped;
282
+ }
283
+
284
+ grouped.english = basePages;
285
+ return grouped;
286
+ }
287
+
265
288
  function validateVeluConfig(docsDir: string, schemaPath: string): { valid: boolean; errors: string[] } {
266
289
  const errors: string[] = [];
267
290
 
@@ -331,4 +354,4 @@ function validateVeluConfig(docsDir: string, schemaPath: string): { valid: boole
331
354
  return { valid: errors.length === 0, errors };
332
355
  }
333
356
 
334
- export { validateVeluConfig, collectPages, VeluConfig, VeluGroup, VeluTab, VeluSeparator, VeluLink, VeluAnchor };
357
+ export { validateVeluConfig, collectPages, collectPagesByLanguage, VeluConfig, VeluGroup, VeluTab, VeluSeparator, VeluLink, VeluAnchor };