nuxtseo-shared 5.1.3 → 5.1.4

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/i18n.d.mts CHANGED
@@ -23,6 +23,29 @@ interface StrategyProps {
23
23
  }
24
24
  declare function generatePathForI18nPages(ctx: StrategyProps): string;
25
25
  declare function splitPathForI18nLocales(path: string, autoI18n: AutoI18nConfig): string | string[];
26
+ interface ExpandedLocaleRoute {
27
+ locale: string;
28
+ path: string;
29
+ }
30
+ /**
31
+ * Detect a compacted i18n route such as `/:locale(en|fr)/about`.
32
+ *
33
+ * Both `nuxt-i18n-micro` and `@nuxtjs/i18n` (experimental `compactRoutes`) collapse
34
+ * per-locale routes into a single regex route using this syntax, so route-table
35
+ * consumers (sitemap, link-checker) see one `:locale(...)` route instead of one per
36
+ * locale.
37
+ */
38
+ declare function isCompactLocaleRoute(path: string): boolean;
39
+ /**
40
+ * Expand a compacted i18n route into one entry per locale.
41
+ *
42
+ * `/:locale(en|fr)/about` -> `[{ locale: 'en', path: '/en/about' }, { locale: 'fr', path: '/fr/about' }]`
43
+ *
44
+ * Pass `knownLocales` to guard against a genuine `:locale` route param: when provided,
45
+ * expansion only runs if at least one captured token is a real locale code. Returns
46
+ * `null` when the path is not a compacted locale route.
47
+ */
48
+ declare function expandCompactLocaleRoute(path: string, knownLocales?: string[]): ExpandedLocaleRoute[] | null;
26
49
  declare function normalizeLocales(nuxtI18nConfig: NuxtI18nOptions): AutoI18nConfig['locales'];
27
50
  declare function mapPathForI18nPages(path: string, autoI18n: AutoI18nConfig): string[] | false;
