@cmssy/remix 9.10.0 → 10.1.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 +9 -114
- package/dist/index.d.cts +2 -29
- package/dist/index.d.ts +2 -29
- package/dist/index.js +4 -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,75 +52,7 @@ 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
|
|
|
@@ -127,10 +60,6 @@ Object.defineProperty(exports, "CMSSY_LOCALE_HEADER", {
|
|
|
127
60
|
enumerable: true,
|
|
128
61
|
get: function () { return core.CMSSY_LOCALE_HEADER; }
|
|
129
62
|
});
|
|
130
|
-
Object.defineProperty(exports, "buildBlockContext", {
|
|
131
|
-
enumerable: true,
|
|
132
|
-
get: function () { return core.buildBlockContext; }
|
|
133
|
-
});
|
|
134
63
|
Object.defineProperty(exports, "createCmssyClient", {
|
|
135
64
|
enumerable: true,
|
|
136
65
|
get: function () { return core.createCmssyClient; }
|
|
@@ -139,30 +68,6 @@ Object.defineProperty(exports, "defineCmssyConfig", {
|
|
|
139
68
|
enumerable: true,
|
|
140
69
|
get: function () { return core.defineCmssyConfig; }
|
|
141
70
|
});
|
|
142
|
-
Object.defineProperty(exports, "fetchLayouts", {
|
|
143
|
-
enumerable: true,
|
|
144
|
-
get: function () { return core.fetchLayouts; }
|
|
145
|
-
});
|
|
146
|
-
Object.defineProperty(exports, "fetchPage", {
|
|
147
|
-
enumerable: true,
|
|
148
|
-
get: function () { return core.fetchPage; }
|
|
149
|
-
});
|
|
150
|
-
Object.defineProperty(exports, "fetchPageMeta", {
|
|
151
|
-
enumerable: true,
|
|
152
|
-
get: function () { return core.fetchPageMeta; }
|
|
153
|
-
});
|
|
154
|
-
Object.defineProperty(exports, "fetchPages", {
|
|
155
|
-
enumerable: true,
|
|
156
|
-
get: function () { return core.fetchPages; }
|
|
157
|
-
});
|
|
158
|
-
Object.defineProperty(exports, "fetchProduct", {
|
|
159
|
-
enumerable: true,
|
|
160
|
-
get: function () { return core.fetchProduct; }
|
|
161
|
-
});
|
|
162
|
-
Object.defineProperty(exports, "fetchProducts", {
|
|
163
|
-
enumerable: true,
|
|
164
|
-
get: function () { return core.fetchProducts; }
|
|
165
|
-
});
|
|
166
71
|
Object.defineProperty(exports, "isVerifiedEditUrl", {
|
|
167
72
|
enumerable: true,
|
|
168
73
|
get: function () { return core.isVerifiedEditUrl; }
|
|
@@ -171,15 +76,5 @@ Object.defineProperty(exports, "localizeHref", {
|
|
|
171
76
|
enumerable: true,
|
|
172
77
|
get: function () { return core.localizeHref; }
|
|
173
78
|
});
|
|
174
|
-
Object.defineProperty(exports, "localizedPath", {
|
|
175
|
-
enumerable: true,
|
|
176
|
-
get: function () { return core.localizedPath; }
|
|
177
|
-
});
|
|
178
|
-
Object.defineProperty(exports, "resolveSiteLocales", {
|
|
179
|
-
enumerable: true,
|
|
180
|
-
get: function () { return core.resolveSiteLocales; }
|
|
181
|
-
});
|
|
182
79
|
exports.createCmssyHeaders = createCmssyHeaders;
|
|
183
80
|
exports.createCmssyLoader = createCmssyLoader;
|
|
184
|
-
exports.createCmssyRobots = createCmssyRobots;
|
|
185
|
-
exports.createCmssySitemap = createCmssySitemap;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CmssyPageData, CmssyLayoutGroup, CmssyConfig } from '@cmssy/core';
|
|
2
|
-
export { CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData,
|
|
2
|
+
export { CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl, localizeHref } from '@cmssy/core';
|
|
3
3
|
|
|
4
4
|
interface CmssyRouteData {
|
|
5
5
|
page: CmssyPageData | null;
|
|
@@ -30,31 +30,4 @@ declare function createCmssyLoader(config: CmssyConfig): ({ request, }: {
|
|
|
30
30
|
*/
|
|
31
31
|
declare function createCmssyHeaders(config: CmssyConfig): () => Record<string, string>;
|
|
32
32
|
|
|
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 };
|
|
33
|
+
export { type CmssyRouteData, createCmssyHeaders, createCmssyLoader };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CmssyPageData, CmssyLayoutGroup, CmssyConfig } from '@cmssy/core';
|
|
2
|
-
export { CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData,
|
|
2
|
+
export { CMSSY_LOCALE_HEADER, CmssyBlockContext, CmssyConfig, CmssyEnvConfig, CmssyLayoutGroup, CmssyPageData, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl, localizeHref } from '@cmssy/core';
|
|
3
3
|
|
|
4
4
|
interface CmssyRouteData {
|
|
5
5
|
page: CmssyPageData | null;
|
|
@@ -30,31 +30,4 @@ declare function createCmssyLoader(config: CmssyConfig): ({ request, }: {
|
|
|
30
30
|
*/
|
|
31
31
|
declare function createCmssyHeaders(config: CmssyConfig): () => Record<string, string>;
|
|
32
32
|
|
|
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 };
|
|
33
|
+
export { type CmssyRouteData, createCmssyHeaders, createCmssyLoader };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { isVerifiedEditUrl, CMSSY_EDIT_QUERY_PARAM,
|
|
2
|
-
export { CMSSY_LOCALE_HEADER,
|
|
1
|
+
import { isVerifiedEditUrl, CMSSY_EDIT_QUERY_PARAM, CMSSY_SECRET_QUERY_PARAM } from '@cmssy/core';
|
|
2
|
+
export { CMSSY_LOCALE_HEADER, createCmssyClient, defineCmssyConfig, isVerifiedEditUrl, localizeHref } from '@cmssy/core';
|
|
3
|
+
import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, CMSSY_LOCALE_HEADER, fetchPage, fetchLayouts, cmssyCspHeaders } from '@cmssy/core/internal';
|
|
3
4
|
|
|
4
5
|
// src/loader.ts
|
|
5
6
|
function createCmssyLoader(config) {
|
|
@@ -53,73 +54,5 @@ function createCmssyHeaders(config) {
|
|
|
53
54
|
return cmssyCspHeaders({ editorOrigin: config.editorOrigin });
|
|
54
55
|
};
|
|
55
56
|
}
|
|
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
57
|
|
|
125
|
-
export { createCmssyHeaders, createCmssyLoader
|
|
58
|
+
export { createCmssyHeaders, createCmssyLoader };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/remix",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.1.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.1.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "tsup",
|