@uniweb/build 0.27.0 → 0.27.1

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.27.0",
3
+ "version": "0.27.1",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -59,17 +59,17 @@
59
59
  "js-yaml": "^4.1.0",
60
60
  "sharp": "^0.35.3",
61
61
  "yaml": "^2.5.0",
62
+ "@uniweb/content-writer": "^0.3.4",
63
+ "@uniweb/projections": "^0.3.7",
62
64
  "@uniweb/schemas": "^0.2.11",
63
- "@uniweb/theming": "^0.1.15",
64
65
  "@uniweb/semantic-parser": "^1.3.1",
65
- "@uniweb/projections": "^0.3.7",
66
- "@uniweb/content-writer": "^0.3.4"
66
+ "@uniweb/theming": "^0.1.15"
67
67
  },
68
68
  "optionalDependencies": {
69
69
  "@uniweb/runtime": "^0.13.0",
70
+ "@uniweb/content-reader": "^1.2.4",
70
71
  "@uniweb/schemas": "^0.2.11",
71
- "@uniweb/semantic-parser": "^1.3.1",
72
- "@uniweb/content-reader": "^1.2.4"
72
+ "@uniweb/semantic-parser": "^1.3.1"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
@@ -526,6 +526,30 @@ export async function buildCollectionEntities(siteRoot, opts = {}) {
526
526
  const entities = []
527
527
  const index = []
528
528
  const warnings = []
529
+
530
+ // ⛔ `@/x` IS A FOUNDATION-RELATIVE ALIAS AND MUST BE RESOLVED BEFORE IT SHIPS.
531
+ //
532
+ // `register` resolves it (`uwx/registry-package.js` builds `scoped` from the
533
+ // publish scope and applies it to BOTH the declaration's name and its refs), so
534
+ // a foundation's `@/member` is stored as `@org/member`. This path did NOT, and
535
+ // carried the alias verbatim into `$model` and `models_required.name_at_export`.
536
+ //
537
+ // ⚠️ The backend resolves Models BY NAME and never mints, so an unresolved alias
538
+ // is refused at restore with a message about a missing Model — which reads as a
539
+ // registration problem rather than a producer one. Measured 2026-08-27 on a live
540
+ // manor: `register` had already stored `@proximify/member` from the same alias,
541
+ // and the push then named `@/member`. One CLI, two paths, one resolver.
542
+ //
543
+ // ⭐ Resolving BEFORE `declarationFor` is what keeps this to one line of behaviour:
544
+ // `resolveDeclaration` already matches a fully-qualified name against the
545
+ // foundation's `@/`-keyed `dataSchemas`, so a resolved name looks up correctly and
546
+ // `declaration.name` — the value that becomes `$model` — is the resolved one.
547
+ const selfScopeOrg =
548
+ typeof opts.org === 'string' ? opts.org.replace(/^@/, '').replace(/\/.*$/, '') : ''
549
+ const resolveSelfScope = (ref) =>
550
+ typeof ref === 'string' && ref.startsWith('@/') && selfScopeOrg
551
+ ? `@${selfScopeOrg}/${ref.slice(2)}`
552
+ : ref
529
553
  // Collections that resolved no data schema (the convention-default soft-skip
530
554
  // below) — not synced as folder entities. The composite deploy delivers these
531
555
  // statically (the "data ball") instead, so the caller can route them there.
@@ -535,7 +559,18 @@ export async function buildCollectionEntities(siteRoot, opts = {}) {
535
559
  // reuse a slug).
536
560
  const seen = new Set()
537
561
  for (const { name, decl } of mapped) {
538
- const modelName = decl.schema || decl.model
562
+ const declaredModel = decl.schema || decl.model
563
+ const modelName = resolveSelfScope(declaredModel)
564
+ // Unresolvable `@/` — no org is known. Ship it rather than throwing (a `status`
565
+ // probe on a never-pushed site has no org and must still count), but say so:
566
+ // the backend's refusal names a missing Model and cannot name this cause.
567
+ if (modelName === declaredModel && typeof declaredModel === 'string' && declaredModel.startsWith('@/')) {
568
+ warnings.push(
569
+ `collection "${name}": \`${declaredModel}\` is foundation-relative and no org is known, ` +
570
+ `so it ships unresolved. The backend resolves Models by name and will refuse it. ` +
571
+ `Pass \`--org @handle\`, or push once so the site records its org.`
572
+ )
573
+ }
539
574
  const declaration = await declarationFor(modelName)
540
575
  if (!declaration) {
541
576
  // A convention-defaulted schema (subfolder-name) that doesn't resolve is a
@@ -265,6 +265,10 @@ export async function emitSyncPackages(siteRoot, opts = {}) {
265
265
  ...(opts.foundationDir ? { foundationDir: opts.foundationDir } : {}),
266
266
  ...(opts.resolveModel ? { resolveModel: opts.resolveModel } : {}),
267
267
  ...(sourceLocale ? { sourceLocale } : {}),
268
+ // The publish org — resolves a foundation-relative `@/x` model ref into
269
+ // `@org/x` before it ships. Absent on an offline probe, which is why
270
+ // buildCollectionEntities warns rather than throws.
271
+ ...(opts.org ? { org: opts.org } : {}),
268
272
  })
269
273
  const warnings = [...col.warnings]
270
274