@ethisyscore/vite-plugin 1.85.0 → 1.87.0

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/dist/index.d.cts CHANGED
@@ -805,6 +805,24 @@ interface ComputePlatformReactPagesInput {
805
805
  pages: PlatformReactPageSource[];
806
806
  /** View name → src-relative module path (e.g. `src/adapter/<module>/XView.tsx`). */
807
807
  viewFiles: Record<string, string>;
808
+ /**
809
+ * Second-chance resolution: EXPORTED name → every src-relative adapter module path
810
+ * that exports it (see {@link parseExportedNames}). Consulted only when a `useView`
811
+ * name matches no {@link viewFiles} basename, so supplying it can never change an
812
+ * already-resolving plugin's output.
813
+ *
814
+ * Exists because an adapter file may legitimately export its component under a name
815
+ * other than its filename, e.g. `ChatChannelCreateFormView.tsx` ending with
816
+ * `export { ChatChannelCreateFormView as ChatChannelCreateForm }`. The filename-only
817
+ * lookup declared such a call unresolvable and refused to generate at all, which is
818
+ * how one plugin ended up with a hand-maintained manifest the generator could no
819
+ * longer reproduce.
820
+ *
821
+ * Values are arrays, not single paths, precisely so a name exported by two DIFFERENT
822
+ * files is reported as ambiguous rather than silently bound to whichever the
823
+ * directory walk happened to reach last.
824
+ */
825
+ viewExports?: Record<string, string[]>;
808
826
  /** Per-file id/title/route overrides for non-filename-derived plugins. */
809
827
  pageOverrides?: Record<string, PlatformReactPageOverride>;
810
828
  }
@@ -820,7 +838,30 @@ interface ComputePlatformReactPagesResult {
820
838
  * key, so such a call matched nothing and produced no binding AND no diagnostic.
821
839
  */
822
840
  unregisteredViews: string[];
841
+ /**
842
+ * `useView` names that matched no adapter FILENAME and are exported by more than one
843
+ * adapter file, so there is no single correct module to bind. Binding one arbitrarily
844
+ * would compile and then render the wrong component, so the name is left unbound and
845
+ * reported (fatal under `strict`, the default) with every candidate path named.
846
+ */
847
+ ambiguousViews: string[];
823
848
  }
849
+ /**
850
+ * The runtime-NAMED exports of one module's source text, in no particular order and
851
+ * deduplicated. Used to resolve a `useView` name against an adapter file that exports
852
+ * its component under a name other than its filename.
853
+ *
854
+ * Covers the export forms that actually occur in the plugin adapter trees:
855
+ * `export function X` (by far the most common), `export const X`, and the alias list
856
+ * `export { X as Y }` / `export { X as Y, X as Z }` / `export { X } from "…"`.
857
+ *
858
+ * Deliberately NOT covered: `export default …` and type-only exports (see
859
+ * {@link EXPORT_DECL_RE} for why both would produce a broken binding), and
860
+ * `export * from "…"` — a star re-export's names cannot be known without following the
861
+ * module graph, which is beyond a text scan. A view reachable only through a star
862
+ * re-export therefore still reports as unresolvable rather than being mis-resolved.
863
+ */
864
+ declare function parseExportedNames(content: string): string[];
824
865
  /**
825
866
  * Pure core: derive the `platformReactPages[]` entries from already-read inputs (no
826
867
  * filesystem). Per page: `id` = `pageOverrides[file].id` ?? kebab(filename), `title`
@@ -896,6 +937,13 @@ interface GeneratePlatformReactManifestConfig {
896
937
  * runtime behind a green build. Failing the generator is what turns that into a
897
938
  * build-time error.
898
939
  *
940
+ * "Cannot be satisfied" means all three diagnostics: an unregistered module key
941
+ * ({@link ComputePlatformReactPagesResult.unregisteredViews}), a name exported by two
942
+ * adapter files ({@link ComputePlatformReactPagesResult.ambiguousViews}), and a name
943
+ * matching neither an adapter filename nor any adapter export
944
+ * ({@link ComputePlatformReactPagesResult.missingViews}). All three leave the name
945
+ * unbound, so all three produce the same runtime blank surface.
946
+ *
899
947
  * Both manifests are still written before the throw, so the emitted files stay in sync
900
948
  * with the page tree; the exception, not a stale file, is the gate. Set `false` only to
901
949
  * unblock a migration mid-flight, and read the returned diagnostics instead.
@@ -911,6 +959,8 @@ interface GeneratePlatformReactManifestResult {
911
959
  missingViews: string[];
912
960
  /** `useView` calls naming an unregistered module key. See {@link ComputePlatformReactPagesResult.unregisteredViews}. */
