@forumulate/cli 0.8.0 → 0.10.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/README.md +11 -3
- package/dist/api/args.d.ts.map +1 -1
- package/dist/api/args.js +1 -0
- package/dist/api/args.js.map +1 -1
- package/dist/api/command.d.ts +1 -1
- package/dist/api/command.d.ts.map +1 -1
- package/dist/api/command.js +86 -11
- package/dist/api/command.js.map +1 -1
- package/dist/api/http.d.ts +8 -0
- package/dist/api/http.d.ts.map +1 -1
- package/dist/api/http.js +3 -2
- package/dist/api/http.js.map +1 -1
- package/dist/api/live-spec.d.ts +48 -0
- package/dist/api/live-spec.d.ts.map +1 -0
- package/dist/api/live-spec.js +72 -0
- package/dist/api/live-spec.js.map +1 -0
- package/dist/api/operations.json +1 -1
- package/dist/api/request.d.ts.map +1 -1
- package/dist/api/request.js +25 -1
- package/dist/api/request.js.map +1 -1
- package/dist/api/send.d.ts +10 -1
- package/dist/api/send.d.ts.map +1 -1
- package/dist/api/send.js +14 -3
- package/dist/api/send.js.map +1 -1
- package/dist/api/slim.d.ts +14 -0
- package/dist/api/slim.d.ts.map +1 -0
- package/dist/api/slim.js +174 -0
- package/dist/api/slim.js.map +1 -0
- package/dist/cache-command.d.ts +12 -0
- package/dist/cache-command.d.ts.map +1 -0
- package/dist/cache-command.js +93 -0
- package/dist/cache-command.js.map +1 -0
- package/dist/check/command.d.ts +48 -0
- package/dist/check/command.d.ts.map +1 -0
- package/dist/check/command.js +256 -0
- package/dist/check/command.js.map +1 -0
- package/dist/check/external.d.ts +66 -0
- package/dist/check/external.d.ts.map +1 -0
- package/dist/check/external.js +177 -0
- package/dist/check/external.js.map +1 -0
- package/dist/check/markdown-links.d.ts +38 -0
- package/dist/check/markdown-links.d.ts.map +1 -0
- package/dist/check/markdown-links.js +166 -0
- package/dist/check/markdown-links.js.map +1 -0
- package/dist/cli.js +42 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +17 -0
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +6 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/groups-api.d.ts.map +1 -1
- package/dist/commands/groups-api.js +20 -2
- package/dist/commands/groups-api.js.map +1 -1
- package/dist/commands/groups-docs.d.ts.map +1 -1
- package/dist/commands/groups-docs.js +8 -2
- package/dist/commands/groups-docs.js.map +1 -1
- package/dist/commands/groups-jobs.d.ts +10 -0
- package/dist/commands/groups-jobs.d.ts.map +1 -0
- package/dist/commands/groups-jobs.js +89 -0
- package/dist/commands/groups-jobs.js.map +1 -0
- package/dist/commands/groups-org.d.ts.map +1 -1
- package/dist/commands/groups-org.js +59 -2
- package/dist/commands/groups-org.js.map +1 -1
- package/dist/commands/groups-site.d.ts.map +1 -1
- package/dist/commands/groups-site.js +47 -10
- package/dist/commands/groups-site.js.map +1 -1
- package/dist/commands/groups-spaces.d.ts.map +1 -1
- package/dist/commands/groups-spaces.js +11 -5
- package/dist/commands/groups-spaces.js.map +1 -1
- package/dist/commands/groups-types.d.ts.map +1 -1
- package/dist/commands/groups-types.js +74 -0
- package/dist/commands/groups-types.js.map +1 -1
- package/dist/commands/groups.d.ts.map +1 -1
- package/dist/commands/groups.js +2 -0
- package/dist/commands/groups.js.map +1 -1
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +18 -3
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/job-wait.d.ts +64 -0
- package/dist/commands/job-wait.d.ts.map +1 -0
- package/dist/commands/job-wait.js +91 -0
- package/dist/commands/job-wait.js.map +1 -0
- package/dist/commands/resource.d.ts +19 -0
- package/dist/commands/resource.d.ts.map +1 -1
- package/dist/commands/resource.js +65 -3
- package/dist/commands/resource.js.map +1 -1
- package/dist/content/library.d.ts +8 -0
- package/dist/content/library.d.ts.map +1 -1
- package/dist/content/library.js +10 -2
- package/dist/content/library.js.map +1 -1
- package/dist/credentials.d.ts +43 -4
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +67 -4
- package/dist/credentials.js.map +1 -1
- package/dist/dev/command.d.ts +41 -0
- package/dist/dev/command.d.ts.map +1 -0
- package/dist/dev/command.js +158 -0
- package/dist/dev/command.js.map +1 -0
- package/dist/doctor/address-checks.d.ts +56 -0
- package/dist/doctor/address-checks.d.ts.map +1 -0
- package/dist/doctor/address-checks.js +183 -0
- package/dist/doctor/address-checks.js.map +1 -0
- package/dist/doctor/boilerplate.d.ts +33 -0
- package/dist/doctor/boilerplate.d.ts.map +1 -0
- package/dist/doctor/boilerplate.js +78 -0
- package/dist/doctor/boilerplate.js.map +1 -0
- package/dist/doctor/command.d.ts +18 -0
- package/dist/doctor/command.d.ts.map +1 -0
- package/dist/doctor/command.js +234 -0
- package/dist/doctor/command.js.map +1 -0
- package/dist/doctor/crawl.d.ts +49 -0
- package/dist/doctor/crawl.d.ts.map +1 -0
- package/dist/doctor/crawl.js +210 -0
- package/dist/doctor/crawl.js.map +1 -0
- package/dist/doctor/extended.d.ts +52 -0
- package/dist/doctor/extended.d.ts.map +1 -0
- package/dist/doctor/extended.js +150 -0
- package/dist/doctor/extended.js.map +1 -0
- package/dist/doctor/page-checks.d.ts +42 -0
- package/dist/doctor/page-checks.d.ts.map +1 -0
- package/dist/doctor/page-checks.js +200 -0
- package/dist/doctor/page-checks.js.map +1 -0
- package/dist/doctor/probe.d.ts +63 -0
- package/dist/doctor/probe.d.ts.map +1 -0
- package/dist/doctor/probe.js +170 -0
- package/dist/doctor/probe.js.map +1 -0
- package/dist/doctor/reader-auth-atlas.d.ts +18 -0
- package/dist/doctor/reader-auth-atlas.d.ts.map +1 -0
- package/dist/doctor/reader-auth-atlas.js +50 -0
- package/dist/doctor/reader-auth-atlas.js.map +1 -0
- package/dist/doctor/robots-params.d.ts +36 -0
- package/dist/doctor/robots-params.d.ts.map +1 -0
- package/dist/doctor/robots-params.js +97 -0
- package/dist/doctor/robots-params.js.map +1 -0
- package/dist/doctor/site.d.ts +42 -0
- package/dist/doctor/site.d.ts.map +1 -0
- package/dist/doctor/site.js +82 -0
- package/dist/doctor/site.js.map +1 -0
- package/dist/doctor.d.ts +21 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +94 -3
- package/dist/doctor.js.map +1 -1
- package/dist/exit-codes.d.ts +40 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +66 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/help-commands.d.ts +13 -0
- package/dist/help-commands.d.ts.map +1 -0
- package/dist/help-commands.js +215 -0
- package/dist/help-commands.js.map +1 -0
- package/dist/help.d.ts +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +74 -11
- package/dist/help.js.map +1 -1
- package/dist/io.d.ts +33 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +81 -0
- package/dist/io.js.map +1 -0
- package/dist/preview-comment.d.ts +20 -0
- package/dist/preview-comment.d.ts.map +1 -0
- package/dist/preview-comment.js +88 -0
- package/dist/preview-comment.js.map +1 -0
- package/dist/publish/about.d.ts +23 -0
- package/dist/publish/about.d.ts.map +1 -0
- package/dist/publish/about.js +66 -0
- package/dist/publish/about.js.map +1 -0
- package/dist/publish/api.d.ts +30 -12
- package/dist/publish/api.d.ts.map +1 -1
- package/dist/publish/api.js +62 -10
- package/dist/publish/api.js.map +1 -1
- package/dist/publish/client.d.ts +19 -0
- package/dist/publish/client.d.ts.map +1 -0
- package/dist/publish/client.js +3 -0
- package/dist/publish/client.js.map +1 -0
- package/dist/publish/command.d.ts +51 -2
- package/dist/publish/command.d.ts.map +1 -1
- package/dist/publish/command.js +157 -17
- package/dist/publish/command.js.map +1 -1
- package/dist/publish/context.d.ts +12 -1
- package/dist/publish/context.d.ts.map +1 -1
- package/dist/publish/context.js.map +1 -1
- package/dist/publish/diff.d.ts +21 -0
- package/dist/publish/diff.d.ts.map +1 -0
- package/dist/publish/diff.js +96 -0
- package/dist/publish/diff.js.map +1 -0
- package/dist/publish/docs-apply.d.ts +8 -1
- package/dist/publish/docs-apply.d.ts.map +1 -1
- package/dist/publish/docs-apply.js +49 -10
- package/dist/publish/docs-apply.js.map +1 -1
- package/dist/publish/docs-plan.d.ts +16 -3
- package/dist/publish/docs-plan.d.ts.map +1 -1
- package/dist/publish/docs-plan.js +57 -6
- package/dist/publish/docs-plan.js.map +1 -1
- package/dist/publish/extras.d.ts +10 -0
- package/dist/publish/extras.d.ts.map +1 -1
- package/dist/publish/extras.js +54 -2
- package/dist/publish/extras.js.map +1 -1
- package/dist/publish/frontmatter.d.ts +1 -1
- package/dist/publish/frontmatter.d.ts.map +1 -1
- package/dist/publish/frontmatter.js +1 -0
- package/dist/publish/frontmatter.js.map +1 -1
- package/dist/publish/index.d.ts +12 -0
- package/dist/publish/index.d.ts.map +1 -0
- package/dist/publish/index.js +17 -0
- package/dist/publish/index.js.map +1 -0
- package/dist/publish/manifest.d.ts.map +1 -1
- package/dist/publish/manifest.js +48 -3
- package/dist/publish/manifest.js.map +1 -1
- package/dist/publish/names.d.ts +28 -0
- package/dist/publish/names.d.ts.map +1 -0
- package/dist/publish/names.js +80 -0
- package/dist/publish/names.js.map +1 -0
- package/dist/publish/posts.d.ts.map +1 -1
- package/dist/publish/posts.js +46 -13
- package/dist/publish/posts.js.map +1 -1
- package/dist/publish/preview.d.ts +56 -0
- package/dist/publish/preview.d.ts.map +1 -0
- package/dist/publish/preview.js +133 -0
- package/dist/publish/preview.js.map +1 -0
- package/dist/publish/redirects.d.ts +13 -0
- package/dist/publish/redirects.d.ts.map +1 -0
- package/dist/publish/redirects.js +154 -0
- package/dist/publish/redirects.js.map +1 -0
- package/dist/publish/reserved.d.ts +49 -0
- package/dist/publish/reserved.d.ts.map +1 -0
- package/dist/publish/reserved.js +118 -0
- package/dist/publish/reserved.js.map +1 -0
- package/dist/publish/rewrite.d.ts +12 -0
- package/dist/publish/rewrite.d.ts.map +1 -1
- package/dist/publish/rewrite.js +22 -0
- package/dist/publish/rewrite.js.map +1 -1
- package/dist/publish/scan-docs.d.ts +10 -0
- package/dist/publish/scan-docs.d.ts.map +1 -0
- package/dist/publish/scan-docs.js +160 -0
- package/dist/publish/scan-docs.js.map +1 -0
- package/dist/publish/scan.d.ts +21 -17
- package/dist/publish/scan.d.ts.map +1 -1
- package/dist/publish/scan.js +99 -232
- package/dist/publish/scan.js.map +1 -1
- package/dist/publish/slots.d.ts +39 -0
- package/dist/publish/slots.d.ts.map +1 -0
- package/dist/publish/slots.js +64 -0
- package/dist/publish/slots.js.map +1 -0
- package/dist/publish/studio-edits.d.ts +25 -0
- package/dist/publish/studio-edits.d.ts.map +1 -0
- package/dist/publish/studio-edits.js +53 -0
- package/dist/publish/studio-edits.js.map +1 -0
- package/dist/publish/tags.d.ts +9 -0
- package/dist/publish/tags.d.ts.map +1 -0
- package/dist/publish/tags.js +194 -0
- package/dist/publish/tags.js.map +1 -0
- package/dist/publish/types.d.ts +84 -1
- package/dist/publish/types.d.ts.map +1 -1
- package/dist/publish/types.js +0 -10
- package/dist/publish/types.js.map +1 -1
- package/dist/publish-command.d.ts +55 -0
- package/dist/publish-command.d.ts.map +1 -0
- package/dist/publish-command.js +197 -0
- package/dist/publish-command.js.map +1 -0
- package/dist/run.d.ts +3 -10
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +171 -112
- package/dist/run.js.map +1 -1
- package/dist/translations/target.d.ts.map +1 -1
- package/dist/translations/target.js +2 -2
- package/dist/translations/target.js.map +1 -1
- package/dist/validate.d.ts +39 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +166 -0
- package/dist/validate.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/dist/whoami.d.ts +41 -0
- package/dist/whoami.d.ts.map +1 -0
- package/dist/whoami.js +161 -0
- package/dist/whoami.js.map +1 -0
- package/package.json +2 -2
- package/dist/publish-dir.d.ts +0 -54
- package/dist/publish-dir.d.ts.map +0 -1
- package/dist/publish-dir.js +0 -119
- package/dist/publish-dir.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-checks.js","sourceRoot":"","sources":["../../src/doctor/address-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descriptions that were written by a template, not by the site's owner.
|
|
3
|
+
*
|
|
4
|
+
* A space with no description of its own fell back to the preset's blurb —
|
|
5
|
+
* "Guides and reference, in a nested tree.", "Community discussions in
|
|
6
|
+
* Community." — and that sentence became the meta description, the og:description
|
|
7
|
+
* a link preview shows, and the summary line of llms.txt (FMU-B08). Nothing was
|
|
8
|
+
* broken in the HTTP sense, so no check noticed; a reader sharing a link noticed.
|
|
9
|
+
*
|
|
10
|
+
* One list, in one place, so `meta-description` and `llms-txt` judge the same
|
|
11
|
+
* strings. Patterns rather than exact strings: the template interpolates the
|
|
12
|
+
* space or site name, and the point is to recognise the template whatever was
|
|
13
|
+
* poured into it. They are generic generator phrasings — any docs platform
|
|
14
|
+
* that fills an empty description from a type preset produces sentences of this
|
|
15
|
+
* shape — not a list of one vendor's copy.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PRESET_DESCRIPTION_PATTERNS: readonly RegExp[];
|
|
18
|
+
export declare function isPresetDescription(text: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* True when a description is headings run together rather than prose.
|
|
21
|
+
*
|
|
22
|
+
* A generated reference landing described itself as its tag names joined with
|
|
23
|
+
* spaces — "Referalli API Analytics and operations Billing Authentication
|
|
24
|
+
* Programs and partners Partner portal Payouts…" (FMU-B09). It has words, so
|
|
25
|
+
* "missing" never fires; it has no sentence in it, which is what this tests:
|
|
26
|
+
* eight words or more, no sentence punctuation at all, and most of the
|
|
27
|
+
* non-trivial words capitalised. A run of CamelCase joins (`PayoutsPartners`)
|
|
28
|
+
* counts too — that is the same list with the spaces lost.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isHeadingSoup(text: string): boolean;
|
|
31
|
+
/** Why a description is not one, or undefined when it reads like one somebody wrote. */
|
|
32
|
+
export declare function descriptionProblem(text: string | undefined): string | undefined;
|
|
33
|
+
//# sourceMappingURL=boilerplate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boilerplate.d.ts","sourceRoot":"","sources":["../../src/doctor/boilerplate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAUxD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGzD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAM/E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRESET_DESCRIPTION_PATTERNS = void 0;
|
|
4
|
+
exports.isPresetDescription = isPresetDescription;
|
|
5
|
+
exports.isHeadingSoup = isHeadingSoup;
|
|
6
|
+
exports.descriptionProblem = descriptionProblem;
|
|
7
|
+
/**
|
|
8
|
+
* Descriptions that were written by a template, not by the site's owner.
|
|
9
|
+
*
|
|
10
|
+
* A space with no description of its own fell back to the preset's blurb —
|
|
11
|
+
* "Guides and reference, in a nested tree.", "Community discussions in
|
|
12
|
+
* Community." — and that sentence became the meta description, the og:description
|
|
13
|
+
* a link preview shows, and the summary line of llms.txt (FMU-B08). Nothing was
|
|
14
|
+
* broken in the HTTP sense, so no check noticed; a reader sharing a link noticed.
|
|
15
|
+
*
|
|
16
|
+
* One list, in one place, so `meta-description` and `llms-txt` judge the same
|
|
17
|
+
* strings. Patterns rather than exact strings: the template interpolates the
|
|
18
|
+
* space or site name, and the point is to recognise the template whatever was
|
|
19
|
+
* poured into it. They are generic generator phrasings — any docs platform
|
|
20
|
+
* that fills an empty description from a type preset produces sentences of this
|
|
21
|
+
* shape — not a list of one vendor's copy.
|
|
22
|
+
*/
|
|
23
|
+
exports.PRESET_DESCRIPTION_PATTERNS = [
|
|
24
|
+
/^guides and reference, in a nested tree\.?$/i,
|
|
25
|
+
/^community discussions in .+\.?$/i,
|
|
26
|
+
/^the latest posts from .+\.?$/i,
|
|
27
|
+
/^published documentation for .+\.?$/i,
|
|
28
|
+
/^documentation for .+\.?$/i,
|
|
29
|
+
/^welcome to .+ (?:docs|documentation)\.?$/i,
|
|
30
|
+
// A not-found page's title used as a description: the address in the
|
|
31
|
+
// sitemap or llms.txt is dead, and the preview says so to everybody.
|
|
32
|
+
/this page isn[’']t here/i,
|
|
33
|
+
];
|
|
34
|
+
function isPresetDescription(text) {
|
|
35
|
+
const t = text.trim();
|
|
36
|
+
return exports.PRESET_DESCRIPTION_PATTERNS.some((re) => re.test(t));
|
|
37
|
+
}
|
|
38
|
+
/** Small words a real sentence has and a list of headings also has. */
|
|
39
|
+
const STOP = new Set(['and', 'or', 'the', 'of', 'a', 'an', 'to', 'in', 'for', 'with', 'on', '&']);
|
|
40
|
+
/**
|
|
41
|
+
* True when a description is headings run together rather than prose.
|
|
42
|
+
*
|
|
43
|
+
* A generated reference landing described itself as its tag names joined with
|
|
44
|
+
* spaces — "Referalli API Analytics and operations Billing Authentication
|
|
45
|
+
* Programs and partners Partner portal Payouts…" (FMU-B09). It has words, so
|
|
46
|
+
* "missing" never fires; it has no sentence in it, which is what this tests:
|
|
47
|
+
* eight words or more, no sentence punctuation at all, and most of the
|
|
48
|
+
* non-trivial words capitalised. A run of CamelCase joins (`PayoutsPartners`)
|
|
49
|
+
* counts too — that is the same list with the spaces lost.
|
|
50
|
+
*/
|
|
51
|
+
function isHeadingSoup(text) {
|
|
52
|
+
const t = text.replace(/(?:…|\.\.\.)\s*$/, '').trim();
|
|
53
|
+
if ((t.match(/[a-z][A-Z][a-z]/g) ?? []).length >= 2 && !/[.,;:!?]/.test(t))
|
|
54
|
+
return true;
|
|
55
|
+
if (/[.,;:!?—–()]/.test(t))
|
|
56
|
+
return false;
|
|
57
|
+
const words = t.split(/\s+/).filter(Boolean);
|
|
58
|
+
if (words.length < 8)
|
|
59
|
+
return false;
|
|
60
|
+
const content = words.filter((w) => !STOP.has(w.toLowerCase()));
|
|
61
|
+
if (content.length === 0)
|
|
62
|
+
return false;
|
|
63
|
+
const capped = content.filter((w) => /^[A-Z0-9]/.test(w)).length;
|
|
64
|
+
return capped / content.length >= 0.5;
|
|
65
|
+
}
|
|
66
|
+
/** Why a description is not one, or undefined when it reads like one somebody wrote. */
|
|
67
|
+
function descriptionProblem(text) {
|
|
68
|
+
if (text === undefined)
|
|
69
|
+
return 'missing';
|
|
70
|
+
if (!text.trim())
|
|
71
|
+
return 'empty';
|
|
72
|
+
if (isPresetDescription(text))
|
|
73
|
+
return `preset text "${text.trim()}"`;
|
|
74
|
+
if (isHeadingSoup(text))
|
|
75
|
+
return `headings run together "${text.trim().slice(0, 80)}…"`;
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=boilerplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boilerplate.js","sourceRoot":"","sources":["../../src/doctor/boilerplate.ts"],"names":[],"mappings":";;;AA4BA,kDAGC;AAgBD,sCAUC;AAGD,gDAMC;AAlED;;;;;;;;;;;;;;;GAeG;AACU,QAAA,2BAA2B,GAAsB;IAC5D,8CAA8C;IAC9C,mCAAmC;IACnC,gCAAgC;IAChC,sCAAsC;IACtC,4BAA4B;IAC5B,4CAA4C;IAC5C,qEAAqE;IACrE,qEAAqE;IACrE,0BAA0B;CAC3B,CAAC;AAEF,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,OAAO,mCAA2B,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,uEAAuE;AACvE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAElG;;;;;;;;;;GAUG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxF,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;AACxC,CAAC;AAED,wFAAwF;AACxF,SAAgB,kBAAkB,CAAC,IAAwB;IACzD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,OAAO,CAAC;IACjC,IAAI,mBAAmB,CAAC,IAAI,CAAC;QAAE,OAAO,gBAAgB,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC;IACrE,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,0BAA0B,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;IACvF,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Http } from '../api/http';
|
|
2
|
+
import { type DoctorReport } from '../doctor';
|
|
3
|
+
export declare const DOCTOR_CHECK_IDS: readonly string[];
|
|
4
|
+
export declare const DOCTOR_HELP = "forumulate doctor \u2014 check a live site from the outside\n\nUsage:\n forumulate doctor <readerUrl> [flags]\n forumulate doctor --site <slug|id> [--org <slug|id>] [flags]\n\nPlain HTTP, no token needed for a URL: the same report against our platform, a\nstaging mount or any other docs host. --site asks the API for every address of\nevery space on a site (needs a token), and checks each copy.\n\nFlags:\n --site <slug|id> every member space, at its custom domain AND its\n platform copy (token: FORUMULATE_TOKEN or `login`)\n --org <slug|id> the org --site is in (default: FORUMULATE_ORG / config)\n --also <url> another address of the same page, e.g. the platform copy\n of a custom-domain page (repeatable)\n --only a,b run just these checks (ids below)\n --json the full report as JSON on stdout (nothing else there)\n --api-base <origin> where /api/health lives, when not on the page's host\n --platform-host <h> the hosting platform's hostname, for white-label and\n canonical checks (default: FORUMULATE_URL's host, else\n forumulate.com)\n --limit <n> sitemap URLs to sample (default 60)\n --timeout <ms> per-request timeout (default 15000)\n\nChecks (id \u2014 what fails it):\n health /api/health not 2xx JSON (also tried under the mount)\n public-read a logged-out reader is sent to sign-in\n canonical the page's canonical names another host\n html-untouched a proxy rewrites the markup (email obfuscation)\n cache-headers no Cache-Control, or no-store, on the page\n robots / sitemap robots.txt missing, disallows the path, no Sitemap:\n crawler-access a crawler gets a different status than a reader\n feeds an advertised feed does not answer 200\n images a picture on the page does not load\n canonical-both-addresses a page's copies (custom domain, platform) name\n different canonicals, or not the primary address\n sitemap-crawl a sitemap URL redirects, 404s, is on another host or\n names another canonical\n cache-consistency pages of one space cached differently (public vs\n private/no-store) with no x-forumulate-cache-reason\n root-redirect a space root answers 302/307, or a redirect with a\n body over 1 KB, or lands on a page canonical elsewhere\n meta-description missing description/og:description, template text\n (\"Guides and reference, in a nested tree.\"), or\n headings run together\n llms-txt /llms.txt missing, no H1, preset summary, links on\n another host, slugs in titles, no sections/descriptions\n favicon /favicon.ico or <link rel=icon> not an image; an\n asset path answering a large HTML page\n consent-tag a consent manager (any CMP: Cookie Munch, Cookiebot,\n OneTrust, Osano, Termly, Usercentrics, Didomi,\n iubenda, Complianz, TCF) not told the page language\n white-label-leaks a custom-domain page or its .md twin links to the\n platform host\n robots-params (advice) prints the Disallow lines that keep crawlers\n off each mount's ?sort= / ?period= / ?range= copies\n reader-auth-atlas (advice, needs --org and a token) the organization\n uses Atlas but signs readers in another way (an\n external_jwt route): prints the relink and the switch\n to the Atlas reader provider (readerAuth: atlas)\n\nExamples:\n forumulate doctor https://docs.acme.com/docs\n forumulate doctor https://acme.com/legal/privacy --also https://forumulate.com/p/acme/legal/privacy\n forumulate doctor --site main --org acme --json > doctor.json\n forumulate doctor https://acme.com/docs --only sitemap-crawl,root-redirect\n\nIn CI: packages/cli/examples/github-action-doctor.yml runs this on a schedule and\non every push, uploads the JSON report and fails the job on any FAIL.\n\nExit status:\n 0 ok 1 failed (verification mismatch, doctor FAIL)\n 2 usage 3 auth (no token, 401, token not allowed)\n 4 not found 5 conflict (409/412, edited in the studio since your last publish)\n 124 --wait timed out (the job keeps running; with --wait, a failed job is 1)\n doctor: 1 when any check FAILs; a SKIP is not a failure.";
|
|
5
|
+
export interface DoctorCommandDeps {
|
|
6
|
+
out: (line: string) => void;
|
|
7
|
+
err: (line: string) => void;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
fetchImpl?: typeof fetch;
|
|
10
|
+
http?: Http;
|
|
11
|
+
userAgent?: string;
|
|
12
|
+
/** The global `--token` (FMU-DOC01); beats FORUMULATE_TOKEN and the stored token. */
|
|
13
|
+
flagToken?: string;
|
|
14
|
+
}
|
|
15
|
+
/** `forumulate doctor …` → an exit code. */
|
|
16
|
+
export declare function runDoctorCommand(argv: string[], deps: DoctorCommandDeps): Promise<number>;
|
|
17
|
+
export declare function printReport(report: DoctorReport, out: (l: string) => void): void;
|
|
18
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/doctor/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAKnC,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAOzE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAI7C,CAAC;AAEF,eAAO,MAAM,WAAW,gtJAwEmC,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,4CAA4C;AAC5C,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4H/F;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAUhF"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DOCTOR_HELP = exports.DOCTOR_CHECK_IDS = void 0;
|
|
4
|
+
exports.runDoctorCommand = runDoctorCommand;
|
|
5
|
+
exports.printReport = printReport;
|
|
6
|
+
const args_1 = require("../api/args");
|
|
7
|
+
const http_1 = require("../api/http");
|
|
8
|
+
const api_base_1 = require("../api-base");
|
|
9
|
+
const config_1 = require("../commands/config");
|
|
10
|
+
const credentials_1 = require("../credentials");
|
|
11
|
+
const exit_codes_1 = require("../exit-codes");
|
|
12
|
+
const doctor_1 = require("../doctor");
|
|
13
|
+
const extended_1 = require("./extended");
|
|
14
|
+
const site_1 = require("./site");
|
|
15
|
+
const probe_1 = require("./probe");
|
|
16
|
+
const reader_auth_atlas_1 = require("./reader-auth-atlas");
|
|
17
|
+
exports.DOCTOR_CHECK_IDS = [
|
|
18
|
+
...doctor_1.BASE_CHECK_IDS,
|
|
19
|
+
...extended_1.EXTENDED_CHECK_IDS,
|
|
20
|
+
reader_auth_atlas_1.READER_AUTH_ATLAS_CHECK,
|
|
21
|
+
];
|
|
22
|
+
exports.DOCTOR_HELP = `forumulate doctor — check a live site from the outside
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
forumulate doctor <readerUrl> [flags]
|
|
26
|
+
forumulate doctor --site <slug|id> [--org <slug|id>] [flags]
|
|
27
|
+
|
|
28
|
+
Plain HTTP, no token needed for a URL: the same report against our platform, a
|
|
29
|
+
staging mount or any other docs host. --site asks the API for every address of
|
|
30
|
+
every space on a site (needs a token), and checks each copy.
|
|
31
|
+
|
|
32
|
+
Flags:
|
|
33
|
+
--site <slug|id> every member space, at its custom domain AND its
|
|
34
|
+
platform copy (token: FORUMULATE_TOKEN or \`login\`)
|
|
35
|
+
--org <slug|id> the org --site is in (default: FORUMULATE_ORG / config)
|
|
36
|
+
--also <url> another address of the same page, e.g. the platform copy
|
|
37
|
+
of a custom-domain page (repeatable)
|
|
38
|
+
--only a,b run just these checks (ids below)
|
|
39
|
+
--json the full report as JSON on stdout (nothing else there)
|
|
40
|
+
--api-base <origin> where /api/health lives, when not on the page's host
|
|
41
|
+
--platform-host <h> the hosting platform's hostname, for white-label and
|
|
42
|
+
canonical checks (default: FORUMULATE_URL's host, else
|
|
43
|
+
${extended_1.DEFAULT_PLATFORM_HOST})
|
|
44
|
+
--limit <n> sitemap URLs to sample (default ${extended_1.DEFAULT_SAMPLE_LIMIT})
|
|
45
|
+
--timeout <ms> per-request timeout (default 15000)
|
|
46
|
+
|
|
47
|
+
Checks (id — what fails it):
|
|
48
|
+
health /api/health not 2xx JSON (also tried under the mount)
|
|
49
|
+
public-read a logged-out reader is sent to sign-in
|
|
50
|
+
canonical the page's canonical names another host
|
|
51
|
+
html-untouched a proxy rewrites the markup (email obfuscation)
|
|
52
|
+
cache-headers no Cache-Control, or no-store, on the page
|
|
53
|
+
robots / sitemap robots.txt missing, disallows the path, no Sitemap:
|
|
54
|
+
crawler-access a crawler gets a different status than a reader
|
|
55
|
+
feeds an advertised feed does not answer 200
|
|
56
|
+
images a picture on the page does not load
|
|
57
|
+
canonical-both-addresses a page's copies (custom domain, platform) name
|
|
58
|
+
different canonicals, or not the primary address
|
|
59
|
+
sitemap-crawl a sitemap URL redirects, 404s, is on another host or
|
|
60
|
+
names another canonical
|
|
61
|
+
cache-consistency pages of one space cached differently (public vs
|
|
62
|
+
private/no-store) with no x-forumulate-cache-reason
|
|
63
|
+
root-redirect a space root answers 302/307, or a redirect with a
|
|
64
|
+
body over 1 KB, or lands on a page canonical elsewhere
|
|
65
|
+
meta-description missing description/og:description, template text
|
|
66
|
+
("Guides and reference, in a nested tree."), or
|
|
67
|
+
headings run together
|
|
68
|
+
llms-txt /llms.txt missing, no H1, preset summary, links on
|
|
69
|
+
another host, slugs in titles, no sections/descriptions
|
|
70
|
+
favicon /favicon.ico or <link rel=icon> not an image; an
|
|
71
|
+
asset path answering a large HTML page
|
|
72
|
+
consent-tag a consent manager (any CMP: Cookie Munch, Cookiebot,
|
|
73
|
+
OneTrust, Osano, Termly, Usercentrics, Didomi,
|
|
74
|
+
iubenda, Complianz, TCF) not told the page language
|
|
75
|
+
white-label-leaks a custom-domain page or its .md twin links to the
|
|
76
|
+
platform host
|
|
77
|
+
robots-params (advice) prints the Disallow lines that keep crawlers
|
|
78
|
+
off each mount's ?sort= / ?period= / ?range= copies
|
|
79
|
+
reader-auth-atlas (advice, needs --org and a token) the organization
|
|
80
|
+
uses Atlas but signs readers in another way (an
|
|
81
|
+
external_jwt route): prints the relink and the switch
|
|
82
|
+
to the Atlas reader provider (readerAuth: atlas)
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
forumulate doctor https://docs.acme.com/docs
|
|
86
|
+
forumulate doctor https://acme.com/legal/privacy --also https://forumulate.com/p/acme/legal/privacy
|
|
87
|
+
forumulate doctor --site main --org acme --json > doctor.json
|
|
88
|
+
forumulate doctor https://acme.com/docs --only sitemap-crawl,root-redirect
|
|
89
|
+
|
|
90
|
+
In CI: packages/cli/examples/github-action-doctor.yml runs this on a schedule and
|
|
91
|
+
on every push, uploads the JSON report and fails the job on any FAIL.
|
|
92
|
+
|
|
93
|
+
${exit_codes_1.EXIT_CODES_HELP}
|
|
94
|
+
doctor: 1 when any check FAILs; a SKIP is not a failure.`;
|
|
95
|
+
const SWITCHES = new Set(['json', 'help', 'h']);
|
|
96
|
+
/** `forumulate doctor …` → an exit code. */
|
|
97
|
+
async function runDoctorCommand(argv, deps) {
|
|
98
|
+
const p = (0, args_1.parseArgs)(argv, SWITCHES);
|
|
99
|
+
if ((0, args_1.has)(p, 'help') || (0, args_1.has)(p, 'h')) {
|
|
100
|
+
deps.out(exports.DOCTOR_HELP);
|
|
101
|
+
return exit_codes_1.EXIT.OK;
|
|
102
|
+
}
|
|
103
|
+
const env = deps.env ?? process.env;
|
|
104
|
+
const json = (0, args_1.has)(p, 'json');
|
|
105
|
+
const usage = (why) => {
|
|
106
|
+
deps.err(why);
|
|
107
|
+
deps.err('Usage: forumulate doctor <readerUrl> | --site <slug|id> [--org …] (doctor --help)');
|
|
108
|
+
return exit_codes_1.EXIT.USAGE;
|
|
109
|
+
};
|
|
110
|
+
const only = (0, args_1.all)(p, 'only')
|
|
111
|
+
.flatMap((v) => v.split(','))
|
|
112
|
+
.map((v) => v.trim())
|
|
113
|
+
.filter(Boolean);
|
|
114
|
+
const unknown = only.filter((id) => !exports.DOCTOR_CHECK_IDS.includes(id));
|
|
115
|
+
if (unknown.length)
|
|
116
|
+
return usage(`Unknown check id(s): ${unknown.join(', ')}. Known: ${exports.DOCTOR_CHECK_IDS.join(', ')}.`);
|
|
117
|
+
const limit = (0, args_1.flag)(p, 'limit') === undefined ? undefined : Number((0, args_1.flag)(p, 'limit'));
|
|
118
|
+
if (limit !== undefined && !(Number.isInteger(limit) && limit > 0))
|
|
119
|
+
return usage('--limit takes a positive whole number.');
|
|
120
|
+
const timeout = (0, args_1.flag)(p, 'timeout') === undefined ? undefined : Number((0, args_1.flag)(p, 'timeout'));
|
|
121
|
+
if (timeout !== undefined && !(Number.isInteger(timeout) && timeout > 0))
|
|
122
|
+
return usage('--timeout takes a positive number of milliseconds.');
|
|
123
|
+
let url = p.positionals[0];
|
|
124
|
+
if (p.positionals.length > 1)
|
|
125
|
+
return usage(`One URL at a time; got ${p.positionals.join(' ')}.`);
|
|
126
|
+
if (url !== undefined) {
|
|
127
|
+
try {
|
|
128
|
+
const parsed = new URL(url);
|
|
129
|
+
if (!/^https?:$/.test(parsed.protocol))
|
|
130
|
+
throw new Error('not http');
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return usage(`"${url}" is not an http(s) URL.`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const siteUrl = (0, api_base_1.siteFromEnv)(env);
|
|
137
|
+
const platformHost = ((0, args_1.flag)(p, 'platform-host') ??
|
|
138
|
+
(siteUrl ? new URL(siteUrl).host : undefined) ??
|
|
139
|
+
extended_1.DEFAULT_PLATFORM_HOST).toLowerCase();
|
|
140
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
141
|
+
const addressSets = [];
|
|
142
|
+
let roots;
|
|
143
|
+
const site = (0, args_1.flag)(p, 'site');
|
|
144
|
+
// The organization's own checks (reader-auth-atlas) need an org and a token;
|
|
145
|
+
// `--site` needs both anyway.
|
|
146
|
+
const orgFlag = (0, args_1.flag)(p, 'org');
|
|
147
|
+
const orgRef = site || orgFlag ? (0, config_1.setting)('org', orgFlag, env, (0, config_1.readConfig)(env)) : undefined;
|
|
148
|
+
const apiHttp = () => {
|
|
149
|
+
const baseUrl = (0, api_base_1.apiBaseFromEnv)(env);
|
|
150
|
+
return (deps.http ??
|
|
151
|
+
new http_1.Http({
|
|
152
|
+
baseUrl,
|
|
153
|
+
token: (0, credentials_1.resolveToken)(baseUrl, env, deps.flagToken),
|
|
154
|
+
userAgent: deps.userAgent ?? '@forumulate/cli',
|
|
155
|
+
fetch: fetchImpl,
|
|
156
|
+
}));
|
|
157
|
+
};
|
|
158
|
+
if (site) {
|
|
159
|
+
const org = orgRef;
|
|
160
|
+
if (!org)
|
|
161
|
+
return usage('--site needs --org <slug|id> (or FORUMULATE_ORG, or `config set org`).');
|
|
162
|
+
const http = apiHttp();
|
|
163
|
+
try {
|
|
164
|
+
const resolved = await (0, site_1.resolveSite)(http, org, site);
|
|
165
|
+
for (const problem of resolved.problems)
|
|
166
|
+
deps.err(`note: ${problem}`);
|
|
167
|
+
if (!url)
|
|
168
|
+
url = resolved.url;
|
|
169
|
+
if (!url) {
|
|
170
|
+
deps.err(`Site ${site} has no space with a public address to check.`);
|
|
171
|
+
return exit_codes_1.EXIT.NOT_FOUND;
|
|
172
|
+
}
|
|
173
|
+
roots = resolved.spaces.flatMap((s) => s.endpoints.map((e) => e.url.replace(/\/+$/, '')));
|
|
174
|
+
const get = (0, probe_1.makeGet)({ fetchImpl, timeoutMs: timeout });
|
|
175
|
+
addressSets.push(...(await (0, site_1.addressSetsFor)(get, resolved)));
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
const err = e;
|
|
179
|
+
deps.err(`Could not read site ${site}: ${err.message ?? String(e)}`);
|
|
180
|
+
return (0, exit_codes_1.exitCodeForError)(e);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!url)
|
|
184
|
+
return usage('Give a reader URL, or --site <slug|id>.');
|
|
185
|
+
const also = (0, args_1.all)(p, 'also');
|
|
186
|
+
if (also.length)
|
|
187
|
+
addressSets.push({ urls: [url, ...also] });
|
|
188
|
+
const report = await (0, doctor_1.runDoctor)({
|
|
189
|
+
url,
|
|
190
|
+
apiBase: (0, args_1.flag)(p, 'api-base') ?? siteUrl,
|
|
191
|
+
fetchImpl,
|
|
192
|
+
only: only.length ? only : undefined,
|
|
193
|
+
platformHost,
|
|
194
|
+
// The platform the copies are compared against: the configured API when
|
|
195
|
+
// one is, else the API of whichever host --platform-host named.
|
|
196
|
+
platformApi: env.FORUMULATE_API_URL?.trim() || env.FORUMULATE_URL?.trim()
|
|
197
|
+
? (0, api_base_1.apiBaseFromEnv)(env)
|
|
198
|
+
: `https://${platformHost}/api`,
|
|
199
|
+
addressSets: addressSets.length ? addressSets : undefined,
|
|
200
|
+
roots,
|
|
201
|
+
limit,
|
|
202
|
+
timeoutMs: timeout,
|
|
203
|
+
});
|
|
204
|
+
// FMU-X01: the organization's reader sign-in, from the API's own recommendation.
|
|
205
|
+
if (orgRef && (!only.length || only.includes(reader_auth_atlas_1.READER_AUTH_ATLAS_CHECK))) {
|
|
206
|
+
const c = await (0, reader_auth_atlas_1.readerAuthAtlasCheck)(apiHttp(), orgRef);
|
|
207
|
+
report.checks.push(c);
|
|
208
|
+
if (c.state === 'pass')
|
|
209
|
+
report.passed += 1;
|
|
210
|
+
else if (c.state === 'fail')
|
|
211
|
+
report.failed += 1;
|
|
212
|
+
else
|
|
213
|
+
report.warnings += 1;
|
|
214
|
+
}
|
|
215
|
+
if (json)
|
|
216
|
+
deps.out(JSON.stringify(report, null, 2));
|
|
217
|
+
else
|
|
218
|
+
printReport(report, deps.out);
|
|
219
|
+
return report.failed > 0 ? exit_codes_1.EXIT.FAILED : exit_codes_1.EXIT.OK;
|
|
220
|
+
}
|
|
221
|
+
function printReport(report, out) {
|
|
222
|
+
out(`Checking ${report.url}`);
|
|
223
|
+
for (const c of report.checks) {
|
|
224
|
+
const mark = c.state === 'pass' ? 'PASS' : c.state === 'fail' ? 'FAIL' : 'SKIP';
|
|
225
|
+
out(` ${mark} ${c.id} ${c.title}`);
|
|
226
|
+
// A detail may be several lines (robots-params prints a robots.txt block).
|
|
227
|
+
for (const line of c.detail.split('\n'))
|
|
228
|
+
out(` ${line}`);
|
|
229
|
+
if (c.state === 'fail' && c.matters)
|
|
230
|
+
out(` why it matters: ${c.matters}`);
|
|
231
|
+
}
|
|
232
|
+
out(`${report.passed} passed, ${report.failed} failed, ${report.warnings} skipped`);
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/doctor/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Check } from '../conformance';
|
|
2
|
+
import { type Get, type Probe } from './probe';
|
|
3
|
+
export interface CrawlResult {
|
|
4
|
+
check: Check;
|
|
5
|
+
/** Every listed URL that was fetched, with its answer. */
|
|
6
|
+
pages: Probe[];
|
|
7
|
+
}
|
|
8
|
+
/** `Sitemap:` lines of robots.txt, else the conventional address. */
|
|
9
|
+
export declare function sitemapsFromRobots(robots: string, origin: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Read sitemaps (following a sitemap index), returning the URL lists per
|
|
12
|
+
* document, so the sample can draw from every space rather than exhaust the
|
|
13
|
+
* first one: a site with a 900-page reference and a 4-page legal space would
|
|
14
|
+
* otherwise never have its legal pages looked at.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readSitemaps(get: Get, start: string[]): Promise<{
|
|
17
|
+
lists: {
|
|
18
|
+
sitemap: string;
|
|
19
|
+
urls: string[];
|
|
20
|
+
}[];
|
|
21
|
+
problems: string[];
|
|
22
|
+
}>;
|
|
23
|
+
/** Up to `limit` URLs, round-robin across the sitemaps so every space is represented. */
|
|
24
|
+
export declare function sample(lists: {
|
|
25
|
+
urls: string[];
|
|
26
|
+
}[], limit: number): string[];
|
|
27
|
+
export declare function sitemapCrawl(get: Get, origin: string, robots: string | undefined, limit: number): Promise<CrawlResult>;
|
|
28
|
+
/**
|
|
29
|
+
* The space a URL belongs to, for grouping: its first path segment, which is
|
|
30
|
+
* where a path-mounted space lives (`/docs`, `/legal`). Pages at the root of a
|
|
31
|
+
* site domain group together under `/`. Coarse, and that is fine — a
|
|
32
|
+
* difference between two spaces is a choice; a difference inside one is what
|
|
33
|
+
* this is looking for.
|
|
34
|
+
*/
|
|
35
|
+
export declare function groupOf(url: string): string;
|
|
36
|
+
/** `public` (a shared cache may keep it) or `private` (it may not), by the directives that decide it. */
|
|
37
|
+
export declare function cacheClass(cc: string | null): 'public' | 'private' | 'none';
|
|
38
|
+
/**
|
|
39
|
+
* `cache-consistency`: the pages of one space are cached the same way.
|
|
40
|
+
*
|
|
41
|
+
* Every legal document answered `private, no-cache, no-store` to a reader with
|
|
42
|
+
* no cookie at all, while the legal index beside it was `public, s-maxage=10`
|
|
43
|
+
* (FMU-B05). Neither header is wrong on its own; the difference is the defect —
|
|
44
|
+
* either something is gated and should say so, or a code path forgot the
|
|
45
|
+
* public header and every reader pays a full origin render. A page that sends
|
|
46
|
+
* a reason header is taken at its word.
|
|
47
|
+
*/
|
|
48
|
+
export declare function cacheConsistency(pages: Probe[]): Check;
|
|
49
|
+
//# sourceMappingURL=crawl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../../src/doctor/crawl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAQL,KAAK,GAAG,EACR,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAmBjB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3E;AAQD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC;IAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkB/E;AAED,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3E;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,CAAC,CAuDtB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY3C;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAK3E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CA0CtD"}
|