@cmssy/core 9.1.1 → 9.2.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/preflight.cjs +156 -0
- package/dist/preflight.d.cts +27 -1
- package/dist/preflight.d.ts +27 -1
- package/dist/preflight.js +154 -1
- package/package.json +1 -1
package/dist/preflight.cjs
CHANGED
|
@@ -14,6 +14,159 @@ function resolvePublicUrl(config) {
|
|
|
14
14
|
return `${base}/public/${config.org}/${config.workspaceSlug}/graphql`;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// src/config.ts
|
|
18
|
+
var DEFAULT_CMSSY_EDITOR_ORIGINS = [
|
|
19
|
+
"https://cmssy.io",
|
|
20
|
+
"https://www.cmssy.io"
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
// src/edit-diagnostics.ts
|
|
24
|
+
var REQUIRED_ENV = [
|
|
25
|
+
["org", "CMSSY_ORG_SLUG"],
|
|
26
|
+
["workspaceSlug", "CMSSY_WORKSPACE_SLUG"],
|
|
27
|
+
["draftSecret", "CMSSY_DRAFT_SECRET"]
|
|
28
|
+
];
|
|
29
|
+
var SETTINGS_FIX = "copy the values from Settings \u2192 Headless in the cmssy dashboard, or run npx @cmssy/cli link";
|
|
30
|
+
async function collectEditDiagnostics(input) {
|
|
31
|
+
const { config } = input;
|
|
32
|
+
const checks = [];
|
|
33
|
+
const missing = REQUIRED_ENV.filter(([key]) => {
|
|
34
|
+
const value = config[key];
|
|
35
|
+
return !(typeof value === "string" && value.trim());
|
|
36
|
+
}).map(([, env]) => env);
|
|
37
|
+
if (missing.length > 0) {
|
|
38
|
+
checks.push({
|
|
39
|
+
name: "configuration",
|
|
40
|
+
status: "fail",
|
|
41
|
+
message: `missing environment variables: ${missing.join(", ")}`,
|
|
42
|
+
fix: SETTINGS_FIX
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
checks.push({
|
|
46
|
+
name: "configuration",
|
|
47
|
+
status: "ok",
|
|
48
|
+
message: "CMSSY_ORG_SLUG, CMSSY_WORKSPACE_SLUG and CMSSY_DRAFT_SECRET are set"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const org = config.org?.trim();
|
|
52
|
+
const workspaceSlug = config.workspaceSlug?.trim();
|
|
53
|
+
const workspace = org && workspaceSlug ? `${org}/${workspaceSlug}` : null;
|
|
54
|
+
let previewUrl;
|
|
55
|
+
if (org && workspaceSlug) {
|
|
56
|
+
const preflight = {
|
|
57
|
+
apiUrl: config.apiUrl,
|
|
58
|
+
org,
|
|
59
|
+
workspaceSlug,
|
|
60
|
+
...input.fetch ? { fetch: input.fetch } : {}
|
|
61
|
+
};
|
|
62
|
+
const reachable = await checkWorkspaceReachable(preflight);
|
|
63
|
+
previewUrl = reachable.previewUrl;
|
|
64
|
+
checks.push({
|
|
65
|
+
name: "workspace",
|
|
66
|
+
status: reachable.status,
|
|
67
|
+
message: reachable.message,
|
|
68
|
+
...reachable.fix ? { fix: reachable.fix } : {}
|
|
69
|
+
});
|
|
70
|
+
const draftSecret = config.draftSecret?.trim();
|
|
71
|
+
if (draftSecret) {
|
|
72
|
+
checks.push(
|
|
73
|
+
await diagnoseSecret(
|
|
74
|
+
{ ...preflight, draftSecret },
|
|
75
|
+
input.providedSecret
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (input.devOrigin) {
|
|
81
|
+
const preview = checkPreviewUrl(previewUrl ?? null, input.devOrigin);
|
|
82
|
+
checks.push({
|
|
83
|
+
name: "preview URL",
|
|
84
|
+
status: preview.status,
|
|
85
|
+
message: preview.message,
|
|
86
|
+
...preview.fix ? { fix: preview.fix } : {}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
checks.push({
|
|
90
|
+
name: "frame-ancestors",
|
|
91
|
+
status: "unknown",
|
|
92
|
+
message: "CSP blocking cannot be detected from inside the frame - if this page never appears in the editor at all, the likely causes are the preview URL pointing elsewhere or a Content-Security-Policy frame-ancestors that blocks the editor",
|
|
93
|
+
fix: `frame-ancestors must allow ${DEFAULT_CMSSY_EDITOR_ORIGINS.join(" ")} (cmssyCspHeaders / applyCmssyCsp set this for you)`
|
|
94
|
+
});
|
|
95
|
+
return { workspace, checks };
|
|
96
|
+
}
|
|
97
|
+
async function diagnoseSecret(preflight, providedSecret) {
|
|
98
|
+
const name = "draft secret";
|
|
99
|
+
if (!providedSecret?.trim()) {
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
status: "fail",
|
|
103
|
+
message: "the request carried no cmssySecret - a bare cmssyEdit=1 is never trusted",
|
|
104
|
+
fix: "open the page from the cmssy editor, which appends the cmssySecret itself"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const platform = await checkDraftSecret(preflight);
|
|
108
|
+
if (platform.status === "fail") {
|
|
109
|
+
return {
|
|
110
|
+
name,
|
|
111
|
+
status: "fail",
|
|
112
|
+
message: `the provided cmssySecret does not match CMSSY_DRAFT_SECRET, and ${platform.message}`,
|
|
113
|
+
...platform.fix ? { fix: platform.fix } : {}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (platform.status === "ok") {
|
|
117
|
+
return {
|
|
118
|
+
name,
|
|
119
|
+
status: "fail",
|
|
120
|
+
message: "CMSSY_DRAFT_SECRET matches this workspace, but the cmssySecret sent with the request does not match it",
|
|
121
|
+
fix: "reload the editor so it opens the preview with the current secret"
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
name,
|
|
126
|
+
status: "unknown",
|
|
127
|
+
message: `could not verify against the platform (${platform.message}); the provided cmssySecret failed local verification against CMSSY_DRAFT_SECRET`,
|
|
128
|
+
fix: `make sure CMSSY_DRAFT_SECRET matches Settings \u2192 Headless, then reload the editor`
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
var STATUS_LABEL = {
|
|
132
|
+
ok: "OK",
|
|
133
|
+
fail: "FAIL",
|
|
134
|
+
unknown: "?"
|
|
135
|
+
};
|
|
136
|
+
var DIAGNOSTICS_CSS = `
|
|
137
|
+
.cmssy-diagnostics{font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;max-width:44rem;margin:3rem auto;padding:0 1.5rem;color:#1f2328}
|
|
138
|
+
.cmssy-diagnostics h1{font-size:1.15rem;margin:0 0 .5rem}
|
|
139
|
+
.cmssy-diagnostics p{margin:.5rem 0}
|
|
140
|
+
.cmssy-diagnostics ul{list-style:none;margin:1.5rem 0;padding:0}
|
|
141
|
+
.cmssy-diagnostics li{margin:0 0 .75rem;padding:.75rem 1rem;border:1px solid #d0d7de;border-radius:6px}
|
|
142
|
+
.cmssy-diagnostics .cmssy-diagnostics-status{font-weight:700;margin-right:.5rem}
|
|
143
|
+
.cmssy-diagnostics .cmssy-diagnostics-ok{color:#1a7f37}
|
|
144
|
+
.cmssy-diagnostics .cmssy-diagnostics-fail{color:#c5273c}
|
|
145
|
+
.cmssy-diagnostics .cmssy-diagnostics-unknown{color:#9a6700}
|
|
146
|
+
.cmssy-diagnostics .cmssy-diagnostics-fix{display:block;margin-top:.25rem;opacity:.75}
|
|
147
|
+
.cmssy-diagnostics .cmssy-diagnostics-note{opacity:.65}
|
|
148
|
+
@media (prefers-color-scheme:dark){
|
|
149
|
+
.cmssy-diagnostics{color:#e6edf3}
|
|
150
|
+
.cmssy-diagnostics li{border-color:#30363d}
|
|
151
|
+
.cmssy-diagnostics .cmssy-diagnostics-ok{color:#3fb950}
|
|
152
|
+
.cmssy-diagnostics .cmssy-diagnostics-fail{color:#f85149}
|
|
153
|
+
.cmssy-diagnostics .cmssy-diagnostics-unknown{color:#d29922}
|
|
154
|
+
}
|
|
155
|
+
`.trim();
|
|
156
|
+
function escapeHtml(value) {
|
|
157
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
158
|
+
}
|
|
159
|
+
function renderEditDiagnostics(diagnostics) {
|
|
160
|
+
const items = diagnostics.checks.map(
|
|
161
|
+
(check) => `<li><span class="cmssy-diagnostics-status cmssy-diagnostics-${check.status}">${STATUS_LABEL[check.status]}</span><strong>${escapeHtml(check.name)}</strong>: ${escapeHtml(check.message)}${check.fix ? `<span class="cmssy-diagnostics-fix">fix: ${escapeHtml(check.fix)}</span>` : ""}</li>`
|
|
162
|
+
).join("");
|
|
163
|
+
const workspaceLine = diagnostics.workspace ? `<p>workspace: <strong>${escapeHtml(diagnostics.workspace)}</strong></p>` : "";
|
|
164
|
+
return `<style>${DIAGNOSTICS_CSS}</style><main class="cmssy-diagnostics"><h1>cmssy editor diagnostics</h1><p>The editor request could not be verified, so the editor preview cannot render.</p>${workspaceLine}<ul>${items}</ul><p class="cmssy-diagnostics-note">This page is shown in development only - production keeps serving a 404 here.</p></main>`;
|
|
165
|
+
}
|
|
166
|
+
function renderEditDiagnosticsDocument(diagnostics) {
|
|
167
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>cmssy editor diagnostics</title><style>body{margin:0;background:#fff}@media (prefers-color-scheme:dark){body{background:#0d1117}}</style></head><body>${renderEditDiagnostics(diagnostics)}</body></html>`;
|
|
168
|
+
}
|
|
169
|
+
|
|
17
170
|
// src/preflight.ts
|
|
18
171
|
var CMSSY_ADMIN_ORIGIN = "https://www.cmssy.io";
|
|
19
172
|
var ALLOWED_FRAME_HOSTS = ["cmssy.io", "www.cmssy.io"];
|
|
@@ -271,3 +424,6 @@ exports.checkDraftSecret = checkDraftSecret;
|
|
|
271
424
|
exports.checkFrameAncestors = checkFrameAncestors;
|
|
272
425
|
exports.checkPreviewUrl = checkPreviewUrl;
|
|
273
426
|
exports.checkWorkspaceReachable = checkWorkspaceReachable;
|
|
427
|
+
exports.collectEditDiagnostics = collectEditDiagnostics;
|
|
428
|
+
exports.renderEditDiagnostics = renderEditDiagnostics;
|
|
429
|
+
exports.renderEditDiagnosticsDocument = renderEditDiagnosticsDocument;
|
package/dist/preflight.d.cts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import { F as FetchLike } from './content-client-D0EdiqbQ.cjs';
|
|
2
2
|
import { CmssyClientConfig } from '@cmssy/types';
|
|
3
3
|
|
|
4
|
+
interface EditDiagnosticsConfig {
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
org?: string;
|
|
7
|
+
workspaceSlug?: string;
|
|
8
|
+
draftSecret?: string;
|
|
9
|
+
}
|
|
10
|
+
interface EditDiagnosticsInput {
|
|
11
|
+
config: EditDiagnosticsConfig;
|
|
12
|
+
providedSecret?: string | null;
|
|
13
|
+
devOrigin?: string;
|
|
14
|
+
fetch?: FetchLike;
|
|
15
|
+
}
|
|
16
|
+
interface EditDiagnosticsCheck {
|
|
17
|
+
name: string;
|
|
18
|
+
status: PreflightStatus;
|
|
19
|
+
message: string;
|
|
20
|
+
fix?: string;
|
|
21
|
+
}
|
|
22
|
+
interface EditDiagnostics {
|
|
23
|
+
workspace: string | null;
|
|
24
|
+
checks: EditDiagnosticsCheck[];
|
|
25
|
+
}
|
|
26
|
+
declare function collectEditDiagnostics(input: EditDiagnosticsInput): Promise<EditDiagnostics>;
|
|
27
|
+
declare function renderEditDiagnostics(diagnostics: EditDiagnostics): string;
|
|
28
|
+
declare function renderEditDiagnosticsDocument(diagnostics: EditDiagnostics): string;
|
|
29
|
+
|
|
4
30
|
type PreflightStatus = "ok" | "fail" | "unknown";
|
|
5
31
|
interface PreflightResult {
|
|
6
32
|
status: PreflightStatus;
|
|
@@ -20,4 +46,4 @@ declare function checkPreviewUrl(previewUrl: string | null | undefined, devOrigi
|
|
|
20
46
|
declare function checkFrameAncestors(cspHeaderValue: string | null | undefined): PreflightResult;
|
|
21
47
|
declare function buildEditorUrl(config: Pick<CmssyClientConfig, "org" | "workspaceSlug">, pageId?: string): string;
|
|
22
48
|
|
|
23
|
-
export { type PreflightConfig, type PreflightResult, type PreflightStatus, type WorkspaceReachableResult, buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable };
|
|
49
|
+
export { type EditDiagnostics, type EditDiagnosticsCheck, type EditDiagnosticsConfig, type EditDiagnosticsInput, type PreflightConfig, type PreflightResult, type PreflightStatus, type WorkspaceReachableResult, buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable, collectEditDiagnostics, renderEditDiagnostics, renderEditDiagnosticsDocument };
|
package/dist/preflight.d.ts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
import { F as FetchLike } from './content-client-D0EdiqbQ.js';
|
|
2
2
|
import { CmssyClientConfig } from '@cmssy/types';
|
|
3
3
|
|
|
4
|
+
interface EditDiagnosticsConfig {
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
org?: string;
|
|
7
|
+
workspaceSlug?: string;
|
|
8
|
+
draftSecret?: string;
|
|
9
|
+
}
|
|
10
|
+
interface EditDiagnosticsInput {
|
|
11
|
+
config: EditDiagnosticsConfig;
|
|
12
|
+
providedSecret?: string | null;
|
|
13
|
+
devOrigin?: string;
|
|
14
|
+
fetch?: FetchLike;
|
|
15
|
+
}
|
|
16
|
+
interface EditDiagnosticsCheck {
|
|
17
|
+
name: string;
|
|
18
|
+
status: PreflightStatus;
|
|
19
|
+
message: string;
|
|
20
|
+
fix?: string;
|
|
21
|
+
}
|
|
22
|
+
interface EditDiagnostics {
|
|
23
|
+
workspace: string | null;
|
|
24
|
+
checks: EditDiagnosticsCheck[];
|
|
25
|
+
}
|
|
26
|
+
declare function collectEditDiagnostics(input: EditDiagnosticsInput): Promise<EditDiagnostics>;
|
|
27
|
+
declare function renderEditDiagnostics(diagnostics: EditDiagnostics): string;
|
|
28
|
+
declare function renderEditDiagnosticsDocument(diagnostics: EditDiagnostics): string;
|
|
29
|
+
|
|
4
30
|
type PreflightStatus = "ok" | "fail" | "unknown";
|
|
5
31
|
interface PreflightResult {
|
|
6
32
|
status: PreflightStatus;
|
|
@@ -20,4 +46,4 @@ declare function checkPreviewUrl(previewUrl: string | null | undefined, devOrigi
|
|
|
20
46
|
declare function checkFrameAncestors(cspHeaderValue: string | null | undefined): PreflightResult;
|
|
21
47
|
declare function buildEditorUrl(config: Pick<CmssyClientConfig, "org" | "workspaceSlug">, pageId?: string): string;
|
|
22
48
|
|
|
23
|
-
export { type PreflightConfig, type PreflightResult, type PreflightStatus, type WorkspaceReachableResult, buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable };
|
|
49
|
+
export { type EditDiagnostics, type EditDiagnosticsCheck, type EditDiagnosticsConfig, type EditDiagnosticsInput, type PreflightConfig, type PreflightResult, type PreflightStatus, type WorkspaceReachableResult, buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable, collectEditDiagnostics, renderEditDiagnostics, renderEditDiagnosticsDocument };
|
package/dist/preflight.js
CHANGED
|
@@ -12,6 +12,159 @@ function resolvePublicUrl(config) {
|
|
|
12
12
|
return `${base}/public/${config.org}/${config.workspaceSlug}/graphql`;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
// src/config.ts
|
|
16
|
+
var DEFAULT_CMSSY_EDITOR_ORIGINS = [
|
|
17
|
+
"https://cmssy.io",
|
|
18
|
+
"https://www.cmssy.io"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
// src/edit-diagnostics.ts
|
|
22
|
+
var REQUIRED_ENV = [
|
|
23
|
+
["org", "CMSSY_ORG_SLUG"],
|
|
24
|
+
["workspaceSlug", "CMSSY_WORKSPACE_SLUG"],
|
|
25
|
+
["draftSecret", "CMSSY_DRAFT_SECRET"]
|
|
26
|
+
];
|
|
27
|
+
var SETTINGS_FIX = "copy the values from Settings \u2192 Headless in the cmssy dashboard, or run npx @cmssy/cli link";
|
|
28
|
+
async function collectEditDiagnostics(input) {
|
|
29
|
+
const { config } = input;
|
|
30
|
+
const checks = [];
|
|
31
|
+
const missing = REQUIRED_ENV.filter(([key]) => {
|
|
32
|
+
const value = config[key];
|
|
33
|
+
return !(typeof value === "string" && value.trim());
|
|
34
|
+
}).map(([, env]) => env);
|
|
35
|
+
if (missing.length > 0) {
|
|
36
|
+
checks.push({
|
|
37
|
+
name: "configuration",
|
|
38
|
+
status: "fail",
|
|
39
|
+
message: `missing environment variables: ${missing.join(", ")}`,
|
|
40
|
+
fix: SETTINGS_FIX
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
checks.push({
|
|
44
|
+
name: "configuration",
|
|
45
|
+
status: "ok",
|
|
46
|
+
message: "CMSSY_ORG_SLUG, CMSSY_WORKSPACE_SLUG and CMSSY_DRAFT_SECRET are set"
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const org = config.org?.trim();
|
|
50
|
+
const workspaceSlug = config.workspaceSlug?.trim();
|
|
51
|
+
const workspace = org && workspaceSlug ? `${org}/${workspaceSlug}` : null;
|
|
52
|
+
let previewUrl;
|
|
53
|
+
if (org && workspaceSlug) {
|
|
54
|
+
const preflight = {
|
|
55
|
+
apiUrl: config.apiUrl,
|
|
56
|
+
org,
|
|
57
|
+
workspaceSlug,
|
|
58
|
+
...input.fetch ? { fetch: input.fetch } : {}
|
|
59
|
+
};
|
|
60
|
+
const reachable = await checkWorkspaceReachable(preflight);
|
|
61
|
+
previewUrl = reachable.previewUrl;
|
|
62
|
+
checks.push({
|
|
63
|
+
name: "workspace",
|
|
64
|
+
status: reachable.status,
|
|
65
|
+
message: reachable.message,
|
|
66
|
+
...reachable.fix ? { fix: reachable.fix } : {}
|
|
67
|
+
});
|
|
68
|
+
const draftSecret = config.draftSecret?.trim();
|
|
69
|
+
if (draftSecret) {
|
|
70
|
+
checks.push(
|
|
71
|
+
await diagnoseSecret(
|
|
72
|
+
{ ...preflight, draftSecret },
|
|
73
|
+
input.providedSecret
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (input.devOrigin) {
|
|
79
|
+
const preview = checkPreviewUrl(previewUrl ?? null, input.devOrigin);
|
|
80
|
+
checks.push({
|
|
81
|
+
name: "preview URL",
|
|
82
|
+
status: preview.status,
|
|
83
|
+
message: preview.message,
|
|
84
|
+
...preview.fix ? { fix: preview.fix } : {}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
checks.push({
|
|
88
|
+
name: "frame-ancestors",
|
|
89
|
+
status: "unknown",
|
|
90
|
+
message: "CSP blocking cannot be detected from inside the frame - if this page never appears in the editor at all, the likely causes are the preview URL pointing elsewhere or a Content-Security-Policy frame-ancestors that blocks the editor",
|
|
91
|
+
fix: `frame-ancestors must allow ${DEFAULT_CMSSY_EDITOR_ORIGINS.join(" ")} (cmssyCspHeaders / applyCmssyCsp set this for you)`
|
|
92
|
+
});
|
|
93
|
+
return { workspace, checks };
|
|
94
|
+
}
|
|
95
|
+
async function diagnoseSecret(preflight, providedSecret) {
|
|
96
|
+
const name = "draft secret";
|
|
97
|
+
if (!providedSecret?.trim()) {
|
|
98
|
+
return {
|
|
99
|
+
name,
|
|
100
|
+
status: "fail",
|
|
101
|
+
message: "the request carried no cmssySecret - a bare cmssyEdit=1 is never trusted",
|
|
102
|
+
fix: "open the page from the cmssy editor, which appends the cmssySecret itself"
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const platform = await checkDraftSecret(preflight);
|
|
106
|
+
if (platform.status === "fail") {
|
|
107
|
+
return {
|
|
108
|
+
name,
|
|
109
|
+
status: "fail",
|
|
110
|
+
message: `the provided cmssySecret does not match CMSSY_DRAFT_SECRET, and ${platform.message}`,
|
|
111
|
+
...platform.fix ? { fix: platform.fix } : {}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (platform.status === "ok") {
|
|
115
|
+
return {
|
|
116
|
+
name,
|
|
117
|
+
status: "fail",
|
|
118
|
+
message: "CMSSY_DRAFT_SECRET matches this workspace, but the cmssySecret sent with the request does not match it",
|
|
119
|
+
fix: "reload the editor so it opens the preview with the current secret"
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
name,
|
|
124
|
+
status: "unknown",
|
|
125
|
+
message: `could not verify against the platform (${platform.message}); the provided cmssySecret failed local verification against CMSSY_DRAFT_SECRET`,
|
|
126
|
+
fix: `make sure CMSSY_DRAFT_SECRET matches Settings \u2192 Headless, then reload the editor`
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
var STATUS_LABEL = {
|
|
130
|
+
ok: "OK",
|
|
131
|
+
fail: "FAIL",
|
|
132
|
+
unknown: "?"
|
|
133
|
+
};
|
|
134
|
+
var DIAGNOSTICS_CSS = `
|
|
135
|
+
.cmssy-diagnostics{font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;max-width:44rem;margin:3rem auto;padding:0 1.5rem;color:#1f2328}
|
|
136
|
+
.cmssy-diagnostics h1{font-size:1.15rem;margin:0 0 .5rem}
|
|
137
|
+
.cmssy-diagnostics p{margin:.5rem 0}
|
|
138
|
+
.cmssy-diagnostics ul{list-style:none;margin:1.5rem 0;padding:0}
|
|
139
|
+
.cmssy-diagnostics li{margin:0 0 .75rem;padding:.75rem 1rem;border:1px solid #d0d7de;border-radius:6px}
|
|
140
|
+
.cmssy-diagnostics .cmssy-diagnostics-status{font-weight:700;margin-right:.5rem}
|
|
141
|
+
.cmssy-diagnostics .cmssy-diagnostics-ok{color:#1a7f37}
|
|
142
|
+
.cmssy-diagnostics .cmssy-diagnostics-fail{color:#c5273c}
|
|
143
|
+
.cmssy-diagnostics .cmssy-diagnostics-unknown{color:#9a6700}
|
|
144
|
+
.cmssy-diagnostics .cmssy-diagnostics-fix{display:block;margin-top:.25rem;opacity:.75}
|
|
145
|
+
.cmssy-diagnostics .cmssy-diagnostics-note{opacity:.65}
|
|
146
|
+
@media (prefers-color-scheme:dark){
|
|
147
|
+
.cmssy-diagnostics{color:#e6edf3}
|
|
148
|
+
.cmssy-diagnostics li{border-color:#30363d}
|
|
149
|
+
.cmssy-diagnostics .cmssy-diagnostics-ok{color:#3fb950}
|
|
150
|
+
.cmssy-diagnostics .cmssy-diagnostics-fail{color:#f85149}
|
|
151
|
+
.cmssy-diagnostics .cmssy-diagnostics-unknown{color:#d29922}
|
|
152
|
+
}
|
|
153
|
+
`.trim();
|
|
154
|
+
function escapeHtml(value) {
|
|
155
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
156
|
+
}
|
|
157
|
+
function renderEditDiagnostics(diagnostics) {
|
|
158
|
+
const items = diagnostics.checks.map(
|
|
159
|
+
(check) => `<li><span class="cmssy-diagnostics-status cmssy-diagnostics-${check.status}">${STATUS_LABEL[check.status]}</span><strong>${escapeHtml(check.name)}</strong>: ${escapeHtml(check.message)}${check.fix ? `<span class="cmssy-diagnostics-fix">fix: ${escapeHtml(check.fix)}</span>` : ""}</li>`
|
|
160
|
+
).join("");
|
|
161
|
+
const workspaceLine = diagnostics.workspace ? `<p>workspace: <strong>${escapeHtml(diagnostics.workspace)}</strong></p>` : "";
|
|
162
|
+
return `<style>${DIAGNOSTICS_CSS}</style><main class="cmssy-diagnostics"><h1>cmssy editor diagnostics</h1><p>The editor request could not be verified, so the editor preview cannot render.</p>${workspaceLine}<ul>${items}</ul><p class="cmssy-diagnostics-note">This page is shown in development only - production keeps serving a 404 here.</p></main>`;
|
|
163
|
+
}
|
|
164
|
+
function renderEditDiagnosticsDocument(diagnostics) {
|
|
165
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>cmssy editor diagnostics</title><style>body{margin:0;background:#fff}@media (prefers-color-scheme:dark){body{background:#0d1117}}</style></head><body>${renderEditDiagnostics(diagnostics)}</body></html>`;
|
|
166
|
+
}
|
|
167
|
+
|
|
15
168
|
// src/preflight.ts
|
|
16
169
|
var CMSSY_ADMIN_ORIGIN = "https://www.cmssy.io";
|
|
17
170
|
var ALLOWED_FRAME_HOSTS = ["cmssy.io", "www.cmssy.io"];
|
|
@@ -264,4 +417,4 @@ function buildEditorUrl(config, pageId) {
|
|
|
264
417
|
return pageId ? `${base}?pageId=${encodeURIComponent(pageId)}` : base;
|
|
265
418
|
}
|
|
266
419
|
|
|
267
|
-
export { buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable };
|
|
420
|
+
export { buildEditorUrl, checkDraftSecret, checkFrameAncestors, checkPreviewUrl, checkWorkspaceReachable, collectEditDiagnostics, renderEditDiagnostics, renderEditDiagnosticsDocument };
|