@uniweb/build 0.1.20 → 0.1.21

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": "@uniweb/build",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -59,7 +59,7 @@
59
59
  "@tailwindcss/vite": "^4.0.0",
60
60
  "@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
61
61
  "vite-plugin-svgr": "^4.0.0",
62
- "@uniweb/core": "0.1.8"
62
+ "@uniweb/core": "0.1.9"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "vite": {
@@ -288,11 +288,14 @@ async function processExplicitSections(sectionsConfig, pagePath, siteRoot, paren
288
288
  * Process a page directory
289
289
  *
290
290
  * @param {string} pagePath - Path to page directory
291
- * @param {string} pageName - Name of the page
291
+ * @param {string} pageName - Name of the page (folder name, not full path)
292
292
  * @param {string} siteRoot - Site root directory for asset resolution
293
+ * @param {Object} options - Route options
294
+ * @param {boolean} options.isIndex - Whether this page is the index for its parent route
295
+ * @param {string} options.parentRoute - The parent route (e.g., '/' or '/docs')
293
296
  * @returns {Object} Page data with assets manifest
294
297
  */
295
- async function processPage(pagePath, pageName, siteRoot) {
298
+ async function processPage(pagePath, pageName, siteRoot, { isIndex = false, parentRoute = '/' } = {}) {
296
299
  const pageConfig = await readYamlFile(join(pagePath, 'page.yml'))
297
300
 
298
301
  // Note: We no longer skip hidden pages here - they still exist as valid pages,
@@ -348,11 +351,16 @@ async function processPage(pagePath, pageName, siteRoot) {
348
351
  }
349
352
 
350
353
  // Determine route
351
- let route = '/' + pageName
352
- if (pageName === 'home' || pageName === 'index') {
353
- route = '/'
354
+ let route
355
+ if (isIndex) {
356
+ // Index page gets the parent route
357
+ route = parentRoute
354
358
  } else if (pageName.startsWith('@')) {
355
- route = '/' + pageName
359
+ // Special pages (layout areas) keep their @ prefix
360
+ route = parentRoute === '/' ? `/@${pageName.slice(1)}` : `${parentRoute}/@${pageName.slice(1)}`
361
+ } else {
362
+ // Normal pages get parent + their name
363
+ route = parentRoute === '/' ? `/${pageName}` : `${parentRoute}/${pageName}`
356
364
  }
357
365
 
358
366
  // Extract configuration
@@ -392,15 +400,50 @@ async function processPage(pagePath, pageName, siteRoot) {
392
400
  }
393
401
  }
394
402
 
403
+ /**
404
+ * Determine the index page name from ordering config
405
+ *
406
+ * @param {Object} orderConfig - { pages: [...], index: 'name' } from parent
407
+ * @param {Array} availableFolders - Array of { name, order } for folders at this level
408
+ * @returns {string|null} The folder name that should be the index, or null
409
+ */
410
+ function determineIndexPage(orderConfig, availableFolders) {
411
+ const { pages: pagesArray, index: indexName } = orderConfig || {}
412
+
413
+ // 1. Explicit pages array - first item is index
414
+ if (Array.isArray(pagesArray) && pagesArray.length > 0) {
415
+ return pagesArray[0]
416
+ }
417
+
418
+ // 2. Explicit index property
419
+ if (indexName) {
420
+ return indexName
421
+ }
422
+
423
+ // 3. Fallback: lowest order value, or first alphabetically
424
+ if (availableFolders.length === 0) return null
425
+
426
+ const sorted = [...availableFolders].sort((a, b) => {
427
+ // Sort by order (lower first), then alphabetically
428
+ const orderA = a.order ?? 999
429
+ const orderB = b.order ?? 999
430
+ if (orderA !== orderB) return orderA - orderB
431
+ return a.name.localeCompare(b.name)
432
+ })
433
+
434
+ return sorted[0].name
435
+ }
436
+
395
437
  /**
396
438
  * Recursively collect pages from a directory
397
439
  *
398
440
  * @param {string} dirPath - Directory to scan
399
- * @param {string} routePrefix - Route prefix for nested pages
441
+ * @param {string} parentRoute - Parent route (e.g., '/' or '/docs')
400
442
  * @param {string} siteRoot - Site root directory for asset resolution
443
+ * @param {Object} orderConfig - { pages: [...], index: 'name' } from parent's config
401
444
  * @returns {Promise<Object>} { pages, assetCollection, header, footer, left, right }
402
445
  */
403
- async function collectPagesRecursive(dirPath, routePrefix, siteRoot) {
446
+ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig = {}) {
404
447
  const entries = await readdir(dirPath)
405
448
  const pages = []
406
449
  let assetCollection = {
@@ -413,30 +456,55 @@ async function collectPagesRecursive(dirPath, routePrefix, siteRoot) {
413
456
  let left = null
414
457
  let right = null
415
458
 
459
+ // First pass: discover all page folders and read their order values
460
+ const pageFolders = []
416
461
  for (const entry of entries) {
417
462
  const entryPath = join(dirPath, entry)
418
463
  const stats = await stat(entryPath)
419
-
420
464
  if (!stats.isDirectory()) continue
421
465
 
422
- // Build the page name/route
423
- const pageName = routePrefix ? `${routePrefix}/${entry}` : entry
466
+ // Read page.yml to get order and child page config
467
+ const pageConfig = await readYamlFile(join(entryPath, 'page.yml'))
468
+ pageFolders.push({
469
+ name: entry,
470
+ path: entryPath,
471
+ order: pageConfig.order,
472
+ childOrderConfig: {
473
+ pages: pageConfig.pages,
474
+ index: pageConfig.index
475
+ }
476
+ })
477
+ }
478
+
479
+ // Determine which page is the index for this level
480
+ const regularFolders = pageFolders.filter(f => !f.name.startsWith('@'))
481
+ const indexPageName = determineIndexPage(orderConfig, regularFolders)
482
+
483
+ // Second pass: process each page folder
484
+ for (const folder of pageFolders) {
485
+ const { name: entry, path: entryPath, childOrderConfig } = folder
486
+ const isIndex = entry === indexPageName
487
+ const isSpecial = entry.startsWith('@')
424
488
 
425
489
  // Process this directory as a page
426
- const result = await processPage(entryPath, pageName, siteRoot)
490
+ const result = await processPage(entryPath, entry, siteRoot, {
491
+ isIndex: isIndex && !isSpecial,
492
+ parentRoute
493
+ })
494
+
427
495
  if (result) {
428
496
  const { page, assetCollection: pageAssets } = result
429
497
  assetCollection = mergeAssetCollections(assetCollection, pageAssets)
430
498
 
431
499
  // Handle special pages (layout areas) - only at root level
432
- if (!routePrefix) {
433
- if (entry === '@header' || page.route === '/@header') {
500
+ if (parentRoute === '/') {
501
+ if (entry === '@header') {
434
502
  header = page
435
- } else if (entry === '@footer' || page.route === '/@footer') {
503
+ } else if (entry === '@footer') {
436
504
  footer = page
437
- } else if (entry === '@left' || page.route === '/@left') {
505
+ } else if (entry === '@left') {
438
506
  left = page
439
- } else if (entry === '@right' || page.route === '/@right') {
507
+ } else if (entry === '@right') {
440
508
  right = page
441
509
  } else {
442
510
  pages.push(page)
@@ -444,13 +512,15 @@ async function collectPagesRecursive(dirPath, routePrefix, siteRoot) {
444
512
  } else {
445
513
  pages.push(page)
446
514
  }
447
- }
448
515
 
449
- // Recursively process subdirectories (but not special @ directories)
450
- if (!entry.startsWith('@')) {
451
- const subResult = await collectPagesRecursive(entryPath, pageName, siteRoot)
452
- pages.push(...subResult.pages)
453
- assetCollection = mergeAssetCollections(assetCollection, subResult.assetCollection)
516
+ // Recursively process subdirectories (but not special @ directories)
517
+ if (!isSpecial) {
518
+ // The child route depends on whether this page is the index
519
+ const childParentRoute = isIndex ? parentRoute : page.route
520
+ const subResult = await collectPagesRecursive(entryPath, childParentRoute, siteRoot, childOrderConfig)
521
+ pages.push(...subResult.pages)
522
+ assetCollection = mergeAssetCollections(assetCollection, subResult.assetCollection)
523
+ }
454
524
  }
455
525
  }
456
526
 
@@ -480,9 +550,15 @@ export async function collectSiteContent(sitePath) {
480
550
  }
481
551
  }
482
552
 
553
+ // Extract page ordering config from site.yml
554
+ const siteOrderConfig = {
555
+ pages: siteConfig.pages,
556
+ index: siteConfig.index
557
+ }
558
+
483
559
  // Recursively collect all pages
484
560
  const { pages, assetCollection, header, footer, left, right } =
485
- await collectPagesRecursive(pagesPath, '', sitePath)
561
+ await collectPagesRecursive(pagesPath, '/', sitePath, siteOrderConfig)
486
562
 
487
563
  // Sort pages by order
488
564
  pages.sort((a, b) => (a.order ?? 999) - (b.order ?? 999))