@uniweb/build 0.14.20 → 0.14.22

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.14.20",
3
+ "version": "0.14.22",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -59,13 +59,13 @@
59
59
  "js-yaml": "^4.1.0",
60
60
  "sharp": "^0.33.2",
61
61
  "yaml": "^2.5.0",
62
- "@uniweb/content-writer": "0.2.6",
63
- "@uniweb/theming": "0.1.4"
62
+ "@uniweb/theming": "0.1.4",
63
+ "@uniweb/content-writer": "0.2.6"
64
64
  },
65
65
  "optionalDependencies": {
66
66
  "@uniweb/content-reader": "1.1.12",
67
- "@uniweb/runtime": "0.8.20",
68
- "@uniweb/schemas": "0.2.4"
67
+ "@uniweb/schemas": "0.2.4",
68
+ "@uniweb/runtime": "0.8.21"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
@@ -74,7 +74,7 @@
74
74
  "@tailwindcss/vite": "^4.0.0",
75
75
  "@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
76
76
  "vite-plugin-svgr": "^4.0.0",
77
- "@uniweb/core": "0.7.14"
77
+ "@uniweb/core": "0.7.15"
78
78
  },
79
79
  "peerDependenciesMeta": {
80
80
  "vite": {
@@ -295,6 +295,16 @@ const CONTENT_PROFILES = {
295
295
  'document.yml': { contentDir: 'content', defaultMode: 'pages', orderField: 'content' }
296
296
  }
297
297
 
298
+ // Short profile aliases, so a caller that knows its own context can select
299
+ // the profile explicitly (collectSiteContent's `profile` option) instead of
300
+ // inferring it from the config filename. unipress — always a document tool —
301
+ // uses this so an author can name a variant config anything (book.yml,
302
+ // print.yml) without it being misread as a site.
303
+ const PROFILE_ALIASES = {
304
+ document: CONTENT_PROFILES['document.yml'],
305
+ site: CONTENT_PROFILES['site.yml']
306
+ }
307
+
298
308
  function getContentProfile(configFile) {
299
309
  return CONTENT_PROFILES[configFile] || CONTENT_PROFILES['site.yml']
300
310
  }
@@ -1813,29 +1823,49 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
1813
1823
  * @param {string} foundationPath - Path to foundation directory
1814
1824
  * @returns {Promise<{ vars: Object, layoutNames: Set<string> }>}
1815
1825
  */
1816
- async function loadFoundationInfo(foundationPath) {
1826
+ export async function loadFoundationInfo(foundationPath) {
1817
1827
  if (!foundationPath) return { vars: {}, layoutNames: new Set() }
1818
1828
 
1819
1829
  // Try dist/meta/schema.json first (built foundation), then root schema.json
1820
1830
  const distSchemaPath = join(foundationPath, 'dist', 'meta', 'schema.json')
1821
1831
  const rootSchemaPath = join(foundationPath, 'schema.json')
1822
1832
 
1823
- const schemaPath = existsSync(distSchemaPath) ? distSchemaPath : rootSchemaPath
1824
-
1825
- if (!existsSync(schemaPath)) {
1826
- return { vars: {}, layoutNames: new Set() }
1833
+ const schemaPath = existsSync(distSchemaPath)
1834
+ ? distSchemaPath
1835
+ : existsSync(rootSchemaPath)
1836
+ ? rootSchemaPath
1837
+ : null
1838
+
1839
+ if (schemaPath) {
1840
+ try {
1841
+ const schemaContent = await readFile(schemaPath, 'utf8')
1842
+ const schema = JSON.parse(schemaContent)
1843
+ // Foundation config is in _self, support both 'vars' (new) and 'themeVars' (legacy)
1844
+ const vars = schema._self?.vars || schema._self?.themeVars || schema.themeVars || {}
1845
+ // Layout names from _layouts (keys are layout component names)
1846
+ const layoutNames = new Set(schema._layouts ? Object.keys(schema._layouts) : [])
1847
+ return { vars, layoutNames }
1848
+ } catch (err) {
1849
+ console.warn('[content-collector] Failed to load foundation schema:', err.message)
1850
+ // Fall through to the source-config fallback below.
1851
+ }
1827
1852
  }
1828
1853
 
1854
+ // No built schema.json — the normal state for `uniweb dev` on a bundled-mode
1855
+ // site that was never built (dev doesn't build the foundation to dist/). Read
1856
+ // the foundation's declared vars straight from its source config
1857
+ // (main.js / foundation.js) so theme tokens like --section-padding-y are
1858
+ // defined; without them, components using py-[var(--section-padding-y)] render
1859
+ // with collapsed section spacing. Layouts aren't resolved from source (they
1860
+ // need component discovery), but they aren't needed to build the theme CSS.
1829
1861
  try {
1830
- const schemaContent = await readFile(schemaPath, 'utf8')
1831
- const schema = JSON.parse(schemaContent)
1832
- // Foundation config is in _self, support both 'vars' (new) and 'themeVars' (legacy)
1833
- const vars = schema._self?.vars || schema._self?.themeVars || schema.themeVars || {}
1834
- // Layout names from _layouts (keys are layout component names)
1835
- const layoutNames = new Set(schema._layouts ? Object.keys(schema._layouts) : [])
1836
- return { vars, layoutNames }
1862
+ const { resolveFoundationSrcPath } = await import('../utils/foundation-source-root.js')
1863
+ const { loadFoundationConfig } = await import('../schema.js')
1864
+ const srcDir = resolveFoundationSrcPath(foundationPath)
1865
+ const config = await loadFoundationConfig(srcDir)
1866
+ return { vars: config?.vars || {}, layoutNames: new Set() }
1837
1867
  } catch (err) {
1838
- console.warn('[content-collector] Failed to load foundation schema:', err.message)
1868
+ console.warn('[content-collector] Failed to load foundation source config:', err.message)
1839
1869
  return { vars: {}, layoutNames: new Set() }
1840
1870
  }
1841
1871
  }
@@ -1974,17 +2004,18 @@ async function collectLayouts(layoutDir, siteRoot, layoutNames = new Set()) {
1974
2004
  * @param {Object} options - Collection options
1975
2005
  * @param {string} options.foundationPath - Path to foundation directory (for theme vars)
1976
2006
  * @param {string} [options.configFile='site.yml'] - Name of the top-level config file inside sitePath. Defaults to 'site.yml'. Document tools (unipress) pass 'document.yml'.
2007
+ * @param {'document'|'site'} [options.profile] - Explicit content profile, authoritative over the filename. Lets a tool that knows its context (unipress → 'document') read an arbitrarily named config with the right directory/mode/ordering. Falls back to the configFile-derived profile when omitted.
1977
2008
  * @returns {Promise<Object>} Site content object with assets manifest
1978
2009
  */
1979
2010
  export async function collectSiteContent(sitePath, options = {}) {
1980
- const { foundationPath, configFile = 'site.yml' } = options
2011
+ const { foundationPath, configFile = 'site.yml', profile: profileName } = options
1981
2012
 
1982
2013
  // Read site config and raw theme config
1983
2014
  const siteConfig = await readYamlFile(join(sitePath, configFile))
1984
2015
 
1985
2016
  // Profile selects workspace-root defaults: site.yml → pages/ + page mode +
1986
2017
  // pages: ordering; document.yml → content/ + folder mode + content: ordering.
1987
- const profile = getContentProfile(configFile)
2018
+ const profile = (profileName && PROFILE_ALIASES[profileName]) || getContentProfile(configFile)
1988
2019
 
1989
2020
  // Resolve content paths from <config>.paths: group, defaulting per profile.
1990
2021
  // Backward compatibility: when the document profile's `content/` is missing