uniweb 0.12.35 → 0.12.36

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.
@@ -4,30 +4,31 @@
4
4
  * Builds foundations with schema generation, or sites.
5
5
  *
6
6
  * Two site build pipelines are available, but they're INTERNAL vocabulary
7
- * after Phase 2 of the CLI ergonomics overhaul. Users see `uniweb deploy`
8
- * (uniweb-edge — runtime-linked) and `uniweb export` (third-party host
9
- * concatenated bundle); the build command itself just dispatches to whichever
10
- * pipeline the caller requested.
7
+ * after Phase 2 of the CLI ergonomics overhaul. Users see `uniweb publish`
8
+ * (Uniweb hosting — runtime-linked), `uniweb deploy --host` (third-party host)
9
+ * and `uniweb export` (self-contained bundle); the build command itself just
10
+ * dispatches to whichever pipeline the caller requested.
11
11
  *
12
- * --bundle (internal; called by `uniweb export`)
12
+ * --bundle (internal; called by `uniweb deploy --host` / `uniweb export`)
13
13
  * Full vite + post-vite pipeline. Produces a static-host JS bundle
14
14
  * (`dist/index.html`, `dist/entry.js`, `_importmap/*`, `_pages/*` for
15
15
  * split mode, sitemap/robots/search-index, prerendered HTML when
16
16
  * configured). Foundation is loaded by URL when site.yml's foundation
17
17
  * is a registry ref; statically inlined when it's a workspace-local
18
- * ref with no auto-publish (the narrow self-contained case).
18
+ * ref (the self-contained case).
19
19
  *
20
- * --link (internal; called by `uniweb deploy`)
21
- * Data-only pipeline. No vite. Emits ONLY what the Uniweb-edge
22
- * deploy needs: `dist/site-content.json` (with full sections),
20
+ * --link (internal; called by `uniweb publish`)
21
+ * Data-only pipeline. No vite. Emits ONLY what Uniweb hosting
22
+ * needs: `dist/site-content.json` (with full sections),
23
23
  * `dist/<lang>/site-content.json` per non-default locale,
24
24
  * `dist/data/*.json` (collections), and `dist/assets/<media>` (images,
25
- * fonts, video posters). Edge stitches runtime + foundation per
25
+ * fonts, video posters). The backend stitches runtime + foundation per
26
26
  * request — the site's JS bundle would be dead weight.
27
27
  *
28
28
  * Bare `uniweb build` for a site defaults to --bundle (the historical
29
29
  * behavior). This is mostly useful for inspecting the build output during
30
- * development; for shipping, use `uniweb deploy` or `uniweb export`.
30
+ * development; for shipping, use `uniweb publish` (Uniweb hosting) or
31
+ * `uniweb deploy --host` / `uniweb export` (third-party / self-contained).
31
32
  *
32
33
  * Usage:
33
34
  * uniweb build # Build current directory (sites default to --bundle)
@@ -40,9 +41,9 @@
40
41
  * s3-cloudfront, github-pages,
41
42
  * generic-static). Default: cloudflare-pages.
42
43
  *
43
- * Internal flags (called by `uniweb deploy` / `uniweb export`):
44
- * --link # Data-only pipeline (Uniweb-edge)
45
- * --bundle # Full vite pipeline (third-party hosts)
44
+ * Internal flags:
45
+ * --link # Data-only pipeline (Uniweb hosting; called by `uniweb publish`)
46
+ * --bundle # Full vite pipeline (third-party / self-contained; deploy --host / export)
46
47
  */
47
48
 
