@cmssy/remix 9.9.0 → 10.0.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/dist/index.cjs +24 -101
- package/dist/index.d.cts +3 -29
- package/dist/index.d.ts +3 -29
- package/dist/index.js +5 -71
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@cmssy/core');
|
|
4
|
+
var internal = require('@cmssy/core/internal');
|
|
4
5
|
|
|
5
6
|
// src/loader.ts
|
|
6
7
|
function createCmssyLoader(config) {
|
|
@@ -10,14 +11,14 @@ function createCmssyLoader(config) {
|
|
|
10
11
|
const url = new URL(request.url);
|
|
11
12
|
const isEdit = await core.isVerifiedEditUrl(url, config);
|
|
12
13
|
const editRequested = url.searchParams.getAll(core.CMSSY_EDIT_QUERY_PARAM).includes("1");
|
|
13
|
-
if (!isEdit && editRequested &&
|
|
14
|
+
if (!isEdit && editRequested && internal.isDevelopment()) {
|
|
14
15
|
const { collectEditDiagnostics, renderEditDiagnostics } = await import('@cmssy/core/preflight');
|
|
15
16
|
const diagnosed = await collectEditDiagnostics({
|
|
16
17
|
config,
|
|
17
18
|
providedSecret: url.searchParams.get(core.CMSSY_SECRET_QUERY_PARAM),
|
|
18
19
|
devOrigin: url.origin
|
|
19
20
|
});
|
|
20
|
-
const locales = await
|
|
21
|
+
const locales = await internal.resolveSiteLocales(config);
|
|
21
22
|
return {
|
|
22
23
|
page: null,
|
|
23
24
|
layouts: [],
|
|
@@ -29,14 +30,14 @@ function createCmssyLoader(config) {
|
|
|
29
30
|
diagnostics: renderEditDiagnostics(diagnosed)
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
|
-
const siteLocales = await
|
|
33
|
+
const siteLocales = await internal.resolveSiteLocales(config);
|
|
33
34
|
const segments = url.pathname.split("/").filter(Boolean);
|
|
34
|
-
const fromPath =
|
|
35
|
-
const locale = request.headers.get(
|
|
35
|
+
const fromPath = internal.splitLocaleFromPath(segments, siteLocales);
|
|
36
|
+
const locale = request.headers.get(internal.CMSSY_LOCALE_HEADER) ?? fromPath.locale;
|
|
36
37
|
const previewSecret = isEdit ? config.draftSecret : void 0;
|
|
37
38
|
const [page, layouts] = await Promise.all([
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
internal.fetchPage(config, fromPath.path, { previewSecret }),
|
|
40
|
+
internal.fetchLayouts(config, fromPath.path, { previewSecret })
|
|
40
41
|
]);
|
|
41
42
|
return {
|
|
42
43
|
page,
|
|
@@ -51,82 +52,10 @@ function createCmssyLoader(config) {
|
|
|
51
52
|
}
|
|
52
53
|
function createCmssyHeaders(config) {
|
|
53
54
|
return function cmssyHeaders() {
|
|
54
|
-
return
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function xmlEscape(value) {
|
|
58
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
59
|
-
}
|
|
60
|
-
function baseUrlFor(config, url, request) {
|
|
61
|
-
if (config.siteUrl) return config.siteUrl.replace(/\/+$/, "");
|
|
62
|
-
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host");
|
|
63
|
-
if (!host) return url.origin.replace(/\/+$/, "");
|
|
64
|
-
const protocol = request.headers.get("x-forwarded-proto") ?? (host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https");
|
|
65
|
-
return `${protocol}://${host}`.replace(/\/+$/, "");
|
|
66
|
-
}
|
|
67
|
-
function createCmssySitemap(config, options = {}) {
|
|
68
|
-
return async function loader({
|
|
69
|
-
request
|
|
70
|
-
}) {
|
|
71
|
-
const baseUrl = baseUrlFor(config, new URL(request.url), request);
|
|
72
|
-
const { defaultLocale, locales } = await core.resolveSiteLocales(config);
|
|
73
|
-
const pages = await core.fetchPages(config);
|
|
74
|
-
const entries = [];
|
|
75
|
-
for (const page of pages) {
|
|
76
|
-
const slug = core.normalizeSlug(page.slug);
|
|
77
|
-
for (const locale of locales) {
|
|
78
|
-
entries.push({
|
|
79
|
-
url: `${baseUrl}${core.localizedPath(slug, locale, defaultLocale)}`,
|
|
80
|
-
lastModified: page.updatedAt ?? void 0
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (options.extra) {
|
|
85
|
-
entries.push(
|
|
86
|
-
...await options.extra({
|
|
87
|
-
baseUrl,
|
|
88
|
-
defaultLocale,
|
|
89
|
-
locales
|
|
90
|
-
})
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
const body = [
|
|
94
|
-
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
95
|
-
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
|
|
96
|
-
...entries.map(
|
|
97
|
-
(entry) => [
|
|
98
|
-
" <url>",
|
|
99
|
-
` <loc>${xmlEscape(entry.url)}</loc>`,
|
|
100
|
-
entry.lastModified ? ` <lastmod>${xmlEscape(entry.lastModified)}</lastmod>` : "",
|
|
101
|
-
" </url>"
|
|
102
|
-
].filter(Boolean).join("\n")
|
|
103
|
-
),
|
|
104
|
-
"</urlset>"
|
|
105
|
-
].join("\n");
|
|
106
|
-
return new Response(body, {
|
|
107
|
-
headers: { "content-type": "application/xml" }
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
function createCmssyRobots(config) {
|
|
112
|
-
return async function loader({
|
|
113
|
-
request
|
|
114
|
-
}) {
|
|
115
|
-
const baseUrl = baseUrlFor(config, new URL(request.url), request);
|
|
116
|
-
const body = [
|
|
117
|
-
"User-agent: *",
|
|
118
|
-
"Allow: /",
|
|
119
|
-
`Sitemap: ${baseUrl}/sitemap.xml`,
|
|
120
|
-
""
|
|
121
|
-
].join("\n");
|
|
122
|
-
return new Response(body, { headers: { "content-type": "text/plain" } });
|
|
55
|
+
return internal.cmssyCspHeaders({ editorOrigin: config.editorOrigin });
|
|
123
56
|
};
|
|
124
57
|
}
|
|
125
58
|
|
|
126
|
-
Object.defineProperty(exports, "CMSSY_LOCALE_HEADER", {
|
|
127
|
-
enumerable: true,
|
|
128
|
-
get: function () { return core.CMSSY_LOCALE_HEADER; }
|
|
129
|
-
});
|
|
130
59
|
Object.defineProperty(exports, "buildBlockContext", {
|
|
131
60
|
enumerable: true,
|
|
132
61
|
get: function () { return core.buildBlockContext; }
|
|
@@ -139,47 +68,41 @@ Object.defineProperty(exports, "defineCmssyConfig", {
|
|
|
139
68
|
enumerable: true,
|
|
140
69
|
get: function () { return core.defineCmssyConfig; }
|
|
141
70
|
});
|
|
142
|
-
Object.defineProperty(exports, "
|
|
143
|
-
enumerable: true,
|
|
144
|
-
get: function () { return core.fetchLayouts; }
|
|
145
|
-
});
|
|
146
|
-
Object.defineProperty(exports, "fetchPage", {
|
|
71
|
+
Object.defineProperty(exports, "isVerifiedEditUrl", {
|
|
147
72
|
enumerable: true,
|
|
148
|
-
get: function () { return core.
|
|
73
|
+
get: function () { return core.isVerifiedEditUrl; }
|
|
149
74
|
});
|
|
150
|
-
Object.defineProperty(exports, "
|
|
75
|
+
Object.defineProperty(exports, "CMSSY_LOCALE_HEADER", {
|
|
151
76
|
enumerable: true,
|
|
152
|
-
get: function () { return
|
|
77
|
+
get: function () { return internal.CMSSY_LOCALE_HEADER; }
|
|
153
78
|
});
|
|
154
|
-
Object.defineProperty(exports, "
|
|
79
|
+
Object.defineProperty(exports, "fetchLayouts", {
|
|
155
80
|
enumerable: true,
|
|
156
|
-
get: function () { return
|
|
81
|
+
get: function () { return internal.fetchLayouts; }
|
|
157
82
|
});
|
|
158
|
-
Object.defineProperty(exports, "
|
|
83
|
+
Object.defineProperty(exports, "fetchPage", {
|
|
159
84
|
enumerable: true,
|
|
160
|
-
get: function () { return
|
|
85
|
+
get: function () { return internal.fetchPage; }
|
|
161
86
|
});
|
|
162
|
-
Object.defineProperty(exports, "
|
|
87
|
+
Object.defineProperty(exports, "fetchPageMeta", {
|
|
163
88
|
enumerable: true,
|
|
164
|
-
get: function () { return
|
|
89
|
+
get: function () { return internal.fetchPageMeta; }
|
|
165
90
|
});
|
|
166
|
-
Object.defineProperty(exports, "
|
|
91
|
+
Object.defineProperty(exports, "fetchPages", {
|
|
167
92
|
enumerable: true,
|
|
168
|
-
get: function () { return
|
|
93
|
+
get: function () { return internal.fetchPages; }
|
|
169
94
|
});
|
|
170
95
|
Object.defineProperty(exports, "localizeHref", {
|
|
171
96
|
enumerable: true,
|
|
172
|
-
get: function () { return
|
|
97
|
+
get: function () { return internal.localizeHref; }
|
|
173
98
|
});
|
|
174
99
|
Object.defineProperty(exports, "localizedPath", {
|
|
175
100
|
enumerable: true,
|
|
176
|
-
get: function () { return
|
|
101
|
+
get: function () { return internal.localizedPath; }
|
|
177
102
|
});
|
|
178
103
|
Object.defineProperty(exports, "resolveSiteLocales", {
|
|
179
104
|
enumerable: true,
|
|
180
|
-
get: function () { return
|
|
105
|
+
get: function () { return internal.resolveSiteLocales; }
|
|
181
106
|
});
|
|
182
107
|
exports.createCmssyHeaders = createCmssyHeaders;
|
|
183
108
|
exports.createCmssyLoader = createCmssyLoader;
|
|
184
|
-
exports.createCmssyRobots = createCmssyRobots;
|
|
185
|
-
exports.createCmssySitemap = createCmssySitemap;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CmssyPageData, CmssyLayoutGroup, CmssyConfig } from '@cmssy/core';
|
|
2
|
-
export {
|
|
2
|
+
export { CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, buildBlockContext, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl } from '@cmssy/core';
|
|
3
|
+
export { CMSSY_LOCALE_HEADER, fetchLayouts, fetchPage, fetchPageMeta, fetchPages, localizeHref, localizedPath, resolveSiteLocales } from '@cmssy/core/internal';
|
|
3
4
|
|
|
4
5
|
interface CmssyRouteData {
|
|
5
6
|
page: CmssyPageData | null;
|
|
@@ -30,31 +31,4 @@ declare function createCmssyLoader(config: CmssyConfig): ({ request, }: {
|
|
|
30
31
|
*/
|
|
31
32
|
declare function createCmssyHeaders(config: CmssyConfig): () => Record<string, string>;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
url: string;
|
|
35
|
-
lastModified?: string;
|
|
36
|
-
}
|
|
37
|
-
interface CmssySitemapOptions {
|
|
38
|
-
/**
|
|
39
|
-
* Records are not pages, so the sitemap cannot know about your products or
|
|
40
|
-
* categories. Add them here; you get the same base URL and locales the page
|
|
41
|
-
* entries use, so the two cannot disagree.
|
|
42
|
-
*/
|
|
43
|
-
extra?: (context: {
|
|
44
|
-
baseUrl: string;
|
|
45
|
-
defaultLocale: string;
|
|
46
|
-
locales: string[];
|
|
47
|
-
}) => Promise<CmssySitemapEntry[]> | CmssySitemapEntry[];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* One `<url>` per language, plus x-default - a translated page is not a
|
|
51
|
-
* duplicate, and telling Google it is keeps the translation out of the index.
|
|
52
|
-
*/
|
|
53
|
-
declare function createCmssySitemap(config: CmssyConfig, options?: CmssySitemapOptions): ({ request, }: {
|
|
54
|
-
request: Request;
|
|
55
|
-
}) => Promise<Response>;
|
|
56
|
-
declare function createCmssyRobots(config: CmssyConfig): ({ request, }: {
|
|
57
|
-
request: Request;
|
|
58
|
-
}) => Promise<Response>;
|
|
59
|
-
|
|
60
|
-
export { type CmssyRouteData, type CmssySitemapEntry, type CmssySitemapOptions, createCmssyHeaders, createCmssyLoader, createCmssyRobots, createCmssySitemap };
|
|
34
|
+
export { type CmssyRouteData, createCmssyHeaders, createCmssyLoader };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CmssyPageData, CmssyLayoutGroup, CmssyConfig } from '@cmssy/core';
|
|
2
|
-
export {
|
|
2
|
+
export { CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, buildBlockContext, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl } from '@cmssy/core';
|
|
3
|
+
export { CMSSY_LOCALE_HEADER, fetchLayouts, fetchPage, fetchPageMeta, fetchPages, localizeHref, localizedPath, resolveSiteLocales } from '@cmssy/core/internal';
|
|
3
4
|
|
|
4
5
|
interface CmssyRouteData {
|
|
5
6
|
page: CmssyPageData | null;
|
|
@@ -30,31 +31,4 @@ declare function createCmssyLoader(config: CmssyConfig): ({ request, }: {
|
|
|
30
31
|
*/
|
|
31
32
|
declare function createCmssyHeaders(config: CmssyConfig): () => Record<string, string>;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
url: string;
|
|
35
|
-
lastModified?: string;
|
|
36
|
-
}
|
|
37
|
-
interface CmssySitemapOptions {
|
|
38
|
-
/**
|
|
39
|
-
* Records are not pages, so the sitemap cannot know about your products or
|
|
40
|
-
* categories. Add them here; you get the same base URL and locales the page
|
|
41
|
-
* entries use, so the two cannot disagree.
|
|
42
|
-
*/
|
|
43
|
-
extra?: (context: {
|
|
44
|
-
baseUrl: string;
|
|
45
|
-
defaultLocale: string;
|
|
46
|
-
locales: string[];
|
|
47
|
-
}) => Promise<CmssySitemapEntry[]> | CmssySitemapEntry[];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* One `<url>` per language, plus x-default - a translated page is not a
|
|
51
|
-
* duplicate, and telling Google it is keeps the translation out of the index.
|
|
52
|
-
*/
|
|
53
|
-
declare function createCmssySitemap(config: CmssyConfig, options?: CmssySitemapOptions): ({ request, }: {
|
|
54
|
-
request: Request;
|
|
55
|
-
}) => Promise<Response>;
|
|
56
|
-
declare function createCmssyRobots(config: CmssyConfig): ({ request, }: {
|
|
57
|
-
request: Request;
|
|
58
|
-
}) => Promise<Response>;
|
|
59
|
-
|
|
60
|
-
export { type CmssyRouteData, type CmssySitemapEntry, type CmssySitemapOptions, createCmssyHeaders, createCmssyLoader, createCmssyRobots, createCmssySitemap };
|
|
34
|
+
export { type CmssyRouteData, createCmssyHeaders, createCmssyLoader };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { isVerifiedEditUrl, CMSSY_EDIT_QUERY_PARAM,
|
|
2
|
-
export {
|
|
1
|
+
import { isVerifiedEditUrl, CMSSY_EDIT_QUERY_PARAM, CMSSY_SECRET_QUERY_PARAM } from '@cmssy/core';
|
|
2
|
+
export { buildBlockContext, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl } from '@cmssy/core';
|
|
3
|
+
import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, CMSSY_LOCALE_HEADER, fetchPage, fetchLayouts, cmssyCspHeaders } from '@cmssy/core/internal';
|
|
4
|
+
export { CMSSY_LOCALE_HEADER, fetchLayouts, fetchPage, fetchPageMeta, fetchPages, localizeHref, localizedPath, resolveSiteLocales } from '@cmssy/core/internal';
|
|
3
5
|
|
|
4
6
|
// src/loader.ts
|
|
5
7
|
function createCmssyLoader(config) {
|
|
@@ -53,73 +55,5 @@ function createCmssyHeaders(config) {
|
|
|
53
55
|
return cmssyCspHeaders({ editorOrigin: config.editorOrigin });
|
|
54
56
|
};
|
|
55
57
|
}
|
|
56
|
-
function xmlEscape(value) {
|
|
57
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
58
|
-
}
|
|
59
|
-
function baseUrlFor(config, url, request) {
|
|
60
|
-
if (config.siteUrl) return config.siteUrl.replace(/\/+$/, "");
|
|
61
|
-
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host");
|
|
62
|
-
if (!host) return url.origin.replace(/\/+$/, "");
|
|
63
|
-
const protocol = request.headers.get("x-forwarded-proto") ?? (host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https");
|
|
64
|
-
return `${protocol}://${host}`.replace(/\/+$/, "");
|
|
65
|
-
}
|
|
66
|
-
function createCmssySitemap(config, options = {}) {
|
|
67
|
-
return async function loader({
|
|
68
|
-
request
|
|
69
|
-
}) {
|
|
70
|
-
const baseUrl = baseUrlFor(config, new URL(request.url), request);
|
|
71
|
-
const { defaultLocale, locales } = await resolveSiteLocales(config);
|
|
72
|
-
const pages = await fetchPages(config);
|
|
73
|
-
const entries = [];
|
|
74
|
-
for (const page of pages) {
|
|
75
|
-
const slug = normalizeSlug(page.slug);
|
|
76
|
-
for (const locale of locales) {
|
|
77
|
-
entries.push({
|
|
78
|
-
url: `${baseUrl}${localizedPath(slug, locale, defaultLocale)}`,
|
|
79
|
-
lastModified: page.updatedAt ?? void 0
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (options.extra) {
|
|
84
|
-
entries.push(
|
|
85
|
-
...await options.extra({
|
|
86
|
-
baseUrl,
|
|
87
|
-
defaultLocale,
|
|
88
|
-
locales
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
const body = [
|
|
93
|
-
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
94
|
-
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
|
|
95
|
-
...entries.map(
|
|
96
|
-
(entry) => [
|
|
97
|
-
" <url>",
|
|
98
|
-
` <loc>${xmlEscape(entry.url)}</loc>`,
|
|
99
|
-
entry.lastModified ? ` <lastmod>${xmlEscape(entry.lastModified)}</lastmod>` : "",
|
|
100
|
-
" </url>"
|
|
101
|
-
].filter(Boolean).join("\n")
|
|
102
|
-
),
|
|
103
|
-
"</urlset>"
|
|
104
|
-
].join("\n");
|
|
105
|
-
return new Response(body, {
|
|
106
|
-
headers: { "content-type": "application/xml" }
|
|
107
|
-
});
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function createCmssyRobots(config) {
|
|
111
|
-
return async function loader({
|
|
112
|
-
request
|
|
113
|
-
}) {
|
|
114
|
-
const baseUrl = baseUrlFor(config, new URL(request.url), request);
|
|
115
|
-
const body = [
|
|
116
|
-
"User-agent: *",
|
|
117
|
-
"Allow: /",
|
|
118
|
-
`Sitemap: ${baseUrl}/sitemap.xml`,
|
|
119
|
-
""
|
|
120
|
-
].join("\n");
|
|
121
|
-
return new Response(body, { headers: { "content-type": "text/plain" } });
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
58
|
|
|
125
|
-
export { createCmssyHeaders, createCmssyLoader
|
|
59
|
+
export { createCmssyHeaders, createCmssyLoader };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/remix",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "React Router 7 bindings for cmssy headless sites: page loader, framing CSP, sitemap and robots.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cmssy",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"vitest": "^2.1.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@cmssy/core": "
|
|
51
|
+
"@cmssy/core": "10.0.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "tsup",
|