913
961
  unregisteredViews: string[];
962
+ /** `useView` names exported by two or more adapter files. See {@link ComputePlatformReactPagesResult.ambiguousViews}. */
963
+ ambiguousViews: string[];
914
964
  featureManifestPath: string;
915
965
  overlayPath: string;
916
966
  }
@@ -1013,4 +1063,4 @@ interface EthisysPluginOptions {
1013
1063
  */
1014
1064
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
1015
1065
 
1016
- export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
1066
+ export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
package/dist/index.d.ts CHANGED
@@ -805,6 +805,24 @@ interface ComputePlatformReactPagesInput {
805
805
  pages: PlatformReactPageSource[];
806
806
  /** View name → src-relative module path (e.g. `src/adapter/<module>/XView.tsx`). */
807
807
  viewFiles: Record<string, string>;
808
+ /**
809
+ * Second-chance resolution: EXPORTED name → every src-relative adapter module path
810
+ * that exports it (see {@link parseExportedNames}). Consulted only when a `useView`
811
+ * name matches no {@link viewFiles} basename, so supplying it can never change an
812
+ * already-resolving plugin's output.
813
+ *
814
+ * Exists because an adapter file may legitimately export its component under a name
815
+ * other than its filename, e.g. `ChatChannelCreateFormView.tsx` ending with
816
+ * `export { ChatChannelCreateFormView as ChatChannelCreateForm }`. The filename-only
817
+ * lookup declared such a call unresolvable and refused to generate at all, which is
818
+ * how one plugin ended up with a hand-maintained manifest the generator could no
819
+ * longer reproduce.
820
+ *
821
+ * Values are arrays, not single paths, precisely so a name exported by two DIFFERENT
822
+ * files is reported as ambiguous rather than silently bound to whichever the
823
+ * directory walk happened to reach last.
824
+ */
825
+ viewExports?: Record<string, string[]>;
808
826
  /** Per-file id/title/route overrides for non-filename-derived plugins. */
809
827
  pageOverrides?: Record<string, PlatformReactPageOverride>;
810
828
  }
@@ -820,7 +838,30 @@ interface ComputePlatformReactPagesResult {
820
838
  * key, so such a call matched nothing and produced no binding AND no diagnostic.
821
839
  */
822
840
  unregisteredViews: string[];
841
+ /**
842
+ * `useView` names that matched no adapter FILENAME and are exported by more than one
843
+ * adapter file, so there is no single correct module to bind. Binding one arbitrarily
844
+ * would compile and then render the wrong component, so the name is left unbound and
845
+ * reported (fatal under `strict`, the default) with every candidate path named.
846
+ */
847
+ ambiguousViews: string[];
823
848
  }
849
+ /**
850
+ * The runtime-NAMED exports of one module's source text, in no particular order and
851
+ * deduplicated. Used to resolve a `useView` name against an adapter file that exports
852
+ * its component under a name other than its filename.
853
+ *
854
+ * Covers the export forms that actually occur in the plugin adapter trees:
855
+ * `export function X` (by far the most common), `export const X`, and the alias list
856
+ * `export { X as Y }` / `export { X as Y, X as Z }` / `export { X } from "…"`.
857
+ *
858
+ * Deliberately NOT covered: `export default …` and type-only exports (see
859
+ * {@link EXPORT_DECL_RE} for why both would produce a broken binding), and
860
+ * `export * from "…"` — a star re-export's names cannot be known without following the
861
+ * module graph, which is beyond a text scan. A view reachable only through a star
862
+ * re-export therefore still reports as unresolvable rather than being mis-resolved.
863
+ */
864
+ declare function parseExportedNames(content: string): string[];
824
865
  /**
825
866
  * Pure core: derive the `platformReactPages[]` entries from already-read inputs (no
826
867
  * filesystem). Per page: `id` = `pageOverrides[file].id` ?? kebab(filename), `title`
@@ -896,6 +937,13 @@ interface GeneratePlatformReactManifestConfig {
896
937
  * runtime behind a green build. Failing the generator is what turns that into a
897
938
  * build-time error.
898
939
  *
940
+ * "Cannot be satisfied" means all three diagnostics: an unregistered module key
941
+ * ({@link ComputePlatformReactPagesResult.unregisteredViews}), a name exported by two
942
+ * adapter files ({@link ComputePlatformReactPagesResult.ambiguousViews}), and a name
943
+ * matching neither an adapter filename nor any adapter export
944
+ * ({@link ComputePlatformReactPagesResult.missingViews}). All three leave the name
945
+ * unbound, so all three produce the same runtime blank surface.
946
+ *
899
947
  * Both manifests are still written before the throw, so the emitted files stay in sync
900
948
  * with the page tree; the exception, not a stale file, is the gate. Set `false` only to
901
949
  * unblock a migration mid-flight, and read the returned diagnostics instead.
@@ -911,6 +959,8 @@ interface GeneratePlatformReactManifestResult {
911
959
  missingViews: string[];
912
960
  /** `useView` calls naming an unregistered module key. See {@link ComputePlatformReactPagesResult.unregisteredViews}. */
913
961
  unregisteredViews: string[];
962
+ /** `useView` names exported by two or more adapter files. See {@link ComputePlatformReactPagesResult.ambiguousViews}. */
963
+ ambiguousViews: string[];
914
964
  featureManifestPath: string;
915
965
  overlayPath: string;
916
966
  }