48
49
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
@@ -246,11 +247,12 @@ async function buildFoundation(projectDir, options = {}) {
246
247
  /**
247
248
  * Ensure a local foundation's `dist/entry.js` is current.
248
249
  *
249
- * Whenever a build or deploy reads a local foundation from disk bundle
250
- * mode (vite imports it, prerender loads it for SSG), or link mode where
251
- * the foundation is uploaded alongside the site the foundation must be
252
- * built and current. Otherwise the verb fails with "Foundation not found
253
- * at .../dist/entry.js" or silently ships stale artifacts.
250
+ * Bundle mode reads a local foundation from disk (vite imports it, prerender
251
+ * loads dist/entry.js for SSG), so the foundation must be built and current.
252
+ * Otherwise the verb fails with "Foundation not found at .../dist/entry.js" or
253
+ * silently ships stale artifacts. (Link mode does NOT read the built foundation
254
+ * it forwards only the `foundation:` ref to the backend and ships no
255
+ * foundation code — so buildSiteLink does not call this.)
254
256
  *
255
257
  * `buildWorkspace()` already cascades when invoked from a workspace root,
256
258
  * but verbs invoked from a site directory (`uniweb build` in `sites/x/`,
@@ -260,8 +262,8 @@ async function buildFoundation(projectDir, options = {}) {
260
262
  *
261
263
  * This helper is idempotent: when the workspace-root cascade has already
262
264
  * run, the freshness check sees a current `dist/entry.js` and returns
263
- * without rebuilding. So adding the call inside `buildSite()` /
264
- * `buildSiteLink()` does not double-build under `buildWorkspace()`.
265
+ * without rebuilding. So calling it inside `buildSite()` does not
266
+ * double-build under `buildWorkspace()`.
265
267
  *
266
268
  * Freshness rule: a built artifact (`dist/entry.js` or the legacy
267
269
  * `dist/foundation.js`) exists AND its mtime is >= the newest mtime of
@@ -525,7 +527,7 @@ function resolveFoundationDir(projectDir, siteConfig) {
525
527
  /**
526
528
  * Build a site in link mode — data only, no vite.
527
529
  *
528
- * Emits exactly what `uniweb deploy` ships to Uniweb-edge:
530
+ * Emits exactly what `uniweb publish` ships to Uniweb hosting:
529
531
  * dist/site-content.json (full sections inlined)
530
532
  * dist/<lang>/site-content.json per non-default locale
531
533
  * dist/data/<collection>.json (+ per-record files for `deferred:`)
@@ -564,10 +566,12 @@ async function buildSiteLink(projectDir, options = {}) {
564
566
  // null and theme defaults come from theme.yml only.
565
567
  const foundationDir = await resolveFoundationDirForSite(projectDir, siteConfig).catch(() => null)
566
568
 
567
- // Cascade: a local foundation in link mode is uploaded alongside the
568
- // site (site-bound mode), so its dist must be current. Idempotent under
569
- // buildWorkspace() the freshness check no-ops when already built.
570
- if (foundationDir) await ensureFoundationFresh(foundationDir)
569
+ // Link mode does NOT (re)build the foundation. It reads only the
570
+ // foundation's SOURCE config (foundation.js::theme.vars, passed as
571
+ // foundationPath below) for theme defaults, and ships NO foundation code —
572
+ // the backend serves the foundation from the registry by the `foundation:`
573
+ // ref. (Bundle mode is the one that needs a current dist/entry.js — see
574
+ // buildSite — so the ensureFoundationFresh cascade lives there, not here.)
571
575
 
572
576
  await buildSiteData({
573
577
  siteRoot: projectDir,
@@ -637,7 +641,6 @@ async function resolveFoundationDirForSite(siteDir, siteConfig) {
637
641
  if (!foundation || typeof foundation !== 'string') return null
638
642
  // Registry ref or URL — no local foundation.
639
643
  if (/^@[a-z0-9_-]+\/[a-z0-9_-]+@/.test(foundation)) return null
640
- if (/^~[A-Za-z0-9_-]+\/[a-z0-9_-]+@/.test(foundation)) return null
641
644
  if (foundation.startsWith('http://') || foundation.startsWith('https://')) return null
642
645
 
643
646
  // Workspace sibling.
@@ -910,14 +913,15 @@ function showNextSteps(hasFoundations, hasSites) {
910
913
  if (hasFoundations) {
911
914
  log('')
912
915
  log(`${colors.bright}Share with clients:${colors.reset}`)
913
- log(` ${colors.bright}uniweb publish${colors.reset} Register your foundation (one-time setup)`)
916
+ log(` ${colors.bright}uniweb register${colors.reset} Release your foundation to the catalog (alias: uniweb release)`)
914
917
  log(` ${colors.bright}uniweb handoff <email>${colors.reset} Hand off a site to a client`)
915
918
  }
916
919
  if (hasSites) {
917
920
  log('')
918
- log(`${colors.bright}Deploy:${colors.reset}`)
919
- log(` ${colors.bright}uniweb deploy${colors.reset} Uniweb hosting`)
920
- log(` Or upload ${colors.cyan}dist/${colors.reset} to any static host`)
921
+ log(`${colors.bright}Ship a site:${colors.reset}`)
922
+ log(` ${colors.bright}uniweb publish${colors.reset} Uniweb hosting (brings the foundation along)`)
923
+ log(` ${colors.bright}uniweb deploy --host${colors.reset}=… Third-party host`)
924
+ log(` Or upload ${colors.cyan}dist/${colors.reset} (\`uniweb export\`) to any static host`)
921
925
  }
922
926
  }
923
927
 
@@ -943,10 +947,10 @@ export async function build(args = []) {
943
947
  const prerenderFlag = args.includes('--prerender')
944
948
  const noPrerenderFlag = args.includes('--no-prerender')
945
949
 
946
- // Internal flags — called by `uniweb deploy` (always --link) and
947
- // `uniweb export` (always --bundle). After Phase 2 of the CLI
948
- // ergonomics overhaul, users don't see these flags directly; they
949
- // pick the deploy target (deploy vs export) and the corresponding
950
+ // Internal flags — called by `uniweb publish` (always --link) and
951
+ // `uniweb deploy --host` / `uniweb export` (always --bundle). After Phase 2
952
+ // of the CLI ergonomics overhaul, users don't see these flags directly; they
953
+ // pick the verb (publish vs deploy vs export) and the corresponding
950
954
  // pipeline runs. Bare `uniweb build` for a site defaults to --bundle
951
955
  // (mostly used during development to inspect the vite output).
952
956
  const linkFlag = args.includes('--link')
@@ -163,9 +163,9 @@ export async function clone(args = [], deps = {}) {
163
163
  const pathFlag = flagValue(args, '--path')
164
164
  const projectFlag = flagValue(args, '--project')
165
165
  const tokenFlag = flagValue(args, '--token')
166
- const explicitRegistry = flagValue(args, '--registry')
166
+ const explicitBackend = flagValue(args, '--backend') || flagValue(args, '--registry')
167
167
  const client = new BackendClient({
168
- originFlag: explicitRegistry,
168
+ originFlag: explicitBackend,
169
169
  token: tokenFlag,
170
170
  getToken: deps.getToken,
171
171
  fetchImpl: deps.fetch,
@@ -295,7 +295,7 @@ export async function clone(args = [], deps = {}) {
295
295
  }
296
296
 
297
297
  const pullExtra = []
298
- if (explicitRegistry) pullExtra.push('--registry', explicitRegistry)
298
+ if (explicitBackend) pullExtra.push('--backend', explicitBackend)
299
299
  if (tokenFlag) pullExtra.push('--token', tokenFlag)
300
300
  if (noCollections) pullExtra.push('--no-collections')
301
301