28
51
  interface I18nModuleResolution {
@@ -40,5 +63,5 @@ declare function resolveI18nConfig(logger?: {
40
63
  }): Promise<false | AutoI18nConfig>;
41
64
  declare function mergeOnKey<T extends Record<string, any>>(arr: T[], key: keyof T): T[];
42
65
 
43
- export { generatePathForI18nPages, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
44
- export type { AutoI18nConfig, I18nModuleResolution, NormalisedLocale, Strategies, StrategyProps };
66
+ export { expandCompactLocaleRoute, generatePathForI18nPages, isCompactLocaleRoute, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
67
+ export type { AutoI18nConfig, ExpandedLocaleRoute, I18nModuleResolution, NormalisedLocale, Strategies, StrategyProps };
package/dist/i18n.d.ts CHANGED
@@ -23,6 +23,29 @@ interface StrategyProps {
23
23
  }
24
24
  declare function generatePathForI18nPages(ctx: StrategyProps): string;
25
25
  declare function splitPathForI18nLocales(path: string, autoI18n: AutoI18nConfig): string | string[];
26
+ interface ExpandedLocaleRoute {
27
+ locale: string;
28
+ path: string;
29
+ }
30
+ /**
31
+ * Detect a compacted i18n route such as `/:locale(en|fr)/about`.
32
+ *
33
+ * Both `nuxt-i18n-micro` and `@nuxtjs/i18n` (experimental `compactRoutes`) collapse
34
+ * per-locale routes into a single regex route using this syntax, so route-table
35
+ * consumers (sitemap, link-checker) see one `:locale(...)` route instead of one per
36
+ * locale.
37
+ */
38
+ declare function isCompactLocaleRoute(path: string): boolean;
39
+ /**
40
+ * Expand a compacted i18n route into one entry per locale.
41
+ *
42
+ * `/:locale(en|fr)/about` -> `[{ locale: 'en', path: '/en/about' }, { locale: 'fr', path: '/fr/about' }]`
43
+ *
44
+ * Pass `knownLocales` to guard against a genuine `:locale` route param: when provided,
45
+ * expansion only runs if at least one captured token is a real locale code. Returns
46
+ * `null` when the path is not a compacted locale route.
47
+ */
48
+ declare function expandCompactLocaleRoute(path: string, knownLocales?: string[]): ExpandedLocaleRoute[] | null;
26
49
  declare function normalizeLocales(nuxtI18nConfig: NuxtI18nOptions): AutoI18nConfig['locales'];
27
50
  declare function mapPathForI18nPages(path: string, autoI18n: AutoI18nConfig): string[] | false;
28
51
  interface I18nModuleResolution {
@@ -40,5 +63,5 @@ declare function resolveI18nConfig(logger?: {
40
63
  }): Promise<false | AutoI18nConfig>;
41
64
  declare function mergeOnKey<T extends Record<string, any>>(arr: T[], key: keyof T): T[];
42
65
 
43
- export { generatePathForI18nPages, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
44
- export type { AutoI18nConfig, I18nModuleResolution, NormalisedLocale, Strategies, StrategyProps };
66
+ export { expandCompactLocaleRoute, generatePathForI18nPages, isCompactLocaleRoute, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
67
+ export type { AutoI18nConfig, ExpandedLocaleRoute, I18nModuleResolution, NormalisedLocale, Strategies, StrategyProps };
package/dist/i18n.mjs CHANGED
@@ -1,7 +1,9 @@
1
1
  import { getNuxtModuleVersion, hasNuxtModuleCompatibility, hasNuxtModule } from '@nuxt/kit';
2
2
  import { joinURL, withHttps, withBase, withLeadingSlash } from 'ufo';
3
3
  import { getNuxtModuleOptions } from './kit.mjs';
4
+ import 'node:url';
4
5
  import 'pathe';
6
+ import 'pkg-types';
5
7
  import 'std-env';
6
8
 
7
9
  const I18N_MODULES = ["@nuxtjs/i18n", "nuxt-i18n-micro"];
@@ -33,6 +35,22 @@ function splitPathForI18nLocales(path, autoI18n) {
33
35
  ...locales.map((l) => `/${l.code}${path}`)
34
36
  ];
35
37
  }
38
+ const COMPACT_LOCALE_PATTERN = /^\/:locale\(([^)]+)\)/;
39
+ function isCompactLocaleRoute(path) {
40
+ return COMPACT_LOCALE_PATTERN.test(path);
41
+ }
42
+ function expandCompactLocaleRoute(path, knownLocales) {
43
+ const match = COMPACT_LOCALE_PATTERN.exec(path);
44
+ if (!match?.[1])
45
+ return null;
46
+ const locales = match[1].split("|");
47
+ if (knownLocales?.length && !locales.some((l) => knownLocales.includes(l)))
48
+ return null;
49
+ return locales.map((locale) => ({
50
+ locale,
51
+ path: path.replace(COMPACT_LOCALE_PATTERN, `/${locale}`)
52
+ }));
53
+ }
36
54
  function normalizeLocales(nuxtI18nConfig) {
37
55
  const rawLocales = nuxtI18nConfig.locales || [];
38
56
  let onlyLocales = nuxtI18nConfig?.bundle?.onlyLocales || [];
@@ -131,4 +149,4 @@ function mergeOnKey(arr, key) {
131
149
  return [...map.values()];
132
150
  }
133
151
 
134
- export { generatePathForI18nPages, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
152
+ export { expandCompactLocaleRoute, generatePathForI18nPages, isCompactLocaleRoute, mapPathForI18nPages, mergeOnKey, normalizeLocales, resolveI18nConfig, resolveI18nModule, splitPathForI18nLocales };
package/dist/kit.d.mts CHANGED
@@ -48,6 +48,28 @@ interface NuxtContentVersion {
48
48
  * Returns `false` when @nuxt/content is not installed or the version is unrecognised.
49
49
  */
50
50
  declare function resolveNuxtContentVersion(): Promise<false | NuxtContentVersion>;
51
+ /**
52
+ * Read the major version of a non-module package as resolved from `rootDir`.
53
+ *
54
+ * Unlike `hasNuxtModuleCompatibility`, this works for plain libraries (e.g.
55
+ * `unhead`, `@unhead/vue`) that aren't registered as Nuxt modules. Returns
56
+ * `undefined` when the package can't be resolved or has no parseable version.
57
+ */
58
+ declare function resolvePackageMajor(id: string, rootDir: string): Promise<number | undefined>;
59
+ type UnheadMajor = 2 | 3;
60
+ /**
61
+ * Resolve the major of the unhead the host app renders with.
62
+ *
63
+ * `@unhead/vue` is what the head-stack packages peer-depend on, so it's the
64
+ * primary signal; falls back to the core `unhead` package, then to `3` (the
65
+ * current default major) when neither resolves.
66
+ *
67
+ * Used to keep head-stack dependencies on a compatible major. For example,
68
+ * `@unhead/schema-org` v3 attaches an object `_resolver` to every graph node
69
+ * that unhead v2's `walkResolver` invokes as a thunk, crashing render; a module
70
+ * that ships both majors can use this to alias to the matching one.
71
+ */
72
+ declare function resolveHostUnheadMajor(rootDir: string): Promise<UnheadMajor>;
51
73
 
52
- export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveNitroPreset, resolveNuxtContentVersion };
53
- export type { NuxtContentVersion, NuxtSeoModuleDetection };
74
+ export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveHostUnheadMajor, resolveNitroPreset, resolveNuxtContentVersion, resolvePackageMajor };
75
+ export type { NuxtContentVersion, NuxtSeoModuleDetection, UnheadMajor };
package/dist/kit.d.ts CHANGED
@@ -48,6 +48,28 @@ interface NuxtContentVersion {
48
48
  * Returns `false` when @nuxt/content is not installed or the version is unrecognised.
49
49
  */
50
50
  declare function resolveNuxtContentVersion(): Promise<false | NuxtContentVersion>;
51
+ /**
52
+ * Read the major version of a non-module package as resolved from `rootDir`.
53
+ *
54
+ * Unlike `hasNuxtModuleCompatibility`, this works for plain libraries (e.g.
55
+ * `unhead`, `@unhead/vue`) that aren't registered as Nuxt modules. Returns
56
+ * `undefined` when the package can't be resolved or has no parseable version.
57
+ */
58
+ declare function resolvePackageMajor(id: string, rootDir: string): Promise<number | undefined>;
59
+ type UnheadMajor = 2 | 3;
60
+ /**
61
+ * Resolve the major of the unhead the host app renders with.
62
+ *
63
+ * `@unhead/vue` is what the head-stack packages peer-depend on, so it's the
64
+ * primary signal; falls back to the core `unhead` package, then to `3` (the
65
+ * current default major) when neither resolves.
66
+ *
67
+ * Used to keep head-stack dependencies on a compatible major. For example,
68
+ * `@unhead/schema-org` v3 attaches an object `_resolver` to every graph node
69
+ * that unhead v2's `walkResolver` invokes as a thunk, crashing render; a module
70
+ * that ships both majors can use this to alias to the matching one.
71
+ */
72
+ declare function resolveHostUnheadMajor(rootDir: string): Promise<UnheadMajor>;
51
73
 
52
- export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveNitroPreset, resolveNuxtContentVersion };
53
- export type { NuxtContentVersion, NuxtSeoModuleDetection };
74
+ export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveHostUnheadMajor, resolveNitroPreset, resolveNuxtContentVersion, resolvePackageMajor };
75
+ export type { NuxtContentVersion, NuxtSeoModuleDetection, UnheadMajor };
package/dist/kit.mjs CHANGED
@@ -1,7 +1,13 @@
1
+ import { pathToFileURL } from 'node:url';
1
2
  import { useNuxt, createResolver, addTemplate, loadNuxtModuleInstance, tryUseNuxt, hasNuxtModule, hasNuxtModuleCompatibility } from '@nuxt/kit';
2
- import { relative } from 'pathe';
3
+ import { relative, dirname } from 'pathe';
4
+ import { resolvePackageJSON, readPackageJSON } from 'pkg-types';
3
5
  import { provider, env } from 'std-env';
4
6
 
7
+ function normalizePackageUrl(rootDir) {
8
+ const url = rootDir.startsWith("file:") ? rootDir : pathToFileURL(rootDir.endsWith("/") ? rootDir : `${rootDir}/`).href;
9
+ return url.endsWith("/") ? url : `${url}/`;
10
+ }
5
11
  const NUXT_SEO_MODULES = /* @__PURE__ */ new Set([
6
12
  "@nuxtjs/robots",
7
13
  "@nuxtjs/sitemap",
@@ -115,5 +121,35 @@ async function resolveNuxtContentVersion() {
115
121
  return { version: 2 };
116
122
  return false;
117
123
  }
124
+ async function resolvePackageMajor(id, rootDir) {
125
+ const url = normalizePackageUrl(rootDir);
126
+ const version = await readPackageJSON(id, { url }).then((pkg) => pkg.version).catch(() => {
127
+ return void 0;
128
+ });
129
+ const major = version ? Number.parseInt(version, 10) : Number.NaN;
130
+ return Number.isFinite(major) ? major : void 0;
131
+ }
132
+ async function resolveHostUnheadMajor(rootDir) {
133
+ const rootUrl = normalizePackageUrl(rootDir);
134
+ const searchUrls = [];
135
+ for (const id of ["@nuxt/nitro-server", "nuxt"]) {
136
+ const pkgJson = await resolvePackageJSON(id, { url: rootUrl }).catch(() => {
137
+ return void 0;
138
+ });
139
+ if (pkgJson)
140
+ searchUrls.push(`${dirname(pkgJson)}/`);
141
+ }
142
+ searchUrls.push(rootUrl);
143
+ for (const id of ["@unhead/vue", "unhead"]) {
144
+ for (const url of searchUrls) {
145
+ const major = await resolvePackageMajor(id, url);
146
+ if (major === 2)
147
+ return 2;
148
+ if (major !== void 0 && major >= 3)
149
+ return 3;
150
+ }
151
+ }
152
+ return 3;
153
+ }
118
154
 
119
- export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveNitroPreset, resolveNuxtContentVersion };
155
+ export { createNitroPromise, createPagesPromise, detectNuxtSeoModules, detectTarget, extendTypes, getNuxtModuleOptions, isNuxtGenerate, resolveHostUnheadMajor, resolveNitroPreset, resolveNuxtContentVersion, resolvePackageMajor };
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16.0"
6
6
  },
7
- "version": "5.1.3",
7
+ "version": "5.1.4",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -4,7 +4,9 @@ import 'nuxt-site-config/kit';
4
4
  import 'ofetch';
5
5
  import 'std-env';
6
6
  import './kit.mjs';
7
+ import 'node:url';
7
8
  import 'pathe';
9
+ import 'pkg-types';
8
10
 
9
11
  const module$1 = defineNuxtModule({
10
12
  meta: {
package/dist/pro.mjs CHANGED
@@ -3,7 +3,9 @@ import { useSiteConfig } from 'nuxt-site-config/kit';
3
3
  import { $fetch } from 'ofetch';
4
4
  import { isTest } from 'std-env';
5
5
  import { detectNuxtSeoModules } from './kit.mjs';
6
+ import 'node:url';
6
7
  import 'pathe';
8
+ import 'pkg-types';
7
9
 
8
10
  function hookNuxtSeoProDataUpload() {
9
11
  const nuxt = useNuxt();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxtseo-shared",
3
3
  "type": "module",
4
- "version": "5.1.3",
4
+ "version": "5.1.4",
5
5
  "description": "Shared utilities for Nuxt SEO modules.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -75,30 +75,32 @@
75
75
  }
76
76
  },
77
77
  "dependencies": {
78
- "@clack/prompts": "^1.2.0",
78
+ "@clack/prompts": "^1.5.1",
79
79
  "@nuxt/devtools-kit": "4.0.0-alpha.3",
80
- "@nuxt/kit": "^4.4.2",
80
+ "@nuxt/kit": "^4.4.7",
81
81
  "birpc": "^4.0.0",
82
82
  "consola": "^3.4.2",
83
83
  "defu": "^6.1.7",
84
84
  "ofetch": "^1.5.1",
85
85
  "pathe": "^2.0.3",
86
- "pkg-types": "^2.3.0",
86
+ "pkg-types": "^2.3.1",
87
87
  "radix3": "^1.1.2",
88
88
  "sirv": "^3.0.2",
89
- "std-env": "^4.0.0",
90
- "ufo": "^1.6.3"
89
+ "std-env": "^4.1.0",
90
+ "ufo": "^1.6.4"
91
91
  },
92
92
  "devDependencies": {
93
- "@arethetypeswrong/cli": "^0.18.2",
93
+ "@arethetypeswrong/cli": "^0.18.3",
94
94
  "@nuxt/module-builder": "^1.0.2",
95
- "@nuxt/schema": "^4.4.2",
96
- "@nuxtjs/i18n": "^10.2.4",
95
+ "@nuxt/schema": "^4.4.7",
96
+ "@nuxtjs/i18n": "^10.4.0",
97
+ "nitropack": "^2.13.4",
98
+ "nuxt": "^4.4.7",
97
99
  "nuxt-site-config": "^4.0.8",
98
- "typescript": "^6.0.2",
99
- "vitest": "^4.1.4",
100
- "vue": "^3.5.32",
101
- "vue-tsc": "^3.2.6"
100
+ "typescript": "^6.0.3",
101
+ "vitest": "^4.1.8",
102
+ "vue": "^3.5.35",
103
+ "vue-tsc": "^3.3.3"
102
104
  },
103
105
  "scripts": {
104
106
  "build": "nuxt-module-build build",
@@ -107,6 +109,6 @@
107
109
  "test": "vitest",
108
110
  "test:run": "vitest run",
109
111
  "test:attw": "attw --pack --profile esm-only",
110
- "typecheck": "vue-tsc --noEmit"
112
+ "typecheck": "nuxt typecheck ."
111
113
  }
112
114
  }