uniweb 0.12.7 → 0.12.9
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 +4 -4
- package/partials/agents.md +6 -1
- package/src/commands/build.js +51 -30
- package/src/commands/deploy.js +695 -415
- package/src/commands/export.js +93 -0
- package/src/commands/publish.js +288 -116
- package/src/framework-index.json +3 -3
- package/src/index.js +26 -8
- package/src/utils/config.js +8 -2
- package/src/utils/env.js +22 -0
- package/src/utils/registry.js +4 -5
- package/templates/foundation/package.json.hbs +1 -1
- package/src/utils/receipt.js +0 -91
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.9",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/core": "0.7.10",
|
|
45
44
|
"@uniweb/kit": "0.9.10",
|
|
46
|
-
"@uniweb/runtime": "0.8.11"
|
|
45
|
+
"@uniweb/runtime": "0.8.11",
|
|
46
|
+
"@uniweb/core": "0.7.10"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@uniweb/build": "0.
|
|
49
|
+
"@uniweb/build": "0.14.1",
|
|
50
50
|
"@uniweb/semantic-parser": "1.1.17",
|
|
51
51
|
"@uniweb/content-reader": "1.1.10"
|
|
52
52
|
},
|
package/partials/agents.md
CHANGED
|
@@ -165,10 +165,15 @@ The `uniweb` block in `package.json` carries platform-specific configuration tha
|
|
|
165
165
|
|
|
166
166
|
| Field | Where used | Default | Purpose |
|
|
167
167
|
|---|---|---|---|
|
|
168
|
-
| `id` | `uniweb publish` | (set
|
|
168
|
+
| `id` | `uniweb publish` | (set via `--name` or scoped `package.json::name`) | The foundation's published id — the bare-name segment in `@org/<id>`. Decoupled from `package.json::name` (a workspace concern), so renaming the foundation on the registry doesn't ripple through site dependencies. Only relevant for catalog-published foundations; site-bound foundations skip this. |
|
|
169
169
|
| `namespace` | `uniweb publish` | (none — see scope resolution) | Legacy explicit org-namespace override. Equivalent to using a scoped `package.json::name` (`"@myorg/foundation"`). Rarely needed in modern foundations. |
|
|
170
170
|
| `runtimePolicy` | `dist/runtime-pin.json` (foundation build) | `"auto-minor"` | Controls how sites using this foundation receive runtime updates. Three values: `"exact"`, `"auto-patch"`, `"auto-minor"`. See "Foundation runtime policy" below. |
|
|
171
171
|
|
|
172
|
+
**Catalog vs site-bound foundations.** Two distribution intents share the same `dist/foundation.js` artifact:
|
|
173
|
+
|
|
174
|
+
- A **catalog foundation** is a deliberate product — named, versioned, listed in the catalog, consumable by other developers' sites. Use `uniweb publish @org/name` for these. The CLI requires an explicit name argument so you don't accidentally catalog a foundation that was meant to be site-bound.
|
|
175
|
+
- A **site-bound foundation** powers exactly one site. Don't run `uniweb publish` for it. Just run `uniweb deploy` from the site directory — the CLI auto-publishes your local foundation as part of the deploy, under a registry slot scoped to the site itself, with no naming ceremony. The foundation isn't visible in the catalog and isn't owned by the developer who happened to run the deploy.
|
|
176
|
+
|
|
172
177
|
**On the split between `package.json::name` and `uniweb.id`:** the workspace name is what pnpm uses for `file:` linking and what `site.yml::foundation` references. The published id is what the registry stores. Keeping them separate means renaming on the registry (e.g. `marketing` → `marketing-pro`) is a one-shot `uniweb publish --name marketing-pro` — it persists to `uniweb.id` without touching the workspace.
|
|
173
178
|
|
|
174
179
|
These are the only fields the platform consumes today. Future platform features that need static configuration will land here too.
|
package/src/commands/build.js
CHANGED
|
@@ -1,33 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Build Command
|
|
3
3
|
*
|
|
4
|
-
* Builds foundations with schema generation, or sites
|
|
5
|
-
* bundle mode.
|
|
4
|
+
* Builds foundations with schema generation, or sites.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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.
|
|
11
|
+
*
|
|
12
|
+
* --bundle (internal; called by `uniweb export`)
|
|
9
13
|
* Full vite + post-vite pipeline. Produces a static-host JS bundle
|
|
10
14
|
* (`dist/index.html`, `dist/entry.js`, `_importmap/*`, `_pages/*` for
|
|
11
15
|
* split mode, sitemap/robots/search-index, prerendered HTML when
|
|
12
|
-
* configured).
|
|
13
|
-
*
|
|
16
|
+
* configured). Foundation is loaded by URL when site.yml's foundation
|
|
17
|
+
* is a registry ref; statically inlined when it's a workspace-local
|
|
18
|
+
* ref with no auto-publish (the narrow self-contained case).
|
|
14
19
|
*
|
|
15
|
-
* --link
|
|
20
|
+
* --link (internal; called by `uniweb deploy`)
|
|
16
21
|
* Data-only pipeline. No vite. Emits ONLY what the Uniweb-edge
|
|
17
22
|
* deploy needs: `dist/site-content.json` (with full sections),
|
|
18
23
|
* `dist/<lang>/site-content.json` per non-default locale,
|
|
19
24
|
* `dist/data/*.json` (collections), and `dist/assets/<media>` (images,
|
|
20
|
-
* fonts, video posters).
|
|
21
|
-
*
|
|
22
|
-
*
|
|
25
|
+
* fonts, video posters). Edge stitches runtime + foundation per
|
|
26
|
+
* request — the site's JS bundle would be dead weight.
|
|
27
|
+
*
|
|
28
|
+
* Bare `uniweb build` for a site defaults to --bundle (the historical
|
|
29
|
+
* behavior). This is mostly useful for inspecting the build output during
|
|
30
|
+
* development; for shipping, use `uniweb deploy` or `uniweb export`.
|
|
23
31
|
*
|
|
24
32
|
* Usage:
|
|
25
33
|
* uniweb build # Build current directory (sites default to --bundle)
|
|
26
34
|
* uniweb build --target foundation # Explicitly build as foundation
|
|
27
35
|
* uniweb build --target site # Explicitly build as site
|
|
28
|
-
* uniweb build --
|
|
29
|
-
* uniweb build --
|
|
30
|
-
* uniweb build --
|
|
36
|
+
* uniweb build --prerender # Force pre-rendering
|
|
37
|
+
* uniweb build --no-prerender # Skip pre-rendering
|
|
38
|
+
* uniweb build --host <name> # Override site.yml deploy.host (e.g.
|
|
39
|
+
* netlify, s3-cloudfront, generic-static)
|
|
40
|
+
*
|
|
41
|
+
* Internal flags (called by `uniweb deploy` / `uniweb export`):
|
|
42
|
+
* --link # Data-only pipeline (Uniweb-edge)
|
|
43
|
+
* --bundle # Full vite pipeline (third-party hosts)
|
|
31
44
|
*/
|
|
32
45
|
|
|
33
46
|
import { existsSync, readFileSync } from 'node:fs'
|
|
@@ -476,11 +489,11 @@ async function buildSiteLink(projectDir, options = {}) {
|
|
|
476
489
|
success(`Translated collections for ${Object.keys(collectionOutputs).length} locale(s)`)
|
|
477
490
|
}
|
|
478
491
|
} catch (err) {
|
|
479
|
-
if (process.env.
|
|
492
|
+
if (process.env.UNIWEB_DEBUG) console.error('Collection translation:', err.message)
|
|
480
493
|
}
|
|
481
494
|
} catch (err) {
|
|
482
495
|
error(`i18n build failed: ${err.message}`)
|
|
483
|
-
if (process.env.
|
|
496
|
+
if (process.env.UNIWEB_DEBUG) console.error(err.stack)
|
|
484
497
|
log(`${colors.yellow}Continuing without localized content${colors.reset}`)
|
|
485
498
|
}
|
|
486
499
|
}
|
|
@@ -529,7 +542,7 @@ async function resolveFoundationDirForSite(siteDir, siteConfig) {
|
|
|
529
542
|
* Build a site
|
|
530
543
|
*/
|
|
531
544
|
async function buildSite(projectDir, options = {}) {
|
|
532
|
-
const { prerender = false, foundationDir, siteConfig = null } = options
|
|
545
|
+
const { prerender = false, foundationDir, siteConfig = null, host = null } = options
|
|
533
546
|
|
|
534
547
|
info('Building site...')
|
|
535
548
|
|
|
@@ -578,13 +591,13 @@ async function buildSite(projectDir, options = {}) {
|
|
|
578
591
|
}
|
|
579
592
|
} catch (err) {
|
|
580
593
|
// Collection translation is optional, don't fail build
|
|
581
|
-
if (process.env.
|
|
594
|
+
if (process.env.UNIWEB_DEBUG) {
|
|
582
595
|
console.error('Collection translation:', err.message)
|
|
583
596
|
}
|
|
584
597
|
}
|
|
585
598
|
} catch (err) {
|
|
586
599
|
error(`i18n build failed: ${err.message}`)
|
|
587
|
-
if (process.env.
|
|
600
|
+
if (process.env.UNIWEB_DEBUG) {
|
|
588
601
|
console.error(err.stack)
|
|
589
602
|
}
|
|
590
603
|
// Don't fail the build, just warn
|
|
@@ -602,6 +615,7 @@ async function buildSite(projectDir, options = {}) {
|
|
|
602
615
|
|
|
603
616
|
const result = await prerenderSite(projectDir, {
|
|
604
617
|
foundationDir: foundationDir || resolveFoundationDir(projectDir, siteConfig),
|
|
618
|
+
host,
|
|
605
619
|
onProgress: (msg) => log(` ${colors.dim}${msg}${colors.reset}`)
|
|
606
620
|
})
|
|
607
621
|
|
|
@@ -632,7 +646,7 @@ async function buildSite(projectDir, options = {}) {
|
|
|
632
646
|
log(` • The foundation's dist/foundation.js exists (build the foundation first)`)
|
|
633
647
|
}
|
|
634
648
|
|
|
635
|
-
if (process.env.
|
|
649
|
+
if (process.env.UNIWEB_DEBUG) {
|
|
636
650
|
console.error(err.stack)
|
|
637
651
|
}
|
|
638
652
|
process.exit(1)
|
|
@@ -699,7 +713,7 @@ async function discoverWorkspacePackages(workspaceDir) {
|
|
|
699
713
|
* Build all packages in a workspace
|
|
700
714
|
*/
|
|
701
715
|
async function buildWorkspace(workspaceDir, options = {}) {
|
|
702
|
-
const { prerenderFlag, noPrerenderFlag } = options
|
|
716
|
+
const { prerenderFlag, noPrerenderFlag, host = null } = options
|
|
703
717
|
|
|
704
718
|
log(`${colors.cyan}${colors.bright}Building workspace...${colors.reset}`)
|
|
705
719
|
log('')
|
|
@@ -746,7 +760,7 @@ async function buildWorkspace(workspaceDir, options = {}) {
|
|
|
746
760
|
// Resolve foundation directory for this site
|
|
747
761
|
const foundationDir = resolveFoundationDir(site.path, siteConfig)
|
|
748
762
|
|
|
749
|
-
await buildSite(site.path, { prerender, foundationDir, siteConfig })
|
|
763
|
+
await buildSite(site.path, { prerender, foundationDir, siteConfig, host })
|
|
750
764
|
log('')
|
|
751
765
|
}
|
|
752
766
|
|
|
@@ -804,13 +818,12 @@ export async function build(args = []) {
|
|
|
804
818
|
const prerenderFlag = args.includes('--prerender')
|
|
805
819
|
const noPrerenderFlag = args.includes('--no-prerender')
|
|
806
820
|
|
|
807
|
-
//
|
|
808
|
-
//
|
|
809
|
-
//
|
|
810
|
-
//
|
|
811
|
-
// Bare `uniweb build` for a site defaults to --bundle
|
|
812
|
-
//
|
|
813
|
-
// of the two explicitly based on the resolved deploy mode.
|
|
821
|
+
// Internal flags — called by `uniweb deploy` (always --link) and
|
|
822
|
+
// `uniweb export` (always --bundle). After Phase 2 of the CLI
|
|
823
|
+
// ergonomics overhaul, users don't see these flags directly; they
|
|
824
|
+
// pick the deploy target (deploy vs export) and the corresponding
|
|
825
|
+
// pipeline runs. Bare `uniweb build` for a site defaults to --bundle
|
|
826
|
+
// (mostly used during development to inspect the vite output).
|
|
814
827
|
const linkFlag = args.includes('--link')
|
|
815
828
|
const bundleFlag = args.includes('--bundle')
|
|
816
829
|
if (linkFlag && bundleFlag) {
|
|
@@ -825,6 +838,14 @@ export async function build(args = []) {
|
|
|
825
838
|
foundationDir = resolve(args[foundationDirIndex + 1])
|
|
826
839
|
}
|
|
827
840
|
|
|
841
|
+
// --host overrides site.yml's deploy.host for this build's prerender
|
|
842
|
+
// step. Validated lazily (inside prerender.js, via the registry).
|
|
843
|
+
let host = null
|
|
844
|
+
const hostIndex = args.indexOf('--host')
|
|
845
|
+
if (hostIndex !== -1 && args[hostIndex + 1]) {
|
|
846
|
+
host = args[hostIndex + 1]
|
|
847
|
+
}
|
|
848
|
+
|
|
828
849
|
// Auto-detect project type if not specified
|
|
829
850
|
if (!targetType) {
|
|
830
851
|
targetType = detectProjectType(projectDir)
|
|
@@ -858,7 +879,7 @@ export async function build(args = []) {
|
|
|
858
879
|
// Run appropriate build
|
|
859
880
|
try {
|
|
860
881
|
if (targetType === 'workspace') {
|
|
861
|
-
await buildWorkspace(projectDir, { prerenderFlag, noPrerenderFlag })
|
|
882
|
+
await buildWorkspace(projectDir, { prerenderFlag, noPrerenderFlag, host })
|
|
862
883
|
} else if (targetType === 'foundation') {
|
|
863
884
|
await buildFoundation(projectDir)
|
|
864
885
|
} else {
|
|
@@ -888,7 +909,7 @@ export async function build(args = []) {
|
|
|
888
909
|
if (prerenderFlag) prerender = true
|
|
889
910
|
if (noPrerenderFlag) prerender = false
|
|
890
911
|
|
|
891
|
-
await buildSite(projectDir, { prerender, foundationDir, siteConfig })
|
|
912
|
+
await buildSite(projectDir, { prerender, foundationDir, siteConfig, host })
|
|
892
913
|
}
|
|
893
914
|
} catch (err) {
|
|
894
915
|
error(err.message)
|