@uniweb/core 0.2.3 → 0.2.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/core",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Core classes for the Uniweb platform - Uniweb, Website, Page, Block",
5
5
  "type": "module",
6
6
  "exports": {
@@ -30,7 +30,7 @@
30
30
  "jest": "^29.7.0"
31
31
  },
32
32
  "dependencies": {
33
- "@uniweb/semantic-parser": "1.0.14"
33
+ "@uniweb/semantic-parser": "1.0.15"
34
34
  },
35
35
  "scripts": {
36
36
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
package/src/block.js CHANGED
@@ -52,9 +52,6 @@ export default class Block {
52
52
  ? blockData.subsections.map((block, i) => new Block(block, `${id}_${i}`))
53
53
  : []
54
54
 
55
- // Input data
56
- this.input = blockData.input || null
57
-
58
55
  // Fetch configuration (from section frontmatter)
59
56
  // Supports local files (path) or remote URLs (url)
60
57
  this.fetch = blockData.fetch || null
package/src/page.js CHANGED
@@ -26,7 +26,6 @@ export default class Page {
26
26
  this.description = pageData.description || ''
27
27
  this.label = pageData.label || null // Short label for navigation (null = use title)
28
28
  this.keywords = pageData.keywords || null
29
- this.order = pageData.order ?? 0
30
29
  this.lastModified = pageData.lastModified || null
31
30
 
32
31
  // Navigation visibility options
@@ -38,11 +37,8 @@ export default class Page {
38
37
  this.layout = {
39
38
  header: pageData.layout?.header !== false,
40
39
  footer: pageData.layout?.footer !== false,
41
- left: pageData.layout?.left !== false,
42
- right: pageData.layout?.right !== false,
43
- // Aliases for backwards compatibility
44
- leftPanel: pageData.layout?.left !== false,
45
- rightPanel: pageData.layout?.right !== false,
40
+ leftPanel: pageData.layout?.leftPanel !== false,
41
+ rightPanel: pageData.layout?.rightPanel !== false,
46
42
  }
47
43
 
48
44
  // SEO configuration
package/src/website.js CHANGED
@@ -167,12 +167,8 @@ export default class Website {
167
167
  }
168
168
  }
169
169
 
170
- // Sort children by order
171
- for (const page of this.pages) {
172
- if (page.children.length > 0) {
173
- page.children.sort((a, b) => (a.order || 0) - (b.order || 0))
174
- }
175
- }
170
+ // Note: Pages arrive pre-sorted from build time.
171
+ // The hierarchy is hydrated from that order - no runtime sorting needed.
176
172
 
177
173
  // Build page ID map for makeHref() resolution
178
174
  // Supports both explicit IDs and route-based lookup
@@ -201,18 +197,22 @@ export default class Website {
201
197
  * @returns {Page|undefined}
202
198
  */
203
199
  getPage(route) {
200
+ // Normalize trailing slashes for consistent matching
201
+ // '/about/' and '/about' should match the same page
202
+ const normalizedRoute = route === '/' ? '/' : route.replace(/\/$/, '')
203
+
204
204
  // Priority 1: Exact match on actual route
205
- const exactMatch = this.pages.find((page) => page.route === route)
205
+ const exactMatch = this.pages.find((page) => page.route === normalizedRoute)
206
206
  if (exactMatch) return exactMatch
207
207
 
208
208
  // Priority 2: Index page nav route match
209
- const indexMatch = this.pages.find((page) => page.isIndex && page.getNavRoute() === route)
209
+ const indexMatch = this.pages.find((page) => page.isIndex && page.getNavRoute() === normalizedRoute)
210
210
  if (indexMatch) return indexMatch
211
211
 
212
212
  // Priority 3: Dynamic route pattern matching
213
213
  // Check cache first
214
- if (this._dynamicPageCache.has(route)) {
215
- return this._dynamicPageCache.get(route)
214
+ if (this._dynamicPageCache.has(normalizedRoute)) {
215
+ return this._dynamicPageCache.get(normalizedRoute)
216
216
  }
217
217
 
218
218
  // Try to match against dynamic route patterns
@@ -220,13 +220,13 @@ export default class Website {
220
220
  // Check if this is a dynamic page (has :param in route)
221
221
  if (!page.route.includes(':')) continue
222
222
 
223
- const match = this._matchDynamicRoute(page.route, route)
223
+ const match = this._matchDynamicRoute(page.route, normalizedRoute)
224
224
  if (match) {
225
225
  // Create a dynamic page instance with the concrete route and params
226
- const dynamicPage = this._createDynamicPage(page, route, match.params)
226
+ const dynamicPage = this._createDynamicPage(page, normalizedRoute, match.params)
227
227
  if (dynamicPage) {
228
228
  // Cache for future requests
229
- this._dynamicPageCache.set(route, dynamicPage)
229
+ this._dynamicPageCache.set(normalizedRoute, dynamicPage)
230
230
  return dynamicPage
231
231
  }
232
232
  }
@@ -739,7 +739,7 @@ export default class Website {
739
739
  *
740
740
  * // Custom filtering
741
741
  * const topLevel = website.getPageHierarchy({
742
- * filter: (page) => page.order < 10
742
+ * filter: (page) => !page.route.startsWith('/admin')
743
743
  * })
744
744
  */
745
745
  getPageHierarchy(options = {}) {
@@ -795,7 +795,6 @@ export default class Website {
795
795
  title: page.title,
796
796
  label: page.getLabel(),
797
797
  description: page.description,
798
- order: page.order,
799
798
  hasContent: page.hasContent(),
800
799
  children: nested && page.hasChildren()
801
800
  ? page.children.filter(isPageVisible).map(buildPageInfo)