@forumulate/cli 0.3.5 → 0.4.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 +100 -21
- package/dist/api-base.d.ts +26 -7
- package/dist/api-base.d.ts.map +1 -1
- package/dist/api-base.js +38 -8
- package/dist/api-base.js.map +1 -1
- package/dist/cli.js +25 -1
- package/dist/cli.js.map +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/doctor.d.ts +13 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +113 -44
- package/dist/doctor.js.map +1 -1
- package/dist/publish/api.d.ts +95 -0
- package/dist/publish/api.d.ts.map +1 -0
- package/dist/publish/api.js +265 -0
- package/dist/publish/api.js.map +1 -0
- package/dist/publish/command.d.ts +44 -0
- package/dist/publish/command.d.ts.map +1 -0
- package/dist/publish/command.js +246 -0
- package/dist/publish/command.js.map +1 -0
- package/dist/publish/compare.d.ts +45 -0
- package/dist/publish/compare.d.ts.map +1 -0
- package/dist/publish/compare.js +124 -0
- package/dist/publish/compare.js.map +1 -0
- package/dist/publish/context.d.ts +46 -0
- package/dist/publish/context.d.ts.map +1 -0
- package/dist/publish/context.js +54 -0
- package/dist/publish/context.js.map +1 -0
- package/dist/publish/docs-apply.d.ts +39 -0
- package/dist/publish/docs-apply.d.ts.map +1 -0
- package/dist/publish/docs-apply.js +178 -0
- package/dist/publish/docs-apply.js.map +1 -0
- package/dist/publish/docs-plan.d.ts +40 -0
- package/dist/publish/docs-plan.d.ts.map +1 -0
- package/dist/publish/docs-plan.js +211 -0
- package/dist/publish/docs-plan.js.map +1 -0
- package/dist/publish/docs-reconcile.d.ts +26 -0
- package/dist/publish/docs-reconcile.d.ts.map +1 -0
- package/dist/publish/docs-reconcile.js +162 -0
- package/dist/publish/docs-reconcile.js.map +1 -0
- package/dist/publish/extras.d.ts +25 -0
- package/dist/publish/extras.d.ts.map +1 -0
- package/dist/publish/extras.js +218 -0
- package/dist/publish/extras.js.map +1 -0
- package/dist/publish/frontmatter.d.ts +45 -0
- package/dist/publish/frontmatter.d.ts.map +1 -0
- package/dist/publish/frontmatter.js +265 -0
- package/dist/publish/frontmatter.js.map +1 -0
- package/dist/publish/manifest.d.ts +5 -0
- package/dist/publish/manifest.d.ts.map +1 -0
- package/dist/publish/manifest.js +144 -0
- package/dist/publish/manifest.js.map +1 -0
- package/dist/publish/posts.d.ts +39 -0
- package/dist/publish/posts.d.ts.map +1 -0
- package/dist/publish/posts.js +350 -0
- package/dist/publish/posts.js.map +1 -0
- package/dist/publish/rewrite.d.ts +20 -0
- package/dist/publish/rewrite.d.ts.map +1 -0
- package/dist/publish/rewrite.js +82 -0
- package/dist/publish/rewrite.js.map +1 -0
- package/dist/publish/scan.d.ts +25 -0
- package/dist/publish/scan.d.ts.map +1 -0
- package/dist/publish/scan.js +351 -0
- package/dist/publish/scan.js.map +1 -0
- package/dist/publish/types.d.ts +155 -0
- package/dist/publish/types.d.ts.map +1 -0
- package/dist/publish/types.js +13 -0
- package/dist/publish/types.js.map +1 -0
- package/dist/run.d.ts +10 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +71 -51
- package/dist/run.js.map +1 -1
- package/package.json +4 -3
- 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,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rewriteLinks = rewriteLinks;
|
|
4
|
+
exports.rewriteAssets = rewriteAssets;
|
|
5
|
+
exports.rewriteValue = rewriteValue;
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
/**
|
|
8
|
+
* What changes between the file on disk and the text the API is sent.
|
|
9
|
+
*
|
|
10
|
+
* Only addresses. The prose — and with it our Markdown directive dialect
|
|
11
|
+
* (`:::note`, `{% tabs %}`, admonitions, components) — goes through as
|
|
12
|
+
* written, because the importer is the product's own converter and a second
|
|
13
|
+
* converter here would be a second, drifting opinion about the same syntax.
|
|
14
|
+
* Every customer publisher that grew its own block converter (two of the four)
|
|
15
|
+
* ended up maintaining it against ours.
|
|
16
|
+
*/
|
|
17
|
+
/** Characters with meaning in a regular expression, escaped. */
|
|
18
|
+
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
19
|
+
/**
|
|
20
|
+
* `[text](../setup/install.md#flags)` → `[text](./install#flags)`.
|
|
21
|
+
*
|
|
22
|
+
* The importer rewrites links between files it is sent in the SAME call, and
|
|
23
|
+
* the publisher only sends what changed — so a changed page linking an
|
|
24
|
+
* unchanged one would keep a link to a `.md` file that does not exist on the
|
|
25
|
+
* web. The CLI knows every file's slug, so it rewrites every link it can
|
|
26
|
+
* resolve itself, in the importer's own form (page-relative `./slug`: the same
|
|
27
|
+
* page is reached at `/slug`, `/space/slug` and `/p/org/space/slug`, and only a
|
|
28
|
+
* relative link is right at all three).
|
|
29
|
+
*/
|
|
30
|
+
function rewriteLinks(source, file, slugByFile) {
|
|
31
|
+
const lower = new Map([...slugByFile].map(([k, v]) => [k.toLowerCase(), v]));
|
|
32
|
+
const target = (ref) => {
|
|
33
|
+
const m = /^(?!\w[\w+.-]*:|\/|#)([^?#\s]+\.(?:md|mdx|markdown))((?:[?#][^\s]*)?)$/i.exec(ref);
|
|
34
|
+
if (!m)
|
|
35
|
+
return null;
|
|
36
|
+
let path;
|
|
37
|
+
try {
|
|
38
|
+
path = node_path_1.posix.normalize(node_path_1.posix.join(node_path_1.posix.dirname(file), decodeURI(m[1])));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const slug = lower.get(path.toLowerCase());
|
|
44
|
+
return slug ? `./${slug}${m[2] ?? ''}` : null;
|
|
45
|
+
};
|
|
46
|
+
let out = source.replace(/(\]\(\s*)(<[^>]+>|[^)\s]+)/g, (all, open, ref) => {
|
|
47
|
+
const t = target(ref.replace(/^<|>$/g, ''));
|
|
48
|
+
return t ? `${open}${t}` : all;
|
|
49
|
+
});
|
|
50
|
+
out = out.replace(/(\bhref\s*=\s*["'])([^"']+)(["'])/g, (all, a, ref, b) => {
|
|
51
|
+
const t = target(ref);
|
|
52
|
+
return t ? `${a}${t}${b}` : all;
|
|
53
|
+
});
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Local images and files → the uploaded asset's URL, wherever the file names
|
|
58
|
+
* them: a Markdown image or link, an HTML `src`/`href`, a front matter value.
|
|
59
|
+
*/
|
|
60
|
+
function rewriteAssets(source, urlByRef) {
|
|
61
|
+
let out = source;
|
|
62
|
+
for (const [ref, url] of urlByRef) {
|
|
63
|
+
const r = esc(ref);
|
|
64
|
+
out = out
|
|
65
|
+
.replace(new RegExp(`(\\]\\(\\s*<?)${r}(>?)`, 'g'), `$1${url}$2`)
|
|
66
|
+
.replace(new RegExp(`(\\b(?:src|href|poster)\\s*=\\s*["'])${r}(["'])`, 'g'), `$1${url}$2`)
|
|
67
|
+
.replace(new RegExp(`(^|\\n)([ \\t]*[\\w-]+\\s*:\\s*["']?)${r}(["']?[ \\t]*(?=\\n|$))`, 'g'), `$1$2${url}$3`)
|
|
68
|
+
.replace(new RegExp(`(\\n[ \\t]*-\\s*["']?)${r}(["']?[ \\t]*(?=\\n|$))`, 'g'), `$1${url}$2`);
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/** The same substitution over a metadata patch (values that were local paths). */
|
|
73
|
+
function rewriteValue(value, urlByRef) {
|
|
74
|
+
if (typeof value === 'string')
|
|
75
|
+
return (urlByRef.get(value.trim()) ?? value);
|
|
76
|
+
if (Array.isArray(value))
|
|
77
|
+
return value.map((v) => rewriteValue(v, urlByRef));
|
|
78
|
+
if (value && typeof value === 'object')
|
|
79
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, rewriteValue(v, urlByRef)]));
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=rewrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewrite.js","sourceRoot":"","sources":["../../src/publish/rewrite.ts"],"names":[],"mappings":";;AA2BA,oCA8BC;AAMD,sCAcC;AAGD,oCAQC;AAxFD,yCAAkC;AAElC;;;;;;;;;GASG;AAEH,gEAAgE;AAChE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,SAAgB,YAAY,CAC1B,MAAc,EACd,IAAY,EACZ,UAA+B;IAE/B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,CAAC,GAAW,EAAiB,EAAE;QAC5C,MAAM,CAAC,GAAG,yEAAyE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9F,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,iBAAK,CAAC,SAAS,CAAC,iBAAK,CAAC,IAAI,CAAC,iBAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC,CAAC;IACF,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,CAAC,GAAG,EAAE,IAAY,EAAE,GAAW,EAAE,EAAE;QACzF,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,GAAG,GAAG,GAAG,CAAC,OAAO,CACf,oCAAoC,EACpC,CAAC,GAAG,EAAE,CAAS,EAAE,GAAW,EAAE,CAAS,EAAE,EAAE;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAClC,CAAC,CACF,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,MAAc,EAAE,QAA6B;IACzE,IAAI,GAAG,GAAG,MAAM,CAAC;IACjB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,GAAG,GAAG;aACN,OAAO,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;aAChE,OAAO,CAAC,IAAI,MAAM,CAAC,wCAAwC,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;aACzF,OAAO,CACN,IAAI,MAAM,CAAC,wCAAwC,CAAC,yBAAyB,EAAE,GAAG,CAAC,EACnF,OAAO,GAAG,IAAI,CACf;aACA,OAAO,CAAC,IAAI,MAAM,CAAC,yBAAyB,CAAC,yBAAyB,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kFAAkF;AAClF,SAAgB,YAAY,CAAI,KAAQ,EAAE,QAA6B;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAM,CAAC;IACjF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAM,CAAC;IAClF,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QACpC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CACjE,CAAC;IACT,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LocalSpace, SpaceSpec } from './types';
|
|
2
|
+
export declare const MANIFEST_NAMES: string[];
|
|
3
|
+
/** The product's slug rule (packages/shared `slugify`), mirrored: this package ships alone. */
|
|
4
|
+
export declare function slugify(input: string, fallback?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* The product's TAG rule (apps/api `normalizeTag`), mirrored for the same reason
|
|
7
|
+
* as `slugify`. Used to compare a front-matter tag list with the stored one: an
|
|
8
|
+
* ASCII-only fold here turned every Japanese or Cyrillic tag into `-`, so two
|
|
9
|
+
* different non-Latin tag lists compared equal and the update was skipped.
|
|
10
|
+
*/
|
|
11
|
+
export declare function tagKey(raw: string): string;
|
|
12
|
+
/** `02-getting-started` → `Getting Started`. */
|
|
13
|
+
export declare function titleize(name: string): string;
|
|
14
|
+
export interface ScanResult extends LocalSpace {
|
|
15
|
+
/** Per file (relative to the space folder): reference as written → absolute asset path. */
|
|
16
|
+
refs: Map<string, Map<string, string>>;
|
|
17
|
+
/** Every Markdown file of the space (relative to the space folder) → its slug. */
|
|
18
|
+
slugByFile: Map<string, string>;
|
|
19
|
+
}
|
|
20
|
+
/** Read one space folder. `kind` decides whether its files are pages or posts. */
|
|
21
|
+
export declare function scanSpace(root: string, spec: SpaceSpec, kind: 'docs' | 'posts', fieldKeys: string[]): ScanResult;
|
|
22
|
+
/** Every relative path → posix, for comparing with `importName`s. */
|
|
23
|
+
export declare const toPosix: (p: string) => string;
|
|
24
|
+
export declare const extOf: (p: string) => string;
|
|
25
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/publish/scan.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAA8B,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAejF,eAAO,MAAM,cAAc,UAA2D,CAAC;AAKvF,+FAA+F;AAC/F,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,MAAM,CAahE;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAc1C;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAwED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,2FAA2F;IAC3F,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvC,kFAAkF;IAClF,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,SAAS,EAAE,MAAM,EAAE,GAClB,UAAU,CAgCZ;AAqPD,qEAAqE;AACrE,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,WAA2B,CAAC;AAC7D,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,WAA6B,CAAC"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extOf = exports.toPosix = exports.MANIFEST_NAMES = void 0;
|
|
4
|
+
exports.slugify = slugify;
|
|
5
|
+
exports.tagKey = tagKey;
|
|
6
|
+
exports.titleize = titleize;
|
|
7
|
+
exports.scanSpace = scanSpace;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const yaml_1 = require("yaml");
|
|
11
|
+
const frontmatter_1 = require("./frontmatter");
|
|
12
|
+
/**
|
|
13
|
+
* A folder on disk, read into what it would publish.
|
|
14
|
+
*
|
|
15
|
+
* Docs: one top-level folder per collection, files at the root in the root
|
|
16
|
+
* collection, nested folders as parent pages (the folder's `index.md` or
|
|
17
|
+
* `README.md` is the parent; a folder without one gets a title-only stub so its
|
|
18
|
+
* children still have somewhere to hang). Everything else — blog, changelog,
|
|
19
|
+
* any type whose pieces are posts — is a flat set of posts, folders or not.
|
|
20
|
+
*/
|
|
21
|
+
const MD = /\.(md|mdx|markdown)$/i;
|
|
22
|
+
/** What a reference may point at to be uploaded rather than linked. */
|
|
23
|
+
const ASSET = /\.(png|jpe?g|gif|webp|svg|avif|ico|pdf|mp4|webm|mp3|zip)$/i;
|
|
24
|
+
exports.MANIFEST_NAMES = ['forumulate.yaml', 'forumulate.yml', 'forumulate.json'];
|
|
25
|
+
const NUMERIC = /^(\d+)[-_. ]+/;
|
|
26
|
+
const DATED = /^(\d{4}-\d{2}-\d{2})[-_]/;
|
|
27
|
+
const BIG = Number.MAX_SAFE_INTEGER;
|
|
28
|
+
/** The product's slug rule (packages/shared `slugify`), mirrored: this package ships alone. */
|
|
29
|
+
function slugify(input, fallback = 'page') {
|
|
30
|
+
return (input
|
|
31
|
+
.normalize('NFC')
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
.normalize('NFD')
|
|
34
|
+
.replace(/[̀-ͯ]/g, '')
|
|
35
|
+
.normalize('NFC')
|
|
36
|
+
.replace(/[^\p{Letter}\p{Number}]+/gu, '-')
|
|
37
|
+
.replace(/^-+|-+$/g, '')
|
|
38
|
+
.slice(0, 70)
|
|
39
|
+
.replace(/-+$/, '') || fallback);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The product's TAG rule (apps/api `normalizeTag`), mirrored for the same reason
|
|
43
|
+
* as `slugify`. Used to compare a front-matter tag list with the stored one: an
|
|
44
|
+
* ASCII-only fold here turned every Japanese or Cyrillic tag into `-`, so two
|
|
45
|
+
* different non-Latin tag lists compared equal and the update was skipped.
|
|
46
|
+
*/
|
|
47
|
+
function tagKey(raw) {
|
|
48
|
+
const t = String(raw ?? '')
|
|
49
|
+
.normalize('NFC')
|
|
50
|
+
.toLowerCase()
|
|
51
|
+
.normalize('NFD')
|
|
52
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
53
|
+
.normalize('NFC')
|
|
54
|
+
.replace(/[^\p{Letter}\p{Number}+#.-]+/gu, '-')
|
|
55
|
+
.replace(/^[-#]+/, '')
|
|
56
|
+
.replace(/^\.+(?![\p{Letter}\p{Number}])/u, '')
|
|
57
|
+
.replace(/^[-#]+/, '')
|
|
58
|
+
.replace(/[-.]+$/, '');
|
|
59
|
+
if (!/[\p{Letter}\p{Number}]/u.test(t))
|
|
60
|
+
return '';
|
|
61
|
+
return t.slice(0, 60).replace(/[-.]+$/, '');
|
|
62
|
+
}
|
|
63
|
+
/** `02-getting-started` → `Getting Started`. */
|
|
64
|
+
function titleize(name) {
|
|
65
|
+
const bare = name.replace(NUMERIC, '').replace(/[-_]+/g, ' ').trim();
|
|
66
|
+
return bare.replace(/\b\p{Letter}/gu, (c) => c.toUpperCase()) || name;
|
|
67
|
+
}
|
|
68
|
+
const isIndex = (file) => /^(index|readme)\.(md|mdx|markdown)$/i.test((0, node_path_1.basename)(file));
|
|
69
|
+
const skipEntry = (name) => name.startsWith('.') ||
|
|
70
|
+
name.startsWith('_') ||
|
|
71
|
+
name === 'node_modules' ||
|
|
72
|
+
exports.MANIFEST_NAMES.includes(name);
|
|
73
|
+
/** `[n, name]` from a numeric prefix, or "no position" sorted by name. */
|
|
74
|
+
function prefixOrder(name) {
|
|
75
|
+
const m = NUMERIC.exec(name);
|
|
76
|
+
return [m ? Number(m[1]) : BIG, name.replace(NUMERIC, '').toLowerCase()];
|
|
77
|
+
}
|
|
78
|
+
function hasMarkdown(dir) {
|
|
79
|
+
for (const e of (0, node_fs_1.readdirSync)(dir)) {
|
|
80
|
+
if (skipEntry(e))
|
|
81
|
+
continue;
|
|
82
|
+
const p = (0, node_path_1.join)(dir, e);
|
|
83
|
+
if ((0, node_fs_1.statSync)(p).isDirectory() ? hasMarkdown(p) : MD.test(e))
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/** `_collection.yml` / `.yaml` / `.json` beside a collection's files. */
|
|
89
|
+
function folderMeta(dir) {
|
|
90
|
+
for (const n of ['_collection.yml', '_collection.yaml', '_collection.json']) {
|
|
91
|
+
const p = (0, node_path_1.join)(dir, n);
|
|
92
|
+
if ((0, node_fs_1.existsSync)(p))
|
|
93
|
+
return ((0, yaml_1.parse)((0, node_fs_1.readFileSync)(p, 'utf8')) ?? {});
|
|
94
|
+
}
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
/** The title a page will get: front matter, else the leading `# heading` (the importer's rule). */
|
|
98
|
+
function titleOf(front, body, fallback) {
|
|
99
|
+
if (typeof front.title === 'string' && front.title.trim())
|
|
100
|
+
return front.title.trim();
|
|
101
|
+
const first = body.split(/\r?\n/).find((l) => l.trim());
|
|
102
|
+
const h1 = first && /^#\s+(.+?)\s*#*\s*$/.exec(first);
|
|
103
|
+
// A title is stored as plain text: the importer keeps the heading's words and
|
|
104
|
+
// drops its marks, so `` `required` `` comes back as `required`.
|
|
105
|
+
const plain = h1?.[1]
|
|
106
|
+
?.replace(/!?\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
107
|
+
.replace(/[`*_~]/g, '')
|
|
108
|
+
.trim();
|
|
109
|
+
return plain || fallback;
|
|
110
|
+
}
|
|
111
|
+
/** Local files a document points at — images, PDFs — resolved from its own folder. */
|
|
112
|
+
function assetRefs(text, fileDir, front) {
|
|
113
|
+
const refs = new Map();
|
|
114
|
+
const consider = (ref) => {
|
|
115
|
+
const clean = ref.trim().replace(/^<|>$/g, '').split(/[?#]/)[0];
|
|
116
|
+
if (!clean || /^[a-z][a-z0-9+.-]*:/i.test(clean) || clean.startsWith('/') || !ASSET.test(clean))
|
|
117
|
+
return;
|
|
118
|
+
const abs = (0, node_path_1.resolve)(fileDir, decodeURI(clean));
|
|
119
|
+
if ((0, node_fs_1.existsSync)(abs) && (0, node_fs_1.statSync)(abs).isFile())
|
|
120
|
+
refs.set(ref.trim(), abs);
|
|
121
|
+
};
|
|
122
|
+
for (const m of text.matchAll(/!?\[[^\]]*\]\(\s*(<[^>]+>|[^)\s]+)/g))
|
|
123
|
+
consider(m[1]);
|
|
124
|
+
for (const m of text.matchAll(/\b(?:src|href|poster)\s*=\s*["']([^"']+)["']/g))
|
|
125
|
+
consider(m[1]);
|
|
126
|
+
const walk = (v) => {
|
|
127
|
+
if (typeof v === 'string')
|
|
128
|
+
consider(v);
|
|
129
|
+
else if (Array.isArray(v))
|
|
130
|
+
v.forEach(walk);
|
|
131
|
+
else if (v && typeof v === 'object')
|
|
132
|
+
Object.values(v).forEach(walk);
|
|
133
|
+
};
|
|
134
|
+
walk(front);
|
|
135
|
+
return refs;
|
|
136
|
+
}
|
|
137
|
+
/** Read one space folder. `kind` decides whether its files are pages or posts. */
|
|
138
|
+
function scanSpace(root, spec, kind, fieldKeys) {
|
|
139
|
+
const absDir = (0, node_path_1.resolve)(root, spec.path || '.');
|
|
140
|
+
const out = {
|
|
141
|
+
dir: spec.path || '',
|
|
142
|
+
absDir,
|
|
143
|
+
collections: [],
|
|
144
|
+
posts: [],
|
|
145
|
+
assets: new Set(),
|
|
146
|
+
warnings: [],
|
|
147
|
+
refs: new Map(),
|
|
148
|
+
slugByFile: new Map(),
|
|
149
|
+
};
|
|
150
|
+
if (!(0, node_fs_1.existsSync)(absDir) || !(0, node_fs_1.statSync)(absDir).isDirectory()) {
|
|
151
|
+
out.warnings.push(`${absDir} is not a folder`);
|
|
152
|
+
return out;
|
|
153
|
+
}
|
|
154
|
+
const read = (abs) => {
|
|
155
|
+
const text = (0, node_fs_1.readFileSync)(abs, 'utf8');
|
|
156
|
+
const rel = (0, node_path_1.relative)(absDir, abs).split(node_path_1.sep).join('/');
|
|
157
|
+
try {
|
|
158
|
+
const { data, body } = (0, frontmatter_1.splitFront)(text);
|
|
159
|
+
const refs = assetRefs(text, (0, node_path_1.dirname)(abs), data);
|
|
160
|
+
if (refs.size)
|
|
161
|
+
out.refs.set(rel, refs);
|
|
162
|
+
for (const a of refs.values())
|
|
163
|
+
out.assets.add(a);
|
|
164
|
+
return { rel, text, data, body };
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
throw new Error(`${rel}: ${e.message}`);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
if (kind === 'posts')
|
|
171
|
+
scanPosts(absDir, out, read);
|
|
172
|
+
else
|
|
173
|
+
scanDocs(absDir, spec, out, read, fieldKeys);
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
function scanPosts(absDir, out, read) {
|
|
177
|
+
const walk = (dir) => {
|
|
178
|
+
for (const e of (0, node_fs_1.readdirSync)(dir).sort()) {
|
|
179
|
+
if (skipEntry(e))
|
|
180
|
+
continue;
|
|
181
|
+
const abs = (0, node_path_1.join)(dir, e);
|
|
182
|
+
if ((0, node_fs_1.statSync)(abs).isDirectory()) {
|
|
183
|
+
walk(abs);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (!MD.test(e))
|
|
187
|
+
continue;
|
|
188
|
+
// A README at the top of a blog folder is a note about the folder.
|
|
189
|
+
if (dir === absDir && /^readme\./i.test(e)) {
|
|
190
|
+
out.warnings.push(`${e}: skipped — a README at the top of a posts folder is a note, not a post`);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const f = read(abs);
|
|
194
|
+
if ((0, frontmatter_1.isDraft)(f.data)) {
|
|
195
|
+
out.warnings.push(`${f.rel}: draft — left out`);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const stem = e.replace(MD, '');
|
|
199
|
+
const dated = DATED.exec(stem);
|
|
200
|
+
const front = { ...f.data };
|
|
201
|
+
if (dated && front.publishedAt === undefined && front.date === undefined)
|
|
202
|
+
front.publishedAt = dated[1];
|
|
203
|
+
if (front.date !== undefined && front.publishedAt === undefined)
|
|
204
|
+
front.publishedAt = front.date;
|
|
205
|
+
const slug = typeof f.data.slug === 'string' && f.data.slug.trim()
|
|
206
|
+
? slugify(f.data.slug)
|
|
207
|
+
: slugify(stem.replace(DATED, '').replace(NUMERIC, ''));
|
|
208
|
+
out.slugByFile.set(f.rel, slug);
|
|
209
|
+
out.posts.push({
|
|
210
|
+
file: f.rel,
|
|
211
|
+
slug,
|
|
212
|
+
title: titleOf(f.data, f.body, slug),
|
|
213
|
+
source: f.text,
|
|
214
|
+
body: f.body,
|
|
215
|
+
front,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
walk(absDir);
|
|
220
|
+
}
|
|
221
|
+
function scanDocs(absDir, spec, out, read, fieldKeys) {
|
|
222
|
+
const rootName = spec.rootCollection ?? '';
|
|
223
|
+
const rootFiles = [];
|
|
224
|
+
const folders = [];
|
|
225
|
+
for (const e of (0, node_fs_1.readdirSync)(absDir).sort()) {
|
|
226
|
+
if (skipEntry(e))
|
|
227
|
+
continue;
|
|
228
|
+
const abs = (0, node_path_1.join)(absDir, e);
|
|
229
|
+
if ((0, node_fs_1.statSync)(abs).isDirectory()) {
|
|
230
|
+
if (hasMarkdown(abs))
|
|
231
|
+
folders.push(e);
|
|
232
|
+
}
|
|
233
|
+
else if (MD.test(e))
|
|
234
|
+
rootFiles.push(e);
|
|
235
|
+
}
|
|
236
|
+
if (rootFiles.length) {
|
|
237
|
+
out.collections.push(collectionOf(absDir, '', rootName ? slugify(rootName) : '', rootName, [-1, ''], {}, out, read, fieldKeys, rootFiles));
|
|
238
|
+
}
|
|
239
|
+
for (const name of folders) {
|
|
240
|
+
const abs = (0, node_path_1.join)(absDir, name);
|
|
241
|
+
const declared = { ...folderMeta(abs), ...(spec.collections?.[name] ?? {}) };
|
|
242
|
+
const [n, key] = prefixOrder(name);
|
|
243
|
+
const order = [typeof declared.order === 'number' ? declared.order : n, key];
|
|
244
|
+
const slug = typeof declared.slug === 'string'
|
|
245
|
+
? slugify(declared.slug)
|
|
246
|
+
: slugify(name.replace(NUMERIC, ''));
|
|
247
|
+
const title = typeof declared.name === 'string' ? declared.name : titleize(name);
|
|
248
|
+
out.collections.push(collectionOf(abs, name, slug, title, order, (declared.nav ?? undefined), out, read, fieldKeys));
|
|
249
|
+
}
|
|
250
|
+
out.collections.sort((a, b) => a.order[0] - b.order[0] || a.order[1].localeCompare(b.order[1]));
|
|
251
|
+
}
|
|
252
|
+
function collectionOf(abs, dir, slug, name, order, nav, out, read, fieldKeys, onlyFiles) {
|
|
253
|
+
const col = { dir, slug, name, order, nav, pages: [] };
|
|
254
|
+
/**
|
|
255
|
+
* Walk one folder. `own` is the page that stands for this folder (its files
|
|
256
|
+
* nest under it; null at the collection's top) and `above` is the page that
|
|
257
|
+
* one nests under — which is where the folder's own index file hangs.
|
|
258
|
+
*/
|
|
259
|
+
const walk = (folder, rel, own, above) => {
|
|
260
|
+
const entries = (onlyFiles ?? (0, node_fs_1.readdirSync)(folder).sort()).filter((e) => !skipEntry(e));
|
|
261
|
+
const files = entries.filter((e) => MD.test(e) && !(0, node_fs_1.statSync)((0, node_path_1.join)(folder, e)).isDirectory());
|
|
262
|
+
const dirs = onlyFiles
|
|
263
|
+
? []
|
|
264
|
+
: entries.filter((e) => (0, node_fs_1.statSync)((0, node_path_1.join)(folder, e)).isDirectory() && hasMarkdown((0, node_path_1.join)(folder, e)));
|
|
265
|
+
const index = rel ? files.find(isIndex) : undefined;
|
|
266
|
+
for (const f of files) {
|
|
267
|
+
const parentSlug = f === index ? above : own;
|
|
268
|
+
const page = pageOf((0, node_path_1.join)(folder, f), rel ? `${rel}/${f}` : f, rel, f === index, parentSlug, slug, out, read, fieldKeys);
|
|
269
|
+
if (page)
|
|
270
|
+
col.pages.push(page);
|
|
271
|
+
}
|
|
272
|
+
for (const d of dirs) {
|
|
273
|
+
const sub = (0, node_path_1.join)(folder, d);
|
|
274
|
+
const subRel = rel ? `${rel}/${d}` : d;
|
|
275
|
+
const subFiles = (0, node_fs_1.readdirSync)(sub).filter((e) => !skipEntry(e) && MD.test(e));
|
|
276
|
+
const subIndex = subFiles.find(isIndex);
|
|
277
|
+
let folderSlug;
|
|
278
|
+
if (subIndex) {
|
|
279
|
+
// The index decides the folder page's address; read it once for that.
|
|
280
|
+
const { data } = (0, frontmatter_1.splitFront)((0, node_fs_1.readFileSync)((0, node_path_1.join)(sub, subIndex), 'utf8'));
|
|
281
|
+
folderSlug =
|
|
282
|
+
typeof data.slug === 'string' && data.slug.trim()
|
|
283
|
+
? slugify(data.slug)
|
|
284
|
+
: slugify(d.replace(NUMERIC, ''));
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
folderSlug = slugify(d.replace(NUMERIC, ''));
|
|
288
|
+
const title = titleize(d);
|
|
289
|
+
col.pages.push({
|
|
290
|
+
file: `${(0, node_path_1.relative)(out.absDir, sub).split(node_path_1.sep).join('/')}/ (no index.md)`,
|
|
291
|
+
importName: `${subRel}/index.md`,
|
|
292
|
+
slug: folderSlug,
|
|
293
|
+
parentSlug: own,
|
|
294
|
+
order: prefixOrder(d),
|
|
295
|
+
title,
|
|
296
|
+
source: `---\ntitle: ${JSON.stringify(title)}\nslug: ${folderSlug}\n---\n`,
|
|
297
|
+
body: '',
|
|
298
|
+
meta: {},
|
|
299
|
+
unknown: [],
|
|
300
|
+
stub: true,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
walk(sub, subRel, folderSlug, own);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
walk(abs, '', null, null);
|
|
307
|
+
return col;
|
|
308
|
+
}
|
|
309
|
+
function pageOf(abs, importName, rel, isFolderIndex, parentSlug, collectionSlug, out, read, fieldKeys) {
|
|
310
|
+
const f = read(abs);
|
|
311
|
+
if ((0, frontmatter_1.isDraft)(f.data)) {
|
|
312
|
+
out.warnings.push(`${f.rel}: draft — left out`);
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
const name = (0, node_path_1.basename)(abs);
|
|
316
|
+
const stem = name.replace(MD, '');
|
|
317
|
+
const declaredSlug = typeof f.data.slug === 'string' && f.data.slug.trim() ? slugify(f.data.slug) : '';
|
|
318
|
+
const folder = node_path_1.posix.basename(rel);
|
|
319
|
+
const atCollectionTop = isIndex(name) && !rel;
|
|
320
|
+
const slug = declaredSlug ||
|
|
321
|
+
(isFolderIndex
|
|
322
|
+
? slugify(folder.replace(NUMERIC, ''))
|
|
323
|
+
: atCollectionTop
|
|
324
|
+
? collectionSlug || slugify(titleOf(f.data, f.body, 'overview'))
|
|
325
|
+
: slugify(stem.replace(NUMERIC, '')));
|
|
326
|
+
const { meta, unknown } = (0, frontmatter_1.pageMeta)(f.data, fieldKeys);
|
|
327
|
+
const n = (0, frontmatter_1.declaredOrder)(f.data);
|
|
328
|
+
const [prefixN, key] = prefixOrder(isFolderIndex ? folder : stem);
|
|
329
|
+
// A folder's index is ordered among the folder's siblings, by the folder's
|
|
330
|
+
// prefix; a collection's own index leads it unless it says otherwise.
|
|
331
|
+
const order = [n ?? (atCollectionTop ? -1 : prefixN), key];
|
|
332
|
+
out.slugByFile.set(f.rel, slug);
|
|
333
|
+
return {
|
|
334
|
+
file: f.rel,
|
|
335
|
+
importName,
|
|
336
|
+
slug,
|
|
337
|
+
parentSlug,
|
|
338
|
+
order,
|
|
339
|
+
title: titleOf(f.data, f.body, slug),
|
|
340
|
+
source: f.text,
|
|
341
|
+
body: f.body,
|
|
342
|
+
meta,
|
|
343
|
+
unknown,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/** Every relative path → posix, for comparing with `importName`s. */
|
|
347
|
+
const toPosix = (p) => p.split(node_path_1.sep).join('/');
|
|
348
|
+
exports.toPosix = toPosix;
|
|
349
|
+
const extOf = (p) => (0, node_path_1.extname)(p).toLowerCase();
|
|
350
|
+
exports.extOf = extOf;
|
|
351
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/publish/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes `forumulate publish <folder>` works in.
|
|
3
|
+
*
|
|
4
|
+
* Three layers, kept apart on purpose: what is ON DISK (`Local*`), what is
|
|
5
|
+
* LIVE (`Live*`), and what would change (`Plan`). Every customer publisher we
|
|
6
|
+
* were shown (four of them, in three languages) mixed the first two — they
|
|
7
|
+
* wrote while they read — so a dry run was a different code path from the real
|
|
8
|
+
* one and drifted from it. Here a plan is computed from the two snapshots and
|
|
9
|
+
* nothing else, and the real run executes that same plan.
|
|
10
|
+
*/
|
|
11
|
+
/** A page's metadata patch, in the API's own field names (`PATCH …/metadata`). */
|
|
12
|
+
export type MetaPatch = Record<string, unknown>;
|
|
13
|
+
/** One Markdown file destined to be a docs page. */
|
|
14
|
+
export interface LocalPage {
|
|
15
|
+
/** Path relative to the publish root, for the plan a person reads. */
|
|
16
|
+
file: string;
|
|
17
|
+
/** Path relative to its collection folder — the name the import door is sent. */
|
|
18
|
+
importName: string;
|
|
19
|
+
/** Where the page lands. Declared in front matter or derived from the file name. */
|
|
20
|
+
slug: string;
|
|
21
|
+
/** The folder page this one nests under, by slug; null at the collection's top. */
|
|
22
|
+
parentSlug: string | null;
|
|
23
|
+
/** Sort key among siblings: declared `order`, a numeric prefix, else the name. */
|
|
24
|
+
order: [number, string];
|
|
25
|
+
/** Front matter title, else the leading `# heading`, else the slug. */
|
|
26
|
+
title: string;
|
|
27
|
+
/** The file exactly as written, with `slug:` declared and references rewritten later. */
|
|
28
|
+
source: string;
|
|
29
|
+
/** The body without front matter — what is compared. */
|
|
30
|
+
body: string;
|
|
31
|
+
/** Metadata the front matter declares, mapped to API field names. */
|
|
32
|
+
meta: MetaPatch;
|
|
33
|
+
/** Front matter keys nothing here understands — reported, never sent. */
|
|
34
|
+
unknown: string[];
|
|
35
|
+
/** Synthesised to stand for a folder that has no index file of its own. */
|
|
36
|
+
stub?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** One top-level folder of a docs space. */
|
|
39
|
+
export interface LocalCollection {
|
|
40
|
+
/** Folder name relative to the space folder; '' for files at the space root. */
|
|
41
|
+
dir: string;
|
|
42
|
+
slug: string;
|
|
43
|
+
name: string;
|
|
44
|
+
order: [number, string];
|
|
45
|
+
nav?: Record<string, unknown>;
|
|
46
|
+
pages: LocalPage[];
|
|
47
|
+
}
|
|
48
|
+
/** One Markdown file destined to be a post (blog, changelog, any non-docs type). */
|
|
49
|
+
export interface LocalPost {
|
|
50
|
+
file: string;
|
|
51
|
+
slug: string;
|
|
52
|
+
title: string;
|
|
53
|
+
source: string;
|
|
54
|
+
body: string;
|
|
55
|
+
/** Front matter as written (keys lower-cased only where the type declares them). */
|
|
56
|
+
front: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
/** Everything one space folder holds. */
|
|
59
|
+
export interface LocalSpace {
|
|
60
|
+
/** The space folder, relative to the publish root ('' = the root itself). */
|
|
61
|
+
dir: string;
|
|
62
|
+
absDir: string;
|
|
63
|
+
collections: LocalCollection[];
|
|
64
|
+
posts: LocalPost[];
|
|
65
|
+
/** Local files (images, PDFs) referenced from pages or posts, absolute paths. */
|
|
66
|
+
assets: Set<string>;
|
|
67
|
+
warnings: string[];
|
|
68
|
+
}
|
|
69
|
+
/** A space as the manifest describes it. */
|
|
70
|
+
export interface SpaceSpec {
|
|
71
|
+
/** Folder under the publish root. */
|
|
72
|
+
path: string;
|
|
73
|
+
/** Space id or slug. */
|
|
74
|
+
space?: string;
|
|
75
|
+
/** Create the space when it does not exist. */
|
|
76
|
+
create?: {
|
|
77
|
+
name?: string;
|
|
78
|
+
type?: string;
|
|
79
|
+
visibility?: 'PUBLIC' | 'PRIVATE';
|
|
80
|
+
};
|
|
81
|
+
name?: string;
|
|
82
|
+
visibility?: 'PUBLIC' | 'PRIVATE';
|
|
83
|
+
settings?: Record<string, unknown>;
|
|
84
|
+
theme?: Record<string, unknown>;
|
|
85
|
+
/** The collection files at the space root go into. */
|
|
86
|
+
rootCollection?: string;
|
|
87
|
+
/** Per-folder overrides: name, slug, order, nav. Keyed by folder name. */
|
|
88
|
+
collections?: Record<string, {
|
|
89
|
+
name?: string;
|
|
90
|
+
slug?: string;
|
|
91
|
+
order?: number;
|
|
92
|
+
nav?: Record<string, unknown>;
|
|
93
|
+
}>;
|
|
94
|
+
openapi?: OpenApiSpec[];
|
|
95
|
+
monitors?: Record<string, unknown>[];
|
|
96
|
+
/** Slugs (pages/posts) or collection slugs that `--prune` must never remove. */
|
|
97
|
+
keep?: string[];
|
|
98
|
+
}
|
|
99
|
+
export interface OpenApiSpec {
|
|
100
|
+
/** A file relative to the manifest, JSON or YAML. */
|
|
101
|
+
spec?: string;
|
|
102
|
+
/** Or a URL the API fetches itself. */
|
|
103
|
+
url?: string;
|
|
104
|
+
/** Collection name (found or created) the reference lands in. */
|
|
105
|
+
collection: string;
|
|
106
|
+
/** Everything else is passed to `POST …/docs/openapi/import` as written. */
|
|
107
|
+
[key: string]: unknown;
|
|
108
|
+
}
|
|
109
|
+
export interface SiteSpec {
|
|
110
|
+
id?: string;
|
|
111
|
+
slug?: string;
|
|
112
|
+
name?: string;
|
|
113
|
+
config?: Record<string, unknown>;
|
|
114
|
+
}
|
|
115
|
+
export interface Manifest {
|
|
116
|
+
/** Where the manifest was read from, or null when there is none. */
|
|
117
|
+
file: string | null;
|
|
118
|
+
org?: string;
|
|
119
|
+
site?: SiteSpec;
|
|
120
|
+
spaces: SpaceSpec[];
|
|
121
|
+
}
|
|
122
|
+
/** A live page, from `GET …/pages` (authenticated) or the public space (anonymous). */
|
|
123
|
+
export interface LivePage {
|
|
124
|
+
id: string;
|
|
125
|
+
slug: string;
|
|
126
|
+
title: string;
|
|
127
|
+
collectionId: string;
|
|
128
|
+
parentId: string | null;
|
|
129
|
+
sortKey: string;
|
|
130
|
+
published: boolean;
|
|
131
|
+
}
|
|
132
|
+
export interface LiveCollection {
|
|
133
|
+
id: string;
|
|
134
|
+
slug: string;
|
|
135
|
+
name: string;
|
|
136
|
+
isDefault: boolean;
|
|
137
|
+
sortKey: string;
|
|
138
|
+
nav?: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
export interface LivePost {
|
|
141
|
+
id: string;
|
|
142
|
+
slug: string;
|
|
143
|
+
title: string;
|
|
144
|
+
published: boolean;
|
|
145
|
+
markdown?: string;
|
|
146
|
+
sections?: Record<string, string>;
|
|
147
|
+
}
|
|
148
|
+
/** What a piece of the plan does — one line in the dry run, one or more calls in the real one. */
|
|
149
|
+
export type Verb = 'create' | 'update' | 'meta' | 'move' | 'order' | 'prune' | 'upload' | 'patch' | 'import' | 'same' | 'skip' | 'warn';
|
|
150
|
+
export interface PlanLine {
|
|
151
|
+
verb: Verb;
|
|
152
|
+
what: string;
|
|
153
|
+
detail?: string;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=types.d.ts.map
|