@@ -1013,4 +1063,4 @@ interface EthisysPluginOptions {
1013
1063
  */
1014
1064
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
1015
1065
 
1016
- export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
1066
+ export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
package/dist/index.js CHANGED
@@ -1637,6 +1637,31 @@ function parsePlatformReactPages(manifestPath, options = {}) {
1637
1637
  return result;
1638
1638
  }
1639
1639
  var DEFAULT_SCHEMA = "https://ethisys.dev/schemas/feature-manifest.json";
1640
+ var EXPORT_DECL_RE = /^[ \t]*export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([A-Za-z_$][\w$]*)/gm;
1641
+ var EXPORT_LIST_RE = /^[ \t]*export\s*\{([^}]*)\}/gm;
1642
+ var EXPORT_SPECIFIER_RE = /^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/;
1643
+ function parseExportedNames(content) {
1644
+ const names = /* @__PURE__ */ new Set();
1645
+ EXPORT_DECL_RE.lastIndex = 0;
1646
+ let m;
1647
+ while ((m = EXPORT_DECL_RE.exec(content)) !== null) {
1648
+ names.add(m[1]);
1649
+ }
1650
+ EXPORT_LIST_RE.lastIndex = 0;
1651
+ while ((m = EXPORT_LIST_RE.exec(content)) !== null) {
1652
+ for (const raw of m[1].split(",")) {
1653
+ const item = raw.trim();
1654
+ if (item.length === 0) continue;
1655
+ if (/^type\s/.test(item)) continue;
1656
+ const spec = EXPORT_SPECIFIER_RE.exec(item);
1657
+ if (spec === null) continue;
1658
+ const exported = spec[2] ?? spec[1];
1659
+ if (exported === "default") continue;
1660
+ names.add(exported);
1661
+ }
1662
+ }
1663
+ return [...names];
1664
+ }
1640
1665
  function computePlatformReactPages(input) {
1641
1666
  const routePrefix = `/extensions/${input.slug}/`;
1642
1667
  const routeRoot = `/extensions/${input.slug}`;
@@ -1653,6 +1678,7 @@ function computePlatformReactPages(input) {
1653
1678
  const entries = [];
1654
1679
  const missingViews = [];
1655
1680
  const unregisteredViews = [];
1681
+ const ambiguousViews = [];
1656
1682
  for (const { file, content, moduleSpecifier } of input.pages) {
1657
1683
  const name = basename(file, ".tsx");
1658
1684
  const override = input.pageOverrides?.[file] ?? {};
@@ -1669,6 +1695,15 @@ function computePlatformReactPages(input) {
1669
1695
  }
1670
1696
  if (input.viewFiles[v] !== void 0) {
1671
1697
  views[v] = input.viewFiles[v];
1698
+ continue;
1699
+ }
1700
+ const byExport = input.viewExports?.[v] ?? [];
1701
+ if (byExport.length === 1) {
1702
+ views[v] = byExport[0];
1703
+ } else if (byExport.length > 1) {
1704
+ ambiguousViews.push(
1705
+ `${file}: view "${v}" matches no adapter filename and is exported by ${byExport.length} adapter files, so the binding is ambiguous: ${byExport.join(", ")}. Rename the view, or give the intended file that basename (a filename match always wins)`
1706
+ );
1672
1707
  } else {
1673
1708
  missingViews.push(`${file}: view "${v}" has no adapter file`);
1674
1709
  }
@@ -1684,7 +1719,7 @@ function computePlatformReactPages(input) {
1684
1719
  views
1685
1720
  });
1686
1721
  }
1687
- return { entries, missingViews, unregisteredViews };
1722
+ return { entries, missingViews, unregisteredViews, ambiguousViews };
1688
1723
  }
