nuxtseo-shared 5.2.3 → 5.2.5

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.
@@ -18,6 +18,8 @@ interface DevToolsUIConfig {
18
18
  }
19
19
  interface SeoModuleInfo {
20
20
  name: string;
21
+ /** npm package name — the stable identifier the client matches installed state on. */
22
+ npm?: string;
21
23
  title: string;
22
24
  icon: string;
23
25
  route: string;
@@ -18,6 +18,8 @@ interface DevToolsUIConfig {
18
18
  }
19
19
  interface SeoModuleInfo {
20
20
  name: string;
21
+ /** npm package name — the stable identifier the client matches installed state on. */
22
+ npm?: string;
21
23
  title: string;
22
24
  icon: string;
23
25
  route: string;
package/dist/devtools.mjs CHANGED
@@ -5,7 +5,16 @@ import { join, dirname } from 'node:path';
5
5
  import { onDevToolsInitialized, extendServerRpc, addCustomTab } from '@nuxt/devtools-kit';
6
6
  import { useNuxt } from '@nuxt/kit';
7
7
  import sirv from 'sirv';
8
+ import { modules } from './const.mjs';
9
+ import { detectNuxtSeoModules } from './kit.mjs';
10
+ import 'node:url';
11
+ import 'pathe';
12
+ import 'pkg-types';
13
+ import 'std-env';
8
14
 
15
+ function npmForSlug(slug) {
16
+ return modules.find((m) => m.slug === slug)?.npm;
17
+ }
9
18
  const UNIFIED_CLIENT_ROUTE = "/__nuxt-seo-devtools";
10
19
  const hashSet = (arr) => [...JSON.stringify(arr)].reduce((h, c) => h * 31 + c.charCodeAt(0) >>> 0, 7).toString(36);
11
20
  function placeholderHtml() {
@@ -31,7 +40,24 @@ function registerSharedRpcOnce(nuxt) {
31
40
  nuxt._seoDevtoolsRpcRegistered = true;
32
41
  onDevToolsInitialized(() => {
33
42
  extendServerRpc("nuxt-seo-modules", {
34
- getInstalledSeoModules: () => nuxt._seoDevtoolsModules || []
43
+ // Registered modules (those that shipped a devtools panel) carry the iframe route.
44
+ // detectNuxtSeoModules adds every *installed* SEO module from nuxt's module list —
45
+ // independent of whether it self-registered a panel or which shared version it ships —
46
+ // so the picker reflects the full install (e.g. site-config, which has no panel).
47
+ getInstalledSeoModules: () => {
48
+ const byNpm = /* @__PURE__ */ new Map();
49
+ for (const m of nuxt._seoDevtoolsModules || []) {
50
+ if (m.npm)
51
+ byNpm.set(m.npm, m);
52
+ }
53
+ for (const det of detectNuxtSeoModules(nuxt)) {
54
+ if (!byNpm.has(det.name)) {
55
+ const meta = modules.find((s) => s.npm === det.name);
56
+ byNpm.set(det.name, { name: meta?.slug ?? det.name, npm: det.name, title: meta?.label ?? det.name, icon: meta?.icon ?? "", route: "" });
57
+ }
58
+ }
59
+ return [...byNpm.values()];
60
+ }
35
61
  }, nuxt);
36
62
  }, nuxt);
37
63
  }
@@ -79,7 +105,7 @@ function setupLayerModule(config, layerDir, nuxt) {
79
105
  const slug = config.slug ?? config.name.replace(/^nuxt-/, "");
80
106
  const clientRoute = `${UNIFIED_CLIENT_ROUTE}/${slug}`;
81
107
  const modules = nuxt._seoDevtoolsModules ??= [];
82
- modules.push({ name: config.name, title: config.title, icon: config.icon, route: clientRoute });
108
+ modules.push({ name: config.name, npm: npmForSlug(slug), title: config.title, icon: config.icon, route: clientRoute });
83
109
  const layers = nuxt._seoDevtoolsLayers ??= [];
84
110
  layers.push({ slug, name: config.name, title: config.title, icon: config.icon, layerDir });
85
111
  addCustomTab({ name: `nuxt-seo-${slug}`, title: config.title, icon: config.icon, view: { type: "iframe", src: clientRoute } });
@@ -115,9 +141,10 @@ function setupLayerModule(config, layerDir, nuxt) {
115
141
  }
116
142
  function setupLegacyModule(config, clientPath, nuxt) {
117
143
  const { name, title, icon, devPort = 3030 } = config;
118
- const route = config.route ?? `/__${name.replace(/^nuxt-/, "")}`;
144
+ const slug = config.slug ?? name.replace(/^nuxt-/, "");
145
+ const route = config.route ?? `/__${slug}`;
119
146
  const modules = nuxt._seoDevtoolsModules ??= [];
120
- modules.push({ name, title, icon, route });
147
+ modules.push({ name, npm: npmForSlug(slug), title, icon, route });
121
148
  const isProductionBuild = existsSync(clientPath) && readdirSync(clientPath).length > 0;
122
149
  if (isProductionBuild) {
123
150
  nuxt.hook("vite:serverCreated", (server) => {
@@ -155,8 +182,9 @@ function setupLegacyModule(config, clientPath, nuxt) {
155
182
  function setupDevToolsUI(config, resolve, nuxt = useNuxt()) {
156
183
  if (!nuxt.options.dev)
157
184
  return;
158
- const layerCandidates = [resolve("./devtools"), resolve("../devtools")];
159
- const layerDir = layerCandidates.find((dir) => existsSync(join(dir, "nuxt.config.ts"))) ?? layerCandidates[0];
185
+ const layerFallback = resolve("./devtools");
186
+ const layerCandidates = [layerFallback, resolve("../devtools")];
187
+ const layerDir = layerCandidates.find((dir) => existsSync(join(dir, "nuxt.config.ts"))) ?? layerFallback;
160
188
  const isLayer = existsSync(join(layerDir, "nuxt.config.ts")) && !existsSync(join(layerDir, "index.html"));
161
189
  registerSharedRpcOnce(nuxt);
162
190
  if (isLayer)
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16.0"
6
6
  },
7
- "version": "5.2.3",
7
+ "version": "5.2.5",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxtseo-shared",
3
3
  "type": "module",
4
- "version": "5.2.3",
4
+ "version": "5.2.5",
5
5
  "description": "Shared utilities for Nuxt SEO modules.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",