@uniweb/core 0.12.0 → 0.12.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/website.js +33 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/core",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Core classes for the Uniweb platform - Uniweb, Website, Page, Block",
5
5
  "type": "module",
6
6
  "exports": {
package/src/website.js CHANGED
@@ -12,6 +12,7 @@ import ObservableState from './observable-state.js'
12
12
  import { normalizeSeo } from './seo.js'
13
13
  import { resolveDefaultLocale, localeLabel } from './locale-config.js'
14
14
  import { matchDynamicRoute, decodeRouteValue } from './route-match.js'
15
+ import { resolveService } from './services.js'
15
16
 
16
17
  /**
17
18
  * Website — orchestration root for a single site instance.
@@ -1041,9 +1042,38 @@ export default class Website {
1041
1042
  */
1042
1043
  isSearchEnabled() {
1043
1044
  const search = this.config?.search
1044
- if (typeof search === 'boolean') return search
1045
- // Enabled by default unless explicitly disabled.
1046
- return search?.enabled !== false
1045
+ if (typeof search === 'boolean') {
1046
+ if (!search) return false
1047
+ } else if (search?.enabled === false) {
1048
+ return false
1049
+ }
1050
+
1051
+ // ⭐ THE HOST GETS A SAY, and this is the half that reaches an already-
1052
+ // published foundation. A foundation bundles its own frozen copy of
1053
+ // `@uniweb/kit`, so a fix made in kit never reaches one built before it.
1054
+ // `@uniweb/core` is different: the runtime carries it and re-exports it
1055
+ // through the import map, so a foundation of any age calls THIS method.
1056
+ //
1057
+ // A host that publishes a services block is stating what it offers. If it
1058
+ // does not name `search`, the site has no search — and a control for a
1059
+ // service the site does not have must not be drawn. That is the rule for
1060
+ // every service (`submit` draws no form, `assistant` and `tracking` draw
1061
+ // nothing); search was the outlier only because it had a legacy local
1062
+ // index to fall through to, and on a host-served site nothing emits one.
1063
+ //
1064
+ // ⛔ Deliberately no reason and no message: not-provisioned is not an
1065
+ // error, and any text a visitor reads is site content — authored and
1066
+ // localized — never a string a service layer invents.
1067
+ //
1068
+ // A site's OWN `search.endpoint` still wins: `resolveService` answers from
1069
+ // the site tier first, so self-hosted search on a host that does not sell
1070
+ // it is untouched.
1071
+ const { url, source } = resolveService(this, 'search')
1072
+ if (source === 'host' && !url) return false
1073
+
1074
+ // Enabled by default — absent means enabled, and a host that publishes no
1075
+ // services block at all has declined nothing (the static-host path).
1076
+ return true
1047
1077
  }
1048
1078
 
1049
1079
  /**