1689
1724
  function walk2(dir) {
1690
1725
  const out = [];
@@ -1711,13 +1746,26 @@ function generatePlatformReactManifest(config) {
1711
1746
  const pageDirs = (Array.isArray(pagesCfg) ? pagesCfg : [pagesCfg]).map((p) => resolve(root, p));
1712
1747
  const exclude = new Set(config.paths?.pageExclude ?? []);
1713
1748
  const viewFiles = {};
1749
+ const viewExportsByName = /* @__PURE__ */ new Map();
1714
1750
  if (existsSync(adapterDir)) {
1715
1751
  for (const f of walk2(adapterDir)) {
1716
1752
  if (f.endsWith(".tsx")) {
1717
- viewFiles[basename(f, ".tsx")] = slash2(relative(root, f));
1753
+ const rel = slash2(relative(root, f));
1754
+ viewFiles[basename(f, ".tsx")] = rel;
1755
+ for (const name of parseExportedNames(readFileSync(f, "utf8"))) {
1756
+ let paths = viewExportsByName.get(name);
1757
+ if (paths === void 0) {
1758
+ paths = /* @__PURE__ */ new Set();
1759
+ viewExportsByName.set(name, paths);
1760
+ }
1761
+ paths.add(rel);
1762
+ }
1718
1763
  }
1719
1764
  }
1720
1765
  }
1766
+ const viewExports = Object.fromEntries(
1767
+ [...viewExportsByName].map(([name, paths]) => [name, [...paths].sort()])
1768
+ );
1721
1769
  const seen = /* @__PURE__ */ new Map();
1722
1770
  const pages = [];
1723
1771
  for (const dir of pageDirs) {
@@ -1741,13 +1789,14 @@ function generatePlatformReactManifest(config) {
1741
1789
  });
1742
1790
  }
1743
1791
  }
1744
- const { entries, missingViews, unregisteredViews } = computePlatformReactPages({
1792
+ const { entries, missingViews, unregisteredViews, ambiguousViews } = computePlatformReactPages({
1745
1793
  module,
1746
1794
  moduleKeys: config.moduleKeys,
1747
1795
  slug,
1748
1796
  routeMeta,
1749
1797
  pages,
1750
1798
  viewFiles,
1799
+ viewExports,
1751
1800
  pageOverrides: config.pageOverrides
1752
1801
  });
1753
1802
  const schema = config.manifest.schema ?? DEFAULT_SCHEMA;
@@ -1793,13 +1842,15 @@ function generatePlatformReactManifest(config) {
1793
1842
  pagesWithoutView,
1794
1843
  missingViews,
1795
1844
  unregisteredViews,
1845
+ ambiguousViews,
1796
1846
  featureManifestPath,
1797
1847
  overlayPath
1798
1848
  };
1799
- if ((config.strict ?? true) && (missingViews.length > 0 || unregisteredViews.length > 0)) {
1849
+ const diagnostics = [...unregisteredViews, ...ambiguousViews, ...missingViews];
1850
+ if ((config.strict ?? true) && diagnostics.length > 0) {
1800
1851
  throw new Error(
1801
- `generate-manifest: ${missingViews.length + unregisteredViews.length} unresolvable useView call(s). Each renders "View not available" at runtime behind a green build:
1802
- ` + [...unregisteredViews, ...missingViews].map((d) => ` - ${d}`).join("\n")
1852
+ `generate-manifest: ${diagnostics.length} unresolvable useView call(s). Each renders "View not available" at runtime behind a green build:
1853
+ ` + diagnostics.map((d) => ` - ${d}`).join("\n")
1803
1854
  );
1804
1855
  }
1805
1856
  return result;
@@ -2142,6 +2193,6 @@ function ethisysManifestPlugin(options = {}) {
2142
2193
  };
2143
2194
  }
2144
2195
 
2145
- export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
2196
+ export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
2146
2197
  //# sourceMappingURL=index.js.map
2147
2198
  //# sourceMappingURL=index.js.map