meno-astro 0.1.13 → 0.1.14

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.
@@ -3,7 +3,7 @@ import {
3
3
  extractLocaleFromPath,
4
4
  isI18nValue,
5
5
  resolveI18nValue
6
- } from "./chunk-LEJMZHGE.js";
6
+ } from "./chunk-GITHFAZG.js";
7
7
 
8
8
  // lib/runtime/i18n.ts
9
9
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -68,4 +68,4 @@ export {
68
68
  deriveLocale,
69
69
  createLocaleMiddleware
70
70
  };
71
- //# sourceMappingURL=chunk-YC3WSC6M.js.map
71
+ //# sourceMappingURL=chunk-ENCYNJWV.js.map
@@ -4265,6 +4265,7 @@ export {
4265
4265
  parseFilterExpression,
4266
4266
  serializeFilterExpression,
4267
4267
  buildSlugIndex,
4268
+ translatePath,
4268
4269
  getLocaleLinks,
4269
4270
  resolveSlugToPageId,
4270
4271
  fontFaceCss,
@@ -4273,4 +4274,4 @@ export {
4273
4274
  generateLibraryTags,
4274
4275
  filterLibrariesByContext
4275
4276
  };
4276
- //# sourceMappingURL=chunk-LEJMZHGE.js.map
4277
+ //# sourceMappingURL=chunk-GITHFAZG.js.map
@@ -11,10 +11,10 @@ import {
11
11
  scanBalanced,
12
12
  splitTopLevel,
13
13
  stripMenoSpanMarker
14
- } from "./chunk-5HBRX7IZ.js";
14
+ } from "./chunk-SYOR6LP4.js";
15
15
  import {
16
16
  singularize
17
- } from "./chunk-LEJMZHGE.js";
17
+ } from "./chunk-GITHFAZG.js";
18
18
 
19
19
  // lib/dialect/emit/emitContext.ts
20
20
  function createEmitContext(width = 80) {
@@ -1415,4 +1415,4 @@ export {
1415
1415
  emit,
1416
1416
  parse
1417
1417
  };
1418
- //# sourceMappingURL=chunk-YJMWK222.js.map
1418
+ //# sourceMappingURL=chunk-MCIBOYQT.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_I18N_CONFIG,
3
3
  migrateI18nConfig
4
- } from "./chunk-LEJMZHGE.js";
4
+ } from "./chunk-GITHFAZG.js";
5
5
 
6
6
  // lib/server/loadI18nConfig.ts
7
7
  import { existsSync, readFileSync } from "fs";
@@ -21,4 +21,4 @@ function loadI18nConfig(projectRoot) {
21
21
  export {
22
22
  loadI18nConfig
23
23
  };
24
- //# sourceMappingURL=chunk-4ICB3SZG.js.map
24
+ //# sourceMappingURL=chunk-P2SFVSXG.js.map
@@ -3,7 +3,7 @@ import {
3
3
  isStyleMapping,
4
4
  responsiveStylesToClasses,
5
5
  shortHash
6
- } from "./chunk-LEJMZHGE.js";
6
+ } from "./chunk-GITHFAZG.js";
7
7
 
8
8
  // lib/runtime/style.ts
9
9
  function resolveMappingValue(mapping, props) {
@@ -89,4 +89,4 @@ export {
89
89
  computeClassName,
90
90
  style
91
91
  };
92
- //# sourceMappingURL=chunk-ANGVNS5N.js.map
92
+ //# sourceMappingURL=chunk-Q43GCLMA.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSupportedTemplateExpression
3
- } from "./chunk-LEJMZHGE.js";
3
+ } from "./chunk-GITHFAZG.js";
4
4
 
5
5
  // lib/dialect/parse/scan.ts
6
6
  var CLOSERS = { "{": "}", "(": ")", "[": "]" };
@@ -503,4 +503,4 @@ export {
503
503
  importedLibraryUrls,
504
504
  stripImportedLibraries
505
505
  };
506
- //# sourceMappingURL=chunk-5HBRX7IZ.js.map
506
+ //# sourceMappingURL=chunk-SYOR6LP4.js.map
@@ -4,17 +4,22 @@
4
4
  * (see dialect/emit/emitNode.ts:renderEmbed). The emitter passes `html` (a raw HTML
5
5
  * string), an optional `class`, and any other attributes.
6
6
  *
7
- * Minimal but correct: inject the raw `html` verbatim. When a wrapper is needed (a
8
- * `class` or extra attributes were supplied) we wrap in a `<div>` carrying them;
9
- * otherwise we emit the HTML bare via a `<Fragment>` so no extra element is introduced.
7
+ * Minimal but correct: inject the raw `html` verbatim except internal `<a href>`s,
8
+ * which are rewritten to the active render locale (`localizeRichTextLinks`, the SSR
9
+ * rich-text parity). When a wrapper is needed (a `class` or extra attributes were
10
+ * supplied) we wrap in a `<div>` carrying them; otherwise we emit the HTML bare via a
11
+ * `<Fragment>` so no extra element is introduced.
10
12
  */
13
+ import { localizeRichTextLinks } from 'meno-astro';
14
+
11
15
  interface Props {
12
16
  html?: string;
13
17
  class?: string;
14
18
  [attr: string]: unknown;
15
19
  }
16
20
 
17
- const { html = '', class: className, ...rest } = Astro.props;
21
+ const { html: rawHtml = '', class: className, ...rest } = Astro.props;
22
+ const html = localizeRichTextLinks(rawHtml);
18
23
  const hasWrapperAttrs = Boolean(className) || Object.keys(rest).length > 0;
19
24
  ---
20
25
  {hasWrapperAttrs ? (
@@ -12,7 +12,14 @@
12
12
  * `target`). Astro's `<a>` needs a string, so we mirror that here: a string href passes
13
13
  * through; an object href is flattened to its (possibly nested) `.href`, and a `target`
14
14
  * found on the object is applied (an explicitly-passed `target` attribute still wins).
15
+ *
16
+ * The flattened href is then **localized to the active render locale** (`localizeHref`):
17
+ * authored hrefs are default-locale paths, so on a `/pl/…` render an internal `/about`
18
+ * becomes `/pl/o-nas` (slug-translated) — SSR `localizeHref` parity. External hrefs and
19
+ * default-locale renders pass through untouched.
15
20
  */
21
+ import { localizeHref } from 'meno-astro';
22
+
16
23
  interface Props {
17
24
  href?: unknown;
18
25
  class?: string;
@@ -39,7 +46,9 @@ function flattenHref(value: unknown): { href?: string; target?: string } {
39
46
  }
40
47
 
41
48
  const { href: rawHref, class: className, ...rest } = Astro.props;
42
- const { href, target } = flattenHref(rawHref);
49
+ const { href: flatHref, target } = flattenHref(rawHref);
50
+ // Internal hrefs are authored as default-locale paths — rewrite for the active locale.
51
+ const href = localizeHref(flatHref) as string | undefined;
43
52
  // An explicit `target` attribute (in `rest`) wins over one lifted from the link object.
44
53
  const attrs = target !== undefined && rest.target === undefined ? { ...rest, target } : rest;
45
54
  ---
@@ -3,9 +3,9 @@ import {
3
3
  emit,
4
4
  normalizeModel,
5
5
  parse
6
- } from "../../chunks/chunk-YJMWK222.js";
7
- import "../../chunks/chunk-5HBRX7IZ.js";
8
- import "../../chunks/chunk-LEJMZHGE.js";
6
+ } from "../../chunks/chunk-MCIBOYQT.js";
7
+ import "../../chunks/chunk-SYOR6LP4.js";
8
+ import "../../chunks/chunk-GITHFAZG.js";
9
9
  import "../../chunks/chunk-5BVKIPKS.js";
10
10
  export {
11
11
  buildAstroLineMap,
package/dist/lib/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  style
3
- } from "../chunks/chunk-ANGVNS5N.js";
3
+ } from "../chunks/chunk-Q43GCLMA.js";
4
4
  import {
5
5
  readComponentMeta,
6
6
  readPageMeta,
7
7
  stripImportedLibraries
8
- } from "../chunks/chunk-5HBRX7IZ.js";
8
+ } from "../chunks/chunk-SYOR6LP4.js";
9
9
  import {
10
10
  createLocaleMiddleware,
11
11
  deriveLocale,
@@ -13,10 +13,10 @@ import {
13
13
  i18n,
14
14
  localeFromAstro,
15
15
  runWithLocale
16
- } from "../chunks/chunk-YC3WSC6M.js";
16
+ } from "../chunks/chunk-ENCYNJWV.js";
17
17
  import {
18
18
  loadI18nConfig
19
- } from "../chunks/chunk-4ICB3SZG.js";
19
+ } from "../chunks/chunk-P2SFVSXG.js";
20
20
  import {
21
21
  buildLocalizedPath,
22
22
  buildSlugIndex,
@@ -33,64 +33,11 @@ import {
33
33
  resolveI18nValue,
34
34
  resolveSlugToPageId,
35
35
  serializeFilterExpression,
36
- serializeSortExpression
37
- } from "../chunks/chunk-LEJMZHGE.js";
36
+ serializeSortExpression,
37
+ translatePath
38
+ } from "../chunks/chunk-GITHFAZG.js";
38
39
  import "../chunks/chunk-5BVKIPKS.js";
39
40
 
40
- // lib/runtime/localeRoutes.ts
41
- function enumerateLocaleStaticPaths(mappings, config) {
42
- if (!config.locales || config.locales.length <= 1) return [];
43
- const paths = [];
44
- for (const { code } of config.locales) {
45
- if (code === config.defaultLocale) continue;
46
- for (const { pageId, slugs } of mappings) {
47
- const slug = (slugs[code] ?? slugs[config.defaultLocale] ?? slugs._default ?? (pageId === "index" ? "" : pageId)).replace(/^\/+/, "");
48
- paths.push({
49
- params: { locale: code, path: slug === "" ? void 0 : slug },
50
- props: { pageId }
51
- });
52
- }
53
- }
54
- return paths;
55
- }
56
- function pageModuleKey(pageId) {
57
- return `/src/pages/${pageId}.astro`;
58
- }
59
- function normalizePathname(pathname) {
60
- return pathname.length > 1 ? pathname.replace(/\/+$/, "") || "/" : pathname;
61
- }
62
- function resolveCurrentPage(pathname, currentLocale, config, mappings, index) {
63
- const { pathWithoutLocale } = extractLocaleFromPath(pathname, config);
64
- const slug = pathWithoutLocale.replace(/^\/+|\/+$/g, "");
65
- const byLocale = resolveSlugToPageId(slug, currentLocale, index) ?? resolveSlugToPageId(slug, config.defaultLocale, index);
66
- if (byLocale) return byLocale;
67
- const asPageId = slug === "" ? "index" : slug;
68
- return mappings.some((m) => m.pageId === asPageId) ? asPageId : void 0;
69
- }
70
- function buildHreflangLinks(pathname, currentLocale, config, mappings) {
71
- if (!config.locales || config.locales.length <= 1 || mappings.length === 0) return [];
72
- const path = normalizePathname(pathname);
73
- const index = buildSlugIndex(mappings);
74
- if (!resolveCurrentPage(path, currentLocale, config, mappings, index)) return [];
75
- const links = getLocaleLinks(path, currentLocale, config, index);
76
- const out = links.map((l) => ({ hreflang: l.langTag, href: l.path }));
77
- const defaultLink = links.find((l) => l.locale === config.defaultLocale);
78
- if (defaultLink) out.push({ hreflang: "x-default", href: defaultLink.path });
79
- return out;
80
- }
81
- function localeListItems(pathname, currentLocale, config, mappings, showCurrent) {
82
- const index = buildSlugIndex(mappings);
83
- const byCode = new Map(config.locales.map((l) => [l.code, l]));
84
- return getLocaleLinks(normalizePathname(pathname), currentLocale, config, index).filter((l) => showCurrent || !l.isCurrent).map((l) => ({
85
- locale: l.locale,
86
- href: l.path,
87
- label: l.nativeName || l.locale,
88
- langTag: l.langTag,
89
- isCurrent: l.isCurrent,
90
- icon: byCode.get(l.locale)?.icon
91
- }));
92
- }
93
-
94
41
  // lib/server/loadSlugMappings.ts
95
42
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
96
43
  import { join, relative, sep } from "path";
@@ -150,7 +97,98 @@ function loadSlugMappings(projectRoot) {
150
97
  }
151
98
  } catch {
152
99
  }
153
- return mappings.sort((a, b) => a.pageId.localeCompare(b.pageId));
100
+ const { defaultLocale } = loadI18nConfig(projectRoot);
101
+ const normalized = mappings.map(
102
+ (m) => "_default" in m.slugs ? m : { ...m, slugs: { ...m.slugs, [defaultLocale]: m.pageId === "index" ? "" : m.pageId } }
103
+ );
104
+ return normalized.sort((a, b) => a.pageId.localeCompare(b.pageId));
105
+ }
106
+
107
+ // lib/runtime/localizeHref.ts
108
+ function isInternalHref(href2) {
109
+ return typeof href2 === "string" && href2.startsWith("/") && !href2.startsWith("//");
110
+ }
111
+ function localizeHrefFor(href2, locale, config, mappings) {
112
+ if (!isInternalHref(href2) || !locale) return href2;
113
+ if (mappings.length > 0) {
114
+ return translatePath(href2, locale, config.defaultLocale, config.defaultLocale, buildSlugIndex(mappings));
115
+ }
116
+ if (locale !== config.defaultLocale) return buildLocalizedPath(href2, locale);
117
+ return href2;
118
+ }
119
+ function localizeHref(href2) {
120
+ if (!isInternalHref(href2)) return href2;
121
+ const ctx = getLocaleContext();
122
+ if (!ctx?.locale || ctx.locale === ctx.config.defaultLocale) return href2;
123
+ return localizeHrefFor(href2, ctx.locale, ctx.config, loadSlugMappings(process.cwd()));
124
+ }
125
+ function localizeRichTextLinks(html) {
126
+ if (typeof html !== "string" || !html) return html;
127
+ const ctx = getLocaleContext();
128
+ if (!ctx?.locale || ctx.locale === ctx.config.defaultLocale) return html;
129
+ const mappings = loadSlugMappings(process.cwd());
130
+ return html.replace(
131
+ /<a\b([^>]*?)href=(["'])([^"']*?)\2([^>]*?)>/gi,
132
+ (match, before, quote, href2, after) => {
133
+ if (!isInternalHref(href2)) return match;
134
+ const localized = localizeHrefFor(href2, ctx.locale, ctx.config, mappings);
135
+ return localized === href2 ? match : `<a${before}href=${quote}${localized}${quote}${after}>`;
136
+ }
137
+ );
138
+ }
139
+
140
+ // lib/runtime/localeRoutes.ts
141
+ function enumerateLocaleStaticPaths(mappings, config) {
142
+ if (!config.locales || config.locales.length <= 1) return [];
143
+ const paths = [];
144
+ for (const { code } of config.locales) {
145
+ if (code === config.defaultLocale) continue;
146
+ for (const { pageId, slugs } of mappings) {
147
+ const slug = (slugs[code] ?? slugs[config.defaultLocale] ?? slugs._default ?? (pageId === "index" ? "" : pageId)).replace(/^\/+/, "");
148
+ paths.push({
149
+ params: { locale: code, path: slug === "" ? void 0 : slug },
150
+ props: { pageId }
151
+ });
152
+ }
153
+ }
154
+ return paths;
155
+ }
156
+ function pageModuleKey(pageId) {
157
+ return `/src/pages/${pageId}.astro`;
158
+ }
159
+ function normalizePathname(pathname) {
160
+ return pathname.length > 1 ? pathname.replace(/\/+$/, "") || "/" : pathname;
161
+ }
162
+ function resolveCurrentPage(pathname, currentLocale, config, mappings, index) {
163
+ const { pathWithoutLocale } = extractLocaleFromPath(pathname, config);
164
+ const slug = pathWithoutLocale.replace(/^\/+|\/+$/g, "");
165
+ const byLocale = resolveSlugToPageId(slug, currentLocale, index) ?? resolveSlugToPageId(slug, config.defaultLocale, index);
166
+ if (byLocale) return byLocale;
167
+ const asPageId = slug === "" ? "index" : slug;
168
+ return mappings.some((m) => m.pageId === asPageId) ? asPageId : void 0;
169
+ }
170
+ function buildHreflangLinks(pathname, currentLocale, config, mappings) {
171
+ if (!config.locales || config.locales.length <= 1 || mappings.length === 0) return [];
172
+ const path = normalizePathname(pathname);
173
+ const index = buildSlugIndex(mappings);
174
+ if (!resolveCurrentPage(path, currentLocale, config, mappings, index)) return [];
175
+ const links = getLocaleLinks(path, currentLocale, config, index);
176
+ const out = links.map((l) => ({ hreflang: l.langTag, href: l.path }));
177
+ const defaultLink = links.find((l) => l.locale === config.defaultLocale);
178
+ if (defaultLink) out.push({ hreflang: "x-default", href: defaultLink.path });
179
+ return out;
180
+ }
181
+ function localeListItems(pathname, currentLocale, config, mappings, showCurrent) {
182
+ const index = buildSlugIndex(mappings);
183
+ const byCode = new Map(config.locales.map((l) => [l.code, l]));
184
+ return getLocaleLinks(normalizePathname(pathname), currentLocale, config, index).filter((l) => showCurrent || !l.isCurrent).map((l) => ({
185
+ locale: l.locale,
186
+ href: l.path,
187
+ label: l.nativeName || l.locale,
188
+ langTag: l.langTag,
189
+ isCurrent: l.isCurrent,
190
+ icon: byCode.get(l.locale)?.icon
191
+ }));
154
192
  }
155
193
 
156
194
  // lib/server/loadFontCss.ts
@@ -441,6 +479,9 @@ export {
441
479
  loadSlugMappings,
442
480
  localeFromAstro,
443
481
  localeListItems,
482
+ localizeHref,
483
+ localizeHrefFor,
484
+ localizeRichTextLinks,
444
485
  pageModuleKey,
445
486
  parseFilterExpression,
446
487
  parseSortExpression,