@aiquants/markdown-explorer 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/LICENSE +21 -0
- package/README.md +588 -2
- package/dist/ExplorerSplit-BESGFcu6.cjs +1 -0
- package/dist/ExplorerSplit-DwEFmvQM.js +1362 -0
- package/dist/MultiLayout-DxPiARsv.js +896 -0
- package/dist/MultiLayout-r_qx1Mfz.cjs +1 -0
- package/dist/TreeLayout-9-20bbSM.cjs +1 -0
- package/dist/TreeLayout-CW7lgV_e.js +19 -0
- package/dist/client/MarkdownExplorer.d.cts +30 -0
- package/dist/client/MarkdownExplorer.d.ts +30 -0
- package/dist/client/storage.d.cts +11 -0
- package/dist/client/storage.d.ts +11 -0
- package/dist/core/config.d.cts +71 -0
- package/dist/core/config.d.ts +71 -0
- package/dist/core/contracts.d.cts +155 -0
- package/dist/core/contracts.d.ts +155 -0
- package/dist/core/geometry.d.cts +51 -0
- package/dist/core/geometry.d.ts +51 -0
- package/dist/core/labels.d.cts +175 -0
- package/dist/core/labels.d.ts +175 -0
- package/dist/core/location.d.cts +82 -0
- package/dist/core/location.d.ts +82 -0
- package/dist/core/paths.d.cts +17 -0
- package/dist/core/paths.d.ts +17 -0
- package/dist/core/revalidation.d.cts +2 -0
- package/dist/core/revalidation.d.ts +2 -0
- package/dist/core/theme.d.cts +6 -0
- package/dist/core/theme.d.ts +6 -0
- package/dist/core/treeSettings.d.cts +48 -0
- package/dist/core/treeSettings.d.ts +48 -0
- package/dist/core/viewSettings.d.cts +15 -0
- package/dist/core/viewSettings.d.ts +15 -0
- package/dist/dataRoute-Bkfwfp1R.js +194 -0
- package/dist/dataRoute-CKbdwkQ7.cjs +1 -0
- package/dist/index-BgkZ9ATV.js +2061 -0
- package/dist/index-y9tVvDW7.cjs +3 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +44 -0
- package/dist/location-Cb2Ak55B.js +382 -0
- package/dist/location-DWHQYntR.cjs +1 -0
- package/dist/sanitizeWorker.cjs +1 -0
- package/dist/sanitizeWorker.js +291 -0
- package/dist/server/anonymous.d.cts +10 -0
- package/dist/server/anonymous.d.ts +10 -0
- package/dist/server/createMarkdownExplorer.d.cts +12 -0
- package/dist/server/createMarkdownExplorer.d.ts +12 -0
- package/dist/server/errors.d.cts +26 -0
- package/dist/server/errors.d.ts +26 -0
- package/dist/server/fileSystemSource.d.cts +38 -0
- package/dist/server/fileSystemSource.d.ts +38 -0
- package/dist/server/ports.d.cts +107 -0
- package/dist/server/ports.d.ts +107 -0
- package/dist/server/sanitizeProtocol.d.cts +17 -0
- package/dist/server/sanitizeProtocol.d.ts +17 -0
- package/dist/server/sanitizer.d.cts +51 -0
- package/dist/server/sanitizer.d.ts +51 -0
- package/dist/server/workerPool.d.cts +42 -0
- package/dist/server/workerPool.d.ts +42 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +7 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +1253 -0
- package/dist/storage-Bkb2Axdi.cjs +1 -0
- package/dist/storage-DA4ItHzl.js +60 -0
- package/dist/storage.cjs +1 -0
- package/dist/storage.d.cts +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +4 -0
- package/dist/styles/markdown-explorer.css +3 -0
- package/docs/behavior/dom-hooks.md +95 -0
- package/docs/behavior/layout.md +203 -0
- package/docs/behavior/localization.md +47 -0
- package/docs/behavior/security.md +134 -0
- package/docs/behavior/url-contract.md +129 -0
- package/package.json +141 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MarkdownExplorerLabels } from "./labels.cjs";
|
|
2
|
+
export type TreeSortMode = "native" | "asc" | "desc";
|
|
3
|
+
export type TreeDoubleClickAction = "recursive" | "toggle";
|
|
4
|
+
export type TreeSelectionMode = "single" | "multiple" | "none";
|
|
5
|
+
export type TreeSettings = {
|
|
6
|
+
readonly sortMode: TreeSortMode;
|
|
7
|
+
readonly directoriesFirst: boolean;
|
|
8
|
+
readonly selectionMode: TreeSelectionMode;
|
|
9
|
+
readonly doubleClickAction: TreeDoubleClickAction;
|
|
10
|
+
readonly expandIconSize: number;
|
|
11
|
+
readonly alwaysExpanded: boolean;
|
|
12
|
+
readonly removeRootIndent: boolean;
|
|
13
|
+
readonly lines: boolean;
|
|
14
|
+
readonly expandIcons: boolean;
|
|
15
|
+
readonly directoryIcons: boolean;
|
|
16
|
+
readonly fileIcons: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type TreeSettingKey = keyof TreeSettings;
|
|
19
|
+
export declare const DEFAULT_TREE_SETTINGS: TreeSettings;
|
|
20
|
+
type DescriptorFor<K extends TreeSettingKey> = {
|
|
21
|
+
readonly key: K;
|
|
22
|
+
readonly labelKey: keyof MarkdownExplorerLabels;
|
|
23
|
+
readonly values: readonly TreeSettings[K][];
|
|
24
|
+
readonly formatValue: (labels: MarkdownExplorerLabels, value: TreeSettings[K]) => string;
|
|
25
|
+
readonly requiresItemSelection: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type TreeSettingDescriptor = {
|
|
28
|
+
[K in TreeSettingKey]: DescriptorFor<K>;
|
|
29
|
+
}[TreeSettingKey];
|
|
30
|
+
export declare const TREE_SETTING_DESCRIPTORS: readonly TreeSettingDescriptor[];
|
|
31
|
+
export declare const visibleTreeSettingDescriptors: (enableItemSelection: boolean) => readonly TreeSettingDescriptor[];
|
|
32
|
+
export declare const advanceTreeSetting: (settings: TreeSettings, key: TreeSettingKey) => TreeSettings;
|
|
33
|
+
export declare const formatTreeSettingValue: (labels: MarkdownExplorerLabels, settings: TreeSettings, key: TreeSettingKey) => string;
|
|
34
|
+
export declare const TREE_SETTINGS_STORAGE_VERSION = 2;
|
|
35
|
+
export type TreeSettingChanges = Partial<TreeSettings>;
|
|
36
|
+
export declare const NO_TREE_SETTING_CHANGES: TreeSettingChanges;
|
|
37
|
+
export declare const readTreeSettingChanges: (stored: unknown) => TreeSettingChanges;
|
|
38
|
+
export declare const applyTreeSettingChanges: (defaults: TreeSettings, changes: TreeSettingChanges) => TreeSettings;
|
|
39
|
+
export declare const recordTreeSettingChange: <K extends TreeSettingKey>(changes: TreeSettingChanges, key: K, value: TreeSettings[K], defaults: TreeSettings) => TreeSettingChanges;
|
|
40
|
+
export declare const serializeTreeSettingChanges: (changes: TreeSettingChanges) => string;
|
|
41
|
+
export type SortableEntry = {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly path: string;
|
|
44
|
+
readonly type: "file" | "directory";
|
|
45
|
+
};
|
|
46
|
+
export type EntryComparator = (left: SortableEntry, right: SortableEntry) => number;
|
|
47
|
+
export declare const createEntryComparator: (settings: Pick<TreeSettings, "sortMode" | "directoriesFirst">) => EntryComparator | undefined;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MarkdownExplorerLabels } from "./labels.js";
|
|
2
|
+
export type TreeSortMode = "native" | "asc" | "desc";
|
|
3
|
+
export type TreeDoubleClickAction = "recursive" | "toggle";
|
|
4
|
+
export type TreeSelectionMode = "single" | "multiple" | "none";
|
|
5
|
+
export type TreeSettings = {
|
|
6
|
+
readonly sortMode: TreeSortMode;
|
|
7
|
+
readonly directoriesFirst: boolean;
|
|
8
|
+
readonly selectionMode: TreeSelectionMode;
|
|
9
|
+
readonly doubleClickAction: TreeDoubleClickAction;
|
|
10
|
+
readonly expandIconSize: number;
|
|
11
|
+
readonly alwaysExpanded: boolean;
|
|
12
|
+
readonly removeRootIndent: boolean;
|
|
13
|
+
readonly lines: boolean;
|
|
14
|
+
readonly expandIcons: boolean;
|
|
15
|
+
readonly directoryIcons: boolean;
|
|
16
|
+
readonly fileIcons: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type TreeSettingKey = keyof TreeSettings;
|
|
19
|
+
export declare const DEFAULT_TREE_SETTINGS: TreeSettings;
|
|
20
|
+
type DescriptorFor<K extends TreeSettingKey> = {
|
|
21
|
+
readonly key: K;
|
|
22
|
+
readonly labelKey: keyof MarkdownExplorerLabels;
|
|
23
|
+
readonly values: readonly TreeSettings[K][];
|
|
24
|
+
readonly formatValue: (labels: MarkdownExplorerLabels, value: TreeSettings[K]) => string;
|
|
25
|
+
readonly requiresItemSelection: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type TreeSettingDescriptor = {
|
|
28
|
+
[K in TreeSettingKey]: DescriptorFor<K>;
|
|
29
|
+
}[TreeSettingKey];
|
|
30
|
+
export declare const TREE_SETTING_DESCRIPTORS: readonly TreeSettingDescriptor[];
|
|
31
|
+
export declare const visibleTreeSettingDescriptors: (enableItemSelection: boolean) => readonly TreeSettingDescriptor[];
|
|
32
|
+
export declare const advanceTreeSetting: (settings: TreeSettings, key: TreeSettingKey) => TreeSettings;
|
|
33
|
+
export declare const formatTreeSettingValue: (labels: MarkdownExplorerLabels, settings: TreeSettings, key: TreeSettingKey) => string;
|
|
34
|
+
export declare const TREE_SETTINGS_STORAGE_VERSION = 2;
|
|
35
|
+
export type TreeSettingChanges = Partial<TreeSettings>;
|
|
36
|
+
export declare const NO_TREE_SETTING_CHANGES: TreeSettingChanges;
|
|
37
|
+
export declare const readTreeSettingChanges: (stored: unknown) => TreeSettingChanges;
|
|
38
|
+
export declare const applyTreeSettingChanges: (defaults: TreeSettings, changes: TreeSettingChanges) => TreeSettings;
|
|
39
|
+
export declare const recordTreeSettingChange: <K extends TreeSettingKey>(changes: TreeSettingChanges, key: K, value: TreeSettings[K], defaults: TreeSettings) => TreeSettingChanges;
|
|
40
|
+
export declare const serializeTreeSettingChanges: (changes: TreeSettingChanges) => string;
|
|
41
|
+
export type SortableEntry = {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly path: string;
|
|
44
|
+
readonly type: "file" | "directory";
|
|
45
|
+
};
|
|
46
|
+
export type EntryComparator = (left: SortableEntry, right: SortableEntry) => number;
|
|
47
|
+
export declare const createEntryComparator: (settings: Pick<TreeSettings, "sortMode" | "directoriesFirst">) => EntryComparator | undefined;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ContentAlign } from "@aiquants/markdown/viewer-settings";
|
|
2
|
+
export type ContentAlignment = ContentAlign;
|
|
3
|
+
export type ExplorerViewSettings = {
|
|
4
|
+
readonly treeExplorer?: number;
|
|
5
|
+
readonly multiExplorer?: number;
|
|
6
|
+
readonly style?: string;
|
|
7
|
+
readonly align?: ContentAlignment;
|
|
8
|
+
};
|
|
9
|
+
export declare const VIEW_SETTINGS_MAX_AGE_SECONDS = 31536000;
|
|
10
|
+
export declare const assertCookieName: (name: unknown) => void;
|
|
11
|
+
export declare const normalizeViewSettings: (value: unknown, styleNames: readonly string[]) => ExplorerViewSettings;
|
|
12
|
+
export declare const readCookieValue: (header: string | null, name: string) => string | undefined;
|
|
13
|
+
export declare const parseViewSettings: (raw: string | undefined, styleNames: readonly string[]) => ExplorerViewSettings;
|
|
14
|
+
export declare const serializeViewSettings: (settings: ExplorerViewSettings) => string;
|
|
15
|
+
export declare const viewSettingsCookieString: (name: string, settings: ExplorerViewSettings, isSecureContext: boolean) => string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ContentAlign } from "@aiquants/markdown/viewer-settings";
|
|
2
|
+
export type ContentAlignment = ContentAlign;
|
|
3
|
+
export type ExplorerViewSettings = {
|
|
4
|
+
readonly treeExplorer?: number;
|
|
5
|
+
readonly multiExplorer?: number;
|
|
6
|
+
readonly style?: string;
|
|
7
|
+
readonly align?: ContentAlignment;
|
|
8
|
+
};
|
|
9
|
+
export declare const VIEW_SETTINGS_MAX_AGE_SECONDS = 31536000;
|
|
10
|
+
export declare const assertCookieName: (name: unknown) => void;
|
|
11
|
+
export declare const normalizeViewSettings: (value: unknown, styleNames: readonly string[]) => ExplorerViewSettings;
|
|
12
|
+
export declare const readCookieValue: (header: string | null, name: string) => string | undefined;
|
|
13
|
+
export declare const parseViewSettings: (raw: string | undefined, styleNames: readonly string[]) => ExplorerViewSettings;
|
|
14
|
+
export declare const serializeViewSettings: (settings: ExplorerViewSettings) => string;
|
|
15
|
+
export declare const viewSettingsCookieString: (name: string, settings: ExplorerViewSettings, isSecureContext: boolean) => string;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
const q = 4096;
|
|
2
|
+
const _ = Object.freeze([
|
|
3
|
+
".env*",
|
|
4
|
+
"*.env",
|
|
5
|
+
"*.env.*",
|
|
6
|
+
"*.env~*",
|
|
7
|
+
"*.env-*",
|
|
8
|
+
"*.env_*",
|
|
9
|
+
"*.env#*",
|
|
10
|
+
".git",
|
|
11
|
+
".git-credentials",
|
|
12
|
+
".svn",
|
|
13
|
+
".hg",
|
|
14
|
+
"node_modules",
|
|
15
|
+
"secrets",
|
|
16
|
+
".secrets",
|
|
17
|
+
"secrets.json",
|
|
18
|
+
"secrets.yml",
|
|
19
|
+
"secrets.yaml",
|
|
20
|
+
"secrets.toml",
|
|
21
|
+
"secrets.ini",
|
|
22
|
+
"secrets.txt",
|
|
23
|
+
".ssh",
|
|
24
|
+
".aws",
|
|
25
|
+
".gnupg",
|
|
26
|
+
".docker",
|
|
27
|
+
".kube",
|
|
28
|
+
".terraform",
|
|
29
|
+
".npmrc",
|
|
30
|
+
".yarnrc",
|
|
31
|
+
".yarnrc.yml",
|
|
32
|
+
".netrc",
|
|
33
|
+
"_netrc",
|
|
34
|
+
".pypirc",
|
|
35
|
+
".pgpass",
|
|
36
|
+
".my.cnf",
|
|
37
|
+
".htpasswd",
|
|
38
|
+
".vault-token",
|
|
39
|
+
"id_rsa*",
|
|
40
|
+
"id_dsa*",
|
|
41
|
+
"id_ecdsa*",
|
|
42
|
+
"id_ed25519*",
|
|
43
|
+
"*.pem",
|
|
44
|
+
"*.key",
|
|
45
|
+
"*.p8",
|
|
46
|
+
"*.p12",
|
|
47
|
+
"*.pfx",
|
|
48
|
+
"*.ppk",
|
|
49
|
+
"*.jks",
|
|
50
|
+
"*.keystore",
|
|
51
|
+
"*.kdbx",
|
|
52
|
+
"*credentials*.json",
|
|
53
|
+
"service-account*.json",
|
|
54
|
+
"*.tfstate",
|
|
55
|
+
"*.tfstate.*",
|
|
56
|
+
"*.tfvars",
|
|
57
|
+
"*.tfvars.json",
|
|
58
|
+
".*_history",
|
|
59
|
+
"fish_history"
|
|
60
|
+
]), h = /[\u0000-\u001f\u007f]/u, O = /\p{Cs}/u, B = (e) => {
|
|
61
|
+
const t = e.split("/").filter((n) => n !== "").at(-1);
|
|
62
|
+
return t === void 0 ? e : t;
|
|
63
|
+
}, A = (e) => e.length > 0 && e.length <= 4096 && !O.test(e) && !h.test(e) && !e.includes("\\"), p = (e) => e.normalize("NFKC").toUpperCase().toLowerCase(), b = /(?:%[0-9A-Fa-f]{2})+/gu, T = new TextDecoder("utf-8"), L = /[/\\]/u, P = (e) => e.replace(
|
|
64
|
+
b,
|
|
65
|
+
(t) => T.decode(
|
|
66
|
+
Uint8Array.from(
|
|
67
|
+
t.slice(1).split("%").map((n) => Number.parseInt(n, 16))
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
), S = (e) => {
|
|
71
|
+
const t = [e];
|
|
72
|
+
let n = e;
|
|
73
|
+
for (let r = 0; r < 3 && n.includes("%"); r += 1) {
|
|
74
|
+
const s = P(n);
|
|
75
|
+
if (s === n) break;
|
|
76
|
+
t.push(s), n = s;
|
|
77
|
+
}
|
|
78
|
+
return t.map(p);
|
|
79
|
+
}, x = (e) => {
|
|
80
|
+
if (typeof e != "string" || e.trim() === "" || e.includes("/") || e.includes("\\"))
|
|
81
|
+
throw new RangeError(`[markdown-explorer] a deny pattern must be one non-blank path segment; got ${JSON.stringify(e)}`);
|
|
82
|
+
const t = p(e).split("*").map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
83
|
+
return new RegExp(`^${t}$`, "su");
|
|
84
|
+
}, u = (e) => {
|
|
85
|
+
if (!Array.isArray(e)) throw new RangeError("[markdown-explorer] deny rules must be an array of segment patterns");
|
|
86
|
+
const t = e.map(x), n = (s) => s !== "" && t.some((o) => o.test(s)), r = (s) => s !== "" && S(s).some((o) => n(o) || o.split(L).some(n));
|
|
87
|
+
return {
|
|
88
|
+
deniesPath: (s) => s.split("/").some(r),
|
|
89
|
+
deniesName: r
|
|
90
|
+
};
|
|
91
|
+
}, D = u(_), N = Object.freeze({ deniesPath: () => !1, deniesName: () => !1 }), Q = (e) => e === void 0 ? D : e === !1 ? N : u(e), W = (e, t) => u(e).deniesPath(t), m = Object.freeze(["unauthorized", "forbidden", "not-found", "not-configured", "invalid", "too-large", "unsupported", "failed"]), j = Object.freeze(["file", "directory"]), k = Object.freeze(["video", "audio", "pdf"]), C = Object.freeze(["info", "warning", "danger"]), w = Object.freeze(["markdown", "text", "image", "media", "file", "failure"]), d = Object.freeze({ min: 1, max: 6 }), Z = 1e4, l = (e) => typeof e == "string" && /^\/(?![/\\])[\x21-\x7E]*$/u.test(e), ee = Object.freeze(["http:", "https:", "mailto:"]), U = /^[a-z0-9-]{1,64}$/u, v = "https://relative.invalid/", f = 64, c = (e, t) => typeof t == "string" && e.includes(t), a = (e) => typeof e == "string" ? JSON.stringify(e.length > f ? `${e.slice(0, f)}…` : e) : typeof e, z = (e) => c(m, e), $ = (e) => c(j, e), H = (e) => c(k, e), te = (e) => c(C, e), X = (e) => c(w, e), y = (e) => typeof e == "string" && U.test(e), ne = (e, t) => {
|
|
92
|
+
if (typeof e != "string") return !1;
|
|
93
|
+
try {
|
|
94
|
+
return t.includes(new URL(e, v).protocol);
|
|
95
|
+
} catch {
|
|
96
|
+
return !1;
|
|
97
|
+
}
|
|
98
|
+
}, R = (e) => {
|
|
99
|
+
if (e === null || typeof e != "object") return "a failure must be an object";
|
|
100
|
+
const { reason: t, code: n } = e;
|
|
101
|
+
return z(t) ? n !== void 0 && !y(n) ? `a failure code must be 1 to 64 lowercase letters, digits or hyphens; got ${a(n)}` : null : `unknown failure reason ${a(t)}`;
|
|
102
|
+
}, I = (e) => {
|
|
103
|
+
if (e === null || typeof e != "object") return "an entry must be an object";
|
|
104
|
+
const { name: t, path: n, type: r, mimeType: s, children: o, lazy: i } = e;
|
|
105
|
+
return typeof t != "string" || t === "" ? "an entry needs a non-empty name" : typeof n != "string" || !A(n) ? "an entry needs an acceptable path" : $(r) ? s !== void 0 && typeof s != "string" ? "an entry mimeType must be a string" : i !== void 0 && typeof i != "boolean" ? "an entry lazy flag must be a boolean" : o !== void 0 && !Array.isArray(o) ? "entry children must be an array" : r === "file" && (o !== void 0 || i === !0) ? "a file entry cannot have children or be lazy" : i === !0 && Array.isArray(o) && o.length > 0 ? "a lazy directory must not list children" : null : `an entry type must be "file" or "directory"; got ${a(r)}`;
|
|
106
|
+
}, g = (e) => {
|
|
107
|
+
if (I(e) !== null) return !1;
|
|
108
|
+
const { children: t } = e;
|
|
109
|
+
return t === void 0 || t.every(g);
|
|
110
|
+
}, F = (e) => {
|
|
111
|
+
if (e === null || typeof e != "object") return !1;
|
|
112
|
+
const { status: t, entries: n, failure: r } = e;
|
|
113
|
+
return t === "ok" ? Array.isArray(n) && n.every(g) : t === "error" && R(r) === null;
|
|
114
|
+
}, re = (e) => {
|
|
115
|
+
if (e === null || typeof e != "object") return !1;
|
|
116
|
+
const { status: t, loadedAt: n } = e;
|
|
117
|
+
return t === "ok" && !(Number.isSafeInteger(n) && n >= 0) ? !1 : F(e);
|
|
118
|
+
}, M = (e) => {
|
|
119
|
+
if (e === null || typeof e != "object") return "a heading must be an object";
|
|
120
|
+
const { text: t, depth: n, id: r } = e;
|
|
121
|
+
return typeof t != "string" || typeof r != "string" ? "a heading needs text and id strings" : typeof n != "number" || !Number.isInteger(n) || n < d.min || n > d.max ? `a heading depth must be an integer in 1..6; got ${String(n)}` : null;
|
|
122
|
+
}, V = (e) => {
|
|
123
|
+
if (e === null || typeof e != "object") return "a document must be an object";
|
|
124
|
+
const t = e, { kind: n } = t;
|
|
125
|
+
if (!X(n)) return `unknown document kind ${a(n)}`;
|
|
126
|
+
if (n === "failure") return R(t.failure);
|
|
127
|
+
if (typeof t.name != "string") return "a document needs a name string";
|
|
128
|
+
switch (n) {
|
|
129
|
+
case "markdown": {
|
|
130
|
+
const { htmlContent: r, headings: s } = t;
|
|
131
|
+
if (typeof r != "string" || !Array.isArray(s)) return "a markdown document needs htmlContent and headings";
|
|
132
|
+
for (const o of s) {
|
|
133
|
+
const i = M(o);
|
|
134
|
+
if (i !== null) return i;
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
case "text":
|
|
139
|
+
return typeof t.text != "string" || typeof t.truncated != "boolean" ? "a text document needs text and truncated" : l(t.url) ? null : "a text document needs a root-relative url";
|
|
140
|
+
case "image":
|
|
141
|
+
return l(t.url) ? null : "an image document needs a root-relative url";
|
|
142
|
+
case "media":
|
|
143
|
+
return l(t.url) ? H(t.mediaType) ? null : `unknown media type ${a(t.mediaType)}` : "a media document needs a root-relative url";
|
|
144
|
+
case "file":
|
|
145
|
+
return l(t.url) ? null : "a file document needs a root-relative url";
|
|
146
|
+
}
|
|
147
|
+
}, se = (e) => V(e) === null, oe = (e, t) => ({ kind: "failure", failure: G(e, t) }), G = (e, t) => y(t) ? { reason: e, code: t } : { reason: e }, Y = Object.freeze(["tree", "children", "document", "refresh", "asset"]), E = Object.freeze({ source: "source", path: "path", version: "v" }), K = "asset", ie = (e, t, n) => {
|
|
148
|
+
const r = `${e}/${K}?${E.path}=${encodeURIComponent(t)}`;
|
|
149
|
+
return n === null ? r : `${r}&${E.version}=${encodeURIComponent(n)}`;
|
|
150
|
+
}, ae = "X-Markdown-Explorer-Scope", ce = "X-Markdown-Explorer", le = "refresh", ue = (e) => Y.includes(e), J = Object.freeze({
|
|
151
|
+
invalid: 400,
|
|
152
|
+
unauthorized: 401,
|
|
153
|
+
forbidden: 403,
|
|
154
|
+
"not-found": 404,
|
|
155
|
+
"too-large": 413,
|
|
156
|
+
"not-configured": 500,
|
|
157
|
+
unsupported: 500,
|
|
158
|
+
failed: 500
|
|
159
|
+
}), de = (e) => {
|
|
160
|
+
const [t, ...n] = m.filter((r) => J[r] === e);
|
|
161
|
+
return t !== void 0 && n.length === 0 ? t : "failed";
|
|
162
|
+
};
|
|
163
|
+
export {
|
|
164
|
+
m as A,
|
|
165
|
+
_ as D,
|
|
166
|
+
Z as E,
|
|
167
|
+
q as M,
|
|
168
|
+
z as a,
|
|
169
|
+
y as b,
|
|
170
|
+
te as c,
|
|
171
|
+
ne as d,
|
|
172
|
+
ie as e,
|
|
173
|
+
G as f,
|
|
174
|
+
H as g,
|
|
175
|
+
V as h,
|
|
176
|
+
A as i,
|
|
177
|
+
I as j,
|
|
178
|
+
ee as k,
|
|
179
|
+
ue as l,
|
|
180
|
+
J as m,
|
|
181
|
+
ce as n,
|
|
182
|
+
le as o,
|
|
183
|
+
ae as p,
|
|
184
|
+
E as q,
|
|
185
|
+
Q as r,
|
|
186
|
+
oe as s,
|
|
187
|
+
W as t,
|
|
188
|
+
B as u,
|
|
189
|
+
de as v,
|
|
190
|
+
F as w,
|
|
191
|
+
R as x,
|
|
192
|
+
re as y,
|
|
193
|
+
se as z
|
|
194
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const _=Object.freeze([".env*","*.env","*.env.*","*.env~*","*.env-*","*.env_*","*.env#*",".git",".git-credentials",".svn",".hg","node_modules","secrets",".secrets","secrets.json","secrets.yml","secrets.yaml","secrets.toml","secrets.ini","secrets.txt",".ssh",".aws",".gnupg",".docker",".kube",".terraform",".npmrc",".yarnrc",".yarnrc.yml",".netrc","_netrc",".pypirc",".pgpass",".my.cnf",".htpasswd",".vault-token","id_rsa*","id_dsa*","id_ecdsa*","id_ed25519*","*.pem","*.key","*.p8","*.p12","*.pfx","*.ppk","*.jks","*.keystore","*.kdbx","*credentials*.json","service-account*.json","*.tfstate","*.tfstate.*","*.tfvars","*.tfvars.json",".*_history","fish_history"]),D=/[\u0000-\u001f\u007f]/u,N=/\p{Cs}/u,x=e=>{const t=e.split("/").filter(n=>n!=="").at(-1);return t===void 0?e:t},y=e=>e.length>0&&e.length<=4096&&!N.test(e)&&!D.test(e)&&!e.includes("\\"),O=e=>e.normalize("NFKC").toUpperCase().toLowerCase(),C=/(?:%[0-9A-Fa-f]{2})+/gu,U=new TextDecoder("utf-8"),H=/[/\\]/u,X=e=>e.replace(C,t=>U.decode(Uint8Array.from(t.slice(1).split("%").map(n=>Number.parseInt(n,16))))),j=e=>{const t=[e];let n=e;for(let r=0;r<3&&n.includes("%");r+=1){const o=X(n);if(o===n)break;t.push(o),n=o}return t.map(O)},k=e=>{if(typeof e!="string"||e.trim()===""||e.includes("/")||e.includes("\\"))throw new RangeError(`[markdown-explorer] a deny pattern must be one non-blank path segment; got ${JSON.stringify(e)}`);const t=O(e).split("*").map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${t}$`,"su")},E=e=>{if(!Array.isArray(e))throw new RangeError("[markdown-explorer] deny rules must be an array of segment patterns");const t=e.map(k),n=o=>o!==""&&t.some(s=>s.test(o)),r=o=>o!==""&&j(o).some(s=>n(s)||s.split(H).some(n));return{deniesPath:o=>o.split("/").some(r),deniesName:r}},w=E(_),I=Object.freeze({deniesPath:()=>!1,deniesName:()=>!1}),v=e=>e===void 0?w:e===!1?I:E(e),$=(e,t)=>E(e).deniesPath(t),d=Object.freeze(["unauthorized","forbidden","not-found","not-configured","invalid","too-large","unsupported","failed"]),z=Object.freeze(["file","directory"]),F=Object.freeze(["video","audio","pdf"]),M=Object.freeze(["info","warning","danger"]),V=Object.freeze(["markdown","text","image","media","file","failure"]),R=Object.freeze({min:1,max:6}),G=1e4,l=e=>typeof e=="string"&&/^\/(?![/\\])[\x21-\x7E]*$/u.test(e),Y=Object.freeze(["http:","https:","mailto:"]),K=/^[a-z0-9-]{1,64}$/u,J="https://relative.invalid/",m=64,c=(e,t)=>typeof t=="string"&&e.includes(t),a=e=>typeof e=="string"?JSON.stringify(e.length>m?`${e.slice(0,m)}…`:e):typeof e,A=e=>c(d,e),Q=e=>c(z,e),g=e=>c(F,e),B=e=>c(M,e),W=e=>c(V,e),f=e=>typeof e=="string"&&K.test(e),q=(e,t)=>{if(typeof e!="string")return!1;try{return t.includes(new URL(e,J).protocol)}catch{return!1}},p=e=>{if(e===null||typeof e!="object")return"a failure must be an object";const{reason:t,code:n}=e;return A(t)?n!==void 0&&!f(n)?`a failure code must be 1 to 64 lowercase letters, digits or hyphens; got ${a(n)}`:null:`unknown failure reason ${a(t)}`},h=e=>{if(e===null||typeof e!="object")return"an entry must be an object";const{name:t,path:n,type:r,mimeType:o,children:s,lazy:i}=e;return typeof t!="string"||t===""?"an entry needs a non-empty name":typeof n!="string"||!y(n)?"an entry needs an acceptable path":Q(r)?o!==void 0&&typeof o!="string"?"an entry mimeType must be a string":i!==void 0&&typeof i!="boolean"?"an entry lazy flag must be a boolean":s!==void 0&&!Array.isArray(s)?"entry children must be an array":r==="file"&&(s!==void 0||i===!0)?"a file entry cannot have children or be lazy":i===!0&&Array.isArray(s)&&s.length>0?"a lazy directory must not list children":null:`an entry type must be "file" or "directory"; got ${a(r)}`},T=e=>{if(h(e)!==null)return!1;const{children:t}=e;return t===void 0||t.every(T)},P=e=>{if(e===null||typeof e!="object")return!1;const{status:t,entries:n,failure:r}=e;return t==="ok"?Array.isArray(n)&&n.every(T):t==="error"&&p(r)===null},Z=e=>{if(e===null||typeof e!="object")return!1;const{status:t,loadedAt:n}=e;return t==="ok"&&!(Number.isSafeInteger(n)&&n>=0)?!1:P(e)},ee=e=>{if(e===null||typeof e!="object")return"a heading must be an object";const{text:t,depth:n,id:r}=e;return typeof t!="string"||typeof r!="string"?"a heading needs text and id strings":typeof n!="number"||!Number.isInteger(n)||n<R.min||n>R.max?`a heading depth must be an integer in 1..6; got ${String(n)}`:null},L=e=>{if(e===null||typeof e!="object")return"a document must be an object";const t=e,{kind:n}=t;if(!W(n))return`unknown document kind ${a(n)}`;if(n==="failure")return p(t.failure);if(typeof t.name!="string")return"a document needs a name string";switch(n){case"markdown":{const{htmlContent:r,headings:o}=t;if(typeof r!="string"||!Array.isArray(o))return"a markdown document needs htmlContent and headings";for(const s of o){const i=ee(s);if(i!==null)return i}return null}case"text":return typeof t.text!="string"||typeof t.truncated!="boolean"?"a text document needs text and truncated":l(t.url)?null:"a text document needs a root-relative url";case"image":return l(t.url)?null:"an image document needs a root-relative url";case"media":return l(t.url)?g(t.mediaType)?null:`unknown media type ${a(t.mediaType)}`:"a media document needs a root-relative url";case"file":return l(t.url)?null:"a file document needs a root-relative url"}},te=e=>L(e)===null,ne=(e,t)=>({kind:"failure",failure:b(e,t)}),b=(e,t)=>f(t)?{reason:e,code:t}:{reason:e},re=Object.freeze(["tree","children","document","refresh","asset"]),u=Object.freeze({source:"source",path:"path",version:"v"}),oe="asset",se=(e,t,n)=>{const r=`${e}/${oe}?${u.path}=${encodeURIComponent(t)}`;return n===null?r:`${r}&${u.version}=${encodeURIComponent(n)}`},ie="X-Markdown-Explorer-Scope",ae="X-Markdown-Explorer",ce="refresh",le=e=>re.includes(e),S=Object.freeze({invalid:400,unauthorized:401,forbidden:403,"not-found":404,"too-large":413,"not-configured":500,unsupported:500,failed:500}),ue=e=>{const[t,...n]=d.filter(r=>S[r]===e);return t!==void 0&&n.length===0?t:"failed"};exports.DEFAULT_DENIED_PATH_SEGMENTS=_;exports.EXPLORER_DATA_QUERY=u;exports.EXPLORER_FAILURE_REASONS=d;exports.EXPLORER_FAILURE_STATUS=S;exports.EXPLORER_LINK_PROTOCOLS=Y;exports.EXPLORER_MAX_HEADINGS=G;exports.EXPLORER_REFRESH_HEADER=ae;exports.EXPLORER_REFRESH_HEADER_VALUE=ce;exports.EXPLORER_SCOPE_HEADER=ie;exports.MAX_DOCUMENT_PATH_LENGTH=4096;exports.documentViolation=L;exports.entryViolation=h;exports.explorerAssetHref=se;exports.failureDocument=ne;exports.failureOf=b;exports.failureReasonOfStatus=ue;exports.failureViolation=p;exports.isAcceptableDocumentPath=y;exports.isAcceptableUrl=q;exports.isDeniedPath=$;exports.isExplorerChildrenResult=P;exports.isExplorerDataOperation=le;exports.isExplorerDocument=te;exports.isExplorerFailureCode=f;exports.isExplorerFailureReason=A;exports.isExplorerMediaType=g;exports.isExplorerNoticeTone=B;exports.isExplorerTreeResult=Z;exports.lastPathSegment=x;exports.resolvePathRules=v;
|