@cmssy/astro 11.3.1 → 11.3.2

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/index.cjs CHANGED
@@ -6,6 +6,7 @@ var react = require('@cmssy/react');
6
6
 
7
7
  // src/middleware.ts
8
8
  var CMSSY_EDIT_PATH_PREFIX = "/cmssy-edit";
9
+ var withoutDuplicateSlashes = (pathname) => pathname.replace(/\/{2,}/g, "/") || "/";
9
10
  function cmssyMiddleware(config, options = {}) {
10
11
  return async function onRequest(context, next) {
11
12
  const { pathname } = context.url;
@@ -14,12 +15,13 @@ function cmssyMiddleware(config, options = {}) {
14
15
  const locale = await internal.localeForPathname(config, pathname);
15
16
  context.request.headers.set(internal.CMSSY_LOCALE_HEADER, locale);
16
17
  const editRequested = context.url.searchParams.getAll(core.CMSSY_EDIT_QUERY_PARAM).includes("1");
18
+ const underEditRoute = pathname === CMSSY_EDIT_PATH_PREFIX || pathname.startsWith(`${CMSSY_EDIT_PATH_PREFIX}/`);
17
19
  if (editRequested) {
18
20
  const verified = await core.isVerifiedEditUrl(context.url, config);
19
- if (verified && !pathname.startsWith(CMSSY_EDIT_PATH_PREFIX)) {
21
+ if (verified && !underEditRoute) {
20
22
  context.request.headers.set(core.CMSSY_EDIT_HEADER, "1");
21
23
  const target = `${CMSSY_EDIT_PATH_PREFIX}${pathname === "/" ? "" : pathname}${context.url.search}`;
22
- const response = await context.rewrite(
24
+ const response = await next(
23
25
  new Request(new URL(target, context.url), context.request)
24
26
  );
25
27
  core.applyCmssyCsp(response, { editorOrigin: config.editorOrigin });
@@ -34,17 +36,24 @@ function cmssyMiddleware(config, options = {}) {
34
36
  ),
35
37
  devOrigin: context.url.origin
36
38
  });
37
- return new Response(renderEditDiagnosticsDocument(diagnostics), {
39
+ const page = new Response(renderEditDiagnosticsDocument(diagnostics), {
38
40
  status: 200,
39
41
  headers: { "content-type": "text/html; charset=utf-8" }
40
42
  });
43
+ try {
44
+ core.applyCmssyCsp(page, { editorOrigin: config.editorOrigin });
45
+ } catch {
46
+ }
47
+ return page;
41
48
  }
42
49
  }
43
- if (options.stripLocalePrefix && pathname.startsWith(`/${locale}`)) {
50
+ const prefix = `/${locale}`;
51
+ const prefixed = pathname === prefix || pathname.startsWith(`${prefix}/`);
52
+ if (options.stripLocalePrefix && prefixed) {
44
53
  const { defaultLocale } = await internal.resolveSiteLocales(config);
45
54
  if (locale !== defaultLocale) {
46
- const stripped = pathname.slice(locale.length + 1) || "/";
47
- return context.rewrite(`${stripped}${context.url.search}`);
55
+ const stripped = withoutDuplicateSlashes(pathname.slice(prefix.length));
56
+ return next(`${stripped}${context.url.search}`);
48
57
  }
49
58
  }
50
59
  return next();
@@ -124,6 +133,10 @@ Object.defineProperty(exports, "localizeHref", {
124
133
  enumerable: true,
125
134
  get: function () { return core.localizeHref; }
126
135
  });
136
+ Object.defineProperty(exports, "resolveEditorOrigin", {
137
+ enumerable: true,
138
+ get: function () { return core.resolveEditorOrigin; }
139
+ });
127
140
  exports.CMSSY_EDIT_PATH_PREFIX = CMSSY_EDIT_PATH_PREFIX;
128
141
  exports.cmssyMiddleware = cmssyMiddleware;
129
142
  exports.loadCmssyPage = loadCmssyPage;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CmssyConfig, CmssyPageData, CmssyLayoutGroup } from '@cmssy/core';
2
- export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, localizeHref } from '@cmssy/core';
2
+ export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, localizeHref, resolveEditorOrigin } from '@cmssy/core';
3
3
  import { BlockDefinition } from '@cmssy/react';
4
4
 
5
5
  declare const CMSSY_EDIT_PATH_PREFIX = "/cmssy-edit";
@@ -14,8 +14,15 @@ interface CmssyMiddlewareOptions {
14
14
  interface AstroContextLike {
15
15
  url: URL;
16
16
  request: Request;
17
- rewrite: (target: string | URL | Request) => Promise<Response> | Response;
18
17
  }
18
+ /**
19
+ * The rewrite payload goes to `next`, not to `context.rewrite`. Both reach
20
+ * `applyRewriteToState`, but `context.rewrite` builds a fresh `AstroMiddleware`
21
+ * and runs this whole chain again on the rewritten URL - where the language
22
+ * prefix it just removed is gone, so a second pass resolved the default
23
+ * language and overwrote the first pass's answer.
24
+ */
25
+ type CmssyNext = (payload?: string | URL | Request) => Promise<Response> | Response;
19
26
  /**
20
27
  * The whole middleware a cmssy Astro app needs, in the order it has to happen:
21
28
  *
@@ -28,10 +35,9 @@ interface AstroContextLike {
28
35
  * The order is not a detail. Resolve the locale after the rewrite and the editor
29
36
  * preview renders in the wrong language; drop the edit flag and the header and
30
37
  * footer become markup the editor can select but not fill. Both mistakes shipped
31
- * in the Next app before this sequence existed - Astro gets it right the first
32
- * time by reusing it.
38
+ * in the Next app before this sequence existed.
33
39
  */
34
- declare function cmssyMiddleware(config: CmssyConfig, options?: CmssyMiddlewareOptions): (context: AstroContextLike, next: () => Promise<Response>) => Promise<Response>;
40
+ declare function cmssyMiddleware(config: CmssyConfig, options?: CmssyMiddlewareOptions): (context: AstroContextLike, next: CmssyNext) => Promise<Response>;
35
41
 
36
42
  interface CmssyPageResult {
37
43
  page: CmssyPageData | null;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CmssyConfig, CmssyPageData, CmssyLayoutGroup } from '@cmssy/core';
2
- export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, localizeHref } from '@cmssy/core';
2
+ export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, localizeHref, resolveEditorOrigin } from '@cmssy/core';
3
3
  import { BlockDefinition } from '@cmssy/react';
4
4
 
5
5
  declare const CMSSY_EDIT_PATH_PREFIX = "/cmssy-edit";
@@ -14,8 +14,15 @@ interface CmssyMiddlewareOptions {
14
14
  interface AstroContextLike {
15
15
  url: URL;
16
16
  request: Request;
17
- rewrite: (target: string | URL | Request) => Promise<Response> | Response;
18
17
  }
18
+ /**
19
+ * The rewrite payload goes to `next`, not to `context.rewrite`. Both reach
20
+ * `applyRewriteToState`, but `context.rewrite` builds a fresh `AstroMiddleware`
21
+ * and runs this whole chain again on the rewritten URL - where the language
22
+ * prefix it just removed is gone, so a second pass resolved the default
23
+ * language and overwrote the first pass's answer.
24
+ */
25
+ type CmssyNext = (payload?: string | URL | Request) => Promise<Response> | Response;
19
26
  /**
20
27
  * The whole middleware a cmssy Astro app needs, in the order it has to happen:
21
28
  *
@@ -28,10 +35,9 @@ interface AstroContextLike {
28
35
  * The order is not a detail. Resolve the locale after the rewrite and the editor
29
36
  * preview renders in the wrong language; drop the edit flag and the header and
30
37
  * footer become markup the editor can select but not fill. Both mistakes shipped
31
- * in the Next app before this sequence existed - Astro gets it right the first
32
- * time by reusing it.
38
+ * in the Next app before this sequence existed.
33
39
  */
34
- declare function cmssyMiddleware(config: CmssyConfig, options?: CmssyMiddlewareOptions): (context: AstroContextLike, next: () => Promise<Response>) => Promise<Response>;
40
+ declare function cmssyMiddleware(config: CmssyConfig, options?: CmssyMiddlewareOptions): (context: AstroContextLike, next: CmssyNext) => Promise<Response>;
35
41
 
36
42
  interface CmssyPageResult {
37
43
  page: CmssyPageData | null;
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { CMSSY_EDIT_HEADER, CMSSY_EDIT_QUERY_PARAM, isVerifiedEditUrl, applyCmssyCsp, CMSSY_SECRET_QUERY_PARAM } from '@cmssy/core';
2
- export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, createCmssyClient, defineCmssyConfig, localizeHref } from '@cmssy/core';
2
+ export { CMSSY_EDIT_HEADER, CMSSY_LOCALE_HEADER, createCmssyClient, defineCmssyConfig, localizeHref, resolveEditorOrigin } from '@cmssy/core';
3
3
  import { CMSSY_LOCALE_HEADER, localeForPathname, isDevelopment, resolveSiteLocales, fetchPage } from '@cmssy/core/internal';
4
4
  import { resolveCmssyLayoutSlot } from '@cmssy/react';
5
5
 
6
6
  // src/middleware.ts
7
7
  var CMSSY_EDIT_PATH_PREFIX = "/cmssy-edit";
8
+ var withoutDuplicateSlashes = (pathname) => pathname.replace(/\/{2,}/g, "/") || "/";
8
9
  function cmssyMiddleware(config, options = {}) {
9
10
  return async function onRequest(context, next) {
10
11
  const { pathname } = context.url;
@@ -13,12 +14,13 @@ function cmssyMiddleware(config, options = {}) {
13
14
  const locale = await localeForPathname(config, pathname);
14
15
  context.request.headers.set(CMSSY_LOCALE_HEADER, locale);
15
16
  const editRequested = context.url.searchParams.getAll(CMSSY_EDIT_QUERY_PARAM).includes("1");
17
+ const underEditRoute = pathname === CMSSY_EDIT_PATH_PREFIX || pathname.startsWith(`${CMSSY_EDIT_PATH_PREFIX}/`);
16
18
  if (editRequested) {
17
19
  const verified = await isVerifiedEditUrl(context.url, config);
18
- if (verified && !pathname.startsWith(CMSSY_EDIT_PATH_PREFIX)) {
20
+ if (verified && !underEditRoute) {
19
21
  context.request.headers.set(CMSSY_EDIT_HEADER, "1");
20
22
  const target = `${CMSSY_EDIT_PATH_PREFIX}${pathname === "/" ? "" : pathname}${context.url.search}`;
21
- const response = await context.rewrite(
23
+ const response = await next(
22
24
  new Request(new URL(target, context.url), context.request)
23
25
  );
24
26
  applyCmssyCsp(response, { editorOrigin: config.editorOrigin });
@@ -33,17 +35,24 @@ function cmssyMiddleware(config, options = {}) {
33
35
  ),
34
36
  devOrigin: context.url.origin
35
37
  });
36
- return new Response(renderEditDiagnosticsDocument(diagnostics), {
38
+ const page = new Response(renderEditDiagnosticsDocument(diagnostics), {
37
39
  status: 200,
38
40
  headers: { "content-type": "text/html; charset=utf-8" }
39
41
  });
42
+ try {
43
+ applyCmssyCsp(page, { editorOrigin: config.editorOrigin });
44
+ } catch {
45
+ }
46
+ return page;
40
47
  }
41
48
  }
42
- if (options.stripLocalePrefix && pathname.startsWith(`/${locale}`)) {
49
+ const prefix = `/${locale}`;
50
+ const prefixed = pathname === prefix || pathname.startsWith(`${prefix}/`);
51
+ if (options.stripLocalePrefix && prefixed) {
43
52
  const { defaultLocale } = await resolveSiteLocales(config);
44
53
  if (locale !== defaultLocale) {
45
- const stripped = pathname.slice(locale.length + 1) || "/";
46
- return context.rewrite(`${stripped}${context.url.search}`);
54
+ const stripped = withoutDuplicateSlashes(pathname.slice(prefix.length));
55
+ return next(`${stripped}${context.url.search}`);
47
56
  }
48
57
  }
49
58
  return next();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/astro",
3
- "version": "11.3.1",
3
+ "version": "11.3.2",
4
4
  "description": "Astro bindings for cmssy headless sites: middleware, page loader, sitemap and robots.",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -39,7 +39,7 @@
39
39
  "dist"
40
40
  ],
41
41
  "peerDependencies": {
42
- "astro": ">=4",
42
+ "astro": ">=4.16",
43
43
  "@cmssy/react": "^11.3.0"
44
44
  },
45
45
  "devDependencies": {
@@ -47,10 +47,10 @@
47
47
  "tsup": "^8.3.0",
48
48
  "typescript": "^5.6.0",
49
49
  "vitest": "^2.1.0",
50
- "@cmssy/react": "11.3.1"
50
+ "@cmssy/react": "11.3.2"
51
51
  },
52
52
  "dependencies": {
53
- "@cmssy/core": "11.3.1"
53
+ "@cmssy/core": "11.3.2"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsup",