@mosaicast/plugin-sdk 0.11.0 → 0.12.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/README.md CHANGED
@@ -397,7 +397,8 @@ ctx.route.navigate('index', { replace: true }); // no back-button step (ta
397
397
  against the host's current router and is not part of the contract.
398
398
  - Pair it with `ShareMetadataProvider` (OpenGraph per subpath) and `SitemapProvider` on the backend so the
399
399
  URLs you navigate to also preview and index properly — and with `PageRouteProvider` (since 0.9.1) so the
400
- ones that do *not* exist answer 404 instead of a 200 with a not-found view in it.
400
+ ones that do *not* exist answer 404 instead of a 200 with a not-found view in it. If your pages come in
401
+ more than one language, [say so](#saying-what-language-a-page-is-in-since-0120) (since 0.12.0).
401
402
 
402
403
  ### Reading the query, and matching a route (since 0.9.0)
403
404
 
@@ -737,6 +738,43 @@ var routes = new PageRouteProviderHarness(new WikiRoutes(store)).check("glossary
737
738
  assertEquals(List.of("glossary/tpyo"), routes.notFound());
738
739
  ```
739
740
 
741
+ ### Saying what language a page is in (since 0.12.0)
742
+
743
+ A URL can now name a language — `?lang=de` (§12.7) — and `sitemap.xml` emits `hreflang` alternates with
744
+ `x-default` on the bare URL. Before 0.12.0 a plugin could not join in, and the host **deliberately emitted
745
+ no alternates** for plugin entries rather than assuming the site's UI languages apply to content it cannot
746
+ read. Two components close that:
747
+
748
+ ```java
749
+ // og:locale for this URL. null (the 3-arg constructor) = whatever the host resolved — most plugin pages.
750
+ new OgMeta(page.title(), page.excerpt(), page.imageUrl(), "de");
751
+
752
+ // locale code → the path that page is written in that language, loc itself included.
753
+ var group = Map.of("en", "/p/wiki/article", "de", "/p/wiki/artikel");
754
+ new SitemapUrl("/p/wiki/article", updatedAt, group);
755
+ new SitemapUrl("/p/wiki/changelog", updatedAt); // nothing translated, as before
756
+ ```
757
+
758
+ **A map of paths, not a list of locale codes**, for two reasons. A list cannot say what language `loc`
759
+ *itself* is in and the host will not guess — hence the required self-entry, which the constructor enforces.
760
+ And translations do not always live at one path: `/p/wiki/artikel` and `/p/wiki/article` are one group, and
761
+ a list of codes has no way to link them. Render one path per language? Map every locale to the same `loc`.
762
+
763
+ **The host still owns URL shape.** Values are paths, never full URLs and never carrying `?lang=` yourself;
764
+ the host adds the parameter, leaves the site default **bare**, points `x-default` there, makes the group
765
+ reciprocal, and confines every alternate to your own `/p/<pluginId>/` namespace exactly as it does `loc`.
766
+ And an alternate is a **claim about content** — list a language only if that page is really written in it.
767
+ Serving your default language to a reader who asked for German is a kindness; telling a crawler a
768
+ translation exists and handing it the original is not.
769
+
770
+ `SitemapProviderHarness` is the test, because the host's answer to anything it will not accept is to
771
+ *drop* it — the provider still returns, and the pages just never appear:
772
+
773
+ ```java
774
+ var sitemap = new SitemapProviderHarness("wiki", new WikiSitemap(store)).collect();
775
+ assertTrue(sitemap.problems().isEmpty()); // outside the namespace, hand-written ?lang=, split groups
776
+ ```
777
+
740
778
  ## Logging — `ctx.logger()` / `ctx.log()` (since 0.4.0)
741
779
 
742
780
  ```java
@@ -907,8 +945,10 @@ first refusal in front of a podcaster.
907
945
 
908
946
  **The extension-point harnesses** (Java): `SearchProviderHarness` calls a provider once per role including
909
947
  anonymous; `UserDataHandlerHarness.eraseTwice(userId)` proves erasure survives the host's retry;
910
- `PageRouteProviderHarness.check(...)` answers which subpaths 404, always probing the plugin root. All three
911
- are shown under
948
+ `PageRouteProviderHarness.check(...)` answers which subpaths 404, always probing the plugin root;
949
+ `SitemapProviderHarness.collect()` (since 0.12.0) reports what the host would silently drop from your
950
+ sitemap entries — a `loc` or an `hreflang` alternate outside your namespace, a hand-written `?lang=`, or one
951
+ translation group declared two different ways. All four are shown under
912
952
  [Optional extension points](#optional-extension-points--searchprovider-userdatahandler-pagerouteprovider).
913
953
 
914
954
  ## Contributing
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  * rejects a mismatch at startup (ARCHITECTURE §7.2). While the SDK is pre-1.0 a breaking change is
18
18
  * therefore a *minor* bump; from `1.0.0` on, breaking means major.
19
19
  */
20
- export declare const PLATFORM_API_VERSION: '0.11.0';
20
+ export declare const PLATFORM_API_VERSION: '0.12.0';
21
21
  /** A user's role (ARCHITECTURE §8.5). Anonymous visitors have no role (`user` is `null`). */
22
22
  export type Role = 'admin' | 'podcaster' | 'fan';
23
23
  /**
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * rejects a mismatch at startup (ARCHITECTURE §7.2). While the SDK is pre-1.0 a breaking change is
20
20
  * therefore a *minor* bump; from `1.0.0` on, breaking means major.
21
21
  */
22
- export const PLATFORM_API_VERSION = '0.11.0';
22
+ export const PLATFORM_API_VERSION = '0.12.0';
23
23
  /**
24
24
  * The id every `user` data path carries: the literal `me`, mirroring the Java `Scope.SELF_ID`.
25
25
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mosaicast/plugin-sdk",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Versioned plugin contract for Mosaicast: the frontend PluginContext types, a Web Component base helper, an i18n helper, plus a test kit under the /testing subpath.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {